下面是Indy控件中有关的原代码,请各位高手帮忙分析一下,看有没有修改的可能。
procedure TIdMessage.LoadFromFile(const AFileName: string; const AHeadersOnly: Boolean = False);
var
vStream: TFileStream;
begin
if (not FileExists(AFilename)) then
begin
raise EIdMessageCannotLoad.CreateFmt(RSIdMessageCannotLoad, [AFilename]);
end;
vStream := TFileStream.Create(AFilename, fmOpenRead and fmShareDenyWrite);
try
LoadFromStream(vStream, AHeadersOnly);
finally
vStream.Free;
end;
end;
procedure TIdMessage.LoadFromStream(AStream: TStream; const AHeadersOnly: Boolean = False);
var
vMsgClient : TIdMessageClient;
begin
// clear message properties, headers before loading
Clear;
vMsgClient := TIdMessageClient.Create(nil);
try
vMsgClient.ProcessMessage(Self, AStream, AHeadersOnly);
finally
FreeAndNil(vMsgClient);
end;
end;
procedure TIdMessageclient.ProcessMessage(AMsg: TIdMessage; AHeaderOnly: Boolean = False);
begin
if IOHandler <> nil then
begin
ReceiveHeader(AMsg);
if (not AHeaderOnly) then
begin
ReceiveBody(AMsg);
end;
end;
end;
function TIdMessageClient.ReceiveHeader(AMsg: TIdMessage; const AAltTerm: string = ''): string;
begin
BeginWork(wmRead); try
repeat
Result := ReadLn;
// Exchange Bug: Exchange sometimes returns . when getting a message instead of
// '' then a . - That is there is no seperation between the header and the message for an
// empty message.
if ((Length(AAltTerm) = 0) and (Result = '.')) or
({APR: why? (Length(AAltTerm) > 0) and }(Result = AAltTerm)) then begin
Break;
end else if Result <> '' then begin
AMsg.Headers.Append(Result);
end;
until False;
AMsg.ProcessHeaders;
finally EndWork(wmRead); end;
end;
procedure TIdMessageClient.ReceiveBody(AMsg: TIdMessage; const ADelim: string = '.');
var
LMsgEnd: Boolean;
LActiveDecoder: TIdMessageDecoder;
LLine: string;
function ProcessTextPart(ADecoder: TIdMessageDecoder): TIdMessageDecoder;
var
LDestStream: TStringStream;
begin
LDestStream := TStringStream.Create('');
try
Result := ADecoder.ReadBody(LDestStream, LMsgEnd);
with TIdText.Create(AMsg.MessageParts) do
begin
ContentType := ADecoder.Headers.Values['Content-Type'];
ContentTransfer := ADecoder.Headers.Values['Content-Transfer-Encoding'];
Body.Text := LDestStream.DataString;
end;
ADecoder.Free;
finally
FreeAndNil(LDestStream);
end;
end;
function ProcessAttachment(ADecoder: TIdMessageDecoder): TIdMessageDecoder;
var
LDestStream: TFileStream;
LTempPathname: string;
begin
LTempPathname := MakeTempFilename;
LDestStream := TFileStream.Create(LTempPathname, fmCreate);
try
Result := ADecoder.ReadBody(LDestStream, LMsgEnd);
with TIdAttachment.Create(AMsg.MessageParts) do
begin
ContentType := ADecoder.Headers.Values['Content-Type'];
ContentTransfer := ADecoder.Headers.Values['Content-Transfer-Encoding'];
// dsiders 2001.12.01
ContentDisposition := ADecoder.Headers.Values['Content-Disposition'];
Filename := ADecoder.Filename;
StoredPathname := LTempPathname;
end;
ADecoder.Free;
finally
FreeAndNil(LDestStream);
end;
end;
const
wDoublePoint = ord('.') shl 8 + ord('.');
Begin
LMsgEnd := False;
if AMsg.NoDecode then
begin
Capture(AMsg.Body, ADelim);
end
else begin
BeginWork(wmRead);
try
LActiveDecoder := nil;
repeat
LLine := ReadLn;
if LLine = ADelim then
begin
Break;
end;
if LActiveDecoder = nil then
begin
LActiveDecoder := TIdMessageDecoderList.CheckForStart(AMsg, LLine);
end;
if LActiveDecoder = nil then begin
if PWord(PChar(LLine))^= wDoublePoint then begin
Delete(LLine,1,1);
end;//if '..'
AMsg.Body.Add(LLine);
end else begin
while LActiveDecoder <> nil do begin
LActiveDecoder.SourceStream := TIdTCPStream.Create(Self);
LActiveDecoder.ReadHeader;
case LActiveDecoder.PartType of
mcptUnknown:
begin
raise EIdException.Create(RSMsgClientUnkownMessagePartType);
end;
mcptText:
begin
LActiveDecoder := ProcessTextPart(LActiveDecoder);
end;
mcptAttachment:
begin
LActiveDecoder := ProcessAttachment(LActiveDecoder);
end;
end;
end;
end;
until LMsgEnd;
finally
EndWork(wmRead);
end;
end;
end;
IdPop3的Retrieve函数源代码如下,从中可以看出它也用到了ReceiveBody方法和ReceiveHeader方法。但用IdMessage控件和IdPop3控件接收邮件没有问题。这是怎么回事呢?
function TIdPOP3.Retrieve(const MsgNum: Integer; AMsg: TIdMessage): Boolean;
begin
if SendCmd('RETR ' + IntToStr(MsgNum)) = wsOk then {Do not Localize}
begin
// This is because of a bug in Exchange? with empty messages. See comment in ReceiveHeader
if Length(ReceiveHeader(AMsg)) = 0 then begin
// Only retreive the body if we do not already have a full RFC
ReceiveBody(AMsg);
end;
end;
// Will only hit here if ok and NO exception, or IF is not executed
Result := LastCmdResult.NumericCode = wsOk;
end;