Exemplo n.º 1
0
            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;
            }
Exemplo n.º 2
0
            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;
            }
Exemplo n.º 3
0
            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);
            }
Exemplo n.º 4
0
 protected ZStream(RubyClass/*!*/ cls, zlib.ZStream/*!*/ stream)
     : base(cls)
 {
     Debug.Assert(stream != null);
     _stream = stream;
 }