restemplate/indy/Protocols/IdCoder00E.pas

132 lines
3.6 KiB
Plaintext

{
$Project$
$Workfile$
$Revision$
$DateUTC$
$Id$
This file is part of the Indy (Internet Direct) project, and is offered
under the dual-licensing agreement described on the Indy website.
(http://www.indyproject.org/)
Copyright:
(c) 1993-2005, Chad Z. Hower and the Indy Pit Crew. All rights reserved.
}
{
$Log$
}
{
Rev 1.4 2004.05.20 1:39:26 PM czhower
Last of the IdStream updates
Rev 1.3 2004.05.20 11:37:20 AM czhower
IdStreamVCL
Rev 1.2 2004.05.20 11:13:16 AM czhower
More IdStream conversions
Rev 1.1 2003.06.13 6:57:10 PM czhower
Speed improvement
Rev 1.0 2003.06.13 4:59:36 PM czhower
Initial checkin
}
unit IdCoder00E;
interface
{$i IdCompilerDefines.inc}
uses
Classes,
IdCoder3to4;
type
TIdDecoder00E = class(TIdDecoder4to3)
public
procedure Decode(ASrcStream: TStream; const ABytes: Integer = -1); override;
end;
TIdEncoder00E = class(TIdEncoder3to4)
public
procedure Encode(ASrcStream, ADestStream: TStream; const ABytes: Integer = -1); override;
end;
implementation
uses
IdGlobal,
IdStream,
SysUtils;
{ TIdDecoder00E }
procedure TIdDecoder00E.Decode(ASrcStream: TStream; const ABytes: Integer = -1);
var
LBuf: TIdBytes;
LSize: TIdStreamSize;
LDataLen, LExpected: Integer;
begin
LSize := IndyLength(ASrcStream, ABytes);
if LSize > 0 then begin
//Param 2 - Start at second char since 00E's have byte 1 as length
TIdStreamHelper.ReadBytes(ASrcStream, LBuf, 1);
//Param 3 - Get output length of input. This is length in bytes,
// not encoded chars. DO NOT include fill chars in calculation
{Assert(Ord(FDecodeTable[LBuf[0]]) = (((LSize-1) div 4) * 3));}
LDataLen := FDecodeTable[LBuf[0]];
SetLength(LBuf, LSize-1);
TIdStreamHelper.ReadBytes(ASrcStream, LBuf, LSize-1);
// RLebeau 4/28/2014: encountered a situation where a UUE encoded attachment
// had some encoded lines that were supposed to end with a space character
// but were actually truncated off. Turns out that Outlook Express is known
// for doing that, for instance. Some other encoding apps might also have a
// similar flaw, so just in case let's calculate what the input length is
// supposed to be and pad the input with spaces if needed before then
// decoding it...
LExpected := ((LDataLen + 2) div 3) * 4;
if Length(LBuf) < LExpected then begin
ExpandBytes(LBuf, Length(LBuf), LExpected-Length(LBuf), Ord(' ')); // should this use FillChar instead?
end;
LBuf := InternalDecode(LBuf, True);
if Assigned(FStream) then begin
TIdStreamHelper.Write(FStream, LBuf, LDataLen);
end;
end;
end;
{ TIdEncoder00E }
procedure TIdEncoder00E.Encode(ASrcStream, ADestStream: TStream; const ABytes: Integer = -1);
var
LStream: TMemoryStream;
LSize: TIdStreamSize;
LEncodeSize: Integer;
LBuf: TIdBytes;
begin
SetLength(LBuf, 1);
LStream := TMemoryStream.Create;
try
LSize := IndyLength(ASrcStream, ABytes);
while LSize > 0 do
begin
LEncodeSize := IndyMin(LSize, Length(FCodingTable)-1);
inherited Encode(ASrcStream, LStream, LEncodeSize);
Dec(LSize, LEncodeSize);
LBuf[0] := FCodingTable[Integer(LEncodeSize)];
TIdStreamHelper.Write(ADestStream, LBuf, 1);
LStream.Position := 0;
ADestStream.CopyFrom(LStream, 0);
if LSize > 0 then begin
WriteStringToStream(ADestStream, EOL);
LStream.Clear;
end;
end;
finally
FreeAndNil(LStream);
end;
end;
end.