Пример #1
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);
            }
Пример #2
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));
            }
Пример #3
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);
            }