Flushing is a rather important part. Most compression streams take as much data as they can and only write when you flush or destroy the stream. That's the case for TBzip2CompressStream, TBase64EncodingStream and Tcompressionstream
I think some old version of FPC didn't have flush of TBase64EncodingStream visible outside private, but that's changed now. Either way it usually flushes on Destroy.
Which means it should be like this:
function GzBase64(const s: string): string;
var OutStream, InpStream, GzStream, b64Stream: TStream;
begin
OutStream := TStringStream.Create('');
try
b64Stream := TBase64EncodingStream.Create(OutStream);
try
GzStream := Tcompressionstream.create(clmax,b64Stream);
try
InpStream := TStringStream.Create(s);
try
// Copy input stream
GzStream.CopyFrom(InpStream,InpStream.Size);
finally
InpStream.Free;
end;
finally
GzStream.Free;
end;
finally
b64Stream.Free;
end;
result := TStringStream(OutStream).DataString;
finally
OutStream.Free;
end;
end;
And the code you posted should be something like this:
function GzBase64(const s: string): string;
var OutStream,CompressStream: TStream;
begin
OutStream := TStringStream.Create('');
try
CompressStream := TBzip2CompressStream.Create(OutStream);
try
CompressStream.WriteBuffer(S[1], Length(S));
finally
CompressStream.Free;
end;
result := form1.IDEncoderMIME1.Encode(TStringStream(OutStream).DataString);
finally
OutStream.Free;
end;
end;