188 lines
4.4 KiB
Plaintext
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.
|