The SPDY protocol specifies to initialize the compression of name/value data with a predefined block of data:
http://mbelshe.github.com/SPDY-Specification/draft-mbelshe-spdy-00.xml#rfc.section.2.6.9.1
(The way zlib compression works is that it will use less bits for strings of characters that 'appear' to reoccur more, so if you pre-load compression with the usual suspects, chances are you'll end up with less bits after compression more of the time. But now for my real question:)
Is this possible with Delphi's TCompressionStream from the ZLib unit?
You need to use deflateSetDictionary. It's available in Delphi XE2's ZLib.pas, but the compression stream classes don't expose the TZStreamRec
field to call it on. Class helpers can access private fields of the associated class, so you can work around that limitation by adding one to TCustomZStream
(adding it to TZCompressionStream
won't work).
type
TCustomZStreamHelper = class helper for TCustomZStream
function SetDictionary(dictionary: PByte; dictLength: Cardinal): Integer;
end;
function TCustomZStreamHelper.SetDictionary(dictionary: PByte;
dictLength: Cardinal): Integer;
begin
if Self is TZCompressionStream then
Result := deflateSetDictionary(Self.FZStream, dictionary, dictLength)
else if Self is TZDecompressionStream then
Result := inflateSetDictionary(Self.FZStream, dictionary, dictLength)
else raise Exception.Create('Invalid class type');
end;
Just call SetDictionary with the SPDY string immediately after creating the compression stream.
The needed functionality is in ZLib but isn't exposed by Delphi.
Delphi XE2's documentation for it's ZLib has the needed function deflateSetDictionary
listed as for internal use only. The description for the function in the ZLib manual advanced functions section makes it clear it has the functionality you desire.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With