So .net does not have a ZlibStream so I am trying to implement my own one using DeflateStream which .net does have. DeflateStream also apparently does not support using Dictionaries so I skip that in my ZlibStream as well.
Writing works well but I have a problem with my Read method.
Here is my Read method:
public override int Read(byte[] buffer, int offset, int count)
{
EnsureDecompressionMode();
if (!_readHeader)
{
// read the header (CMF|FLG|optional DIC)
_readHeader = true;
}
var res = _deflate.Read(buffer, offset, count);
if (res == 0) // EOF
{
// read adler32 checksum
BaseStream.ReadFully(_scratch, 0, 4);
var checksum = (uint)_scratch[0] << 24 |
(uint)_scratch[1] << 16 |
(uint)_scratch[2] << 8 |
(uint)_scratch[3];
if (checksum != _adler32.Checksum)
{
throw new ZlibException("Invalid checksum");
}
}
else
{
_adler32.CalculateChecksum(buffer, offset, res);
}
return res;
}
Where:
_scratchis abyte[4]used as a temporary buffer_deflateis aDeflateStream.
Zlib's format is CMF|FLG|optional DICT|compressed data|adler32|. So I need a way to stop reading when the adler32 is reached. Initially, I thought DeflateStream would return EOF when it's done but it turns out it reads till EOF of the underlying stream. So it also reads the adler32 as if it's compressed data. So when I try to read adler32 from BaseStream inside the if block, an EOF exception is thrown.
So how do I make DeflateStream stop reading the adler32 as if it's compressed data and instead EOF there or do something equivalent, so that I can read adler32 from the BaseStream without compression?
Since files have a fixed size can't you simply stop at
base.Length - typeof(int)? Adjust the read-buffer if necessary and then read the uncompressed checksum.Someting like:
not tested