private void finish()
{
if (_z == null) return;
if (_streamMode == StreamMode.Writer)
{
bool done = false;
do
{
_z.OutputBuffer = _workingBuffer;
_z.NextOut = 0;
_z.AvailableBytesOut = _workingBuffer.Length;
int rc = (_wantCompress)
? _z.Deflate(ZlibConstants.Z_FINISH)
: _z.Inflate(ZlibConstants.Z_FINISH);
if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK)
throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message);
if (_workingBuffer.Length - _z.AvailableBytesOut > 0)
{
_stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut);
}
done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0;
// If GZIP and de-compress, we're done when 8 bytes remain.
if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress)
done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0);
}
while (!done);
Flush();
// workitem 7159
if (_flavor == ZlibStreamFlavor.GZIP)
{
//Console.WriteLine("GZipStream: Last write");
if (_wantCompress)
{
// Emit the GZIP trailer: CRC32 and size mod 2^32
int c1 = crc.Crc32Result;
_stream.Write(BitConverter.GetBytes(c1), 0, 4);
int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF);
_stream.Write(BitConverter.GetBytes(c2), 0, 4);
//Console.WriteLine("GZipStream: Writing trailer crc(0x{0:X8}) isize({1})", c1, c2);
}
else
{
//Console.WriteLine("ZlibBaseStream::finish / Writer / GZIP / decompression");
// should validate the trailer here
throw new ZlibException("Writing with decompression is not supported.");
}
}
}
// workitem 7159
else if (_streamMode == StreamMode.Reader)
{
if (_flavor == ZlibStreamFlavor.GZIP)
{
if (!_wantCompress)
{
// Read and potentially verify the GZIP trailer: CRC32 and size mod 2^32
byte[] trailer = new byte[8];
if (_z.AvailableBytesIn != 8)
throw new ZlibException(String.Format("Can't handle this! AvailableBytesIn={0}",
_z.AvailableBytesIn ));
Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length);
Int32 crc32_expected = BitConverter.ToInt32(trailer, 0);
int crc32_actual = crc.Crc32Result;
Int32 isize_expected = BitConverter.ToInt32(trailer, 4);
Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF);
// Console.WriteLine("GZipStream: slurped trailer crc(0x{0:X8}) isize({1})", crc32_expected, isize_expected);
// Console.WriteLine("GZipStream: calc'd data crc(0x{0:X8}) isize({1})", crc32_actual, isize_actual);
if (crc32_actual != crc32_expected)
throw new ZlibException(String.Format("Bad CRC32 in GZIP stream. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected));
if (isize_actual != isize_expected)
throw new ZlibException(String.Format("Bad size in GZIP stream. (actual({0})!=expected({1}))", isize_actual, isize_expected));
}
else
{
//Console.WriteLine("ZlibBaseStream::finish / Reader / GZIP / compression");
// should emit the GZIP trailer here
throw new ZlibException("Reading with compression is not supported.");
}
}
}
}