예제 #1
0
 public int Inflate(FlushType flush)
 {
     if (this.istate == null)
         throw new ZlibException("No Inflate State!");
     else
         return this.istate.Inflate(flush);
 }
예제 #2
0
    private static byte[] ZlibCodecDecompress(byte[] data)
    {
        int buffer_size = 0x800;

        byte[] buffer = new byte[buffer_size];
        bool   flag   = false;

        using (MemoryStream stream = new MemoryStream()) {
            ZlibCodec codec = new ZlibCodec();
            codec.InitializeInflate(flag);
            codec.InputBuffer      = data;
            codec.AvailableBytesIn = data.Length;
            codec.NextIn           = 0;
            codec.OutputBuffer     = buffer;
            FlushType[] typeArray1 = new FlushType[2];
            typeArray1[1] = FlushType.Finish;
            foreach (FlushType type in typeArray1)
            {
                int count = 0;
                do
                {
                    codec.AvailableBytesOut = buffer_size;
                    codec.NextOut           = 0;
                    codec.Inflate(type);
                    count = buffer_size - codec.AvailableBytesOut;
                    if (count > 0)
                    {
                        stream.Write(buffer, 0, count);
                    }
                }while (((type == FlushType.None) && ((codec.AvailableBytesIn != 0) || (codec.AvailableBytesOut == 0))) || ((type == FlushType.Finish) && (count != 0)));
            }
            codec.EndInflate();
            return(stream.ToArray());
        }
    }
예제 #3
0
 private static void addHeaders(string fileName, long fileLength, object response, FlushType flushType)
 {
     var addHeader = response.GetType().GetMethod("AddHeader");
     addHeader.Invoke(response, new object[] { "Content-Length", fileLength.ToString(CultureInfo.InvariantCulture) });
     var contentDisposition = flushType == FlushType.Inline ? "inline;filename=" : "attachment;filename=";
     addHeader.Invoke(response, new object[] { "content-disposition", contentDisposition + fileName });
 }
예제 #4
0
 protected ZLibStatus inflate(FlushType f)
 {
     if (istate == null)
     {
         return(ZLibStatus.Z_STREAM_ERROR);
     }
     return(istate.inflate(this, f));
 }
예제 #5
0
 public ZLibStatus deflate(FlushType flush)
 {
     if (dstate == null)
     {
         return(ZLibStatus.Z_STREAM_ERROR);
     }
     return(dstate.deflate(this, flush));
 }
예제 #6
0
 public ZLibStatus deflate(FlushType flush)
 {
     if (dstate == null)
     {
         return ZLibStatus.Z_STREAM_ERROR;
     }
     return dstate.deflate(this, flush);
 }
예제 #7
0
 public ZOutputStream(Stream output, CompressionLevel level, bool nowrap)
     : base()
 {
     this.FlushMode = FlushType.Z_PARTIAL_FLUSH;
     this._output   = output;
     this.deflateInit(level, nowrap);
     this.compress = true;
 }
예제 #8
0
 public ZOutputStream(Stream output)
     : base()
 {
     this.FlushMode = FlushType.Z_PARTIAL_FLUSH;
     this._output   = output;
     this.inflateInit();
     this.compress = false;
 }
예제 #9
0
    internal BlockState method_24(FlushType A_0)
    {
        int num = 0xffff;

        if (0xffff > (this.byte_0.Length - 5))
        {
            num = this.byte_0.Length - 5;
        }
        while (true)
        {
            if (this.int_44 <= 1)
            {
                this.method_27();
                if ((this.int_44 == 0) && (A_0 == FlushType.None))
                {
                    return(BlockState.NeedMore);
                }
                if (this.int_44 == 0)
                {
                    this.method_23(A_0 == FlushType.Finish);
                    if (this.class1068_0.int_3 == 0)
                    {
                        if (A_0 != FlushType.Finish)
                        {
                            return(BlockState.NeedMore);
                        }
                        return(BlockState.FinishStarted);
                    }
                    if (A_0 != FlushType.Finish)
                    {
                        return(BlockState.BlockDone);
                    }
                    return(BlockState.FinishDone);
                }
            }
            this.int_56 += this.int_44;
            this.int_44  = 0;
            int num2 = this.int_31 + num;
            if ((this.int_56 == 0) || (this.int_56 >= num2))
            {
                this.int_44 = this.int_56 - num2;
                this.int_56 = num2;
                this.method_23(false);
                if (this.class1068_0.int_3 == 0)
                {
                    return(BlockState.NeedMore);
                }
            }
            if ((this.int_56 - this.int_31) >= (this.int_59 - int_25))
            {
                this.method_23(false);
                if (this.class1068_0.int_3 == 0)
                {
                    return(BlockState.NeedMore);
                }
            }
        }
    }
예제 #10
0
        /// <summary>Deflate one batch of data.</summary>
        /// <remarks>You must have set InputBuffer and OutputBuffer before calling this method.</remarks>
        /// <example>
        ///   <code>
        ///     private void DeflateBuffer(CompressionLevel level) { int bufferSize = 1024; byte[] buffer = new
        ///     byte[bufferSize]; ZlibCodec compressor = new ZlibCodec();
        ///
        ///     Console.WriteLine("\n============================================"); Console.WriteLine("Size of Buffer
        ///     to Deflate: {0} bytes.", UncompressedBytes.Length); MemoryStream ms = new MemoryStream();
        ///
        ///     int rc = compressor.InitializeDeflate(level);
        ///
        ///     compressor.InputBuffer = UncompressedBytes; compressor.NextIn = 0; compressor.AvailableBytesIn =
        ///     UncompressedBytes.Length;
        ///
        ///     compressor.OutputBuffer = buffer;
        ///
        ///     // pass 1: deflate do { compressor.NextOut = 0; compressor.AvailableBytesOut = buffer.Length; rc =
        ///     compressor.Deflate(FlushType.None);
        ///
        ///     if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END) throw new
        ///     Exception("deflating: " + compressor.Message);
        ///
        ///     ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut); } while
        ///     (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
        ///
        ///     // pass 2: finish and flush do { compressor.NextOut = 0; compressor.AvailableBytesOut = buffer.Length;
        ///     rc = compressor.Deflate(FlushType.Finish);
        ///
        ///     if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK) throw new
        ///     Exception("deflating: " + compressor.Message);
        ///
        ///     if (buffer.Length - compressor.AvailableBytesOut &gt; 0) ms.Write(buffer, 0, buffer.Length -
        ///     compressor.AvailableBytesOut); } while (compressor.AvailableBytesIn &gt; 0 ||
        ///     compressor.AvailableBytesOut == 0);
        ///
        ///     compressor.EndDeflate();
        ///
        ///     ms.Seek(0, SeekOrigin.Begin); CompressedBytes = new byte[compressor.TotalBytesOut];
        ///     ms.Read(CompressedBytes, 0, CompressedBytes.Length); }
        ///   </code>
        /// </example>
        /// <param name="flush">whether to flush all data as you deflate. Generally you will want to use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to flush everything.</param>
        /// <returns>Z_OK if all goes well.</returns>
        internal int Deflate(FlushType flush)
        {
            if (this.Dstate == null)
            {
                throw new ZlibException("No Deflate State!");
            }

            return(this.Dstate.Deflate(flush));
        }
예제 #11
0
    public virtual void vmethod_1(FlushType A_0)
    {
        int num = 0x12;

        if (this.bool_0)
        {
            throw new ObjectDisposedException(BookmarkStart.b("户嘹唻尽ጿ㙁㙃⍅⥇❉", num));
        }
        this.stream9_0.flushType_0 = A_0;
    }
예제 #12
0
    public virtual void vmethod_1(FlushType A_0)
    {
        int num = 1;

        if (this.bool_0)
        {
            throw new ObjectDisposedException(BookmarkStart.b("挦䰨䴪䄬丮䔰嘲昴䌶䬸帺尼刾", num));
        }
        this.stream9_0.flushType_0 = A_0;
    }
예제 #13
0
    public int method_5(FlushType A_0)
    {
        int num = 15;

        if (this.class609_0 == null)
        {
            throw new Exception0(BookmarkStart.b("笴堶ᤸ爺匼夾ⵀ≂ㅄ≆楈ᡊ㥌⹎═㙒瑔", num));
        }
        return(this.class609_0.method_5(A_0));
    }
예제 #14
0
    public int method_14(FlushType A_0)
    {
        int num = 5;

        if (this.class935_0 == null)
        {
            throw new Exception0(BookmarkStart.b("攪䈬༮田嘲匴嬶堸伺堼Ἶቀ㝂⑄㍆ⱈ橊", num));
        }
        return(this.class935_0.method_39(A_0));
    }
예제 #15
0
 internal FileLogConfig()
 {
     this.Extension     = "log";
     this.LogMode       = FileLogMode.SingleFile;
     this.LogNameFormat = "yyyy-MM-dd hh-mm-ss";
     this.Path          = "SeeSharpLog.log";
     this.MaxLogSize    = 100000000L;
     this.Encode        = Encoding.Unicode;
     this.Flush         = FlushType.SyncFlush;
 }
 public ZlibBaseStream(Stream stream, ZlibStreamFlavor flavor, bool leaveOpen)
 {
     this._flushMode = FlushType.None;
     this._stream = stream;
     this._leaveOpen = leaveOpen;
     this._flavor = flavor;
     if (flavor != ZlibStreamFlavor.GZIP)
         return;
     this.crc = new Crc32();
 }
예제 #17
0
 public ZlibBaseStream( Stream stream,
     CompressionMode compressionMode,
     CompressionLevel level,
     bool leaveOpen)
     : base()
 {
     this.flushMode = FlushType.None;
     this.stream = stream;
     this.leaveOpen = leaveOpen;
     this.compressionMode = compressionMode;
     this.level = level;
 }
예제 #18
0
 /// <summary>
 /// 使用指定的流, CompressionLevel 值和 CompressionMode 值以及一个指定是否将流保留为打开状态的值,初始化 <see cref="Py.Zip.Zlib.ZipBaseStream"/> 的新实例。
 /// </summary>
 /// <param name="stream">要解压或压缩缩的流。</param>
 /// <param name="compressionMode">指示当前操作是解压或压缩。</param>
 /// <param name="leaveOpen">true 将流保留为打开状态,否则为 false。</param>
 /// <param name="level">使用的解压等级。</param>
 /// <exception cref="ArgumentNullException"><paramref name="stream"/> 为 null。</exception>
 /// <exception cref="InvalidOperationException"><paramref name="stream"/> 访问权限为 ReadOnly,mode 值为 Compress。</exception>
 public ZipBaseStream(Stream stream, CompressionMode compressionMode, CompressionLevel level, bool leaveOpen)
     : base()
 {
     Thrower.ThrowArgumentNullExceptionIf(stream, "stream");
     Thrower.ThrowInvalidOperationExceptionIf(!stream.CanWrite && compressionMode == CompressionMode.Compress, "当前流不可写");
     _flushMode = FlushType.None;
     //_workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     _stream          = stream;
     _leaveOpen       = leaveOpen;
     _compressionMode = compressionMode;
     _level           = level;
     _isGZip          = this is GZipStream;
 }
예제 #19
0
 public Stream0(Stream stream, System.IO.Compression.Zlib.CompressionMode compressionMode, CompressionLevel level, Enum4 flavor, bool leaveOpen)
 {
     this.flushType_0        = FlushType.None;
     this.stream_0           = stream;
     this.bool_0             = leaveOpen;
     this.compressionMode_0  = compressionMode;
     this.enum4_0            = flavor;
     this.compressionLevel_0 = level;
     if (flavor == Enum4.const_2)
     {
         this.CRC32 = new CRC32();
     }
 }
예제 #20
0
        internal BlockState DeflateNone(FlushType flush)
        {
            int num = 0xffff;

            if (num > (this.pending.Length - 5))
            {
                num = this.pending.Length - 5;
            }
Label_0021:
            if (this.lookahead <= 1)
            {
                this._fillWindow();
                if ((this.lookahead == 0) && (flush == FlushType.None))
                {
                    return(BlockState.NeedMore);
                }
                if (this.lookahead == 0)
                {
                    this.flush_block_only(flush == FlushType.Finish);
                    if (this._codec.AvailableBytesOut == 0)
                    {
                        return((flush != FlushType.Finish) ? BlockState.NeedMore : BlockState.FinishStarted);
                    }
                    return((flush != FlushType.Finish) ? BlockState.BlockDone : BlockState.FinishDone);
                }
            }
            this.strstart += this.lookahead;
            this.lookahead = 0;
            int num2 = this.block_start + num;

            if ((this.strstart == 0) || (this.strstart >= num2))
            {
                this.lookahead = this.strstart - num2;
                this.strstart  = num2;
                this.flush_block_only(false);
                if (this._codec.AvailableBytesOut == 0)
                {
                    return(BlockState.NeedMore);
                }
            }
            if ((this.strstart - this.block_start) < (this.w_size - MIN_LOOKAHEAD))
            {
                goto Label_0021;
            }
            this.flush_block_only(false);
            if (this._codec.AvailableBytesOut != 0)
            {
                goto Label_0021;
            }
            return(BlockState.NeedMore);
        }
예제 #21
0
 public ZlibBaseStream(System.IO.Stream stream, ZlibStreamFlavor flavor, bool leaveOpen)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream = stream;
     this._leaveOpen = leaveOpen;
     this._flavor = flavor;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         crc = new CRC32();
     }
 }
예제 #22
0
 public ZlibBaseStream(System.IO.Stream stream, ZlibStreamFlavor flavor, bool leaveOpen)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream    = stream;
     this._leaveOpen = leaveOpen;
     this._flavor    = flavor;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         crc = new CRC32();
     }
 }
예제 #23
0
 public ZlibBaseStream(Stream stream, CompressionMode compressionMode, CompressionLevel level, ZlibStreamFlavor flavor, bool leaveOpen)
 {
     this._flushMode       = FlushType.None;
     this._stream          = stream;
     this._leaveOpen       = leaveOpen;
     this._compressionMode = compressionMode;
     this._flavor          = flavor;
     this._level           = level;
     if (flavor != ZlibStreamFlavor.GZIP)
     {
         return;
     }
     this.crc = new CRC32();
 }
예제 #24
0
        /// <summary>
        /// Flushes the fileData into the user's browser.
        /// It's designed for the ASP.NET Applications.
        /// </summary>
        /// <param name="fileName">name of the file</param>
        /// <param name="fileData">byte array containing the file's data</param>
        /// <param name="flushType">How to flush an in memory PDF file</param>
        public static void FlushInBrowser(string fileName, byte[] fileData, FlushType flushType = FlushType.Attachment)
        {
            var fileLength = fileData.Length;

            var context = getCurrentHttpContext();
            var response = getCurrentResponse(context);
            setNoCache(response);
            setContentType(response);
            addHeaders(fileName, fileLength, response, flushType);
            setBufferTrue(response);
            clearResponse(response);
            writeToOutputStream(fileData, fileLength, response);
            responseEnd(response);
        }
예제 #25
0
 public ZlibBaseStream(System.IO.Stream stream,
                       CompressionMode compressionMode,
                       CompressionLevel level,
                       bool leaveOpen)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream          = stream;
     this._leaveOpen       = leaveOpen;
     this._compressionMode = compressionMode;
     this._level           = level;
     // workitem 7159
 }
예제 #26
0
 public ZlibBaseStream(Stream stream, CompressionMode compressionMode, CompressionLevel level, ZlibStreamFlavor flavor, bool leaveOpen)
 {
     _flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     _stream          = stream;
     _leaveOpen       = leaveOpen;
     _compressionMode = compressionMode;
     _flavor          = flavor;
     _level           = level;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         crc = new Crc.CRC32();
     }
 }
예제 #27
0
 public ZlibBaseStream(Stream stream,
     CompressionMode compressionMode,
     CompressionLevel level,
     ZlibStreamFlavor flavor,
     bool leaveOpen)
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream = stream;
     this._leaveOpen = leaveOpen;
     this._compressionMode = compressionMode;
     this._flavor = flavor;
     this._level = level;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP) {
         this.crc = new CRC32();
     }
 }
 public ZlibBaseStream(System.IO.Stream stream,
                       CompressionMode compressionMode,
                       CompressionLevel level,
                       ZlibStreamFlavor flavor,
                       bool leaveOpen,
                       int windowBits)
     : base()
 {
     this._flushMode = FlushType.None;
     //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT];
     this._stream = stream;
     this._leaveOpen = leaveOpen;
     this._compressionMode = compressionMode;
     this._flavor = flavor;
     this._level = level;
     this.windowBitsMax = windowBits;
     // workitem 7159
     if (flavor == ZlibStreamFlavor.GZIP)
     {
         this.crc = new BestHTTP.Decompression.Crc.CRC32();
     }
 }
예제 #29
0
        public ZLibStatus inflate(FlushType ff)
        {
            ZLibStatus r;
            int b;

            if (base.next_in == null)
                return ZLibStatus.Z_STREAM_ERROR;
            var f = ff == FlushType.Z_FINISH ? ZLibStatus.Z_BUF_ERROR : ZLibStatus.Z_OK;
            r = ZLibStatus.Z_BUF_ERROR;
            while (true)
            {
                //System.out.println("mode: "+this.mode);
                switch (this._mode)
                {
                    case InflateMode.METHOD:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        if (((this.method = base.next_in[base.next_in_index++]) & 0xf) != Z_DEFLATED)
                        {
                            this._mode = InflateMode.BAD;
                            base.msg = "unknown compression method";
                            this._marker = 5;       // can't try inflateSync
                            break;
                        }
                        if ((this.method >> 4) + 8 > this._wbits)
                        {
                            this._mode = InflateMode.BAD;
                            base.msg = "invalid window size";
                            this._marker = 5;       // can't try inflateSync
                            break;
                        }
                        this._mode = InflateMode.FLAG;
                        goto case InflateMode.FLAG;
                    case InflateMode.FLAG:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        b = (base.next_in[base.next_in_index++]) & 0xff;

                        if ((((this.method << 8) + b) % 31) != 0)
                        {
                            this._mode = InflateMode.BAD;
                            base.msg = "incorrect header check";
                            this._marker = 5;       // can't try inflateSync
                            break;
                        }

                        if ((b & PRESET_DICT) == 0)
                        {
                            this._mode = InflateMode.BLOCKS;
                            break;
                        }
                        this._mode = InflateMode.DICT4;
                        goto case InflateMode.DICT4;
                    case InflateMode.DICT4:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need = ((base.next_in[base.next_in_index++] & 0xff) << 24) & 0xff000000L;
                        this._mode = InflateMode.DICT3;
                        goto case InflateMode.DICT3;
                    case InflateMode.DICT3:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need += ((base.next_in[base.next_in_index++] & 0xff) << 16) & 0xff0000L;
                        this._mode = InflateMode.DICT2;
                        goto case InflateMode.DICT2;
                    case InflateMode.DICT2:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need += ((base.next_in[base.next_in_index++] & 0xff) << 8) & 0xff00L;
                        this._mode = InflateMode.DICT1;
                        goto case InflateMode.DICT1;
                    case InflateMode.DICT1:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need += (base.next_in[base.next_in_index++] & 0xffL);
                        base.adler = this._need;
                        this._mode = InflateMode.DICT0;
                        return ZLibStatus.Z_NEED_DICT;
                    case InflateMode.DICT0:
                        this._mode = InflateMode.BAD;
                        base.msg = "need dictionary";
                        this._marker = 0;       // can try inflateSync
                        return ZLibStatus.Z_STREAM_ERROR;
                    case InflateMode.BLOCKS:

                        r = this._blocks.proc(this, r);
                        if (r == ZLibStatus.Z_DATA_ERROR)
                        {
                            this._mode = InflateMode.BAD;
                            this._marker = 0;     // can try inflateSync
                            break;
                        }
                        if (r == ZLibStatus.Z_OK)
                        {
                            r = f;
                        }
                        if (r != ZLibStatus.Z_STREAM_END)
                        {
                            return r;
                        }
                        r = f;
                        this._blocks.reset(this, this._was);
                        if (this._nowrap != 0)
                        {
                            this._mode = InflateMode.DONE;
                            break;
                        }
                        this._mode = InflateMode.CHECK4;
                        goto case InflateMode.CHECK4;
                    case InflateMode.CHECK4:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need = ((base.next_in[base.next_in_index++] & 0xff) << 24) & 0xff000000L;
                        this._mode = InflateMode.CHECK3;
                        goto case InflateMode.CHECK3;
                    case InflateMode.CHECK3:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need += ((base.next_in[base.next_in_index++] & 0xff) << 16) & 0xff0000L;
                        this._mode = InflateMode.CHECK2;
                        goto case InflateMode.CHECK2;
                    case InflateMode.CHECK2:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need += ((base.next_in[base.next_in_index++] & 0xff) << 8) & 0xff00L;
                        this._mode = InflateMode.CHECK1;
                        goto case InflateMode.CHECK1;
                    case InflateMode.CHECK1:

                        if (base.avail_in == 0) return r; r = f;

                        base.avail_in--; base.total_in++;
                        this._need += (base.next_in[base.next_in_index++] & 0xffL);

                        if (((int)(this._was[0])) != ((int)(this._need)))
                        {
                            this._mode = InflateMode.BAD;
                            base.msg = "incorrect data check";
                            this._marker = 5;       // can't try inflateSync
                            break;
                        }

                        this._mode = InflateMode.DONE;
                        goto case InflateMode.DONE;
                    case InflateMode.DONE:
                        return ZLibStatus.Z_STREAM_END;
                    case InflateMode.BAD:
                        return ZLibStatus.Z_DATA_ERROR;
                    default:
                        return ZLibStatus.Z_STREAM_ERROR;
                }
            }
        }
예제 #30
0
 public ZLibStatus inflate(byte[] inputBufer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset, int outputCount, FlushType flushType)
 {
     this.next_in = inputBufer;
     this.next_in_index = inputOffset;
     this.avail_in = inputCount;
     this.next_out = outputBuffer;
     this.next_out_index = outputOffset;
     this.avail_out = outputCount;
     return this.inflate(flushType);
 }
예제 #31
0
 public ZInputStream()
 {
     this.FlushMode = FlushType.Z_PARTIAL_FLUSH;
 }
예제 #32
0
        public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count)
        {
            // According to MS documentation, any implementation of the IO.Stream.Read function must:
            // (a) throw an exception if offset & count reference an invalid part of the buffer,
            //     or if count < 0, or if buffer is null
            // (b) return 0 only upon EOF, or if count = 0
            // (c) if not EOF, then return at least 1 byte, up to <count> bytes

            if (_streamMode == StreamMode.Undefined)
            {
                if (!this._stream.CanRead) throw new ZlibException("The stream is not readable.");
                // for the first read, set up some controls.
                _streamMode = StreamMode.Reader;
                // (The first reference to _z goes through the private accessor which
                // may initialize it.)
                z.AvailableBytesIn = 0;
                if (_flavor == ZlibStreamFlavor.GZIP)
                {
                    _gzipHeaderByteCount = _ReadAndValidateGzipHeader();
                    // workitem 8501: handle edge case (decompress empty stream)
                    if (_gzipHeaderByteCount == 0)
                        return 0;
                }
            }

            if (_streamMode != StreamMode.Reader)
                throw new ZlibException("Cannot Read after Writing.");

            if (count == 0) return 0;
            // workitem 10562
            // this quits too early if the input buffer has been consumed but
            // there's still output which hasn't been created yet (e.g. block
            // data for tables / tree, or the trailing adler32 data). we
            // need to wait for a Z_STREAM_END from Deflate instead.
            //if (nomoreinput && _wantCompress) return 0;  // workitem 8557
            if (buffer == null) throw new ArgumentNullException("buffer");
            if (count < 0) throw new ArgumentOutOfRangeException("count");
            if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset");
            if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count");

            int rc = 0;

            // set up the output of the deflate/inflate codec:
            _z.OutputBuffer = buffer;
            _z.NextOut = offset;
            _z.AvailableBytesOut = count;

            // This is necessary in case _workingBuffer has been resized. (new byte[])
            // (The first reference to _workingBuffer goes through the private accessor which
            // may initialize it.)
            _z.InputBuffer = workingBuffer;

            do
            {
                // need data in _workingBuffer in order to deflate/inflate.  Here, we check if we have any.
                if ((_z.AvailableBytesIn == 0) && (!nomoreinput))
                {
                    // No data available, so try to Read data from the captive stream.
                    _z.NextIn = 0;
                    _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length);
                    if (_z.AvailableBytesIn == 0)
                        nomoreinput = true;

                }
                // workitem 10562
                // if we've consumed all the input then we need to generate any
                // remaining block data and checksums and put them in the pending array
                if (nomoreinput) _flushMode = FlushType.Finish;
                // we have data in InputBuffer; now compress or decompress as appropriate
                rc = (_wantCompress)
                    ? _z.Deflate(_flushMode)
                    : _z.Inflate(_flushMode);

                if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR))
                    return 0;

                if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
                    throw new ZlibException(String.Format("{0}flating:  rc={1}  msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message));

                if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count))
                {
                    // workitem 10562
                    // we've genuinely reached the end of the output stream now,
                    // including any block data and adler32 which appears after
                    // the compressed input data. we don't have any more bytes
                    // to return so we can stop processing
                    return 0; // nothing more to read
                };
            }
            //while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK);
            //while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK);
            while (_z.AvailableBytesOut > 0 && rc == ZlibConstants.Z_OK);

            // workitem 10562
            // the following is no longer required as we now call _z.Deflate
            // in the main loop above instead
            //// workitem 8557
            //// is there more room in output?
            //if (_z.AvailableBytesOut > 0)
            //{
            //    if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0)
            //    {
            //        // deferred
            //    }
            //
            //    // are we completely done reading?
            //    if (nomoreinput)
            //    {
            //        // and in compression?
            //        if (_wantCompress)
            //        {
            //            // no more input data available; therefore we flush to
            //            // try to complete the read
            //            rc = _z.Deflate(FlushType.Finish);
            //
            //            if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END)
            //                throw new ZlibException(String.Format("Deflating:  rc={0}  msg={1}", rc, _z.Message));
            //        }
            //    }
            //}

            rc = (count - _z.AvailableBytesOut);

            // calculate CRC after reading
            if (crc != null)
                crc.SlurpBlock(buffer, offset, rc);

            return rc;
        }
예제 #33
0
 public ZLibStatus deflate(byte[] bufer, int offset, int count, byte[] p1, int p2, int p3, FlushType flushType)
 {
     throw new NotImplementedException();
 }
예제 #34
0
파일: Inflate.cs 프로젝트: RestRT/RestRT
        internal int Inflate(FlushType flush)
        {
            int r;
            int b;
            int f = (int)flush;

            if (_codec.InputBuffer == null)
                throw new ZlibException("InputBuffer is null. ");

            f = (f == (int)FlushType.Finish)
                ? ZlibConstants.Z_BUF_ERROR
                : ZlibConstants.Z_OK;
            r = ZlibConstants.Z_BUF_ERROR;
            while (true)
            {
                switch (mode)
                {
                    case METHOD:
                        if (_codec.AvailableBytesIn == 0)
                            return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;

                        if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED)
                        {
                            mode = BAD;
                            _codec.Message = String.Format("unknown compression method (0x{0:X2})", method);
                            marker = 5; // can't try inflateSync
                            break;
                        }
                        if ((method >> 4) + 8 > wbits)
                        {
                            mode = BAD;
                            _codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8);
                            marker = 5; // can't try inflateSync
                            break;
                        }
                        mode = FLAG;
                        goto case FLAG;

                    case FLAG:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff;

                        if ((((method << 8) + b) % 31) != 0)
                        {
                            mode = BAD;
                            _codec.Message = "incorrect header check";
                            marker = 5; // can't try inflateSync
                            break;
                        }

                        if ((b & PRESET_DICT) == 0)
                        {
                            mode = BLOCKS;
                            break;
                        }
                        mode = DICT4;
                        goto case DICT4;

                    case DICT4:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need = ((_codec.InputBuffer[_codec.NextIn++] & 0xff) << 24) & unchecked((int)0xff000000L);
                        mode = DICT3;
                        goto case DICT3;

                    case DICT3:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need += (((_codec.InputBuffer[_codec.NextIn++] & 0xff) << 16) & 0xff0000L);
                        mode = DICT2;
                        goto case DICT2;

                    case DICT2:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need += (((_codec.InputBuffer[_codec.NextIn++] & 0xff) << 8) & 0xff00L);
                        mode = DICT1;
                        goto case DICT1;

                    case DICT1:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need += (_codec.InputBuffer[_codec.NextIn++] & 0xffL);
                        _codec._Adler32 = need;
                        mode = DICT0;
                        return ZlibConstants.Z_NEED_DICT;

                    case DICT0:
                        mode = BAD;
                        _codec.Message = "need dictionary";
                        marker = 0; // can try inflateSync
                        return ZlibConstants.Z_STREAM_ERROR;

                    case BLOCKS:
                        r = blocks.Process(r);
                        if (r == ZlibConstants.Z_DATA_ERROR)
                        {
                            mode = BAD;
                            marker = 0; // can try inflateSync
                            break;
                        }
                        if (r == ZlibConstants.Z_OK) r = f;

                        if (r != ZlibConstants.Z_STREAM_END) return r;

                        r = f;
                        blocks.Reset(was);
                        if (!HandleRfc1950HeaderBytes)
                        {
                            mode = DONE;
                            break;
                        }
                        mode = CHECK4;
                        goto case CHECK4;

                    case CHECK4:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need = ((_codec.InputBuffer[_codec.NextIn++] & 0xff) << 24) & unchecked((int)0xff000000L);
                        mode = CHECK3;
                        goto case CHECK3;

                    case CHECK3:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need += (((_codec.InputBuffer[_codec.NextIn++] & 0xff) << 16) & 0xff0000L);
                        mode = CHECK2;
                        goto case CHECK2;

                    case CHECK2:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;

                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        need += (((_codec.InputBuffer[_codec.NextIn++] & 0xff) << 8) & 0xff00L);
                        mode = CHECK1;
                        goto case CHECK1;

                    case CHECK1:

                        if (_codec.AvailableBytesIn == 0) return r;

                        r = f;

                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        need += (_codec.InputBuffer[_codec.NextIn++] & 0xffL);
                        unchecked
                        {
                            if (((int)(was[0])) != ((int)(need)))
                            {
                                mode = BAD;
                                _codec.Message = "incorrect data check";
                                marker = 5; // can't try inflateSync
                                break;
                            }
                        }
                        mode = DONE;
                        goto case DONE;

                    case DONE:
                        return ZlibConstants.Z_STREAM_END;

                    case BAD:
                        throw new ZlibException(String.Format("Bad state ({0})", _codec.Message));
                    //return ZlibConstants.Z_DATA_ERROR;

                    default:
                        throw new ZlibException("Stream error.");
                    //return ZlibConstants.Z_STREAM_ERROR;

                }
            }
        }
예제 #35
0
        private ZLibStatus deflateReset()
        {
            base.total_in = base.total_out = 0;
            base.msg = null; //
            base.data_type = BlockType.Z_UNKNOWN;

            pending = 0;
            pending_out = 0;

            if (noheader < 0)
            {
                noheader = 0; // was set to -1 by deflate(..., FlushType.Z_FINISH);
            }
            _status = (noheader != 0) ? BUSY_STATE : INIT_STATE;
            base.adler = Adler32.adler32(0, null, 0, 0);

            last_flush = FlushType.Z_NO_FLUSH;

            tr_init();
            lm_init();
            return ZLibStatus.Z_OK;
        }
예제 #36
0
 /// <summary>
 /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer.
 /// </summary>
 /// <remarks>
 /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and 
 /// AvailableBytesOut  before calling this method.
 /// </remarks>
 /// <example>
 /// <code>
 /// private void InflateBuffer()
 /// {
 ///     int bufferSize = 1024;
 ///     byte[] buffer = new byte[bufferSize];
 ///     ZlibCodec decompressor = new ZlibCodec();
 /// 
 ///     Console.WriteLine("\n============================================");
 ///     Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length);
 ///     MemoryStream ms = new MemoryStream(DecompressedBytes);
 /// 
 ///     int rc = decompressor.InitializeInflate();
 /// 
 ///     decompressor.InputBuffer = CompressedBytes;
 ///     decompressor.NextIn = 0;
 ///     decompressor.AvailableBytesIn = CompressedBytes.Length;
 /// 
 ///     decompressor.OutputBuffer = buffer;
 /// 
 ///     // pass 1: inflate 
 ///     do
 ///     {
 ///         decompressor.NextOut = 0;
 ///         decompressor.AvailableBytesOut = buffer.Length;
 ///         rc = decompressor.Inflate(FlushType.None);
 /// 
 ///         if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
 ///             throw new Exception("inflating: " + decompressor.Message);
 /// 
 ///         ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut);
 ///     }
 ///     while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
 /// 
 ///     // pass 2: finish and flush
 ///     do
 ///     {
 ///         decompressor.NextOut = 0;
 ///         decompressor.AvailableBytesOut = buffer.Length;
 ///         rc = decompressor.Inflate(FlushType.Finish);
 /// 
 ///         if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
 ///             throw new Exception("inflating: " + decompressor.Message);
 /// 
 ///         if (buffer.Length - decompressor.AvailableBytesOut &gt; 0)
 ///             ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut);
 ///     }
 ///     while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
 /// 
 ///     decompressor.EndInflate();
 /// }
 ///
 /// </code>
 /// </example>
 /// <param name="flush">The flush to use when inflating.</param>
 /// <returns>Z_OK if everything goes well.</returns>
 internal int Inflate(FlushType flush)
 {
     if (istate == null)
         throw new ZlibException("No Inflate State!");
     return istate.Inflate(flush);
 }
예제 #37
0
파일: ZlibCodec.cs 프로젝트: virmitio/coapp
 ///<summary>
 ///  Inflate the data in the InputBuffer, placing the result in the OutputBuffer.
 ///</summary>
 ///<remarks>
 ///  You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and AvailableBytesOut before calling this method.
 ///</remarks>
 ///<example>
 ///  <code>private void InflateBuffer()
 ///    {
 ///    int bufferSize = 1024;
 ///    byte[] buffer = new byte[bufferSize];
 ///    ZlibCodec decompressor = new ZlibCodec();
 /// 
 ///    Console.WriteLine("\n============================================");
 ///    Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length);
 ///    MemoryStream ms = new MemoryStream(DecompressedBytes);
 /// 
 ///    int rc = decompressor.InitializeInflate();
 /// 
 ///    decompressor.InputBuffer = CompressedBytes;
 ///    decompressor.NextIn = 0;
 ///    decompressor.AvailableBytesIn = CompressedBytes.Length;
 /// 
 ///    decompressor.OutputBuffer = buffer;
 /// 
 ///    // pass 1: inflate 
 ///    do
 ///    {
 ///    decompressor.NextOut = 0;
 ///    decompressor.AvailableBytesOut = buffer.Length;
 ///    rc = decompressor.Inflate(FlushType.None);
 /// 
 ///    if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
 ///    throw new Exception("inflating: " + decompressor.Message);
 /// 
 ///    ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut);
 ///    }
 ///    while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
 /// 
 ///    // pass 2: finish and flush
 ///    do
 ///    {
 ///    decompressor.NextOut = 0;
 ///    decompressor.AvailableBytesOut = buffer.Length;
 ///    rc = decompressor.Inflate(FlushType.Finish);
 /// 
 ///    if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
 ///    throw new Exception("inflating: " + decompressor.Message);
 /// 
 ///    if (buffer.Length - decompressor.AvailableBytesOut &gt; 0)
 ///    ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut);
 ///    }
 ///    while (decompressor.AvailableBytesIn &gt; 0 || decompressor.AvailableBytesOut == 0);
 /// 
 ///    decompressor.EndInflate();
 ///    }</code>
 ///</example>
 ///<param name="flush"> The flush to use when inflating. </param>
 ///<returns> Z_OK if everything goes well. </returns>
 public int Inflate(FlushType flush) {
     if (istate == null) {
         throw new ZlibException("No Inflate State!");
     }
     return istate.Inflate(flush);
 }
        internal int Deflate(FlushType flush)
        {
            int old_flush;

            if (_codec.OutputBuffer == null ||
                (_codec.InputBuffer == null && _codec.AvailableBytesIn != 0) ||
                (status == FINISH_STATE && flush != FlushType.Finish))
            {
                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_STREAM_ERROR)];
                throw new ZlibException(String.Format("Something is fishy. [{0}]", _codec.Message));
            }
            if (_codec.AvailableBytesOut == 0)
            {
                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
                throw new ZlibException("OutputBuffer is full (AvailableBytesOut == 0)");
            }

            old_flush = last_flush;
            last_flush = (int)flush;

            // Write the zlib (rfc1950) header bytes
            if (status == INIT_STATE)
            {
                int header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
                int level_flags = (((int)compressionLevel - 1) & 0xff) >> 1;

                if (level_flags > 3)
                    level_flags = 3;
                header |= (level_flags << 6);
                if (strstart != 0)
                    header |= PRESET_DICT;
                header += 31 - (header % 31);

                status = BUSY_STATE;
                //putShortMSB(header);
                unchecked
                {
                    pending[pendingCount++] = (byte)(header >> 8);
                    pending[pendingCount++] = (byte)header;
                }
                // Save the adler32 of the preset dictionary:
                if (strstart != 0)
                {
                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24);
                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16);
                    pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8);
                    pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF);
                }
                _codec._Adler32 = Adler.Adler32(0, null, 0, 0);
            }

            // Flush as much pending output as possible
            if (pendingCount != 0)
            {
                _codec.flush_pending();
                if (_codec.AvailableBytesOut == 0)
                {
                    //System.out.println("  avail_out==0");
                    // Since avail_out is 0, deflate will be called again with
                    // more output space, but possibly with both pending and
                    // avail_in equal to zero. There won't be anything to do,
                    // but this is not an error situation so make sure we
                    // return OK instead of BUF_ERROR at next call of deflate:
                    last_flush = -1;
                    return ZlibConstants.Z_OK;
                }

                // Make sure there is something to do and avoid duplicate consecutive
                // flushes. For repeated and useless calls with Z_FINISH, we keep
                // returning Z_STREAM_END instead of Z_BUFF_ERROR.
            }
            else if (_codec.AvailableBytesIn == 0 &&
                     (int)flush <= old_flush &&
                     flush != FlushType.Finish)
            {
                // workitem 8557
                //
                // Not sure why this needs to be an error.  pendingCount == 0, which
                // means there's nothing to deflate.  And the caller has not asked
                // for a FlushType.Finish, but...  that seems very non-fatal.  We
                // can just say "OK" and do nothing.

                // _codec.Message = z_errmsg[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
                // throw new ZlibException("AvailableBytesIn == 0 && flush<=old_flush && flush != FlushType.Finish");

                return ZlibConstants.Z_OK;
            }

            // User must not provide more input after the first FINISH:
            if (status == FINISH_STATE && _codec.AvailableBytesIn != 0)
            {
                _codec.Message = _ErrorMessage[ZlibConstants.Z_NEED_DICT - (ZlibConstants.Z_BUF_ERROR)];
                throw new ZlibException("status == FINISH_STATE && _codec.AvailableBytesIn != 0");
            }

            // Start a new block or continue the current one.
            if (_codec.AvailableBytesIn != 0 || lookahead != 0 || (flush != FlushType.None && status != FINISH_STATE))
            {
                BlockState bstate = DeflateFunction(flush);

                if (bstate == BlockState.FinishStarted || bstate == BlockState.FinishDone)
                {
                    status = FINISH_STATE;
                }
                if (bstate == BlockState.NeedMore || bstate == BlockState.FinishStarted)
                {
                    if (_codec.AvailableBytesOut == 0)
                    {
                        last_flush = -1; // avoid BUF_ERROR next call, see above
                    }
                    return ZlibConstants.Z_OK;
                    // If flush != Z_NO_FLUSH && avail_out == 0, the next call
                    // of deflate should use the same flush parameter to make sure
                    // that the flush is complete. So we don't have to output an
                    // empty block here, this will be done at next call. This also
                    // ensures that for a very small output buffer, we emit at most
                    // one empty block.
                }

                if (bstate == BlockState.BlockDone)
                {
                    if (flush == FlushType.Partial)
                    {
                        _tr_align();
                    }
                    else
                    {
                        // FlushType.Full or FlushType.Sync
                        _tr_stored_block(0, 0, false);
                        // For a full flush, this empty block will be recognized
                        // as a special marker by inflate_sync().
                        if (flush == FlushType.Full)
                        {
                            // clear hash (forget the history)
                            for (int i = 0; i < hash_size; i++)
                                head[i] = 0;
                        }
                    }
                    _codec.flush_pending();
                    if (_codec.AvailableBytesOut == 0)
                    {
                        last_flush = -1; // avoid BUF_ERROR at next call, see above
                        return ZlibConstants.Z_OK;
                    }
                }
            }

            if (flush != FlushType.Finish)
                return ZlibConstants.Z_OK;

            if (!WantRfc1950HeaderBytes || Rfc1950BytesEmitted)
                return ZlibConstants.Z_STREAM_END;

            // Write the zlib trailer (adler32)
            pending[pendingCount++] = (byte)((_codec._Adler32 & 0xFF000000) >> 24);
            pending[pendingCount++] = (byte)((_codec._Adler32 & 0x00FF0000) >> 16);
            pending[pendingCount++] = (byte)((_codec._Adler32 & 0x0000FF00) >> 8);
            pending[pendingCount++] = (byte)(_codec._Adler32 & 0x000000FF);
            //putShortMSB((int)(SharedUtils.URShift(_codec._Adler32, 16)));
            //putShortMSB((int)(_codec._Adler32 & 0xffff));

            _codec.flush_pending();

            // If avail_out is zero, the application will call deflate again
            // to flush the rest.

            Rfc1950BytesEmitted = true; // write the trailer only once!

            return pendingCount != 0 ? ZlibConstants.Z_OK : ZlibConstants.Z_STREAM_END;
        }
        // Compress as much as possible from the input stream, return the current
        // block state.
        // This function does not perform lazy evaluation of matches and inserts
        // new strings in the dictionary only for unmatched strings or for short
        // matches. It is used only for the fast compression options.
        internal BlockState DeflateFast(FlushType flush)
        {
            //    short hash_head = 0; // head of the hash chain
            int hash_head = 0; // head of the hash chain
            bool bflush; // set if current block must be flushed

            while (true)
            {
                // Make sure that we always have enough lookahead, except
                // at the end of the input file. We need MAX_MATCH bytes
                // for the next match, plus MIN_MATCH bytes to insert the
                // string following the next match.
                if (lookahead < MIN_LOOKAHEAD)
                {
                    _fillWindow();
                    if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
                    {
                        return BlockState.NeedMore;
                    }
                    if (lookahead == 0)
                        break; // flush the current block
                }

                // Insert the string window[strstart .. strstart+2] in the
                // dictionary, and set hash_head to the head of the hash chain:
                if (lookahead >= MIN_MATCH)
                {
                    ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;

                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
                    hash_head = (head[ins_h] & 0xffff);
                    prev[strstart & w_mask] = head[ins_h];
                    head[ins_h] = unchecked((short)strstart);
                }

                // Find the longest match, discarding those <= prev_length.
                // At this point we have always match_length < MIN_MATCH

                if (hash_head != 0L && ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
                {
                    // To simplify the code, we prevent matches with the string
                    // of window index 0 (in particular we have to avoid a match
                    // of the string with itself at the start of the input file).
                    if (compressionStrategy != CompressionStrategy.HuffmanOnly)
                    {
                        match_length = longest_match(hash_head);
                    }
                    // longest_match() sets match_start
                }
                if (match_length >= MIN_MATCH)
                {
                    //        check_match(strstart, match_start, match_length);

                    bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);

                    lookahead -= match_length;

                    // Insert new strings in the hash table only if the match length
                    // is not too large. This saves time but degrades compression.
                    if (match_length <= config.MaxLazy && lookahead >= MIN_MATCH)
                    {
                        match_length--; // string at strstart already in hash table
                        do
                        {
                            strstart++;

                            ins_h = ((ins_h << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
                            //      prev[strstart&w_mask]=hash_head=head[ins_h];
                            hash_head = (head[ins_h] & 0xffff);
                            prev[strstart & w_mask] = head[ins_h];
                            head[ins_h] = unchecked((short)strstart);

                            // strstart never exceeds WSIZE-MAX_MATCH, so there are
                            // always MIN_MATCH bytes ahead.
                        }
                        while (--match_length != 0);
                        strstart++;
                    }
                    else
                    {
                        strstart += match_length;
                        match_length = 0;
                        ins_h = window[strstart] & 0xff;

                        ins_h = (((ins_h) << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
                        // If lookahead < MIN_MATCH, ins_h is garbage, but it does not
                        // matter since it will be recomputed at next deflate call.
                    }
                }
                else
                {
                    // No match, output a literal byte

                    bflush = _tr_tally(0, window[strstart] & 0xff);
                    lookahead--;
                    strstart++;
                }
                if (bflush)
                {
                    flush_block_only(false);
                    if (_codec.AvailableBytesOut == 0)
                        return BlockState.NeedMore;
                }
            }

            flush_block_only(flush == FlushType.Finish);
            if (_codec.AvailableBytesOut == 0)
            {
                if (flush == FlushType.Finish)
                    return BlockState.FinishStarted;
                else
                    return BlockState.NeedMore;
            }
            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
        }
예제 #40
0
 public ZLibStatus deflate(FlushType flushType)
 {
     throw new NotImplementedException();
 }
예제 #41
0
        // Copy without compression as much as possible from the input stream, return
        // the current block state.
        // This function does not insert new strings in the dictionary since
        // uncompressible data is probably not useful. This function is used
        // only for the level=0 compression option.
        // NOTE: this function should be optimized to avoid extra copying from
        // window to pending_buf.
        private int deflate_stored(FlushType flush)
        {
            // Stored blocks are limited to 0xffff bytes, pending_buf is limited
            // to pending_buf_size, and each stored block has a 5 byte header:

            int max_block_size = 0xffff;
            int max_start;

            if (max_block_size > _pendingBufferSize - 5)
            {
                max_block_size = _pendingBufferSize - 5;
            }

            // Copy as much as possible from input to output:
            while (true)
            {
                // Fill the window as much as possible:
                if (_validBytesAhead <= 1)
                {
                    fill_window();
                    if (_validBytesAhead == 0 && flush == FlushType.Z_NO_FLUSH) return NeedMore;
                    if (_validBytesAhead == 0) break; // flush the current block
                }

                _startInsertString += _validBytesAhead;
                _validBytesAhead = 0;

                // Emit a stored block if pending_buf will be full:
                max_start = _blockStart + max_block_size;
                if (_startInsertString == 0 || _startInsertString >= max_start)
                {
                    // strstart == 0 is possible when wraparound on 16-bit machine
                    _validBytesAhead = (int)(_startInsertString - max_start);
                    _startInsertString = (int)max_start;

                    flush_block_only(false);
                    if (base.avail_out == 0) return NeedMore;

                }

                // Flush if we may have to slide, otherwise block_start may become
                // negative and the data will be gone:
                if (_startInsertString - _blockStart >= _windowSize - MIN_LOOKAHEAD)
                {
                    flush_block_only(false);
                    if (base.avail_out == 0) return NeedMore;
                }
            }

            flush_block_only(flush == FlushType.Z_FINISH);
            if (base.avail_out == 0)
                return (flush == FlushType.Z_FINISH) ? FinishStarted : NeedMore;

            return flush == FlushType.Z_FINISH ? FinishDone : BlockDone;
        }
예제 #42
0
        internal int Inflate(FlushType flush)
        {
            int b;

            if (_codec.InputBuffer == null)
                throw new ZlibException("InputBuffer is null. ");

            //             int f = (flush == FlushType.Finish)
            //                 ? ZlibConstants.Z_BUF_ERROR
            //                 : ZlibConstants.Z_OK;

            // workitem 8870
            int f = ZlibConstants.Z_OK;
            int r = ZlibConstants.Z_BUF_ERROR;

            while (true)
            {
                switch (mode)
                {
                    case InflateManagerMode.METHOD:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        if (((method = _codec.InputBuffer[_codec.NextIn++]) & 0xf) != Z_DEFLATED)
                        {
                            mode = InflateManagerMode.BAD;
                            _codec.Message = String.Format("unknown compression method (0x{0:X2})", method);
                            marker = 5; // can't try inflateSync
                            break;
                        }
                        if ((method >> 4) + 8 > wbits)
                        {
                            mode = InflateManagerMode.BAD;
                            _codec.Message = String.Format("invalid window size ({0})", (method >> 4) + 8);
                            marker = 5; // can't try inflateSync
                            break;
                        }
                        mode = InflateManagerMode.FLAG;
                        break;


                    case InflateManagerMode.FLAG:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        b = (_codec.InputBuffer[_codec.NextIn++]) & 0xff;

                        if ((((method << 8) + b) % 31) != 0)
                        {
                            mode = InflateManagerMode.BAD;
                            _codec.Message = "incorrect header check";
                            marker = 5; // can't try inflateSync
                            break;
                        }

                        mode = ((b & PRESET_DICT) == 0)
                            ? InflateManagerMode.BLOCKS
                            : InflateManagerMode.DICT4;
                        break;

                    case InflateManagerMode.DICT4:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
                        mode = InflateManagerMode.DICT3;
                        break;

                    case InflateManagerMode.DICT3:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
                        mode = InflateManagerMode.DICT2;
                        break;

                    case InflateManagerMode.DICT2:

                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
                        mode = InflateManagerMode.DICT1;
                        break;


                    case InflateManagerMode.DICT1:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
                        _codec._Adler32 = expectedCheck;
                        mode = InflateManagerMode.DICT0;
                        return ZlibConstants.Z_NEED_DICT;


                    case InflateManagerMode.DICT0:
                        mode = InflateManagerMode.BAD;
                        _codec.Message = "need dictionary";
                        marker = 0; // can try inflateSync
                        return ZlibConstants.Z_STREAM_ERROR;


                    case InflateManagerMode.BLOCKS:
                        r = blocks.Process(r);
                        if (r == ZlibConstants.Z_DATA_ERROR)
                        {
                            mode = InflateManagerMode.BAD;
                            marker = 0; // can try inflateSync
                            break;
                        }

                        if (r == ZlibConstants.Z_OK) r = f;

                        if (r != ZlibConstants.Z_STREAM_END)
                            return r;

                        r = f;
                        computedCheck = blocks.Reset();
                        if (!HandleRfc1950HeaderBytes)
                        {
                            mode = InflateManagerMode.DONE;
                            return ZlibConstants.Z_STREAM_END;
                        }
                        mode = InflateManagerMode.CHECK4;
                        break;

                    case InflateManagerMode.CHECK4:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        expectedCheck = (uint)((_codec.InputBuffer[_codec.NextIn++] << 24) & 0xff000000);
                        mode = InflateManagerMode.CHECK3;
                        break;

                    case InflateManagerMode.CHECK3:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 16) & 0x00ff0000);
                        mode = InflateManagerMode.CHECK2;
                        break;

                    case InflateManagerMode.CHECK2:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--;
                        _codec.TotalBytesIn++;
                        expectedCheck += (uint)((_codec.InputBuffer[_codec.NextIn++] << 8) & 0x0000ff00);
                        mode = InflateManagerMode.CHECK1;
                        break;

                    case InflateManagerMode.CHECK1:
                        if (_codec.AvailableBytesIn == 0) return r;
                        r = f;
                        _codec.AvailableBytesIn--; _codec.TotalBytesIn++;
                        expectedCheck += (uint)(_codec.InputBuffer[_codec.NextIn++] & 0x000000ff);
                        if (computedCheck != expectedCheck)
                        {
                            mode = InflateManagerMode.BAD;
                            _codec.Message = "incorrect data check";
                            marker = 5; // can't try inflateSync
                            break;
                        }
                        mode = InflateManagerMode.DONE;
                        return ZlibConstants.Z_STREAM_END;

                    case InflateManagerMode.DONE:
                        return ZlibConstants.Z_STREAM_END;

                    case InflateManagerMode.BAD:
                        throw new ZlibException(String.Format("Bad state ({0})", _codec.Message));

                    default:
                        throw new ZlibException("Stream error.");

                }
            }
        }
예제 #43
0
        // Compress as much as possible from the input stream, return the current
        // block state.
        // This function does not perform lazy evaluation of matches and inserts
        // new strings in the dictionary only for unmatched strings or for short
        // matches. It is used only for the fast compression options.
        private int deflate_fast(FlushType flush)
        {
            //    short hash_head = 0; // head of the hash chain
            int hash_head = 0; // head of the hash chain
            bool bflush;      // set if current block must be flushed

            while (true)
            {
                // Make sure that we always have enough lookahead, except
                // at the end of the input file. We need MAX_MATCH bytes
                // for the next match, plus MIN_MATCH bytes to insert the
                // string following the next match.
                if (_validBytesAhead < MIN_LOOKAHEAD)
                {
                    fill_window();
                    if (_validBytesAhead < MIN_LOOKAHEAD && flush == FlushType.Z_NO_FLUSH)
                    {
                        return NeedMore;
                    }
                    if (_validBytesAhead == 0) break; // flush the current block
                }

                // Insert the string window[strstart .. strstart+2] in the
                // dictionary, and set hash_head to the head of the hash chain:
                if (_validBytesAhead >= MIN_MATCH)
                {
                    _insertedHashIndex = (((_insertedHashIndex) << _hashShift) ^ (_window[(_startInsertString) + (MIN_MATCH - 1)] & 0xff)) & _hashMask;

                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
                    hash_head = (_head[_insertedHashIndex] & 0xffff);
                    _previous[_startInsertString & _windowMask] = _head[_insertedHashIndex];
                    _head[_insertedHashIndex] = (short)_startInsertString;
                }

                // Find the longest match, discarding those <= prev_length.
                // At this point we have always match_length < MIN_MATCH

                if (hash_head != 0L &&
                    ((_startInsertString - hash_head) & 0xffff) <= _windowSize - MIN_LOOKAHEAD
                    )
                {
                    // To simplify the code, we prevent matches with the string
                    // of window index 0 (in particular we have to avoid a match
                    // of the string with itself at the start of the input file).
                    if (strategy != CompressionStrategy.Z_HUFFMAN_ONLY)
                    {
                        _matchLength = longest_match(hash_head);
                    }
                    // longest_match() sets match_start
                }
                if (_matchLength >= MIN_MATCH)
                {
                    //        check_match(strstart, match_start, match_length);

                    bflush = _tr_tally(_startInsertString - _startMatchString, _matchLength - MIN_MATCH);

                    _validBytesAhead -= _matchLength;

                    // Insert new strings in the hash table only if the match length
                    // is not too large. This saves time but degrades compression.
                    if (_matchLength <= _maxLazyMatch &&
                        _validBytesAhead >= MIN_MATCH)
                    {
                        _matchLength--; // string at strstart already in hash table
                        do
                        {
                            _startInsertString++;

                            _insertedHashIndex = ((_insertedHashIndex << _hashShift) ^ (_window[(_startInsertString) + (MIN_MATCH - 1)] & 0xff)) & _hashMask;
                            //      prev[strstart&w_mask]=hash_head=head[ins_h];
                            hash_head = (_head[_insertedHashIndex] & 0xffff);
                            _previous[_startInsertString & _windowMask] = _head[_insertedHashIndex];
                            _head[_insertedHashIndex] = (short)_startInsertString;

                            // strstart never exceeds WSIZE-MAX_MATCH, so there are
                            // always MIN_MATCH bytes ahead.
                        }
                        while (--_matchLength != 0);
                        _startInsertString++;
                    }
                    else
                    {
                        _startInsertString += _matchLength;
                        _matchLength = 0;
                        _insertedHashIndex = _window[_startInsertString] & 0xff;

                        _insertedHashIndex = (((_insertedHashIndex) << _hashShift) ^ (_window[_startInsertString + 1] & 0xff)) & _hashMask;
                        // If lookahead < MIN_MATCH, ins_h is garbage, but it does not
                        // matter since it will be recomputed at next deflate call.
                    }
                }
                else
                {
                    // No match, output a literal byte

                    bflush = _tr_tally(0, _window[_startInsertString] & 0xff);
                    _validBytesAhead--;
                    _startInsertString++;
                }
                if (bflush)
                {

                    flush_block_only(false);
                    if (base.avail_out == 0) return NeedMore;
                }
            }

            flush_block_only(flush == FlushType.Z_FINISH);
            if (base.avail_out == 0)
            {
                if (flush == FlushType.Z_FINISH) return FinishStarted;
                else return NeedMore;
            }
            return flush == FlushType.Z_FINISH ? FinishDone : BlockDone;
        }
        // Same as above, but achieves better compression. We use a lazy
        // evaluation for matches: a match is finally adopted only if there is
        // no better match at the next window position.
        internal BlockState DeflateSlow(FlushType flush)
        {
            //    short hash_head = 0;    // head of hash chain
            int hash_head = 0; // head of hash chain
            bool bflush; // set if current block must be flushed

            // Process the input block.
            while (true)
            {
                // Make sure that we always have enough lookahead, except
                // at the end of the input file. We need MAX_MATCH bytes
                // for the next match, plus MIN_MATCH bytes to insert the
                // string following the next match.

                if (lookahead < MIN_LOOKAHEAD)
                {
                    _fillWindow();
                    if (lookahead < MIN_LOOKAHEAD && flush == FlushType.None)
                        return BlockState.NeedMore;

                    if (lookahead == 0)
                        break; // flush the current block
                }

                // Insert the string window[strstart .. strstart+2] in the
                // dictionary, and set hash_head to the head of the hash chain:

                if (lookahead >= MIN_MATCH)
                {
                    ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
                    hash_head = (head[ins_h] & 0xffff);
                    prev[strstart & w_mask] = head[ins_h];
                    head[ins_h] = unchecked((short)strstart);
                }

                // Find the longest match, discarding those <= prev_length.
                prev_length = match_length;
                prev_match = match_start;
                match_length = MIN_MATCH - 1;

                if (hash_head != 0 && prev_length < config.MaxLazy &&
                    ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD)
                {
                    // To simplify the code, we prevent matches with the string
                    // of window index 0 (in particular we have to avoid a match
                    // of the string with itself at the start of the input file).

                    if (compressionStrategy != CompressionStrategy.HuffmanOnly)
                    {
                        match_length = longest_match(hash_head);
                    }
                    // longest_match() sets match_start

                    if (match_length <= 5 && (compressionStrategy == CompressionStrategy.Filtered ||
                                              (match_length == MIN_MATCH && strstart - match_start > 4096)))
                    {

                        // If prev_match is also MIN_MATCH, match_start is garbage
                        // but we will ignore the current match anyway.
                        match_length = MIN_MATCH - 1;
                    }
                }

                // If there was a match at the previous step and the current
                // match is not better, output the previous match:
                if (prev_length >= MIN_MATCH && match_length <= prev_length)
                {
                    int max_insert = strstart + lookahead - MIN_MATCH;
                    // Do not insert strings in hash table beyond this.

                    //          check_match(strstart-1, prev_match, prev_length);

                    bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);

                    // Insert in hash table all strings up to the end of the match.
                    // strstart-1 and strstart are already inserted. If there is not
                    // enough lookahead, the last two strings are not inserted in
                    // the hash table.
                    lookahead -= (prev_length - 1);
                    prev_length -= 2;
                    do
                    {
                        if (++strstart <= max_insert)
                        {
                            ins_h = (((ins_h) << hash_shift) ^ (window[(strstart) + (MIN_MATCH - 1)] & 0xff)) & hash_mask;
                            //prev[strstart&w_mask]=hash_head=head[ins_h];
                            hash_head = (head[ins_h] & 0xffff);
                            prev[strstart & w_mask] = head[ins_h];
                            head[ins_h] = unchecked((short)strstart);
                        }
                    }
                    while (--prev_length != 0);
                    match_available = 0;
                    match_length = MIN_MATCH - 1;
                    strstart++;

                    if (bflush)
                    {
                        flush_block_only(false);
                        if (_codec.AvailableBytesOut == 0)
                            return BlockState.NeedMore;
                    }
                }
                else if (match_available != 0)
                {

                    // If there was no match at the previous position, output a
                    // single literal. If there was a match but the current match
                    // is longer, truncate the previous match to a single literal.

                    bflush = _tr_tally(0, window[strstart - 1] & 0xff);

                    if (bflush)
                    {
                        flush_block_only(false);
                    }
                    strstart++;
                    lookahead--;
                    if (_codec.AvailableBytesOut == 0)
                        return BlockState.NeedMore;
                }
                else
                {
                    // There is no previous match to compare with, wait for
                    // the next step to decide.

                    match_available = 1;
                    strstart++;
                    lookahead--;
                }
            }

            if (match_available != 0)
            {
                bflush = _tr_tally(0, window[strstart - 1] & 0xff);
                match_available = 0;
            }
            flush_block_only(flush == FlushType.Finish);

            if (_codec.AvailableBytesOut == 0)
            {
                if (flush == FlushType.Finish)
                    return BlockState.FinishStarted;
                else
                    return BlockState.NeedMore;
            }

            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
        }
예제 #45
0
        // Same as above, but achieves better compression. We use a lazy
        // evaluation for matches: a match is finally adopted only if there is
        // no better match at the next window position.
        private int deflate_slow(FlushType flush)
        {
            //    short hash_head = 0;    // head of hash chain
            int hash_head = 0;    // head of hash chain
            bool bflush;         // set if current block must be flushed

            // Process the input block.
            while (true)
            {
                // Make sure that we always have enough lookahead, except
                // at the end of the input file. We need MAX_MATCH bytes
                // for the next match, plus MIN_MATCH bytes to insert the
                // string following the next match.

                if (_validBytesAhead < MIN_LOOKAHEAD)
                {
                    fill_window();
                    if (_validBytesAhead < MIN_LOOKAHEAD && flush == FlushType.Z_NO_FLUSH)
                    {
                        return NeedMore;
                    }
                    if (_validBytesAhead == 0) break; // flush the current block
                }

                // Insert the string window[strstart .. strstart+2] in the
                // dictionary, and set hash_head to the head of the hash chain:

                if (_validBytesAhead >= MIN_MATCH)
                {
                    _insertedHashIndex = (((_insertedHashIndex) << _hashShift) ^ (_window[(_startInsertString) + (MIN_MATCH - 1)] & 0xff)) & _hashMask;
                    //  prev[strstart&w_mask]=hash_head=head[ins_h];
                    hash_head = (_head[_insertedHashIndex] & 0xffff);
                    _previous[_startInsertString & _windowMask] = _head[_insertedHashIndex];
                    _head[_insertedHashIndex] = (short)_startInsertString;
                }

                // Find the longest match, discarding those <= prev_length.
                _previousLength = _matchLength; _previousMatch = _startMatchString;
                _matchLength = MIN_MATCH - 1;

                if (hash_head != 0 && _previousLength < _maxLazyMatch &&
                    ((_startInsertString - hash_head) & 0xffff) <= _windowSize - MIN_LOOKAHEAD
                    )
                {
                    // To simplify the code, we prevent matches with the string
                    // of window index 0 (in particular we have to avoid a match
                    // of the string with itself at the start of the input file).

                    if (strategy != CompressionStrategy.Z_HUFFMAN_ONLY)
                    {
                        _matchLength = longest_match(hash_head);
                    }
                    // longest_match() sets match_start

                    if (_matchLength <= 5 && (strategy == CompressionStrategy.Z_FILTERED ||
                        (_matchLength == MIN_MATCH &&
                        _startInsertString - _startMatchString > 4096)))
                    {

                        // If prev_match is also MIN_MATCH, match_start is garbage
                        // but we will ignore the current match anyway.
                        _matchLength = MIN_MATCH - 1;
                    }
                }

                // If there was a match at the previous step and the current
                // match is not better, output the previous match:
                if (_previousLength >= MIN_MATCH && _matchLength <= _previousLength)
                {
                    int max_insert = _startInsertString + _validBytesAhead - MIN_MATCH;
                    // Do not insert strings in hash table beyond this.

                    //          check_match(strstart-1, prev_match, prev_length);

                    bflush = _tr_tally(_startInsertString - 1 - _previousMatch, _previousLength - MIN_MATCH);

                    // Insert in hash table all strings up to the end of the match.
                    // strstart-1 and strstart are already inserted. If there is not
                    // enough lookahead, the last two strings are not inserted in
                    // the hash table.
                    _validBytesAhead -= _previousLength - 1;
                    _previousLength -= 2;
                    do
                    {
                        if (++_startInsertString <= max_insert)
                        {
                            _insertedHashIndex = (((_insertedHashIndex) << _hashShift) ^ (_window[(_startInsertString) + (MIN_MATCH - 1)] & 0xff)) & _hashMask;
                            //prev[strstart&w_mask]=hash_head=head[ins_h];
                            hash_head = (_head[_insertedHashIndex] & 0xffff);
                            _previous[_startInsertString & _windowMask] = _head[_insertedHashIndex];
                            _head[_insertedHashIndex] = (short)_startInsertString;
                        }
                    }
                    while (--_previousLength != 0);
                    _matchAvailable = false;
                    _matchLength = MIN_MATCH - 1;
                    _startInsertString++;

                    if (bflush)
                    {
                        flush_block_only(false);
                        if (base.avail_out == 0) return NeedMore;
                    }
                }
                else if (_matchAvailable != false)
                {

                    // If there was no match at the previous position, output a
                    // single literal. If there was a match but the current match
                    // is longer, truncate the previous match to a single literal.

                    bflush = _tr_tally(0, _window[_startInsertString - 1] & 0xff);

                    if (bflush)
                    {
                        flush_block_only(false);
                    }
                    _startInsertString++;
                    _validBytesAhead--;
                    if (base.avail_out == 0) return NeedMore;
                }
                else
                {
                    // There is no previous match to compare with, wait for
                    // the next step to decide.

                    _matchAvailable = true;
                    _startInsertString++;
                    _validBytesAhead--;
                }
            }

            if (_matchAvailable != false)
            {
                bflush = _tr_tally(0, _window[_startInsertString - 1] & 0xff);
                _matchAvailable = false;
            }
            flush_block_only(flush == FlushType.Z_FINISH);

            if (base.avail_out == 0)
            {
                if (flush == FlushType.Z_FINISH) return FinishStarted;
                else return NeedMore;
            }

            return flush == FlushType.Z_FINISH ? FinishDone : BlockDone;
        }
        // Copy without compression as much as possible from the input stream, return
        // the current block state.
        // This function does not insert new strings in the dictionary since
        // uncompressible data is probably not useful. This function is used
        // only for the level=0 compression option.
        // NOTE: this function should be optimized to avoid extra copying from
        // window to pending_buf.
        internal BlockState DeflateNone(FlushType flush)
        {
            // Stored blocks are limited to 0xffff bytes, pending is limited
            // to pending_buf_size, and each stored block has a 5 byte header:

            int max_block_size = 0xffff;
            int max_start;

            if (max_block_size > pending.Length - 5)
            {
                max_block_size = pending.Length - 5;
            }

            // Copy as much as possible from input to output:
            while (true)
            {
                // Fill the window as much as possible:
                if (lookahead <= 1)
                {
                    _fillWindow();
                    if (lookahead == 0 && flush == FlushType.None)
                        return BlockState.NeedMore;
                    if (lookahead == 0)
                        break; // flush the current block
                }

                strstart += lookahead;
                lookahead = 0;

                // Emit a stored block if pending will be full:
                max_start = block_start + max_block_size;
                if (strstart == 0 || strstart >= max_start)
                {
                    // strstart == 0 is possible when wraparound on 16-bit machine
                    lookahead = (int)(strstart - max_start);
                    strstart = (int)max_start;

                    flush_block_only(false);
                    if (_codec.AvailableBytesOut == 0)
                        return BlockState.NeedMore;
                }

                // Flush if we may have to slide, otherwise block_start may become
                // negative and the data will be gone:
                if (strstart - block_start >= w_size - MIN_LOOKAHEAD)
                {
                    flush_block_only(false);
                    if (_codec.AvailableBytesOut == 0)
                        return BlockState.NeedMore;
                }
            }

            flush_block_only(flush == FlushType.Finish);
            if (_codec.AvailableBytesOut == 0)
                return (flush == FlushType.Finish) ? BlockState.FinishStarted : BlockState.NeedMore;

            return flush == FlushType.Finish ? BlockState.FinishDone : BlockState.BlockDone;
        }
예제 #47
0
        public ZLibStatus deflate(FlushType flush)
        {
            FlushType old_flush;

            if (flush > FlushType.Z_FINISH || flush < 0)
            {
                return ZLibStatus.Z_STREAM_ERROR;
            }

            if (base.next_out == null ||
                (base.next_in == null && base.avail_in != 0) ||
                (_status == FINISH_STATE && flush != FlushType.Z_FINISH))
            {
                base.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_STREAM_ERROR)];
                return ZLibStatus.Z_STREAM_ERROR;
            }
            if (base.avail_out == 0)
            {
                base.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_BUF_ERROR)];
                return ZLibStatus.Z_BUF_ERROR;
            }

            old_flush = last_flush;
            last_flush = flush;

            // Write the zlib header
            if (_status == INIT_STATE)
            {
                int header = (Z_DEFLATED + ((this._windowBits - 8) << 4)) << 8;
                int level_flags = (((int)this.level - 1) & 0xff) >> 1;

                if (level_flags > 3) level_flags = 3;
                header |= (level_flags << 6);
                if (this._startInsertString != 0) header |= PRESET_DICT;
                header += 31 - (header % 31);

                _status = BUSY_STATE;
                putShortMSB(header);


                // Save the adler32 of the preset dictionary:
                if (this._startInsertString != 0)
                {
                    putShortMSB((int)(base.adler >> 16));
                    putShortMSB((int)(base.adler & 0xffff));
                }
                base.adler = Adler32.adler32(0, null, 0, 0);
            }

            // Flush as much pending output as possible
            if (pending != 0)
            {
                this.flush_pending();
                if (base.avail_out == 0)
                {
                    //System.out.println("  avail_out==0");
                    // Since avail_out is 0, deflate will be called again with
                    // more output space, but possibly with both pending and
                    // avail_in equal to zero. There won't be anything to do,
                    // but this is not an error situation so make sure we
                    // return OK instead of BUF_ERROR at next call of deflate:
                    last_flush = (FlushType)(-1);
                    return ZLibStatus.Z_OK;
                }

                // Make sure there is something to do and avoid duplicate consecutive
                // flushes. For repeated and useless calls with Z_FINISH, we keep
                // returning Z_STREAM_END instead of Z_BUFF_ERROR.
            }
            else if (base.avail_in == 0 && flush <= old_flush &&
                flush != FlushType.Z_FINISH)
            {
                base.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_BUF_ERROR)];
                return ZLibStatus.Z_BUF_ERROR;
            }

            // User must not provide more input after the first FINISH:
            if (_status == FINISH_STATE && base.avail_in != 0)
            {
                base.msg = z_errmsg[ZLibStatus.Z_NEED_DICT - (ZLibStatus.Z_BUF_ERROR)];
                return ZLibStatus.Z_BUF_ERROR;
            }

            // Start a new block or continue the current one.
            if (base.avail_in != 0 || this._validBytesAhead != 0 ||
                (flush != FlushType.Z_NO_FLUSH && _status != FINISH_STATE))
            {
                int bstate = -1;
                switch (config_table[level].Function)
                {
                    case DefalteFlavor.STORED:
                        bstate = deflate_stored(flush);
                        break;
                    case DefalteFlavor.FAST:
                        bstate = deflate_fast(flush);
                        break;
                    case DefalteFlavor.SLOW:
                        bstate = deflate_slow(flush);
                        break;
                    default:
                        break;
                }

                if (bstate == FinishStarted || bstate == FinishDone)
                {
                    _status = FINISH_STATE;
                }
                if (bstate == NeedMore || bstate == FinishStarted)
                {
                    if (base.avail_out == 0)
                    {
                        last_flush = (FlushType)(-1); // avoid BUF_ERROR next call, see above
                    }
                    return ZLibStatus.Z_OK;
                    // If flush != Z_NO_FLUSH && avail_out == 0, the next call
                    // of deflate should use the same flush parameter to make sure
                    // that the flush is complete. So we don't have to output an
                    // empty block here, this will be done at next call. This also
                    // ensures that for a very small output buffer, we emit at most
                    // one empty block.
                }

                if (bstate == BlockDone)
                {
                    if (flush == FlushType.Z_PARTIAL_FLUSH)
                    {
                        _tr_align();
                    }
                    else
                    { // FULL_FLUSH or SYNC_FLUSH
                        _tr_stored_block(0, 0, false);
                        // For a full flush, this empty block will be recognized
                        // as a special marker by inflate_sync().
                        if (flush == FlushType.Z_FULL_FLUSH)
                        {
                            //state.head[s.hash_size-1]=0;
                            for (int i = 0; i < this._hashSize/*-1*/; i++)  // forget history
                                this._head[i] = 0;
                        }
                    }
                    this.flush_pending();
                    if (base.avail_out == 0)
                    {
                        last_flush = (FlushType)(-1); // avoid BUF_ERROR at next call, see above
                        return ZLibStatus.Z_OK;
                    }
                }
            }

            if (flush != FlushType.Z_FINISH) return ZLibStatus.Z_OK;
            if (noheader != 0) return ZLibStatus.Z_STREAM_END;

            // Write the zlib trailer (adler32)
            putShortMSB((int)(base.adler >> 16));
            putShortMSB((int)(base.adler & 0xffff));
            this.flush_pending();

            // If avail_out is zero, the application will call deflate again
            // to flush the rest.
            noheader = -1; // write the trailer only once!
            return pending != 0 ? ZLibStatus.Z_OK : ZLibStatus.Z_STREAM_END;
        }
예제 #48
0
 /// <summary>
 /// Deflate one batch of data.
 /// </summary>
 /// <remarks>
 /// You must have set InputBuffer and OutputBuffer before calling this method.
 /// </remarks>
 /// <example>
 /// <code>
 /// private void DeflateBuffer(CompressionLevel level)
 /// {
 ///     int bufferSize = 1024;
 ///     byte[] buffer = new byte[bufferSize];
 ///     ZlibCodec compressor = new ZlibCodec();
 /// 
 ///     Console.WriteLine("\n============================================");
 ///     Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length);
 ///     MemoryStream ms = new MemoryStream();
 /// 
 ///     int rc = compressor.InitializeDeflate(level);
 /// 
 ///     compressor.InputBuffer = UncompressedBytes;
 ///     compressor.NextIn = 0;
 ///     compressor.AvailableBytesIn = UncompressedBytes.Length;
 /// 
 ///     compressor.OutputBuffer = buffer;
 /// 
 ///     // pass 1: deflate 
 ///     do
 ///     {
 ///         compressor.NextOut = 0;
 ///         compressor.AvailableBytesOut = buffer.Length;
 ///         rc = compressor.Deflate(FlushType.None);
 /// 
 ///         if (rc != ZlibConstants.Z_OK &amp;&amp; rc != ZlibConstants.Z_STREAM_END)
 ///             throw new Exception("deflating: " + compressor.Message);
 /// 
 ///         ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut);
 ///     }
 ///     while (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
 /// 
 ///     // pass 2: finish and flush
 ///     do
 ///     {
 ///         compressor.NextOut = 0;
 ///         compressor.AvailableBytesOut = buffer.Length;
 ///         rc = compressor.Deflate(FlushType.Finish);
 /// 
 ///         if (rc != ZlibConstants.Z_STREAM_END &amp;&amp; rc != ZlibConstants.Z_OK)
 ///             throw new Exception("deflating: " + compressor.Message);
 /// 
 ///         if (buffer.Length - compressor.AvailableBytesOut &gt; 0)
 ///             ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut);
 ///     }
 ///     while (compressor.AvailableBytesIn &gt; 0 || compressor.AvailableBytesOut == 0);
 /// 
 ///     compressor.EndDeflate();
 /// 
 ///     ms.Seek(0, SeekOrigin.Begin);
 ///     CompressedBytes = new byte[compressor.TotalBytesOut];
 ///     ms.Read(CompressedBytes, 0, CompressedBytes.Length);
 /// }
 /// </code>
 /// </example>
 /// <param name="flush">whether to flush all data as you deflate. Generally you will want to 
 /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to 
 /// flush everything. 
 /// </param>
 /// <returns>Z_OK if all goes well.</returns>
 public int Deflate(FlushType flush)
 {
     if (dstate == null)
         throw new ZlibException("No Deflate State!");
     return dstate.Deflate(flush);
 }
예제 #49
0
 public ZLibStatus inflate(byte[] outputBuffer, int outputOffset, int outputCount, FlushType flushType)
 {
     throw new NotImplementedException();
 }