internal static int Process(zlib.ZStream /*!*/ zst, MutableString str, zlib.FlushStrategy flush, bool compress, out MutableString /*!*/ result, ref MutableString trailingUncompressedData) { result = MutableString.CreateBinary(); // add previously compressed data to the output: if (zst.next_out != null) { result.Append(zst.next_out, 0, zst.next_out_index); } int err; int bufferStart = zst.next_out_index; err = Process(zst, str, flush, compress, ref trailingUncompressedData); result.Append(zst.next_out, bufferStart, zst.next_out_index - bufferStart); if (err == Z_STREAM_END && (flush == zlib.FlushStrategy.Z_FINISH || str == null)) { err = compress ? zst.deflateEnd() : zst.inflateEnd(); } zst.next_out = null; zst.next_out_index = 0; zst.avail_out = 0; return(err); }
internal static int Process(zlib.ZStream /*!*/ zst, MutableString str, zlib.FlushStrategy flush, bool compress, ref MutableString trailingUncompressedData) { if (str == null) { str = MutableString.FrozenEmpty; flush = zlib.FlushStrategy.Z_FINISH; } else if (str.Length == 0 && flush == NO_FLUSH) { return(Z_OK); } // data still available from previous input: if (zst.avail_in > 0) { int err = Process(zst, flush, compress, ref trailingUncompressedData); // double flush: if (compress && flush != zlib.FlushStrategy.Z_FINISH && err == (int)zlib.ZLibResultCode.Z_DATA_ERROR) { return(Z_OK); } // append new input to the current input: if (err != Z_OK && err != Z_STREAM_END) { byte[] currentInput = zst.next_in; byte[] newInput = str.ToByteArray(); int minLength = zst.next_in_index + zst.avail_in + newInput.Length; if (currentInput.Length < minLength) { Array.Resize(ref currentInput, Math.Max(currentInput.Length * 2, minLength)); } Buffer.BlockCopy(newInput, 0, currentInput, zst.next_in_index + zst.avail_in, newInput.Length); zst.next_in = currentInput; zst.avail_in += newInput.Length; return(err); } } if (str != null) { byte[] input = str.ToByteArray(); zst.next_in = input; zst.next_in_index = 0; zst.avail_in = input.Length; } else { zst.avail_in = 0; } return(Process(zst, flush, compress, ref trailingUncompressedData)); }
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); }