* Added ASCII85 encoder

git-svn-id: trunk@13441 -
This commit is contained in:
michael 2009-07-25 14:47:00 +00:00
parent b4914d063a
commit e888b92717

View File

@ -73,9 +73,155 @@ type
end;
// TODO encoder...
TASCII85EncoderStream = class(TOwnerStream)
private
FPos,
FCount,
FTuple : Cardinal;
FWidth : Integer;
FBoundary : Boolean;
protected
Procedure WriteBoundary;
Procedure Flush;
procedure Encode;
public
Constructor Create(ADest: TStream; AWidth : Integer = 72; ABoundary : Boolean = False);
Destructor Destroy; Override;
function Write(Const aBuffer; aCount : longint) : longint; override;
Property Width : Integer Read FWidth;
Property Boundary : Boolean Read FBoundary;
end;
implementation
{ TASCII85EncoderStream }
Procedure TASCII85EncoderStream.WriteBoundary;
Const
SBoundary = '<~';
begin
Source.Write(SBoundary[1],2);
FPos:=2;
end;
Procedure TASCII85EncoderStream.Encode;
Var
S : String[7];
I,J : Integer;
Buf : Array[0..4] of Byte;
begin
If (FTuple=0) then
begin
// Write 'z'
S:='z';
Inc(FPos);
If (FPos>FWidth) then
begin
S:=S+sLineBreak;
FPos:=0;
end;
end
else
begin
For I:=0 to 4 do
begin
Buf[i]:=FTuple mod 85;
FTuple:=FTuple div 85;
end;
J:=0;
S:='';
For I:=FCount+1 downto 0 do
begin
Inc(j);
S[J]:=Char(Buf[i]+Ord('!'));
SetLength(S,J);
Inc(FPos);
If (FPos>FWidth) then
begin
FPos:=0;
S:=S+sLinebreak;
J:=Length(S);
end;
end;
end;
Source.Write(S[1],Length(S));
FTuple:=0;
FCount:=-1;
end;
Procedure TASCII85EncoderStream.Flush;
Const
Boundary1 = '~>'+slinebreak;
Boundary2 = slinebreak+Boundary1;
Var
S : String;
begin
If FCount>0 then
Encode;
If FBoundary then
begin
If FPos+2>FWidth then
S:=Boundary2
else
S:=Boundary1;
Source.Write(S[1],Length(S));
FBoundary:=False;
end;
end;
Constructor TASCII85EncoderStream.Create(ADest: TStream; AWidth : Integer = 72; ABoundary : Boolean = False);
begin
Inherited Create(ADest);
FWidth:=AWidth;
FBoundary:=ABoundary;
If FBoundary then
WriteBoundary;
end;
Destructor TASCII85EncoderStream.Destroy;
begin
Flush;
Inherited;
end;
function TASCII85EncoderStream.Write(Const aBuffer; aCount : longint) : longint;
Var
P : PByte;
C : Byte;
begin
P:=@Abuffer;
Result:=ACount;
While ACount>0 do
begin
C:=P^;
Case FCount of
0 : FTuple:=FTuple or (C shl 24);
1 : FTuple:=FTuple or (C shl 16);
2 : FTuple:=FTuple or (C shl 8);
3 : begin
FTuple:=FTuple or C;
encode;
end;
end;
Inc(FCount);
Inc(P);
Dec(ACount);
end;
end;
{ TRingBuffer }
function TASCII85RingBuffer.GetBufferSize() : Cardinal; inline;