481 lines
13 KiB
Plaintext
481 lines
13 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.18 27.08.2004 22:03:20 Andreas Hausladen
|
|
Optimized encoders
|
|
speed optimization ("const" for string parameters)
|
|
|
|
|
|
Rev 1.17 7/23/04 7:00:14 PM RLebeau
|
|
Added extra exception handling to DecodeString() and Encode()
|
|
|
|
|
|
Rev 1.16 2004.06.14 9:23:06 PM czhower
|
|
Bug fix.
|
|
|
|
|
|
Rev 1.15 22/05/2004 12:05:20 CCostelloe
|
|
Bug fix
|
|
|
|
|
|
Rev 1.14 2004.05.20 1:39:20 PM czhower
|
|
Last of the IdStream updates
|
|
|
|
|
|
Rev 1.13 2004.05.20 11:37:08 AM czhower
|
|
IdStreamVCL
|
|
|
|
|
|
Rev 1.12 2004.05.20 11:13:10 AM czhower
|
|
More IdStream conversions
|
|
|
|
|
|
Rev 1.11 2004.05.19 3:06:48 PM czhower
|
|
IdStream / .NET fix
|
|
|
|
|
|
Rev 1.10 2004.02.03 5:44:56 PM czhower
|
|
Name changes
|
|
|
|
|
|
Rev 1.9 1/27/2004 3:58:16 PM SPerry
|
|
StringStream ->IdStringStream
|
|
|
|
|
|
Rev 1.8 27/1/2004 1:57:58 PM SGrobety
|
|
Additional bug fix
|
|
|
|
|
|
Rev 1.6 11/10/2003 7:39:22 PM BGooijen
|
|
Did all todo's ( TStream to TIdStream mainly )
|
|
|
|
|
|
Rev 1.5 2003.10.02 10:52:48 PM czhower
|
|
.Net
|
|
|
|
|
|
Rev 1.4 2003.06.24 12:02:08 AM czhower
|
|
Coders now decode properly again.
|
|
|
|
|
|
Rev 1.3 2003.06.13 6:57:08 PM czhower
|
|
Speed improvement
|
|
|
|
|
|
Rev 1.2 2003.06.13 3:41:18 PM czhower
|
|
Optimizaitions.
|
|
|
|
|
|
Rev 1.1 2003.06.13 2:24:06 PM czhower
|
|
Speed improvement
|
|
|
|
|
|
Rev 1.0 11/14/2002 02:14:30 PM JPMugaas
|
|
}
|
|
unit IdCoder;
|
|
|
|
interface
|
|
|
|
{$i IdCompilerDefines.inc}
|
|
|
|
uses
|
|
Classes,
|
|
IdBaseComponent,
|
|
IdGlobal;
|
|
|
|
type
|
|
TIdEncoder = class(TIdBaseComponent)
|
|
public
|
|
function Encode(const AIn: string; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
): string; overload;
|
|
procedure Encode(const AIn: string; ADestStrings: TStrings; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
); overload;
|
|
procedure Encode(const AIn: string; ADestStream: TStream; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
); overload;
|
|
|
|
function Encode(ASrcStream: TStream; const ABytes: Integer = -1): string; overload;
|
|
procedure Encode(ASrcStream: TStream; ADestStrings: TStrings; const ABytes: Integer = -1); overload;
|
|
procedure Encode(ASrcStream: TStream; ADestStream: TStream; const ABytes: Integer = -1); overload; virtual; abstract;
|
|
|
|
class function EncodeString(const AIn: string; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
): string; overload;
|
|
class procedure EncodeString(const AIn: string; ADestStrings: TStrings;
|
|
AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
); overload;
|
|
class procedure EncodeString(const AIn: string; ADestStream: TStream;
|
|
AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
); overload;
|
|
|
|
class function EncodeBytes(const ABytes: TIdBytes): string; overload;
|
|
class procedure EncodeBytes(const ABytes: TIdBytes; ADestStrings: TStrings); overload;
|
|
class procedure EncodeBytes(const ABytes: TIdBytes; ADestStream: TStream); overload;
|
|
|
|
class function EncodeStream(ASrcStream: TStream; const ABytes: Integer = -1): string; overload;
|
|
class procedure EncodeStream(ASrcStream: TStream; ADestStrings: TStrings; const ABytes: Integer = -1); overload;
|
|
class procedure EncodeStream(ASrcStream: TStream; ADestStream: TStream; const ABytes: Integer = -1); overload;
|
|
end;
|
|
|
|
TIdEncoderClass = class of TIdEncoder;
|
|
|
|
TIdDecoder = class(TIdBaseComponent)
|
|
protected
|
|
FStream: TStream;
|
|
public
|
|
procedure DecodeBegin(ADestStream: TStream); virtual;
|
|
procedure DecodeEnd; virtual;
|
|
|
|
procedure Decode(const AIn: string); overload;
|
|
procedure Decode(ASrcStream: TStream; const ABytes: Integer = -1); overload; virtual; abstract;
|
|
|
|
class function DecodeString(const AIn: string; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
): string;
|
|
class function DecodeBytes(const AIn: string): TIdBytes;
|
|
class procedure DecodeStream(const AIn: string; ADestStream: TStream);
|
|
end;
|
|
|
|
TIdDecoderClass = class of TIdDecoder;
|
|
|
|
implementation
|
|
|
|
uses
|
|
{$IFDEF DOTNET}
|
|
IdStreamNET,
|
|
{$ELSE}
|
|
IdStreamVCL,
|
|
{$ENDIF}
|
|
IdGlobalProtocols, SysUtils;
|
|
|
|
{ TIdDecoder }
|
|
|
|
procedure TIdDecoder.DecodeBegin(ADestStream: TStream);
|
|
begin
|
|
FStream := ADestStream;
|
|
end;
|
|
|
|
procedure TIdDecoder.DecodeEnd;
|
|
begin
|
|
FStream := nil;
|
|
end;
|
|
|
|
procedure TIdDecoder.Decode(const AIn: string);
|
|
var
|
|
LStream: TMemoryStream;
|
|
LEncoding: IIdTextEncoding;
|
|
begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
LEncoding := IndyTextEncoding_8Bit;
|
|
WriteStringToStream(LStream, AIn, LEncoding{$IFDEF STRING_IS_ANSI}, LEncoding{$ENDIF});
|
|
LEncoding := nil;
|
|
LStream.Position := 0;
|
|
Decode(LStream);
|
|
finally
|
|
LStream.Free;
|
|
end;
|
|
end;
|
|
|
|
class function TIdDecoder.DecodeString(const AIn: string; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ADestEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
): string;
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
DecodeStream(AIn, LStream);
|
|
LStream.Position := 0;
|
|
EnsureEncoding(AByteEncoding, enc8Bit);
|
|
Result := ReadStringFromStream(LStream, -1, AByteEncoding{$IFDEF STRING_IS_ANSI}, ADestEncoding{$ENDIF});
|
|
finally
|
|
LStream.Free;
|
|
end;
|
|
end;
|
|
|
|
class function TIdDecoder.DecodeBytes(const AIn: string): TIdBytes;
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
Result := nil;
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
DecodeStream(AIn, LStream);
|
|
LStream.Position := 0;
|
|
ReadTIdBytesFromStream(LStream, Result, -1);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdDecoder.DecodeStream(const AIn: string; ADestStream: TStream);
|
|
var
|
|
LDecoder: TIdDecoder;
|
|
begin
|
|
LDecoder := Create(nil);
|
|
try
|
|
LDecoder.DecodeBegin(ADestStream);
|
|
try
|
|
LDecoder.Decode(AIn);
|
|
finally
|
|
LDecoder.DecodeEnd;
|
|
end;
|
|
finally
|
|
LDecoder.Free;
|
|
end;
|
|
end;
|
|
|
|
{ TIdEncoder }
|
|
|
|
function TIdEncoder.Encode(const AIn: string; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
): string;
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
if AIn <> '' then begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
EnsureEncoding(AByteEncoding, enc8Bit);
|
|
WriteStringToStream(LStream, AIn, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF});
|
|
LStream.Position := 0;
|
|
Result := Encode(LStream);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end else begin
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
procedure TIdEncoder.Encode(const AIn: string; ADestStrings: TStrings;
|
|
AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
);
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
EnsureEncoding(AByteEncoding, enc8Bit);
|
|
WriteStringToStream(LStream, AIn, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF});
|
|
LStream.Position := 0;
|
|
Encode(LStream, ADestStrings);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
|
|
procedure TIdEncoder.Encode(const AIn: string; ADestStream: TStream;
|
|
AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
);
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
EnsureEncoding(AByteEncoding, enc8Bit);
|
|
WriteStringToStream(LStream, AIn, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF});
|
|
LStream.Position := 0;
|
|
Encode(LStream, ADestStream);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
|
|
function TIdEncoder.Encode(ASrcStream: TStream; const ABytes: Integer = -1) : string;
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
Encode(ASrcStream, LStream, ABytes);
|
|
LStream.Position := 0;
|
|
Result := ReadStringFromStream(LStream, -1, IndyTextEncoding_8Bit);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
|
|
procedure TIdEncoder.Encode(ASrcStream: TStream; ADestStrings: TStrings; const ABytes: Integer = -1);
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
ADestStrings.Clear;
|
|
// TODO: provide an Encode() implementation that can save its output directly
|
|
// to ADestStrings without having to waste memory encoding the data entirely
|
|
// to memory first. In Delphi 2009+ in particular, TStrings.LoadFromStream()
|
|
// wastes a lot of memory handling large streams...
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
Encode(ASrcStream, LStream, ABytes);
|
|
LStream.Position := 0;
|
|
ADestStrings.LoadFromStream(LStream);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
|
|
class function TIdEncoder.EncodeString(const AIn: string; AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
): string;
|
|
var
|
|
LEncoder: TIdEncoder;
|
|
begin
|
|
LEncoder := Create(nil);
|
|
try
|
|
Result := LEncoder.Encode(AIn, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF});
|
|
finally
|
|
LEncoder.Free;
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdEncoder.EncodeString(const AIn: string; ADestStrings: TStrings;
|
|
AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
);
|
|
var
|
|
LEncoder: TIdEncoder;
|
|
begin
|
|
LEncoder := Create(nil);
|
|
try
|
|
LEncoder.Encode(AIn, ADestStrings, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF});
|
|
finally
|
|
LEncoder.Free;
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdEncoder.EncodeString(const AIn: string; ADestStream: TStream;
|
|
AByteEncoding: IIdTextEncoding = nil
|
|
{$IFDEF STRING_IS_ANSI}; ASrcEncoding: IIdTextEncoding = nil{$ENDIF}
|
|
);
|
|
var
|
|
LEncoder: TIdEncoder;
|
|
begin
|
|
LEncoder := Create(nil);
|
|
try
|
|
LEncoder.Encode(AIn, ADestStream, AByteEncoding{$IFDEF STRING_IS_ANSI}, ASrcEncoding{$ENDIF});
|
|
finally
|
|
LEncoder.Free;
|
|
end;
|
|
end;
|
|
|
|
class function TIdEncoder.EncodeBytes(const ABytes: TIdBytes): string;
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
if ABytes <> nil then begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
WriteTIdBytesToStream(LStream, ABytes);
|
|
LStream.Position := 0;
|
|
Result := EncodeStream(LStream);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end else begin
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdEncoder.EncodeBytes(const ABytes: TIdBytes; ADestStrings: TStrings);
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
if ABytes <> nil then begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
WriteTIdBytesToStream(LStream, ABytes);
|
|
LStream.Position := 0;
|
|
EncodeStream(LStream, ADestStrings);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdEncoder.EncodeBytes(const ABytes: TIdBytes; ADestStream: TStream);
|
|
var
|
|
LStream: TMemoryStream;
|
|
begin
|
|
if ABytes <> nil then begin
|
|
LStream := TMemoryStream.Create;
|
|
try
|
|
WriteTIdBytesToStream(LStream, ABytes);
|
|
LStream.Position := 0;
|
|
EncodeStream(LStream, ADestStream);
|
|
finally
|
|
FreeAndNil(LStream);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class function TIdEncoder.EncodeStream(ASrcStream: TStream; const ABytes: Integer = -1): string;
|
|
var
|
|
LEncoder: TIdEncoder;
|
|
begin
|
|
if ASrcStream <> nil then begin
|
|
LEncoder := Create(nil);
|
|
try
|
|
Result := LEncoder.Encode(ASrcStream, ABytes);
|
|
finally
|
|
LEncoder.Free;
|
|
end;
|
|
end else begin
|
|
Result := '';
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdEncoder.EncodeStream(ASrcStream: TStream; ADestStrings: TStrings; const ABytes: Integer = -1);
|
|
var
|
|
LEncoder: TIdEncoder;
|
|
begin
|
|
if ASrcStream <> nil then begin
|
|
LEncoder := Create(nil);
|
|
try
|
|
LEncoder.Encode(ASrcStream, ADestStrings, ABytes);
|
|
finally
|
|
LEncoder.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
class procedure TIdEncoder.EncodeStream(ASrcStream: TStream; ADestStream: TStream; const ABytes: Integer = -1);
|
|
var
|
|
LEncoder: TIdEncoder;
|
|
begin
|
|
if ASrcStream <> nil then begin
|
|
LEncoder := Create(nil);
|
|
try
|
|
LEncoder.Encode(ASrcStream, ADestStream, ABytes);
|
|
finally
|
|
LEncoder.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
end.
|
|
|
|
|