i am asking about the possibility of compressing TIdMemoryBufferStream
Using TIdCompressorZLib
how can it be done properly using the following code
procedure TClientThread.SendBuffer(Buffer: TIdBytes; BufferSize: Cardinal);
Var
Strm: TIdMemoryBufferStream;
IdCompressorZLib : TIdCompressorZLib;
begin
Strm := TIdMemoryBufferStream.Create(PByte(Buffer), BufferSize);
IdCompressorZLib := TIdCompressorZLib.Create(nil);
try
// then can't figure what the right process to do
FTCP.Socket.WriteLn('Stream');
FTCP.Socket.LargeStream := True;
FTCP.Socket.Write(Strm, 0, True);
finally
FreeAndNil(Strm);
FreeAndNil(IdCompressorZLib);
end;
end;
i am not sure about the right process that needs to be done
as example should i create another variable as StrmB
then calling the compress to it ?
The TIdCompressorZLib
component is intended to be used only with the Compressor
property of the TIdHTTP
and TIdFTP
components.
For general purpose compression over a TCP connection, you can assign a TIdCompressionIntercept
component to the TCP connection's IOHandler.Intercept
property, eg:
var
Compressor : TIdCompressionIntercept;
begin
Compressor := TIdCompressionIntercept.Create(nil);
try
Compressor.CompressionLevel := 9;
FTCP.Socket.Intercept := Compressor;
try
// any data written here will be compressed....
finally
FTCP.Socket.Intercept := nil;
end;
finally
Compressor.Free;
end;
end;
However, since you are sending the byte size of the compressed data (by setting the AWriteByteCount
parameter to True in TIdIOHandler.Write(TStream)
), that will not work with the compression intercept.
Indy's IdZLib
unit has a TCompressionStream
class, and various ...CompressStream/Ex()
functions, that you can use instead, eg:
procedure TClientThread.SendBuffer(Buffer: TIdBytes; BufferSize: Cardinal);
var
Strm: TMemoryStream;
Compressor : TCompressionStream;
begin
Strm := TMemoryStream.Create;
try
Compressor := TCompressionStream.Create(clMax, Strm, False);
try
WriteTIdBytesToStream(Compressor, Buffer, BufferSize);
finally
Compressor.Free;
end;
FTCP.Socket.WriteLn('Stream');
FTCP.Socket.LargeStream := True;
FTCP.Socket.Write(Strm, 0, True);
finally
Strm.Free;
end;
end;
Or:
procedure TClientThread.SendBuffer(Buffer: TIdBytes; BufferSize: Cardinal);
var
InStrm: TIdMemoryBufferStream;
OutStrm: TMemoryStream;
begin
OutStrm := TMemoryStream.Create;
try
InStrm := TIdMemoryBufferStream.Create(PByte(Buffer), BufferSize);
try
CompressStreamEx(InStrm, OutStrm, clMax, zsZLib);
finally
InStrm.Free;
end;
FTCP.Socket.WriteLn('Stream');
FTCP.Socket.LargeStream := True;
FTCP.Socket.Write(OutStrm, 0, True);
finally
OutStrm.Free;
end;
end;