private static int Process(zlib.ZStream /*!*/ zst, zlib.FlushStrategy flush, bool compress,
ref MutableString trailingUncompressedData)
{
if (zst.next_out == null)
{
zst.next_out = new byte[DEFAULTALLOC];
zst.next_out_index = 0;
zst.avail_out = zst.next_out.Length;
}
int result = compress ? zst.deflate(flush) : zst.inflate(flush);
while (result == Z_OK && zst.avail_out == 0)
{
byte[] output = zst.next_out;
int oldLength = output.Length;
Array.Resize(ref output, oldLength * 2);
zst.next_out = output;
zst.avail_out = oldLength;
result = compress ? zst.deflate(flush) : zst.inflate(flush);
}
if (!compress && (result == Z_STREAM_END || result == Z_STREAM_ERROR && !zst.IsInitialized))
{
// MRI hack: any data left in the stream are saved into a separate buffer and returned when "finish" is called
// This is weird behavior, one would expect the rest of the stream is either ignored or copied to the output buffer.
#if COPY_UNCOMPRESSED_DATA_TO_OUTPUT_BUFFER
Debug.Assert(zst.next_in_index + zst.avail_in <= zst.next_in.Length);
Debug.Assert(zst.next_out_index + zst.avail_out <= zst.next_out.Length);
if (zst.avail_in > zst.avail_out)
{
byte[] output = zst.next_out;
int oldLength = output.Length;
Array.Resize(ref output, Math.Max(zst.next_out_index + zst.avail_in, oldLength * 2));
zst.next_out = output;
}
Buffer.BlockCopy(zst.next_in, zst.next_in_index, zst.next_out, zst.next_out_index, zst.avail_in);
// MRI subtracts till 0 is reached:
zst.avail_out = Math.Max(zst.avail_out - zst.avail_in, 0);
zst.next_out_index += zst.avail_in;
zst.avail_in = 0;
#else
if (trailingUncompressedData == null)
{
trailingUncompressedData = MutableString.CreateBinary();
}
trailingUncompressedData.Append(zst.next_in, zst.next_in_index, zst.avail_in);
// MRI subtracts till 0 is reached:
zst.avail_out = Math.Max(zst.avail_out - zst.avail_in, 0);
zst.avail_in = 0;
#endif
result = Z_STREAM_END;
}
return(result);
}