restemplate/indy/Protocols/IdCoderMIME.pas

188 lines
4.4 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.3 26/03/2005 19:19:30 CCostelloe
Fixes for "uneven size" exception
Rev 1.2 2004.01.21 1:04:54 PM czhower
InitComponenet
Rev 1.1 10/6/2003 5:37:02 PM SGrobety
Bug fix in decoders.
Rev 1.0 11/14/2002 02:14:54 PM JPMugaas
}
unit IdCoderMIME;
interface
{$i IdCompilerDefines.inc}
uses
Classes,
IdCoder3to4,
IdGlobal;
type
TIdEncoderMIME = class(TIdEncoder3to4)
protected
procedure InitComponent; override;
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
public
constructor Create(AOwner: TComponent); reintroduce; overload;
{$ENDIF}
end;
TIdDecoderMIME = class(TIdDecoder4to3)
protected
procedure InitComponent; override;
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
public
constructor Create(AOwner: TComponent); reintroduce; overload;
{$ENDIF}
end;
{WARNING: This is not a general-purpose decoder. It is used, for example, by
IdMessageCoderMIME for line-by-line decoding of base64 encoded parts that are
processed on a line-by-line basis, as against the complete encoded block.}
TIdDecoderMIMELineByLine = class(TIdDecoderMIME)
protected
FLeftFromLastTime: TIdBytes;
public
procedure DecodeBegin(ADestStream: TStream); override;
procedure DecodeEnd; override;
procedure Decode(ASrcStream: TStream; const ABytes: Integer = -1); override;
end;
const
GBase64CodeTable: string =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; {Do not Localize}
var
GBase64DecodeTable: TIdDecodeTable;
implementation
uses
{$IFDEF DOTNET}
IdStreamNET,
{$ELSE}
IdStreamVCL,
{$ENDIF}
SysUtils;
{ TIdDecoderMIMELineByLine }
procedure TIdDecoderMIMELineByLine.DecodeBegin(ADestStream: TStream);
begin
inherited DecodeBegin(ADestStream);
{Clear out any bytes that may be left from a previous decode...}
SetLength(FLeftFromLastTime, 0);
end;
procedure TIdDecoderMIMELineByLine.DecodeEnd;
var
LStream: TMemoryStream;
LPos: Integer;
begin
if Length(FLeftFromLastTime) > 0 then begin
LPos := Length(FLeftFromLastTime);
SetLength(FLeftFromLastTime, 4);
while LPos < 4 do begin
FLeftFromLastTime[LPos] := Ord(FFillChar);
Inc(LPos);
end;
LStream := TMemoryStream.Create;
try
WriteTIdBytesToStream(LStream, FLeftFromLastTime);
LStream.Position := 0;
inherited Decode(LStream);
finally
FreeAndNil(LStream);
SetLength(FLeftFromLastTime, 0);
end;
end;
inherited DecodeEnd;
end;
procedure TIdDecoderMIMELineByLine.Decode(ASrcStream: TStream; const ABytes: Integer = -1);
var
LMod, LDiv: integer;
LIn, LSrc: TIdBytes;
LStream: TMemoryStream;
begin
LIn := FLeftFromLastTime;
if ReadTIdBytesFromStream(ASrcStream, LSrc, ABytes) > 0 then begin
AppendBytes(LIn, LSrc);
end;
LMod := Length(LIn) mod 4;
if LMod <> 0 then begin
LDiv := (Length(LIn) div 4) * 4;
FLeftFromLastTime := Copy(LIn, LDiv, Length(LIn)-LDiv);
LIn := Copy(LIn, 0, LDiv);
end else begin
SetLength(FLeftFromLastTime, 0);
end;
LStream := TMemoryStream.Create;
try
WriteTIdBytesToStream(LStream, LIn);
LStream.Position := 0;
inherited Decode(LStream, ABytes);
finally
FreeAndNil(LStream);
end;
end;
{ TIdDecoderMIME }
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
constructor TIdDecoderMIME.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
{$ENDIF}
procedure TIdDecoderMIME.InitComponent;
begin
inherited InitComponent;
FDecodeTable := GBase64DecodeTable;
FCodingTable := ToBytes(GBase64CodeTable);
FFillChar := '='; {Do not Localize}
end;
{ TIdEncoderMIME }
{$IFDEF WORKAROUND_INLINE_CONSTRUCTORS}
constructor TIdEncoderMIME.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
{$ENDIF}
procedure TIdEncoderMIME.InitComponent;
begin
inherited InitComponent;
FCodingTable := ToBytes(GBase64CodeTable);
FFillChar := '='; {Do not Localize}
end;
initialization
TIdDecoder4to3.ConstructDecodeTable(GBase64CodeTable, GBase64DecodeTable);
end.