Hay un bug en la unit BASE64, concretamente en Decode64, que no afecta al funcionamiento pero si altera en 1 o 2 bytes el tamaño del buffer. Vuelvo a publicar la unit completa y un ejemplo de como conseguir usar Streams.
Código Delphi
[-]
unit BASE64;
interface
type
TAByte = Array of Byte;
PAByte = ^TAByte;
function Decode64(S: String): TAByte;
function Encode64(Bin: PByte; Count: integer): String;
implementation
const
SB64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
type
SAByte = Array[0..0] of Byte;
PSAByte = ^SAByte;
function find(C: CHAR): integer;
begin
Result:= 0;
while (SB64[Result+1] <> C) and (Result < 64) do inc(Result);
end;
function Decode64(S: String): TAByte;
var
B0, B1, B2, B3: BYTE;
L, n, i: integer;
begin
n:= 1;
i:= 0;
L:= Length(S);
if S[L] = '=' then dec(L);
if S[L] = '=' then dec(L);
SetLength(Result, (L*3) div 4);
repeat
B0:= find(S[n]);
B1:= find(S[n+1]);
B2:= find(S[n+2]);
B3:= find(S[n+3]);
Result[i]:= (B0 shl 2) or (B1 shr 4);
if B2 = 64 then break;
Result[i+1]:= (B1 shl 4) or (B2 shr 2);
if B3 = 64 then break;
Result[i+2]:= (B2 shl 6) or B3;
inc(n, 4);
inc(i, 3);
until n>L;
end;
function Encode64(Bin: PByte; Count: integer): String;
var
B0, B1, B2: BYTE;
ABin: PSAByte;
Add, L, n, i: integer;
begin
if Count = 0 then exit;
ABin:= PSAByte(Bin);
n:= 0;
i:=1;
L:= ((Count+2) div 3)*4;
SetLength(Result, L);
repeat
B0:= ABin^[n];
B1:= 0; B2:= 0;
if (Count - n) > 0 then B1:= ABin^[n+1];
if (Count - n) > 1 then B2:= ABin^[n+2];
Result[i]:= SB64[(B0 shr 2) and $003F +1];
Result[i+1]:= SB64[((B0 shl 4) or (B1 shr 4)) and $003F +1];
Result[i+2]:= SB64[((B1 shl 2) or (B2 shr 6)) and $003F +1];
Result[i+3]:= SB64[(B2 and $3F) +1];
inc(n,3);
inc(i,4);
until n >= Count;
if n - Count >= 1 then Result[L]:= '=';
if n - Count = 2 then Result[L-1]:= '=';
end;
end.
Para usar TMemoryStream sin modificar la Unit puedes implementar algo como esto:
Código Delphi
[-]
function StreamEncode64(var MStream: TMemoryStream): string;
begin
Result:= Encode64(MStream.Memory, MStream.Size);
end;
procedure StreamDencode64(var S: String; var MStream: TMemoryStream);
var
Bytes: TAByte;
Size: integer;
begin
Bytes:= Decode64(S);
Size:= Length(Bytes);
MStream.SetSize(Size);
Move(Bytes[0], MStream.Memory^, Size);
SetLength(Bytes,0);
end;
Saludos.