Example #1
0
 internal void Reset()
 {
     mode   = InflateBlockMode.TYPE;
     bitk   = 0;
     bitb   = 0;
     readAt = writeAt = 0;
 }
 internal InflateBlocks(ZlibCodec codec, int w)
 {
     this.codec = codec;
     hufts      = new int[MANY * 3];
     window     = new byte[w];
     end        = w;
     mode       = InflateBlockMode.TYPE;
     Reset();
 }
 internal InfBlocks(ZStream z, bool needCheck, int w)
 {
     hufts          = new int[MANY * 3];
     Window         = new byte[w];
     End            = w;
     this.needCheck = needCheck;
     mode           = InflateBlockMode.TYPE;
     reset(z, null);
 }
 internal InflateBlocks(ICompressor z, Object checkfn, int w)
 {
     hufts        = new int[MANY * 3];
     window       = new byte[w];
     end          = w;
     this.checkfn = checkfn;
     mode         = InflateBlockMode.TYPE;
     reset(z, null);
 }
Example #5
0
        private int table; // table lengths (14 bits)

        #endregion Fields

        #region Constructors

        internal InflateBlocks(ZlibCodec codec, object checkfn, int w)
        {
            this.Codec = codec;
            this.hufts = new int[Many * 3];
            this.Window = new byte[w];
            this.End = w;
            this.checkfn = checkfn;
            this.mode = InflateBlockMode.Type;
            this.Reset();
        }
 internal InflateBlocks(ZlibCodec codec, object checkfn, int w)
 {
     this._codec  = codec;
     this.hufts   = new int[0x10e0];
     this.window  = new byte[w];
     this.end     = w;
     this.checkfn = checkfn;
     this.mode    = InflateBlockMode.TYPE;
     this.Reset();
 }
Example #7
0
        private int table;                      // table lengths (14 bits)

        internal InflateBlocks(ZlibCodec codec, object checkfn, int w)
        {
            this.Codec   = codec;
            this.hufts   = new int[Many * 3];
            this.Window  = new byte[w];
            this.End     = w;
            this.checkfn = checkfn;
            this.mode    = InflateBlockMode.Type;
            this.Reset();
        }
Example #8
0
 internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w)
 {
     _codec       = codec;
     hufts        = new int[MANY * 3];
     window       = new byte[w];
     end          = w;
     this.checkfn = checkfn;
     mode         = InflateBlockMode.TYPE;
     Reset();
 }
Example #9
0
        internal uint Reset()
        {
            uint result = check;

            mode   = InflateBlockMode.TYPE;
            bitk   = 0;
            bitb   = 0;
            readAt = (writeAt = 0);
            if (checkfn != null)
            {
                _codec._Adler32 = (check = Adler.Adler32(0u, null, 0, 0));
            }
            return(result);
        }
        internal uint Reset()
        {
            uint check = this.check;

            this.mode   = InflateBlockMode.TYPE;
            this.bitk   = 0;
            this.bitb   = 0;
            this.readAt = this.writeAt = 0;
            if (this.checkfn != null)
            {
                this._codec._Adler32 = this.check = Adler.Adler32(0, null, 0, 0);
            }
            return(check);
        }
Example #11
0
        internal uint Reset()
        {
            uint oldCheck = check;

            mode   = InflateBlockMode.TYPE;
            bitk   = 0;
            bitb   = 0;
            readAt = writeAt = 0;

            if (checkfn != null)
            {
                _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0);
            }
            return(oldCheck);
        }
Example #12
0
        /// <returns>
        /// </returns>
        internal uint Reset()
        {
            uint oldCheck = this.check;

            this.mode   = InflateBlockMode.Type;
            this.Bitk   = 0;
            this.Bitb   = 0;
            this.ReadAt = this.WriteAt = 0;

            if (this.checkfn != null)
            {
                this.Codec.Adler32 = this.check = Adler.Adler32(0, null, 0, 0);
            }

            return(oldCheck);
        }
Example #13
0
        internal void reset(ICompressor z, long[] c)
        {
            if (c != null)
            {
                c[0] = check;
            }
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
            }

            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            read = write = 0;

            if (checkfn != null)
            {
                z.adler = check = Adler32.adler32(0L, null, 0, 0);
            }
        }
Example #14
0
        internal void reset(ZStream z, long[] c)
        {
            if (c != null)
            {
                c[0] = check;
            }
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
            }
            if (mode == InflateBlockMode.CODES)
            {
                codesfree(z);
            }
            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            read = write = 0;

            if (checkfn != null)
            {
                z.adler = check = Adler32.adler32(0L, null, 0, 0);
            }
        }
        /// <summary>
        /// Resets this InfBlocks class instance
        /// </summary>
        internal void reset(ZStream z, long[] c)
        {
            if (c != null)
            {
                c[0] = check;
            }
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
                blens = null;
            }
            if (mode == InflateBlockMode.CODES)
            {
                codes.free(z);
            }
            mode    = InflateBlockMode.TYPE;
            BitK    = 0;
            BitB    = 0;
            ReadPos = WritePos = 0;

            if (this.needCheck)
            {
                z.adler = check = Adler32.GetAdler32Checksum(0L, null, 0, 0);
            }
        }
 internal InflateBlocks(ICompressor z, Object checkfn, int w)
 {
     hufts = new int[MANY * 3];
     window = new byte[w];
     end = w;
     this.checkfn = checkfn;
     mode = InflateBlockMode.TYPE;
     reset(z, null);
 }
Example #17
0
        /// <summary>
        /// Resets this InfBlocks class instance
        /// </summary>
        internal void reset(ZStream z, long[] c)
        {
            if (c != null)
                c[0] = check;
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
                blens = null;
            }
            if (mode == InflateBlockMode.CODES)
            {
                codes.free(z);
            }
            mode = InflateBlockMode.TYPE;
            BitK = 0;
            BitB = 0;
            ReadPos = WritePos = 0;

            if (this.needCheck)
                z.adler = check = Adler32.GetAdler32Checksum(0L, null, 0, 0);
        }
        /// <summary>
        /// Block processing functions
        /// </summary>
        internal int proc(ZStream z, int r)
        {
            int t; // temporary storage
            int b; // bit buffer
            int k; // bits in bit buffer
            int p; // input data pointer
            int n; // bytes available there
            int q; // output Window WritePos pointer
            int m; // bytes to End of Window or ReadPos pointer

            // copy input/output information to locals (UPDATE macro restores)
            {
                p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK;
            }
            {
                q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
            }

            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:

                    while (k < (3))
                    {
                        if (n != 0)
                        {
                            r = (int)ZLibResultCode.Z_OK;
                        }
                        else
                        {
                            BitB        = b; BitK = k;
                            z.avail_in  = n;
                            z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos    = q;
                            return(inflate_flush(z, r));
                        }

                        n--;
                        b |= (z.next_in[p++] & 0xff) << k;
                        k += 8;
                    }
                    t    = (int)(b & 7);
                    last = t & 1;

                    switch (ZLibUtil.URShift(t, 1))
                    {
                    case 0:          // stored
                    {
                        b = ZLibUtil.URShift(b, (3)); k -= (3);
                    }
                        t = k & 7;         // go to byte boundary
                        {
                            b = ZLibUtil.URShift(b, (t)); k -= (t);
                        }
                        mode = InflateBlockMode.LENS;         // get length of stored block
                        break;

                    case 1:          // fixed
                    {
                        int[]   bl = new int[1];
                        int[]   bd = new int[1];
                        int[][] tl = new int[1][];
                        int[][] td = new int[1][];

                        InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
                        codes = new InfCodes(bl[0], bd[0], tl[0], td[0], z);
                    }
                        {
                            b = ZLibUtil.URShift(b, (3)); k -= (3);
                        }

                        mode = InflateBlockMode.CODES;
                        break;

                    case 2:          // dynamic
                    {
                        b = ZLibUtil.URShift(b, (3)); k -= (3);
                    }

                        mode = InflateBlockMode.TABLE;
                        break;

                    case 3:          // illegal
                    {
                        b = ZLibUtil.URShift(b, (3)); k -= (3);
                    }
                        mode  = InflateBlockMode.BAD;
                        z.msg = "invalid block type";
                        r     = (int)ZLibResultCode.Z_DATA_ERROR;

                        BitB       = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos   = q;
                        return(inflate_flush(z, r));
                    }
                    break;

                case InflateBlockMode.LENS:

                    while (k < (32))
                    {
                        if (n != 0)
                        {
                            r = (int)ZLibResultCode.Z_OK;
                        }
                        else
                        {
                            BitB        = b; BitK = k;
                            z.avail_in  = n;
                            z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos    = q;
                            return(inflate_flush(z, r));
                        }

                        n--;
                        b |= (z.next_in[p++] & 0xff) << k;
                        k += 8;
                    }

                    if (((ZLibUtil.URShift((~b), 16)) & 0xffff) != (b & 0xffff))
                    {
                        mode  = InflateBlockMode.BAD;
                        z.msg = "invalid stored block lengths";
                        r     = (int)ZLibResultCode.Z_DATA_ERROR;

                        BitB       = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos   = q;
                        return(inflate_flush(z, r));
                    }
                    left = (b & 0xffff);
                    b    = k = 0;  // dump bits
                    mode = (left != 0) ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    break;

                case InflateBlockMode.STORED:
                    if (n == 0)
                    {
                        BitB       = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos   = q;
                        return(inflate_flush(z, r));
                    }

                    if (m == 0)
                    {
                        if (q == End && ReadPos != 0)
                        {
                            q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                        }
                        if (m == 0)
                        {
                            WritePos = q;
                            r        = inflate_flush(z, r);
                            q        = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                            if (q == End && ReadPos != 0)
                            {
                                q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                            }
                            if (m == 0)
                            {
                                BitB       = b; BitK = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos   = q;
                                return(inflate_flush(z, r));
                            }
                        }
                    }
                    r = (int)ZLibResultCode.Z_OK;

                    t = left;
                    if (t > n)
                    {
                        t = n;
                    }
                    if (t > m)
                    {
                        t = m;
                    }
                    Array.Copy(z.next_in, p, Window, q, t);
                    p += t; n -= t;
                    q += t; m -= t;
                    if ((left -= t) != 0)
                    {
                        break;
                    }
                    mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                    break;

                case InflateBlockMode.TABLE:

                    while (k < (14))
                    {
                        if (n != 0)
                        {
                            r = (int)ZLibResultCode.Z_OK;
                        }
                        else
                        {
                            BitB        = b; BitK = k;
                            z.avail_in  = n;
                            z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos    = q;
                            return(inflate_flush(z, r));
                        }

                        n--;
                        b |= (z.next_in[p++] & 0xff) << k;
                        k += 8;
                    }

                    table = t = (b & 0x3fff);
                    if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                    {
                        mode  = InflateBlockMode.BAD;
                        z.msg = "too many length or distance symbols";
                        r     = (int)ZLibResultCode.Z_DATA_ERROR;

                        BitB       = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos   = q;
                        return(inflate_flush(z, r));
                    }
                    t     = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                    blens = new int[t];
                    {
                        b = ZLibUtil.URShift(b, (14)); k -= (14);
                    }

                    index = 0;
                    mode  = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;

                case InflateBlockMode.BTREE:
                    while (index < 4 + (ZLibUtil.URShift(table, 10)))
                    {
                        while (k < (3))
                        {
                            if (n != 0)
                            {
                                r = (int)ZLibResultCode.Z_OK;
                            }
                            else
                            {
                                BitB        = b; BitK = k;
                                z.avail_in  = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos    = q;
                                return(inflate_flush(z, r));
                            }

                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        blens[ZLibUtil.border[index++]] = b & 7;

                        {
                            b = ZLibUtil.URShift(b, (3)); k -= (3);
                        }
                    }

                    while (index < 19)
                    {
                        blens[ZLibUtil.border[index++]] = 0;
                    }

                    bb[0] = 7;
                    t     = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z);
                    if (t != (int)ZLibResultCode.Z_OK)
                    {
                        r = t;
                        if (r == (int)ZLibResultCode.Z_DATA_ERROR)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }

                        BitB       = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos   = q;
                        return(inflate_flush(z, r));
                    }

                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;

                case InflateBlockMode.DTREE:
                    while (true)
                    {
                        t = table;
                        if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                        {
                            break;
                        }


                        int i, j, c;

                        t = bb[0];

                        while (k < (t))
                        {
                            if (n != 0)
                            {
                                r = (int)ZLibResultCode.Z_OK;
                            }
                            else
                            {
                                BitB        = b; BitK = k;
                                z.avail_in  = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos    = q;
                                return(inflate_flush(z, r));
                            }

                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        t = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 1];
                        c = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 2];

                        if (c < 16)
                        {
                            b = ZLibUtil.URShift(b, (t)); k -= (t);
                            blens[index++] = c;
                        }
                        else
                        {
                            // c == 16..18
                            i = c == 18 ? 7 : c - 14;
                            j = c == 18 ? 11 : 3;

                            while (k < (t + i))
                            {
                                if (n != 0)
                                {
                                    r = (int)ZLibResultCode.Z_OK;
                                }
                                else
                                {
                                    BitB        = b; BitK = k;
                                    z.avail_in  = n;
                                    z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    WritePos    = q;
                                    return(inflate_flush(z, r));
                                }

                                n--;
                                b |= (z.next_in[p++] & 0xff) << k;
                                k += 8;
                            }

                            b = ZLibUtil.URShift(b, (t)); k -= (t);

                            j += (b & ZLibUtil.inflate_mask[i]);

                            b = ZLibUtil.URShift(b, (i)); k -= (i);

                            i = index;
                            t = table;
                            if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
                            {
                                blens = null;
                                mode  = InflateBlockMode.BAD;
                                z.msg = "invalid bit length repeat";
                                r     = (int)ZLibResultCode.Z_DATA_ERROR;

                                BitB       = b; BitK = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos   = q;
                                return(inflate_flush(z, r));
                            }

                            c = c == 16 ? blens[i - 1] : 0;
                            do
                            {
                                blens[i++] = c;
                            }while (--j != 0);
                            index = i;
                        }
                    }

                    tb[0] = -1;
                    {
                        int[] bl = new int[1];
                        int[] bd = new int[1];
                        int[] tl = new int[1];
                        int[] td = new int[1];


                        bl[0] = 9;     // must be <= 9 for lookahead assumptions
                        bd[0] = 6;     // must be <= 9 for lookahead assumptions
                        t     = table;
                        t     = InfTree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, z);
                        if (t != (int)ZLibResultCode.Z_OK)
                        {
                            if (t == (int)ZLibResultCode.Z_DATA_ERROR)
                            {
                                blens = null;
                                mode  = InflateBlockMode.BAD;
                            }
                            r = t;

                            BitB       = b; BitK = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos   = q;
                            return(inflate_flush(z, r));
                        }

                        codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
                    }
                    blens = null;
                    mode  = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;

                case InflateBlockMode.CODES:
                    BitB       = b; BitK = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    WritePos   = q;

                    if ((r = codes.proc(this, z, r)) != (int)ZLibResultCode.Z_STREAM_END)
                    {
                        return(inflate_flush(z, r));
                    }
                    r = (int)ZLibResultCode.Z_OK;
                    codes.free(z);

                    p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK;
                    q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);

                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    WritePos = q;
                    r        = inflate_flush(z, r);
                    q        = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                    if (ReadPos != WritePos)
                    {
                        BitB       = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos   = q;
                        return(inflate_flush(z, r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    r = (int)ZLibResultCode.Z_STREAM_END;

                    BitB       = b; BitK = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    WritePos   = q;
                    return(inflate_flush(z, r));

                case InflateBlockMode.BAD:
                    r = (int)ZLibResultCode.Z_DATA_ERROR;

                    BitB       = b; BitK = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    WritePos   = q;
                    return(inflate_flush(z, r));


                default:
                    r = (int)ZLibResultCode.Z_STREAM_ERROR;

                    BitB       = b; BitK = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    WritePos   = q;
                    return(inflate_flush(z, r));
                }
            }
        }
Example #19
0
        internal int Process(int r)
        {
            int t; // temporary storage
            int nextIn = codec.NextIn; // input data pointer
            int availIn = codec.AvailableBytesIn; // bytes available there
            int bits = bitb; // bit buffer
            int bitsNum = bitk; // bits in bit buffer
            int q = writeAt; // output window write pointer
            int m = q < readAt ? readAt - q - 1 : end - q; // bytes to end of window or read pointer

            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                    case InflateBlockMode.TYPE:
                        while( bitsNum < 3 ) {
                            if (availIn != 0) {
                                r = RCode.Okay;
                            } else {
                                return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                            }

                            availIn--;
                            bits |= codec.InputBuffer[nextIn++] << bitsNum;
                            bitsNum += 8;
                        }

                        last = bits & 0x1;
                        switch( ( bits & 0x7 ) >> 1 ) {
                            case 0:  // stored
                                bits >>= 3; bitsNum -= 3;
                                t = bitsNum & 7; // go to byte boundary
                                bits >>= t; bitsNum -= t;
                                mode = InflateBlockMode.LENS; // get length of stored block
                                break;

                            case 1:  // fixed
                                int bl, bd;
                                int[] tl, td;
                                InfTree.InflateTreesFixed(out bl, out bd, out tl, out td);
                                codes.Init(bl, bd, tl, 0, td, 0);
                                bits >>= 3; bitsNum -= 3;
                                mode = InflateBlockMode.CODES;
                                break;

                            case 2:  // dynamic
                                bits >>= 3; bitsNum -= 3;
                                mode = InflateBlockMode.TABLE;
                                break;

                            case 3:  // illegal
                                throw new InvalidDataException( "invalid block type" );
                        } break;

                    case InflateBlockMode.LENS:
                        while( bitsNum < 32 ) {
                            if( availIn != 0 ) {
                                r = RCode.Okay;
                            } else {
                                return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                            }
                            availIn--;
                            bits |= codec.InputBuffer[nextIn++] << bitsNum;
                            bitsNum += 8;
                        }

                        if ( ( ( ~bits >> 16 ) & 0xffff ) != ( bits & 0xffff ) ) {
                            throw new InvalidDataException( "invalid stored block lengths" );
                        }
                        left = bits & 0xffff;
                        bits = bitsNum = 0; // dump bits
                        mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                        break;

                    case InflateBlockMode.STORED:
                        if( availIn == 0 ) {
                            return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                        }

                        if( m == 0 ) {
                            if( q == end && readAt != 0 ) {
                                q = 0;
                                m = q < readAt ? readAt - q - 1 : end - q;
                            }
                            if( m == 0 ) {
                                writeAt = q;
                                r = Flush(r);
                                q = writeAt;
                                m = q < readAt ? readAt - q - 1 : end - q;

                                if( q == end && readAt != 0 ) {
                                    q = 0;
                                    m = q < readAt ? readAt - q - 1 : end - q;
                                }
                                if( m == 0 ) {
                                    return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                                }
                            }
                        }
                        r = RCode.Okay;

                        t = left;
                        if (t > availIn)
                            t = availIn;
                        if (t > m)
                            t = m;
                        Array.Copy(codec.InputBuffer, nextIn, window, q, t);
                        nextIn += t; availIn -= t;
                        q += t; m -= t;
                        if ((left -= t) != 0)
                            break;
                        mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                        break;

                    case InflateBlockMode.TABLE:
                        while (bitsNum < 14) {
                            if( availIn != 0 ) {
                                r = RCode.Okay;
                            } else {
                                return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                            }

                            availIn--;
                            bits |= codec.InputBuffer[nextIn++] << bitsNum;
                            bitsNum += 8;
                        }

                        table = t = (bits & 0x3fff);
                        if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29) {
                            throw new InvalidDataException( "too many length or distance symbols" );
                        }

                        t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                        if (blens == null || blens.Length < t) {
                            blens = new int[t];
                        } else {
                            Array.Clear(blens, 0, t);
                        }

                        bits >>= 14;
                        bitsNum -= 14;

                        index = 0;
                        mode = InflateBlockMode.BTREE;
                        goto case InflateBlockMode.BTREE;

                    case InflateBlockMode.BTREE:
                        while (index < 4 + (table >> 10)) {
                            while( bitsNum < 3 ) {
                                if( availIn != 0 ) {
                                    r = RCode.Okay;
                                } else {
                                    return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                                }

                                availIn--;
                                bits |= codec.InputBuffer[nextIn++] << bitsNum;
                                bitsNum += 8;
                            }

                            blens[border[index++]] = bits & 7;
                            bits >>= 3; bitsNum -= 3;
                        }

                        while (index < 19) {
                            blens[border[index++]] = 0;
                        }

                        bb = 7;
                        inftree.InflateTreeBits(blens, ref bb, ref tb, hufts, codec);
                        index = 0;
                        mode = InflateBlockMode.DTREE;
                        goto case InflateBlockMode.DTREE;

                    case InflateBlockMode.DTREE:
                        while (true) {
                            t = table;
                            if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f))) {
                                break;
                            }
                            t = bb;

                            while (bitsNum < t) {
                                if (availIn != 0) {
                                    r = RCode.Okay;
                                } else {
                                    return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                                }

                                availIn--;
                                bits |= codec.InputBuffer[nextIn++] << bitsNum;
                                bitsNum += 8;
                            }

                            t = hufts[(tb + (bits & Constants.InflateMask[t])) * 3 + 1];
                            int c = hufts[(tb + (bits & Constants.InflateMask[t])) * 3 + 2];

                            if( c < 16 ) {
                                bits >>= t; bitsNum -= t;
                                blens[index++] = c;
                            } else {
                                // c == 16..18
                                int i = c == 18 ? 7 : c - 14;
                                int j = c == 18 ? 11 : 3;

                                while( bitsNum < ( t + i ) ) {
                                    if( availIn != 0 ) {
                                        r = RCode.Okay;
                                    } else {
                                        return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                                    }

                                    availIn--;
                                    bits |= codec.InputBuffer[nextIn++] << bitsNum;
                                    bitsNum += 8;
                                }

                                bits >>= t; bitsNum -= t;
                                j += (bits & Constants.InflateMask[i]);
                                bits >>= i; bitsNum -= i;

                                i = index;
                                if (i + j > 258 + (table & 0x1f) + ((table >> 5) & 0x1f) || (c == 16 && i < 1)) {
                                    throw new InvalidDataException( "invalid bit length repeat" );
                                }

                                c = (c == 16) ? blens[i-1] : 0;
                                do {
                                    blens[i++] = c;
                                } while (--j != 0);
                                index = i;
                            }
                        }

                        tb = -1;
                        {
                            int bl = 9;  // must be <= 9 for lookahead assumptions
                            int bd = 6; // must be <= 9 for lookahead assumptions
                            int tl = 0;
                            int td = 0;
                            inftree.InflateTreesDynamic(257 + (table & 0x1f), 1 + ((table >> 5) & 0x1f), blens,
                                                        ref bl, ref bd, ref tl, ref td, hufts, codec);
                            codes.Init(bl, bd, hufts, tl, hufts, td);
                        }
                        mode = InflateBlockMode.CODES;
                        goto case InflateBlockMode.CODES;

                    case InflateBlockMode.CODES:
                        UpdateState( bits, bitsNum, availIn, nextIn, q );

                        r = codes.Process(this, r);
                        if( r != RCode.StreamEnd ) {
                            return Flush(r);
                        }

                        r = RCode.Okay;
                        nextIn = codec.NextIn;
                        availIn = codec.AvailableBytesIn;
                        bits = bitb;
                        bitsNum = bitk;
                        q = writeAt;
                        m = q < readAt ? readAt - q - 1 : end - q;

                        if (last == 0)
                        {
                            mode = InflateBlockMode.TYPE;
                            break;
                        }
                        mode = InflateBlockMode.DRY;
                        goto case InflateBlockMode.DRY;

                    case InflateBlockMode.DRY:
                        writeAt = q;
                        r = Flush(r);
                        q = writeAt;
                        m = q < readAt ? readAt - q - 1 : end - q;
                        if (readAt != writeAt) {
                            return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );
                        }
                        mode = InflateBlockMode.DONE;
                        goto case InflateBlockMode.DONE;

                    case InflateBlockMode.DONE:
                        return RanOutOfInput( bits, bitsNum, availIn, nextIn, q, r );

                    default:
                        throw new InvalidOperationException( "Invalid inflate block mode: " + mode );
                }
            }
        }
Example #20
0
        /// <param name="r">
        /// </param><returns></returns>
        internal int Process(int r)
        {
            // copy input/output information to locals (UPDATE macro restores)
            int p = this.Codec.NextIn;
            int n = this.Codec.AvailableBytesIn;
            int b = this.Bitb;
            int k = this.Bitk;

            int q = this.WriteAt;
            int m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;

            // process input based on current state
            while (true)
            {
                int t; // temporary storage
                switch (this.mode)
                {
                    case InflateBlockMode.Type:

                        while (k < 3)
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Zok;
                            }
                            else
                            {
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                this.Codec.NextIn = p;
                                this.WriteAt = q;
                                return this.Flush(r);
                            }

                            n--;
                            b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        t = b & 7;
                        this.last = t & 1;

                        switch ((uint)t >> 1)
                        {
                            case 0: // stored
                                b >>= 3;
                                k -= 3;
                                t = k & 7; // go to byte boundary
                                b >>= t;
                                k -= t;
                                this.mode = InflateBlockMode.Lens; // get length of stored block
                                break;

                            case 1: // fixed
                                var bl = new int[1];
                                var bd = new int[1];
                                var tl = new int[1][];
                                var td = new int[1][];
                                InfTree.InflateTreesFixed(bl, bd, tl, td);
                                this.codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                                b >>= 3;
                                k -= 3;
                                this.mode = InflateBlockMode.Codes;
                                break;

                            case 2: // dynamic
                                b >>= 3;
                                k -= 3;
                                this.mode = InflateBlockMode.Table;
                                break;

                            case 3: // illegal
                                b >>= 3;
                                k -= 3;
                                this.mode = InflateBlockMode.Bad;
                                this.Codec.Message = "invalid block type";
                                r = ZlibConstants.ZDataError;
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                this.Codec.NextIn = p;
                                this.WriteAt = q;
                                return this.Flush(r);
                        }

                        break;

                    case InflateBlockMode.Lens:

                        while (k < 32)
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Zok;
                            }
                            else
                            {
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                this.Codec.NextIn = p;
                                this.WriteAt = q;
                                return this.Flush(r);
                            }

                            n--;
                            b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
                        {
                            this.mode = InflateBlockMode.Bad;
                            this.Codec.Message = "invalid stored block lengths";
                            r = ZlibConstants.ZDataError;

                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                            this.Codec.NextIn = p;
                            this.WriteAt = q;
                            return this.Flush(r);
                        }

                        this.left = b & 0xffff;
                        b = k = 0; // dump bits
                        this.mode = this.left != 0
                                        ? InflateBlockMode.Stored
                                        : (this.last != 0 ? InflateBlockMode.Dry : InflateBlockMode.Type);
                        break;

                    case InflateBlockMode.Stored:
                        if (n == 0)
                        {
                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                            this.Codec.NextIn = p;
                            this.WriteAt = q;
                            return this.Flush(r);
                        }

                        if (m == 0)
                        {
                            if (q == this.End && this.ReadAt != 0)
                            {
                                q = 0;
                                m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                            }

                            if (m == 0)
                            {
                                this.WriteAt = q;
                                r = this.Flush(r);
                                q = this.WriteAt;
                                m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                                if (q == this.End && this.ReadAt != 0)
                                {
                                    q = 0;
                                    m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                                }

                                if (m == 0)
                                {
                                    this.Bitb = b;
                                    this.Bitk = k;
                                    this.Codec.AvailableBytesIn = n;
                                    this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                    this.Codec.NextIn = p;
                                    this.WriteAt = q;
                                    return this.Flush(r);
                                }
                            }
                        }

                        r = ZlibConstants.Zok;

                        t = this.left;
                        if (t > n)
                        {
                            t = n;
                        }

                        if (t > m)
                        {
                            t = m;
                        }

                        Array.Copy(this.Codec.InputBuffer, p, this.Window, q, t);
                        p += t;
                        n -= t;
                        q += t;
                        m -= t;
                        if ((this.left -= t) != 0)
                        {
                            break;
                        }

                        this.mode = this.last != 0 ? InflateBlockMode.Dry : InflateBlockMode.Type;
                        break;

                    case InflateBlockMode.Table:

                        while (k < 14)
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Zok;
                            }
                            else
                            {
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                this.Codec.NextIn = p;
                                this.WriteAt = q;
                                return this.Flush(r);
                            }

                            n--;
                            b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        this.table = t = b & 0x3fff;
                        if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                        {
                            this.mode = InflateBlockMode.Bad;
                            this.Codec.Message = "too many length or distance symbols";
                            r = ZlibConstants.ZDataError;

                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                            this.Codec.NextIn = p;
                            this.WriteAt = q;
                            return this.Flush(r);
                        }

                        t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                        if (this.blens == null || this.blens.Length < t)
                        {
                            this.blens = new int[t];
                        }
                        else
                        {
                            Array.Clear(this.blens, 0, t);

                            // for (int i = 0; i < t; i++) { blens[i] = 0; }
                        }

                        b >>= 14;
                        k -= 14;

                        this.index = 0;
                        this.mode = InflateBlockMode.Btree;
                        goto case InflateBlockMode.Btree;

                    case InflateBlockMode.Btree:
                        while (this.index < 4 + (this.table >> 10))
                        {
                            while (k < 3)
                            {
                                if (n != 0)
                                {
                                    r = ZlibConstants.Zok;
                                }
                                else
                                {
                                    this.Bitb = b;
                                    this.Bitk = k;
                                    this.Codec.AvailableBytesIn = n;
                                    this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                    this.Codec.NextIn = p;
                                    this.WriteAt = q;
                                    return this.Flush(r);
                                }

                                n--;
                                b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                                k += 8;
                            }

                            this.blens[Border[this.index++]] = b & 7;

                            b >>= 3;
                            k -= 3;
                        }

                        while (this.index < 19)
                        {
                            this.blens[Border[this.index++]] = 0;
                        }

                        this.bb[0] = 7;
                        t = this.inftree.InflateTreesBits(this.blens, this.bb, this.tb, this.hufts, this.Codec);
                        if (t != ZlibConstants.Zok)
                        {
                            r = t;
                            if (r == ZlibConstants.ZDataError)
                            {
                                this.blens = null;
                                this.mode = InflateBlockMode.Bad;
                            }

                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                            this.Codec.NextIn = p;
                            this.WriteAt = q;
                            return this.Flush(r);
                        }

                        this.index = 0;
                        this.mode = InflateBlockMode.Dtree;
                        goto case InflateBlockMode.Dtree;

                    case InflateBlockMode.Dtree:
                        while (true)
                        {
                            t = this.table;
                            if (!(this.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                            {
                                break;
                            }

                            t = this.bb[0];

                            while (k < t)
                            {
                                if (n != 0)
                                {
                                    r = ZlibConstants.Zok;
                                }
                                else
                                {
                                    this.Bitb = b;
                                    this.Bitk = k;
                                    this.Codec.AvailableBytesIn = n;
                                    this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                    this.Codec.NextIn = p;
                                    this.WriteAt = q;
                                    return this.Flush(r);
                                }

                                n--;
                                b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                                k += 8;
                            }

                            t = this.hufts[(this.tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1];
                            int c = this.hufts[(this.tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2];

                            if (c < 16)
                            {
                                b >>= t;
                                k -= t;
                                this.blens[this.index++] = c;
                            }
                            else
                            {
                                // c == 16..18
                                int i = c == 18 ? 7 : c - 14;
                                int j = c == 18 ? 11 : 3;

                                while (k < (t + i))
                                {
                                    if (n != 0)
                                    {
                                        r = ZlibConstants.Zok;
                                    }
                                    else
                                    {
                                        this.Bitb = b;
                                        this.Bitk = k;
                                        this.Codec.AvailableBytesIn = n;
                                        this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                        this.Codec.NextIn = p;
                                        this.WriteAt = q;
                                        return this.Flush(r);
                                    }

                                    n--;
                                    b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                                    k += 8;
                                }

                                b >>= t;
                                k -= t;

                                j += b & InternalInflateConstants.InflateMask[i];

                                b >>= i;
                                k -= i;

                                i = this.index;
                                t = this.table;
                                if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
                                {
                                    this.blens = null;
                                    this.mode = InflateBlockMode.Bad;
                                    this.Codec.Message = "invalid bit length repeat";
                                    r = ZlibConstants.ZDataError;

                                    this.Bitb = b;
                                    this.Bitk = k;
                                    this.Codec.AvailableBytesIn = n;
                                    this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                    this.Codec.NextIn = p;
                                    this.WriteAt = q;
                                    return this.Flush(r);
                                }

                                c = (c == 16) ? this.blens[i - 1] : 0;
                                do
                                {
                                    this.blens[i++] = c;
                                }
                                while (--j != 0);
                                this.index = i;
                            }
                        }

                        this.tb[0] = -1;
                        {
                            var bl = new[] { 9 }; // must be <= 9 for lookahead assumptions
                            var bd = new[] { 6 }; // must be <= 9 for lookahead assumptions
                            var tl = new int[1];
                            var td = new int[1];

                            t = this.table;
                            t = this.inftree.InflateTreesDynamic(
                                257 + (t & 0x1f),
                                1 + ((t >> 5) & 0x1f),
                                this.blens,
                                bl,
                                bd,
                                tl,
                                td,
                                this.hufts,
                                this.Codec);

                            if (t != ZlibConstants.Zok)
                            {
                                if (t == ZlibConstants.ZDataError)
                                {
                                    this.blens = null;
                                    this.mode = InflateBlockMode.Bad;
                                }

                                r = t;

                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                                this.Codec.NextIn = p;
                                this.WriteAt = q;
                                return this.Flush(r);
                            }

                            this.codes.Init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0]);
                        }

                        this.mode = InflateBlockMode.Codes;
                        goto case InflateBlockMode.Codes;

                    case InflateBlockMode.Codes:
                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                        this.Codec.NextIn = p;
                        this.WriteAt = q;

                        r = this.codes.Process(this, r);
                        if (r != ZlibConstants.ZStreamEnd)
                        {
                            return this.Flush(r);
                        }

                        r = ZlibConstants.Zok;
                        p = this.Codec.NextIn;
                        n = this.Codec.AvailableBytesIn;
                        b = this.Bitb;
                        k = this.Bitk;
                        q = this.WriteAt;
                        m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;

                        if (this.last == 0)
                        {
                            this.mode = InflateBlockMode.Type;
                            break;
                        }

                        this.mode = InflateBlockMode.Dry;
                        goto case InflateBlockMode.Dry;

                    case InflateBlockMode.Dry:
                        this.WriteAt = q;
                        r = this.Flush(r);
                        q = this.WriteAt;
                        m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                        if (this.ReadAt != this.WriteAt)
                        {
                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                            this.Codec.NextIn = p;
                            this.WriteAt = q;
                            return this.Flush(r);
                        }

                        this.mode = InflateBlockMode.Done;
                        goto case InflateBlockMode.Done;

                    case InflateBlockMode.Done:
                        r = ZlibConstants.ZStreamEnd;
                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                        this.Codec.NextIn = p;
                        this.WriteAt = q;
                        return this.Flush(r);

                    case InflateBlockMode.Bad:
                        r = ZlibConstants.ZDataError;

                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                        this.Codec.NextIn = p;
                        this.WriteAt = q;
                        return this.Flush(r);

                    default:
                        r = ZlibConstants.ZStreamError;

                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn += p - this.Codec.NextIn;
                        this.Codec.NextIn = p;
                        this.WriteAt = q;
                        return this.Flush(r);
                }
            }
        }
Example #21
0
        /// <summary>
        /// Block processing functions
        /// </summary>
        internal int proc(ZStream z, int r)
        {
            int t; // temporary storage
            int b; // bit buffer
            int k; // bits in bit buffer
            int p; // input data pointer
            int n; // bytes available there
            int q; // output Window WritePos pointer
            int m; // bytes to End of Window or ReadPos pointer

            // copy input/output information to locals (UPDATE macro restores)
            {
                p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK;
            }
            {
                q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
            }

            // process input based on current state
            while (true)
            {
                switch (mode)
                {

                    case InflateBlockMode.TYPE:

                        while (k < (3))
                        {
                            if (n != 0)
                            {
                                r = (int)ZLibResultCode.Z_OK;
                            }
                            else
                            {
                                BitB = b; BitK = k;
                                z.avail_in = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos = q;
                                return inflate_flush(z, r);
                            }
                            ;
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }
                        t = (int)(b & 7);
                        last = t & 1;

                        switch (ZLibUtil.URShift(t, 1))
                        {

                            case 0:  // stored
                                {
                                    b = ZLibUtil.URShift(b, (3)); k -= (3);
                                }
                                t = k & 7; // go to byte boundary
                                {
                                    b = ZLibUtil.URShift(b, (t)); k -= (t);
                                }
                                mode = InflateBlockMode.LENS; // get length of stored block
                                break;

                            case 1:  // fixed
                                {
                                    int[] bl = new int[1];
                                    int[] bd = new int[1];
                                    int[][] tl = new int[1][];
                                    int[][] td = new int[1][];

                                    InfTree.inflate_trees_fixed(bl, bd, tl, td, z);
                                    codes = new InfCodes(bl[0], bd[0], tl[0], td[0], z);
                                }
                                {
                                    b = ZLibUtil.URShift(b, (3)); k -= (3);
                                }

                                mode = InflateBlockMode.CODES;
                                break;

                            case 2:  // dynamic
                                {
                                    b = ZLibUtil.URShift(b, (3)); k -= (3);
                                }

                                mode = InflateBlockMode.TABLE;
                                break;

                            case 3:  // illegal
                                {
                                    b = ZLibUtil.URShift(b, (3)); k -= (3);
                                }
                                mode = InflateBlockMode.BAD;
                                z.msg = "invalid block type";
                                r = (int)ZLibResultCode.Z_DATA_ERROR;

                                BitB = b; BitK = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos = q;
                                return inflate_flush(z, r);
                        }
                        break;

                    case InflateBlockMode.LENS:

                        while (k < (32))
                        {
                            if (n != 0)
                            {
                                r = (int)ZLibResultCode.Z_OK;
                            }
                            else
                            {
                                BitB = b; BitK = k;
                                z.avail_in = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos = q;
                                return inflate_flush(z, r);
                            }
                            ;
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        if (((ZLibUtil.URShift((~b), 16)) & 0xffff) != (b & 0xffff))
                        {
                            mode = InflateBlockMode.BAD;
                            z.msg = "invalid stored block lengths";
                            r = (int)ZLibResultCode.Z_DATA_ERROR;

                            BitB = b; BitK = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos = q;
                            return inflate_flush(z, r);
                        }
                        left = (b & 0xffff);
                        b = k = 0; // dump bits
                        mode = (left != 0) ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                        break;

                    case InflateBlockMode.STORED:
                        if (n == 0)
                        {
                            BitB = b; BitK = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos = q;
                            return inflate_flush(z, r);
                        }

                        if (m == 0)
                        {
                            if (q == End && ReadPos != 0)
                            {
                                q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                            }
                            if (m == 0)
                            {
                                WritePos = q;
                                r = inflate_flush(z, r);
                                q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                                if (q == End && ReadPos != 0)
                                {
                                    q = 0; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                                }
                                if (m == 0)
                                {
                                    BitB = b; BitK = k;
                                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    WritePos = q;
                                    return inflate_flush(z, r);
                                }
                            }
                        }
                        r = (int)ZLibResultCode.Z_OK;

                        t = left;
                        if (t > n)
                            t = n;
                        if (t > m)
                            t = m;
                        Array.Copy(z.next_in, p, Window, q, t);
                        p += t; n -= t;
                        q += t; m -= t;
                        if ((left -= t) != 0)
                            break;
                        mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                        break;

                    case InflateBlockMode.TABLE:

                        while (k < (14))
                        {
                            if (n != 0)
                            {
                                r = (int)ZLibResultCode.Z_OK;
                            }
                            else
                            {
                                BitB = b; BitK = k;
                                z.avail_in = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos = q;
                                return inflate_flush(z, r);
                            }
                            ;
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        table = t = (b & 0x3fff);
                        if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                        {
                            mode = InflateBlockMode.BAD;
                            z.msg = "too many length or distance symbols";
                            r = (int)ZLibResultCode.Z_DATA_ERROR;

                            BitB = b; BitK = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos = q;
                            return inflate_flush(z, r);
                        }
                        t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                        blens = new int[t];
                        {
                            b = ZLibUtil.URShift(b, (14)); k -= (14);
                        }

                        index = 0;
                        mode = InflateBlockMode.BTREE;
                        goto case InflateBlockMode.BTREE;

                    case InflateBlockMode.BTREE:
                        while (index < 4 + (ZLibUtil.URShift(table, 10)))
                        {
                            while (k < (3))
                            {
                                if (n != 0)
                                {
                                    r = (int)ZLibResultCode.Z_OK;
                                }
                                else
                                {
                                    BitB = b; BitK = k;
                                    z.avail_in = n;
                                    z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    WritePos = q;
                                    return inflate_flush(z, r);
                                }
                                ;
                                n--;
                                b |= (z.next_in[p++] & 0xff) << k;
                                k += 8;
                            }

                            blens[ZLibUtil.border[index++]] = b & 7;

                            {
                                b = ZLibUtil.URShift(b, (3)); k -= (3);
                            }
                        }

                        while (index < 19)
                        {
                            blens[ZLibUtil.border[index++]] = 0;
                        }

                        bb[0] = 7;
                        t = InfTree.inflate_trees_bits(blens, bb, tb, hufts, z);
                        if (t != (int)ZLibResultCode.Z_OK)
                        {
                            r = t;
                            if (r == (int)ZLibResultCode.Z_DATA_ERROR)
                            {
                                blens = null;
                                mode = InflateBlockMode.BAD;
                            }

                            BitB = b; BitK = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos = q;
                            return inflate_flush(z, r);
                        }

                        index = 0;
                        mode = InflateBlockMode.DTREE;
                        goto case InflateBlockMode.DTREE;

                    case InflateBlockMode.DTREE:
                        while (true)
                        {
                            t = table;
                            if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                            {
                                break;
                            }

                            int i, j, c;

                            t = bb[0];

                            while (k < (t))
                            {
                                if (n != 0)
                                {
                                    r = (int)ZLibResultCode.Z_OK;
                                }
                                else
                                {
                                    BitB = b; BitK = k;
                                    z.avail_in = n;
                                    z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    WritePos = q;
                                    return inflate_flush(z, r);
                                }
                                ;
                                n--;
                                b |= (z.next_in[p++] & 0xff) << k;
                                k += 8;
                            }

                            t = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 1];
                            c = hufts[(tb[0] + (b & ZLibUtil.inflate_mask[t])) * 3 + 2];

                            if (c < 16)
                            {
                                b = ZLibUtil.URShift(b, (t)); k -= (t);
                                blens[index++] = c;
                            }
                            else
                            {
                                // c == 16..18
                                i = c == 18 ? 7 : c - 14;
                                j = c == 18 ? 11 : 3;

                                while (k < (t + i))
                                {
                                    if (n != 0)
                                    {
                                        r = (int)ZLibResultCode.Z_OK;
                                    }
                                    else
                                    {
                                        BitB = b; BitK = k;
                                        z.avail_in = n;
                                        z.total_in += p - z.next_in_index; z.next_in_index = p;
                                        WritePos = q;
                                        return inflate_flush(z, r);
                                    }
                                    ;
                                    n--;
                                    b |= (z.next_in[p++] & 0xff) << k;
                                    k += 8;
                                }

                                b = ZLibUtil.URShift(b, (t)); k -= (t);

                                j += (b & ZLibUtil.inflate_mask[i]);

                                b = ZLibUtil.URShift(b, (i)); k -= (i);

                                i = index;
                                t = table;
                                if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
                                {
                                    blens = null;
                                    mode = InflateBlockMode.BAD;
                                    z.msg = "invalid bit length repeat";
                                    r = (int)ZLibResultCode.Z_DATA_ERROR;

                                    BitB = b; BitK = k;
                                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    WritePos = q;
                                    return inflate_flush(z, r);
                                }

                                c = c == 16 ? blens[i - 1] : 0;
                                do
                                {
                                    blens[i++] = c;
                                }
                                while (--j != 0);
                                index = i;
                            }
                        }

                        tb[0] = -1;
                        {
                            int[] bl = new int[1];
                            int[] bd = new int[1];
                            int[] tl = new int[1];
                            int[] td = new int[1];

                            bl[0] = 9; // must be <= 9 for lookahead assumptions
                            bd[0] = 6; // must be <= 9 for lookahead assumptions
                            t = table;
                            t = InfTree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, z);
                            if (t != (int)ZLibResultCode.Z_OK)
                            {
                                if (t == (int)ZLibResultCode.Z_DATA_ERROR)
                                {
                                    blens = null;
                                    mode = InflateBlockMode.BAD;
                                }
                                r = t;

                                BitB = b; BitK = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                WritePos = q;
                                return inflate_flush(z, r);
                            }

                            codes = new InfCodes(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
                        }
                        blens = null;
                        mode = InflateBlockMode.CODES;
                        goto case InflateBlockMode.CODES;

                    case InflateBlockMode.CODES:
                        BitB = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos = q;

                        if ((r = codes.proc(this, z, r)) != (int)ZLibResultCode.Z_STREAM_END)
                        {
                            return inflate_flush(z, r);
                        }
                        r = (int)ZLibResultCode.Z_OK;
                        codes.free(z);

                        p = z.next_in_index; n = z.avail_in; b = BitB; k = BitK;
                        q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);

                        if (last == 0)
                        {
                            mode = InflateBlockMode.TYPE;
                            break;
                        }
                        mode = InflateBlockMode.DRY;
                        goto case InflateBlockMode.DRY;

                    case InflateBlockMode.DRY:
                        WritePos = q;
                        r = inflate_flush(z, r);
                        q = WritePos; m = (int)(q < ReadPos ? ReadPos - q - 1 : End - q);
                        if (ReadPos != WritePos)
                        {
                            BitB = b; BitK = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            WritePos = q;
                            return inflate_flush(z, r);
                        }
                        mode = InflateBlockMode.DONE;
                        goto case InflateBlockMode.DONE;

                    case InflateBlockMode.DONE:
                        r = (int)ZLibResultCode.Z_STREAM_END;

                        BitB = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos = q;
                        return inflate_flush(z, r);

                    case InflateBlockMode.BAD:
                        r = (int)ZLibResultCode.Z_DATA_ERROR;

                        BitB = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos = q;
                        return inflate_flush(z, r);

                    default:
                        r = (int)ZLibResultCode.Z_STREAM_ERROR;

                        BitB = b; BitK = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        WritePos = q;
                        return inflate_flush(z, r);

                }
            }
        }
Example #22
0
        internal int Process(int r)
        {
            int table;
            int num9;
            int nextIn           = this._codec.NextIn;
            int availableBytesIn = this._codec.AvailableBytesIn;
            int bitb             = this.bitb;
            int bitk             = this.bitk;
            int writeAt          = this.writeAt;
            int num7             = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);

            goto TR_0075;
TR_0031:
            r         = 1;
            this.bitb = bitb;
            this.bitk = bitk;
            this._codec.AvailableBytesIn = availableBytesIn;
            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
            this._codec.NextIn           = nextIn;
            this.writeAt = writeAt;
            return(this.Flush(r));

TR_0033:
            this.writeAt = writeAt;
            r            = this.Flush(r);
            writeAt      = this.writeAt;
            num7         = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
            if (this.readAt != this.writeAt)
            {
                this.bitb = bitb;
                this.bitk = bitk;
                this._codec.AvailableBytesIn = availableBytesIn;
                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                this._codec.NextIn           = nextIn;
                this.writeAt = writeAt;
                return(this.Flush(r));
            }
            this.mode = InflateBlockMode.DONE;
            goto TR_0031;
TR_0038:
            this.bitb = bitb;
            this.bitk = bitk;
            this._codec.AvailableBytesIn = availableBytesIn;
            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
            this._codec.NextIn           = nextIn;
            this.writeAt = writeAt;
            r            = this.codes.Process(this, r);
            if (r != 1)
            {
                return(this.Flush(r));
            }
            r                = 0;
            nextIn           = this._codec.NextIn;
            availableBytesIn = this._codec.AvailableBytesIn;
            bitb             = this.bitb;
            bitk             = this.bitk;
            writeAt          = this.writeAt;
            num7             = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
            if (this.last != 0)
            {
                this.mode = InflateBlockMode.DRY;
                goto TR_0033;
            }
            else
            {
                this.mode = InflateBlockMode.TYPE;
            }
            goto TR_0075;
TR_0056:
            while (true)
            {
                table = this.table;
                if (this.index >= ((0x102 + (table & 0x1f)) + ((table >> 5) & 0x1f)))
                {
                    this.tb[0] = -1;
                    int[] bl = new int[] { 9 };
                    int[] bd = new int[] { 6 };
                    int[] tl = new int[1];
                    int[] td = new int[1];
                    table = this.table;
                    table = this.inftree.inflate_trees_dynamic(0x101 + (table & 0x1f), 1 + ((table >> 5) & 0x1f), this.blens, bl, bd, tl, td, this.hufts, this._codec);
                    if (table == 0)
                    {
                        this.codes.Init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0]);
                        this.mode = InflateBlockMode.CODES;
                        break;
                    }
                    if (table == -3)
                    {
                        this.blens = null;
                        this.mode  = InflateBlockMode.BAD;
                    }
                    r         = table;
                    this.bitb = bitb;
                    this.bitk = bitk;
                    this._codec.AvailableBytesIn = availableBytesIn;
                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                    this._codec.NextIn           = nextIn;
                    this.writeAt = writeAt;
                    return(this.Flush(r));
                }
                table = this.bb[0];
                while (true)
                {
                    if (bitk >= table)
                    {
                        table = this.hufts[((this.tb[0] + (bitb & InternalInflateConstants.InflateMask[table])) * 3) + 1];
                        int num12 = this.hufts[((this.tb[0] + (bitb & InternalInflateConstants.InflateMask[table])) * 3) + 2];
                        if (num12 < 0x10)
                        {
                            bitb             = bitb >> (table & 0x1f);
                            bitk            -= table;
                            this.index       = (num9 = this.index) + 1;
                            this.blens[num9] = num12;
                        }
                        else
                        {
                            int index = (num12 != 0x12) ? (num12 - 14) : 7;
                            int num11 = (num12 != 0x12) ? 3 : 11;
                            while (true)
                            {
                                if (bitk >= (table + index))
                                {
                                    bitb   = bitb >> (table & 0x1f);
                                    num11 += bitb & InternalInflateConstants.InflateMask[index];
                                    bitb   = bitb >> (index & 0x1f);
                                    bitk   = (bitk - table) - index;
                                    index  = this.index;
                                    table  = this.table;
                                    if (((index + num11) <= ((0x102 + (table & 0x1f)) + ((table >> 5) & 0x1f))) && ((num12 != 0x10) || (index >= 1)))
                                    {
                                        num12 = (num12 != 0x10) ? 0 : this.blens[index - 1];
                                        while (true)
                                        {
                                            this.blens[index++] = num12;
                                            if (--num11 == 0)
                                            {
                                                this.index = index;
                                                break;
                                            }
                                        }
                                        break;
                                    }
                                    this.blens          = null;
                                    this.mode           = InflateBlockMode.BAD;
                                    this._codec.Message = "invalid bit length repeat";
                                    r         = -3;
                                    this.bitb = bitb;
                                    this.bitk = bitk;
                                    this._codec.AvailableBytesIn = availableBytesIn;
                                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                    this._codec.NextIn           = nextIn;
                                    this.writeAt = writeAt;
                                    return(this.Flush(r));
                                }
                                if (availableBytesIn == 0)
                                {
                                    this.bitb = bitb;
                                    this.bitk = bitk;
                                    this._codec.AvailableBytesIn = availableBytesIn;
                                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                    this._codec.NextIn           = nextIn;
                                    this.writeAt = writeAt;
                                    return(this.Flush(r));
                                }
                                r = 0;
                                availableBytesIn--;
                                bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f);
                                bitk += 8;
                            }
                        }
                        break;
                    }
                    if (availableBytesIn == 0)
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    r = 0;
                    availableBytesIn--;
                    bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f);
                    bitk += 8;
                }
            }
            goto TR_0038;
TR_0075:
            while (true)
            {
                InflateBlockMode mode = this.mode;
                switch (mode)
                {
                case InflateBlockMode.TYPE:
                {
                    while (true)
                    {
                        if (bitk >= 3)
                        {
                            table     = bitb & 7;
                            this.last = table & 1;
                            switch ((table >> 1))
                            {
                            case 0:
                                bitk     -= 3;
                                table     = bitk & 7;
                                bitb      = (bitb >> 3) >> (table & 0x1f);
                                bitk     -= table;
                                this.mode = InflateBlockMode.LENS;
                                break;

                            case 1:
                            {
                                int[]   bl = new int[1];
                                int[]   bd = new int[1];
                                int[][] tl = new int[1][];
                                int[][] td = new int[1][];
                                InfTree.inflate_trees_fixed(bl, bd, tl, td, this._codec);
                                this.codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                                bitb      = bitb >> 3;
                                bitk     -= 3;
                                this.mode = InflateBlockMode.CODES;
                                break;
                            }

                            case 2:
                                bitb      = bitb >> 3;
                                bitk     -= 3;
                                this.mode = InflateBlockMode.TABLE;
                                break;

                            case 3:
                                bitb                = bitb >> 3;
                                bitk               -= 3;
                                this.mode           = InflateBlockMode.BAD;
                                this._codec.Message = "invalid block type";
                                r         = -3;
                                this.bitb = bitb;
                                this.bitk = bitk;
                                this._codec.AvailableBytesIn = availableBytesIn;
                                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                this._codec.NextIn           = nextIn;
                                this.writeAt = writeAt;
                                return(this.Flush(r));

                            default:
                                break;
                            }
                            break;
                        }
                        if (availableBytesIn == 0)
                        {
                            this.bitb = bitb;
                            this.bitk = bitk;
                            this._codec.AvailableBytesIn = availableBytesIn;
                            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                            this._codec.NextIn           = nextIn;
                            this.writeAt = writeAt;
                            return(this.Flush(r));
                        }
                        r = 0;
                        availableBytesIn--;
                        bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f);
                        bitk += 8;
                    }
                    continue;
                }

                case InflateBlockMode.LENS:
                {
                    while (true)
                    {
                        if (bitk >= 0x20)
                        {
                            if (((~bitb >> 0x10) & 0xffff) == (bitb & 0xffff))
                            {
                                this.left = bitb & 0xffff;
                                bitb      = bitk = 0;
                                this.mode = (this.left == 0) ? ((this.last == 0) ? InflateBlockMode.TYPE : InflateBlockMode.DRY) : InflateBlockMode.STORED;
                                break;
                            }
                            this.mode           = InflateBlockMode.BAD;
                            this._codec.Message = "invalid stored block lengths";
                            r         = -3;
                            this.bitb = bitb;
                            this.bitk = bitk;
                            this._codec.AvailableBytesIn = availableBytesIn;
                            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                            this._codec.NextIn           = nextIn;
                            this.writeAt = writeAt;
                            return(this.Flush(r));
                        }
                        if (availableBytesIn == 0)
                        {
                            this.bitb = bitb;
                            this.bitk = bitk;
                            this._codec.AvailableBytesIn = availableBytesIn;
                            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                            this._codec.NextIn           = nextIn;
                            this.writeAt = writeAt;
                            return(this.Flush(r));
                        }
                        r = 0;
                        availableBytesIn--;
                        bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f);
                        bitk += 8;
                    }
                    continue;
                }

                case InflateBlockMode.STORED:
                {
                    if (availableBytesIn == 0)
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    if (num7 == 0)
                    {
                        if ((writeAt == this.end) && (this.readAt != 0))
                        {
                            writeAt = 0;
                            num7    = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
                        }
                        if (num7 == 0)
                        {
                            this.writeAt = writeAt;
                            r            = this.Flush(r);
                            writeAt      = this.writeAt;
                            num7         = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
                            if ((writeAt == this.end) && (this.readAt != 0))
                            {
                                writeAt = 0;
                                num7    = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
                            }
                            if (num7 == 0)
                            {
                                this.bitb = bitb;
                                this.bitk = bitk;
                                this._codec.AvailableBytesIn = availableBytesIn;
                                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                this._codec.NextIn           = nextIn;
                                this.writeAt = writeAt;
                                return(this.Flush(r));
                            }
                        }
                    }
                    r     = 0;
                    table = this.left;
                    if (table > availableBytesIn)
                    {
                        table = availableBytesIn;
                    }
                    if (table > num7)
                    {
                        table = num7;
                    }
                    Array.Copy(this._codec.InputBuffer, nextIn, this.window, writeAt, table);
                    nextIn           += table;
                    availableBytesIn -= table;
                    writeAt          += table;
                    num7             -= table;
                    this.left         = num9 = this.left - table;
                    if (num9 == 0)
                    {
                        this.mode = (this.last == 0) ? InflateBlockMode.TYPE : InflateBlockMode.DRY;
                    }
                    continue;
                }

                case InflateBlockMode.TABLE:
                    while (true)
                    {
                        if (bitk >= 14)
                        {
                            this.table = table = bitb & 0x3fff;
                            if (((table & 0x1f) > 0x1d) || (((table >> 5) & 0x1f) > 0x1d))
                            {
                                this.mode           = InflateBlockMode.BAD;
                                this._codec.Message = "too many length or distance symbols";
                                r         = -3;
                                this.bitb = bitb;
                                this.bitk = bitk;
                                this._codec.AvailableBytesIn = availableBytesIn;
                                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                this._codec.NextIn           = nextIn;
                                this.writeAt = writeAt;
                                return(this.Flush(r));
                            }
                            table = (0x102 + (table & 0x1f)) + ((table >> 5) & 0x1f);
                            if ((this.blens != null) && (this.blens.Length >= table))
                            {
                                Array.Clear(this.blens, 0, table);
                            }
                            else
                            {
                                this.blens = new int[table];
                            }
                            bitb       = bitb >> 14;
                            bitk      -= 14;
                            this.index = 0;
                            this.mode  = InflateBlockMode.BTREE;
                            break;
                        }
                        if (availableBytesIn == 0)
                        {
                            this.bitb = bitb;
                            this.bitk = bitk;
                            this._codec.AvailableBytesIn = availableBytesIn;
                            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                            this._codec.NextIn           = nextIn;
                            this.writeAt = writeAt;
                            return(this.Flush(r));
                        }
                        r = 0;
                        availableBytesIn--;
                        bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f);
                        bitk += 8;
                    }
                    break;

                case InflateBlockMode.BTREE:
                    break;

                case InflateBlockMode.DTREE:
                    goto TR_0056;

                case InflateBlockMode.CODES:
                    goto TR_0038;

                case InflateBlockMode.DRY:
                    goto TR_0033;

                case InflateBlockMode.DONE:
                    goto TR_0031;

                case InflateBlockMode.BAD:
                    r         = -3;
                    this.bitb = bitb;
                    this.bitk = bitk;
                    this._codec.AvailableBytesIn = availableBytesIn;
                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                    this._codec.NextIn           = nextIn;
                    this.writeAt = writeAt;
                    return(this.Flush(r));

                default:
                    r         = -2;
                    this.bitb = bitb;
                    this.bitk = bitk;
                    this._codec.AvailableBytesIn = availableBytesIn;
                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                    this._codec.NextIn           = nextIn;
                    this.writeAt = writeAt;
                    return(this.Flush(r));
                }
                while (true)
                {
                    if (this.index >= (4 + (this.table >> 10)))
                    {
                        while (true)
                        {
                            if (this.index >= 0x13)
                            {
                                this.bb[0] = 7;
                                table      = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, this._codec);
                                if (table == 0)
                                {
                                    this.index = 0;
                                    this.mode  = InflateBlockMode.DTREE;
                                    break;
                                }
                                r = table;
                                if (r == -3)
                                {
                                    this.blens = null;
                                    this.mode  = InflateBlockMode.BAD;
                                }
                                this.bitb = bitb;
                                this.bitk = bitk;
                                this._codec.AvailableBytesIn = availableBytesIn;
                                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                this._codec.NextIn           = nextIn;
                                this.writeAt = writeAt;
                                return(this.Flush(r));
                            }
                            this.index = (num9 = this.index) + 1;
                            this.blens[border[num9]] = 0;
                        }
                        break;
                    }
                    while (true)
                    {
                        if (bitk >= 3)
                        {
                            this.index = (num9 = this.index) + 1;
                            this.blens[border[num9]] = bitb & 7;
                            bitb  = bitb >> 3;
                            bitk -= 3;
                            break;
                        }
                        if (availableBytesIn == 0)
                        {
                            this.bitb = bitb;
                            this.bitk = bitk;
                            this._codec.AvailableBytesIn = availableBytesIn;
                            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                            this._codec.NextIn           = nextIn;
                            this.writeAt = writeAt;
                            return(this.Flush(r));
                        }
                        r = 0;
                        availableBytesIn--;
                        bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << (bitk & 0x1f);
                        bitk += 8;
                    }
                }
                break;
            }
            goto TR_0056;
        }
        internal int Process(int r)
        {
            int num  = this._codec.NextIn;
            int num2 = this._codec.AvailableBytesIn;
            int num3 = this.bitb;
            int num4 = this.bitk;
            int num5 = this.writeAt;
            int num6 = (num5 >= this.readAt) ? (this.end - num5) : (this.readAt - num5 - 1);

            while (true)
            {
                switch (this.mode)
                {
                case InflateBlockMode.TYPE:
                    break;

                case InflateBlockMode.LENS:
                    goto IL_030c;

                case InflateBlockMode.STORED:
                    goto IL_03dd;

                case InflateBlockMode.TABLE:
                    goto IL_068c;

                case InflateBlockMode.BTREE:
                    goto IL_085f;

                case InflateBlockMode.DTREE:
                    goto IL_0965;

                case InflateBlockMode.CODES:
                    goto IL_0da6;

                case InflateBlockMode.DRY:
                    goto IL_0e90;

                case InflateBlockMode.DONE:
                    goto end_IL_0057;

                case InflateBlockMode.BAD:
                    r         = -3;
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));

                default:
                    r         = -2;
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                while (num4 < 3)
                {
                    if (num2 != 0)
                    {
                        r = 0;
                        num2--;
                        num3 |= (this._codec.InputBuffer[num++] & 0xFF) << num4;
                        num4 += 8;
                        continue;
                    }
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                int num8 = num3 & 7;
                this.last = (num8 & 1);
                switch ((uint)num8 >> 1)
                {
                case 0u:
                    num3    >>= 3;
                    num4     -= 3;
                    num8      = (num4 & 7);
                    num3    >>= num8;
                    num4     -= num8;
                    this.mode = InflateBlockMode.LENS;
                    break;

                case 1u:
                {
                    int[]   array  = new int[1];
                    int[]   array2 = new int[1];
                    int[][] array3 = new int[1][];
                    int[][] array4 = new int[1][];
                    InfTree.inflate_trees_fixed(array, array2, array3, array4, this._codec);
                    this.codes.Init(array[0], array2[0], array3[0], 0, array4[0], 0);
                    num3    >>= 3;
                    num4     -= 3;
                    this.mode = InflateBlockMode.CODES;
                    break;
                }

                case 2u:
                    num3    >>= 3;
                    num4     -= 3;
                    this.mode = InflateBlockMode.TABLE;
                    break;

                case 3u:
                    num3              >>= 3;
                    num4               -= 3;
                    this.mode           = InflateBlockMode.BAD;
                    this._codec.Message = "invalid block type";
                    r         = -3;
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                continue;
IL_068c:
                while (num4 < 14)
                {
                    if (num2 != 0)
                    {
                        r = 0;
                        num2--;
                        num3 |= (this._codec.InputBuffer[num++] & 0xFF) << num4;
                        num4 += 8;
                        continue;
                    }
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                num8 = (this.table = (num3 & 0x3FFF));
                if ((num8 & 0x1F) <= 29 && (num8 >> 5 & 0x1F) <= 29)
                {
                    num8 = 258 + (num8 & 0x1F) + (num8 >> 5 & 0x1F);
                    if (this.blens == null || this.blens.Length < num8)
                    {
                        this.blens = new int[num8];
                    }
                    else
                    {
                        Array.Clear(this.blens, 0, num8);
                    }
                    num3     >>= 14;
                    num4      -= 14;
                    this.index = 0;
                    this.mode  = InflateBlockMode.BTREE;
                    goto IL_085f;
                }
                this.mode           = InflateBlockMode.BAD;
                this._codec.Message = "too many length or distance symbols";
                r         = -3;
                this.bitb = num3;
                this.bitk = num4;
                this._codec.AvailableBytesIn = num2;
                this._codec.TotalBytesIn    += num - this._codec.NextIn;
                this._codec.NextIn           = num;
                this.writeAt = num5;
                return(this.Flush(r));

IL_030c:
                while (num4 < 32)
                {
                    if (num2 != 0)
                    {
                        r = 0;
                        num2--;
                        num3 |= (this._codec.InputBuffer[num++] & 0xFF) << num4;
                        num4 += 8;
                        continue;
                    }
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                if ((~num3 >> 16 & 0xFFFF) != (num3 & 0xFFFF))
                {
                    this.mode           = InflateBlockMode.BAD;
                    this._codec.Message = "invalid stored block lengths";
                    r         = -3;
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                this.left = (num3 & 0xFFFF);
                num3      = (num4 = 0);
                this.mode = (InflateBlockMode)((this.left == 0) ? ((this.last != 0) ? 7 : 0) : 2);
                continue;
IL_0da6:
                this.bitb = num3;
                this.bitk = num4;
                this._codec.AvailableBytesIn = num2;
                this._codec.TotalBytesIn    += num - this._codec.NextIn;
                this._codec.NextIn           = num;
                this.writeAt = num5;
                r            = this.codes.Process(this, r);
                if (r != 1)
                {
                    return(this.Flush(r));
                }
                r    = 0;
                num  = this._codec.NextIn;
                num2 = this._codec.AvailableBytesIn;
                num3 = this.bitb;
                num4 = this.bitk;
                num5 = this.writeAt;
                num6 = ((num5 >= this.readAt) ? (this.end - num5) : (this.readAt - num5 - 1));
                if (this.last == 0)
                {
                    this.mode = InflateBlockMode.TYPE;
                    continue;
                }
                this.mode = InflateBlockMode.DRY;
                goto IL_0e90;
IL_03dd:
                if (num2 == 0)
                {
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                if (num6 == 0)
                {
                    if (num5 == this.end && this.readAt != 0)
                    {
                        num5 = 0;
                        num6 = ((num5 >= this.readAt) ? (this.end - num5) : (this.readAt - num5 - 1));
                    }
                    if (num6 == 0)
                    {
                        this.writeAt = num5;
                        r            = this.Flush(r);
                        num5         = this.writeAt;
                        num6         = ((num5 >= this.readAt) ? (this.end - num5) : (this.readAt - num5 - 1));
                        if (num5 == this.end && this.readAt != 0)
                        {
                            num5 = 0;
                            num6 = ((num5 >= this.readAt) ? (this.end - num5) : (this.readAt - num5 - 1));
                        }
                        if (num6 == 0)
                        {
                            this.bitb = num3;
                            this.bitk = num4;
                            this._codec.AvailableBytesIn = num2;
                            this._codec.TotalBytesIn    += num - this._codec.NextIn;
                            this._codec.NextIn           = num;
                            this.writeAt = num5;
                            return(this.Flush(r));
                        }
                    }
                }
                r    = 0;
                num8 = this.left;
                if (num8 > num2)
                {
                    num8 = num2;
                }
                if (num8 > num6)
                {
                    num8 = num6;
                }
                Array.Copy(this._codec.InputBuffer, num, this.window, num5, num8);
                num  += num8;
                num2 -= num8;
                num5 += num8;
                num6 -= num8;
                if ((this.left -= num8) == 0)
                {
                    this.mode = (InflateBlockMode)((this.last != 0) ? 7 : 0);
                }
                continue;
IL_0965:
                while (true)
                {
                    num8 = this.table;
                    if (this.index < 258 + (num8 & 0x1F) + (num8 >> 5 & 0x1F))
                    {
                        num8 = this.bb[0];
                        while (num4 < num8)
                        {
                            if (num2 != 0)
                            {
                                r = 0;
                                num2--;
                                num3 |= (this._codec.InputBuffer[num++] & 0xFF) << num4;
                                num4 += 8;
                                continue;
                            }
                            this.bitb = num3;
                            this.bitk = num4;
                            this._codec.AvailableBytesIn = num2;
                            this._codec.TotalBytesIn    += num - this._codec.NextIn;
                            this._codec.NextIn           = num;
                            this.writeAt = num5;
                            return(this.Flush(r));
                        }
                        num8 = this.hufts[(this.tb[0] + (num3 & InternalInflateConstants.InflateMask[num8])) * 3 + 1];
                        int num12 = this.hufts[(this.tb[0] + (num3 & InternalInflateConstants.InflateMask[num8])) * 3 + 2];
                        if (num12 < 16)
                        {
                            num3 >>= num8;
                            num4  -= num8;
                            this.blens[this.index++] = num12;
                            continue;
                        }
                        int num13 = (num12 != 18) ? (num12 - 14) : 7;
                        int num14 = (num12 != 18) ? 3 : 11;
                        while (num4 < num8 + num13)
                        {
                            if (num2 != 0)
                            {
                                r = 0;
                                num2--;
                                num3 |= (this._codec.InputBuffer[num++] & 0xFF) << num4;
                                num4 += 8;
                                continue;
                            }
                            this.bitb = num3;
                            this.bitk = num4;
                            this._codec.AvailableBytesIn = num2;
                            this._codec.TotalBytesIn    += num - this._codec.NextIn;
                            this._codec.NextIn           = num;
                            this.writeAt = num5;
                            return(this.Flush(r));
                        }
                        num3 >>= num8;
                        num4  -= num8;
                        num14 += (num3 & InternalInflateConstants.InflateMask[num13]);
                        num3 >>= num13;
                        num4  -= num13;
                        num13  = this.index;
                        num8   = this.table;
                        if (num13 + num14 <= 258 + (num8 & 0x1F) + (num8 >> 5 & 0x1F) && (num12 != 16 || num13 >= 1))
                        {
                            num12 = ((num12 == 16) ? this.blens[num13 - 1] : 0);
                            while (true)
                            {
                                this.blens[num13++] = num12;
                                if (--num14 == 0)
                                {
                                    break;
                                }
                            }
                            this.index = num13;
                            continue;
                        }
                        this.blens          = null;
                        this.mode           = InflateBlockMode.BAD;
                        this._codec.Message = "invalid bit length repeat";
                        r         = -3;
                        this.bitb = num3;
                        this.bitk = num4;
                        this._codec.AvailableBytesIn = num2;
                        this._codec.TotalBytesIn    += num - this._codec.NextIn;
                        this._codec.NextIn           = num;
                        this.writeAt = num5;
                        return(this.Flush(r));
                    }
                    break;
                }
                this.tb[0] = -1;
                int[] array5 = new int[1]
                {
                    9
                };
                int[] array6 = new int[1]
                {
                    6
                };
                int[] array7 = new int[1];
                int[] array8 = new int[1];
                num8 = this.table;
                num8 = this.inftree.inflate_trees_dynamic(257 + (num8 & 0x1F), 1 + (num8 >> 5 & 0x1F), this.blens, array5, array6, array7, array8, this.hufts, this._codec);
                switch (num8)
                {
                case -3:
                    this.blens = null;
                    this.mode  = InflateBlockMode.BAD;
                    goto default;

                default:
                    r         = num8;
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));

                case 0:
                    break;
                }
                this.codes.Init(array5[0], array6[0], this.hufts, array7[0], this.hufts, array8[0]);
                this.mode = InflateBlockMode.CODES;
                goto IL_0da6;
IL_085f:
                while (this.index < 4 + (this.table >> 10))
                {
                    while (num4 < 3)
                    {
                        if (num2 != 0)
                        {
                            r = 0;
                            num2--;
                            num3 |= (this._codec.InputBuffer[num++] & 0xFF) << num4;
                            num4 += 8;
                            continue;
                        }
                        this.bitb = num3;
                        this.bitk = num4;
                        this._codec.AvailableBytesIn = num2;
                        this._codec.TotalBytesIn    += num - this._codec.NextIn;
                        this._codec.NextIn           = num;
                        this.writeAt = num5;
                        return(this.Flush(r));
                    }
                    this.blens[InflateBlocks.border[this.index++]] = (num3 & 7);
                    num3 >>= 3;
                    num4  -= 3;
                }
                while (this.index < 19)
                {
                    this.blens[InflateBlocks.border[this.index++]] = 0;
                }
                this.bb[0] = 7;
                num8       = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, this._codec);
                if (num8 != 0)
                {
                    r = num8;
                    if (r == -3)
                    {
                        this.blens = null;
                        this.mode  = InflateBlockMode.BAD;
                    }
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                this.index = 0;
                this.mode  = InflateBlockMode.DTREE;
                goto IL_0965;
IL_0e90:
                this.writeAt = num5;
                r            = this.Flush(r);
                num5         = this.writeAt;
                num6         = ((num5 >= this.readAt) ? (this.end - num5) : (this.readAt - num5 - 1));
                if (this.readAt != this.writeAt)
                {
                    this.bitb = num3;
                    this.bitk = num4;
                    this._codec.AvailableBytesIn = num2;
                    this._codec.TotalBytesIn    += num - this._codec.NextIn;
                    this._codec.NextIn           = num;
                    this.writeAt = num5;
                    return(this.Flush(r));
                }
                this.mode = InflateBlockMode.DONE;
                break;
                continue;
end_IL_0057:
                break;
            }
            r         = 1;
            this.bitb = num3;
            this.bitk = num4;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += num - this._codec.NextIn;
            this._codec.NextIn           = num;
            this.writeAt = num5;
            return(this.Flush(r));
        }
Example #24
0
        /// <returns>
        /// </returns>
        internal uint Reset()
        {
            uint oldCheck = this.check;
            this.mode = InflateBlockMode.Type;
            this.Bitk = 0;
            this.Bitb = 0;
            this.ReadAt = this.WriteAt = 0;

            if (this.checkfn != null)
            {
                this.Codec.Adler32 = this.check = Adler.Adler32(0, null, 0, 0);
            }

            return oldCheck;
        }
        internal int Process(int r)
        {
            int table;
            int nextIn           = this._codec.NextIn;
            int availableBytesIn = this._codec.AvailableBytesIn;
            int bitb             = this.bitb;
            int bitk             = this.bitk;
            int writeAt          = this.writeAt;
            int num7             = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);

Label_0057:
            switch (this.mode)
            {
            case InflateBlockMode.TYPE:
                while (bitk < 3)
                {
                    if (availableBytesIn != 0)
                    {
                        r = 0;
                    }
                    else
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    availableBytesIn--;
                    bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << bitk;
                    bitk += 8;
                }
                table     = bitb & 7;
                this.last = table & 1;
                switch (((uint)(table >> 1)))
                {
                case 0:
                    bitb      = bitb >> 3;
                    bitk     -= 3;
                    table     = bitk & 7;
                    bitb      = bitb >> table;
                    bitk     -= table;
                    this.mode = InflateBlockMode.LENS;
                    break;

                case 1:
                {
                    int[]   numArray  = new int[1];
                    int[]   numArray2 = new int[1];
                    int[][] numArray3 = new int[1][];
                    int[][] numArray4 = new int[1][];
                    InfTree.inflate_trees_fixed(numArray, numArray2, numArray3, numArray4, this._codec);
                    this.codes.Init(numArray[0], numArray2[0], numArray3[0], 0, numArray4[0], 0);
                    bitb      = bitb >> 3;
                    bitk     -= 3;
                    this.mode = InflateBlockMode.CODES;
                    break;
                }

                case 2:
                    bitb      = bitb >> 3;
                    bitk     -= 3;
                    this.mode = InflateBlockMode.TABLE;
                    break;

                case 3:
                    bitb                = bitb >> 3;
                    bitk               -= 3;
                    this.mode           = InflateBlockMode.BAD;
                    this._codec.Message = "invalid block type";
                    r         = -3;
                    this.bitb = bitb;
                    this.bitk = bitk;
                    this._codec.AvailableBytesIn = availableBytesIn;
                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                    this._codec.NextIn           = nextIn;
                    this.writeAt = writeAt;
                    return(this.Flush(r));
                }
                goto Label_0057;

            case InflateBlockMode.LENS:
                while (bitk < 0x20)
                {
                    if (availableBytesIn != 0)
                    {
                        r = 0;
                    }
                    else
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    availableBytesIn--;
                    bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << bitk;
                    bitk += 8;
                }
                if (((~bitb >> 0x10) & 0xffff) != (bitb & 0xffff))
                {
                    this.mode           = InflateBlockMode.BAD;
                    this._codec.Message = "invalid stored block lengths";
                    r         = -3;
                    this.bitb = bitb;
                    this.bitk = bitk;
                    this._codec.AvailableBytesIn = availableBytesIn;
                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                    this._codec.NextIn           = nextIn;
                    this.writeAt = writeAt;
                    return(this.Flush(r));
                }
                this.left = bitb & 0xffff;
                bitb      = bitk = 0;
                this.mode = (this.left == 0) ? ((this.last == 0) ? InflateBlockMode.TYPE : InflateBlockMode.DRY) : InflateBlockMode.STORED;
                goto Label_0057;

            case InflateBlockMode.STORED:
                if (availableBytesIn != 0)
                {
                    if (num7 == 0)
                    {
                        if ((writeAt == this.end) && (this.readAt != 0))
                        {
                            writeAt = 0;
                            num7    = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
                        }
                        if (num7 == 0)
                        {
                            this.writeAt = writeAt;
                            r            = this.Flush(r);
                            writeAt      = this.writeAt;
                            num7         = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
                            if ((writeAt == this.end) && (this.readAt != 0))
                            {
                                writeAt = 0;
                                num7    = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
                            }
                            if (num7 == 0)
                            {
                                this.bitb = bitb;
                                this.bitk = bitk;
                                this._codec.AvailableBytesIn = availableBytesIn;
                                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                                this._codec.NextIn           = nextIn;
                                this.writeAt = writeAt;
                                return(this.Flush(r));
                            }
                        }
                    }
                    r     = 0;
                    table = this.left;
                    if (table > availableBytesIn)
                    {
                        table = availableBytesIn;
                    }
                    if (table > num7)
                    {
                        table = num7;
                    }
                    Array.Copy(this._codec.InputBuffer, nextIn, this.window, writeAt, table);
                    nextIn           += table;
                    availableBytesIn -= table;
                    writeAt          += table;
                    num7             -= table;
                    this.left        -= table;
                    if (this.left == 0)
                    {
                        this.mode = (this.last == 0) ? InflateBlockMode.TYPE : InflateBlockMode.DRY;
                    }
                    goto Label_0057;
                }
                this.bitb = bitb;
                this.bitk = bitk;
                this._codec.AvailableBytesIn = availableBytesIn;
                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                this._codec.NextIn           = nextIn;
                this.writeAt = writeAt;
                return(this.Flush(r));

            case InflateBlockMode.TABLE:
                while (bitk < 14)
                {
                    if (availableBytesIn != 0)
                    {
                        r = 0;
                    }
                    else
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    availableBytesIn--;
                    bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << bitk;
                    bitk += 8;
                }
                this.table = table = bitb & 0x3fff;
                if (((table & 0x1f) > 0x1d) || (((table >> 5) & 0x1f) > 0x1d))
                {
                    this.mode           = InflateBlockMode.BAD;
                    this._codec.Message = "too many length or distance symbols";
                    r         = -3;
                    this.bitb = bitb;
                    this.bitk = bitk;
                    this._codec.AvailableBytesIn = availableBytesIn;
                    this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                    this._codec.NextIn           = nextIn;
                    this.writeAt = writeAt;
                    return(this.Flush(r));
                }
                table = (0x102 + (table & 0x1f)) + ((table >> 5) & 0x1f);
                if ((this.blens == null) || (this.blens.Length < table))
                {
                    this.blens = new int[table];
                }
                else
                {
                    Array.Clear(this.blens, 0, table);
                }
                bitb       = bitb >> 14;
                bitk      -= 14;
                this.index = 0;
                this.mode  = InflateBlockMode.BTREE;
                break;

            case InflateBlockMode.BTREE:
                break;

            case InflateBlockMode.DTREE:
                goto Label_0965;

            case InflateBlockMode.CODES:
                goto Label_0DA6;

            case InflateBlockMode.DRY:
                goto Label_0E90;

            case InflateBlockMode.DONE:
                goto Label_0F45;

            case InflateBlockMode.BAD:
                r         = -3;
                this.bitb = bitb;
                this.bitk = bitk;
                this._codec.AvailableBytesIn = availableBytesIn;
                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                this._codec.NextIn           = nextIn;
                this.writeAt = writeAt;
                return(this.Flush(r));

            default:
                r         = -2;
                this.bitb = bitb;
                this.bitk = bitk;
                this._codec.AvailableBytesIn = availableBytesIn;
                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                this._codec.NextIn           = nextIn;
                this.writeAt = writeAt;
                return(this.Flush(r));
            }
            while (this.index < (4 + (this.table >> 10)))
            {
                while (bitk < 3)
                {
                    if (availableBytesIn != 0)
                    {
                        r = 0;
                    }
                    else
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    availableBytesIn--;
                    bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << bitk;
                    bitk += 8;
                }
                this.blens[border[this.index++]] = bitb & 7;
                bitb  = bitb >> 3;
                bitk -= 3;
            }
            while (this.index < 0x13)
            {
                this.blens[border[this.index++]] = 0;
            }
            this.bb[0] = 7;
            table      = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, this._codec);
            if (table != 0)
            {
                r = table;
                if (r == -3)
                {
                    this.blens = null;
                    this.mode  = InflateBlockMode.BAD;
                }
                this.bitb = bitb;
                this.bitk = bitk;
                this._codec.AvailableBytesIn = availableBytesIn;
                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                this._codec.NextIn           = nextIn;
                this.writeAt = writeAt;
                return(this.Flush(r));
            }
            this.index = 0;
            this.mode  = InflateBlockMode.DTREE;
Label_0965:
            table = this.table;
            if (this.index < ((0x102 + (table & 0x1f)) + ((table >> 5) & 0x1f)))
            {
                table = this.bb[0];
                while (bitk < table)
                {
                    if (availableBytesIn != 0)
                    {
                        r = 0;
                    }
                    else
                    {
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    availableBytesIn--;
                    bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << bitk;
                    bitk += 8;
                }
                table = this.hufts[((this.tb[0] + (bitb & InternalInflateConstants.InflateMask[table])) * 3) + 1];
                int num12 = this.hufts[((this.tb[0] + (bitb & InternalInflateConstants.InflateMask[table])) * 3) + 2];
                if (num12 < 0x10)
                {
                    bitb  = bitb >> table;
                    bitk -= table;
                    this.blens[this.index++] = num12;
                }
                else
                {
                    int index = (num12 != 0x12) ? (num12 - 14) : 7;
                    int num11 = (num12 != 0x12) ? 3 : 11;
                    while (bitk < (table + index))
                    {
                        if (availableBytesIn != 0)
                        {
                            r = 0;
                        }
                        else
                        {
                            this.bitb = bitb;
                            this.bitk = bitk;
                            this._codec.AvailableBytesIn = availableBytesIn;
                            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                            this._codec.NextIn           = nextIn;
                            this.writeAt = writeAt;
                            return(this.Flush(r));
                        }
                        availableBytesIn--;
                        bitb |= (this._codec.InputBuffer[nextIn++] & 0xff) << bitk;
                        bitk += 8;
                    }
                    bitb   = bitb >> table;
                    bitk  -= table;
                    num11 += bitb & InternalInflateConstants.InflateMask[index];
                    bitb   = bitb >> index;
                    bitk  -= index;
                    index  = this.index;
                    table  = this.table;
                    if (((index + num11) > ((0x102 + (table & 0x1f)) + ((table >> 5) & 0x1f))) || ((num12 == 0x10) && (index < 1)))
                    {
                        this.blens          = null;
                        this.mode           = InflateBlockMode.BAD;
                        this._codec.Message = "invalid bit length repeat";
                        r         = -3;
                        this.bitb = bitb;
                        this.bitk = bitk;
                        this._codec.AvailableBytesIn = availableBytesIn;
                        this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                        this._codec.NextIn           = nextIn;
                        this.writeAt = writeAt;
                        return(this.Flush(r));
                    }
                    num12 = (num12 != 0x10) ? 0 : this.blens[index - 1];
                    do
                    {
                        this.blens[index++] = num12;
                    }while (--num11 != 0);
                    this.index = index;
                }
                goto Label_0965;
            }
            this.tb[0] = -1;
            int[] bl = new int[] { 9 };
            int[] bd = new int[] { 6 };
            int[] tl = new int[1];
            int[] td = new int[1];
            table = this.table;
            table = this.inftree.inflate_trees_dynamic(0x101 + (table & 0x1f), 1 + ((table >> 5) & 0x1f), this.blens, bl, bd, tl, td, this.hufts, this._codec);
            switch (table)
            {
            case 0:
                this.codes.Init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0]);
                this.mode = InflateBlockMode.CODES;
                goto Label_0DA6;

            case -3:
                this.blens = null;
                this.mode  = InflateBlockMode.BAD;
                break;
            }
            r         = table;
            this.bitb = bitb;
            this.bitk = bitk;
            this._codec.AvailableBytesIn = availableBytesIn;
            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
            this._codec.NextIn           = nextIn;
            this.writeAt = writeAt;
            return(this.Flush(r));

Label_0DA6:
            this.bitb = bitb;
            this.bitk = bitk;
            this._codec.AvailableBytesIn = availableBytesIn;
            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
            this._codec.NextIn           = nextIn;
            this.writeAt = writeAt;
            r            = this.codes.Process(this, r);
            if (r != 1)
            {
                return(this.Flush(r));
            }
            r                = 0;
            nextIn           = this._codec.NextIn;
            availableBytesIn = this._codec.AvailableBytesIn;
            bitb             = this.bitb;
            bitk             = this.bitk;
            writeAt          = this.writeAt;
            num7             = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
            if (this.last == 0)
            {
                this.mode = InflateBlockMode.TYPE;
                goto Label_0057;
            }
            this.mode = InflateBlockMode.DRY;
Label_0E90:
            this.writeAt = writeAt;
            r            = this.Flush(r);
            writeAt      = this.writeAt;
            num7         = (writeAt >= this.readAt) ? (this.end - writeAt) : ((this.readAt - writeAt) - 1);
            if (this.readAt != this.writeAt)
            {
                this.bitb = bitb;
                this.bitk = bitk;
                this._codec.AvailableBytesIn = availableBytesIn;
                this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
                this._codec.NextIn           = nextIn;
                this.writeAt = writeAt;
                return(this.Flush(r));
            }
            this.mode = InflateBlockMode.DONE;
Label_0F45:
            r         = 1;
            this.bitb = bitb;
            this.bitk = bitk;
            this._codec.AvailableBytesIn = availableBytesIn;
            this._codec.TotalBytesIn    += nextIn - this._codec.NextIn;
            this._codec.NextIn           = nextIn;
            this.writeAt = writeAt;
            return(this.Flush(r));
        }
Example #26
0
        /// <param name="r">
        /// </param><returns></returns>
        internal int Process(int r)
        {
            // copy input/output information to locals (UPDATE macro restores)
            int p = this.Codec.NextIn;
            int n = this.Codec.AvailableBytesIn;
            int b = this.Bitb;
            int k = this.Bitk;

            int q = this.WriteAt;
            int m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;

            // process input based on current state
            while (true)
            {
                int t; // temporary storage
                switch (this.mode)
                {
                case InflateBlockMode.Type:

                    while (k < 3)
                    {
                        if (n != 0)
                        {
                            r = ZlibConstants.Zok;
                        }
                        else
                        {
                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                            this.Codec.NextIn           = p;
                            this.WriteAt = q;
                            return(this.Flush(r));
                        }

                        n--;
                        b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                        k += 8;
                    }

                    t         = b & 7;
                    this.last = t & 1;

                    switch ((uint)t >> 1)
                    {
                    case 0:         // stored
                        b       >>= 3;
                        k        -= 3;
                        t         = k & 7; // go to byte boundary
                        b       >>= t;
                        k        -= t;
                        this.mode = InflateBlockMode.Lens;         // get length of stored block
                        break;

                    case 1:         // fixed
                        var bl = new int[1];
                        var bd = new int[1];
                        var tl = new int[1][];
                        var td = new int[1][];
                        InfTree.InflateTreesFixed(bl, bd, tl, td);
                        this.codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                        b       >>= 3;
                        k        -= 3;
                        this.mode = InflateBlockMode.Codes;
                        break;

                    case 2:         // dynamic
                        b       >>= 3;
                        k        -= 3;
                        this.mode = InflateBlockMode.Table;
                        break;

                    case 3:         // illegal
                        b                         >>= 3;
                        k                          -= 3;
                        this.mode                   = InflateBlockMode.Bad;
                        this.Codec.Message          = "invalid block type";
                        r                           = ZlibConstants.ZDataError;
                        this.Bitb                   = b;
                        this.Bitk                   = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                        this.Codec.NextIn           = p;
                        this.WriteAt                = q;
                        return(this.Flush(r));
                    }

                    break;

                case InflateBlockMode.Lens:

                    while (k < 32)
                    {
                        if (n != 0)
                        {
                            r = ZlibConstants.Zok;
                        }
                        else
                        {
                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                            this.Codec.NextIn           = p;
                            this.WriteAt = q;
                            return(this.Flush(r));
                        }

                        n--;
                        b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                        k += 8;
                    }

                    if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
                    {
                        this.mode          = InflateBlockMode.Bad;
                        this.Codec.Message = "invalid stored block lengths";
                        r = ZlibConstants.ZDataError;

                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                        this.Codec.NextIn           = p;
                        this.WriteAt = q;
                        return(this.Flush(r));
                    }

                    this.left = b & 0xffff;
                    b         = k = 0; // dump bits
                    this.mode = this.left != 0
                                        ? InflateBlockMode.Stored
                                        : (this.last != 0 ? InflateBlockMode.Dry : InflateBlockMode.Type);
                    break;

                case InflateBlockMode.Stored:
                    if (n == 0)
                    {
                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                        this.Codec.NextIn           = p;
                        this.WriteAt = q;
                        return(this.Flush(r));
                    }

                    if (m == 0)
                    {
                        if (q == this.End && this.ReadAt != 0)
                        {
                            q = 0;
                            m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                        }

                        if (m == 0)
                        {
                            this.WriteAt = q;
                            r            = this.Flush(r);
                            q            = this.WriteAt;
                            m            = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                            if (q == this.End && this.ReadAt != 0)
                            {
                                q = 0;
                                m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                            }

                            if (m == 0)
                            {
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                                this.Codec.NextIn           = p;
                                this.WriteAt = q;
                                return(this.Flush(r));
                            }
                        }
                    }

                    r = ZlibConstants.Zok;

                    t = this.left;
                    if (t > n)
                    {
                        t = n;
                    }

                    if (t > m)
                    {
                        t = m;
                    }

                    Array.Copy(this.Codec.InputBuffer, p, this.Window, q, t);
                    p += t;
                    n -= t;
                    q += t;
                    m -= t;
                    if ((this.left -= t) != 0)
                    {
                        break;
                    }

                    this.mode = this.last != 0 ? InflateBlockMode.Dry : InflateBlockMode.Type;
                    break;

                case InflateBlockMode.Table:

                    while (k < 14)
                    {
                        if (n != 0)
                        {
                            r = ZlibConstants.Zok;
                        }
                        else
                        {
                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                            this.Codec.NextIn           = p;
                            this.WriteAt = q;
                            return(this.Flush(r));
                        }

                        n--;
                        b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                        k += 8;
                    }

                    this.table = t = b & 0x3fff;
                    if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                    {
                        this.mode          = InflateBlockMode.Bad;
                        this.Codec.Message = "too many length or distance symbols";
                        r = ZlibConstants.ZDataError;

                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                        this.Codec.NextIn           = p;
                        this.WriteAt = q;
                        return(this.Flush(r));
                    }

                    t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                    if (this.blens == null || this.blens.Length < t)
                    {
                        this.blens = new int[t];
                    }
                    else
                    {
                        Array.Clear(this.blens, 0, t);

                        // for (int i = 0; i < t; i++) { blens[i] = 0; }
                    }

                    b >>= 14;
                    k  -= 14;

                    this.index = 0;
                    this.mode  = InflateBlockMode.Btree;
                    goto case InflateBlockMode.Btree;

                case InflateBlockMode.Btree:
                    while (this.index < 4 + (this.table >> 10))
                    {
                        while (k < 3)
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Zok;
                            }
                            else
                            {
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                                this.Codec.NextIn           = p;
                                this.WriteAt = q;
                                return(this.Flush(r));
                            }

                            n--;
                            b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        this.blens[Border[this.index++]] = b & 7;

                        b >>= 3;
                        k  -= 3;
                    }

                    while (this.index < 19)
                    {
                        this.blens[Border[this.index++]] = 0;
                    }

                    this.bb[0] = 7;
                    t          = this.inftree.InflateTreesBits(this.blens, this.bb, this.tb, this.hufts, this.Codec);
                    if (t != ZlibConstants.Zok)
                    {
                        r = t;
                        if (r == ZlibConstants.ZDataError)
                        {
                            this.blens = null;
                            this.mode  = InflateBlockMode.Bad;
                        }

                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                        this.Codec.NextIn           = p;
                        this.WriteAt = q;
                        return(this.Flush(r));
                    }

                    this.index = 0;
                    this.mode  = InflateBlockMode.Dtree;
                    goto case InflateBlockMode.Dtree;

                case InflateBlockMode.Dtree:
                    while (true)
                    {
                        t = this.table;
                        if (!(this.index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                        {
                            break;
                        }

                        t = this.bb[0];

                        while (k < t)
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Zok;
                            }
                            else
                            {
                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                                this.Codec.NextIn           = p;
                                this.WriteAt = q;
                                return(this.Flush(r));
                            }

                            n--;
                            b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        t = this.hufts[(this.tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1];
                        int c = this.hufts[(this.tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2];

                        if (c < 16)
                        {
                            b >>= t;
                            k  -= t;
                            this.blens[this.index++] = c;
                        }
                        else
                        {
                            // c == 16..18
                            int i = c == 18 ? 7 : c - 14;
                            int j = c == 18 ? 11 : 3;

                            while (k < (t + i))
                            {
                                if (n != 0)
                                {
                                    r = ZlibConstants.Zok;
                                }
                                else
                                {
                                    this.Bitb = b;
                                    this.Bitk = k;
                                    this.Codec.AvailableBytesIn = n;
                                    this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                                    this.Codec.NextIn           = p;
                                    this.WriteAt = q;
                                    return(this.Flush(r));
                                }

                                n--;
                                b |= (this.Codec.InputBuffer[p++] & 0xff) << k;
                                k += 8;
                            }

                            b >>= t;
                            k  -= t;

                            j += b & InternalInflateConstants.InflateMask[i];

                            b >>= i;
                            k  -= i;

                            i = this.index;
                            t = this.table;
                            if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
                            {
                                this.blens         = null;
                                this.mode          = InflateBlockMode.Bad;
                                this.Codec.Message = "invalid bit length repeat";
                                r = ZlibConstants.ZDataError;

                                this.Bitb = b;
                                this.Bitk = k;
                                this.Codec.AvailableBytesIn = n;
                                this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                                this.Codec.NextIn           = p;
                                this.WriteAt = q;
                                return(this.Flush(r));
                            }

                            c = (c == 16) ? this.blens[i - 1] : 0;
                            do
                            {
                                this.blens[i++] = c;
                            }while (--j != 0);
                            this.index = i;
                        }
                    }

                    this.tb[0] = -1;
                    {
                        var bl = new[] { 9 };     // must be <= 9 for lookahead assumptions
                        var bd = new[] { 6 };     // must be <= 9 for lookahead assumptions
                        var tl = new int[1];
                        var td = new int[1];

                        t = this.table;
                        t = this.inftree.InflateTreesDynamic(
                            257 + (t & 0x1f),
                            1 + ((t >> 5) & 0x1f),
                            this.blens,
                            bl,
                            bd,
                            tl,
                            td,
                            this.hufts,
                            this.Codec);

                        if (t != ZlibConstants.Zok)
                        {
                            if (t == ZlibConstants.ZDataError)
                            {
                                this.blens = null;
                                this.mode  = InflateBlockMode.Bad;
                            }

                            r = t;

                            this.Bitb = b;
                            this.Bitk = k;
                            this.Codec.AvailableBytesIn = n;
                            this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                            this.Codec.NextIn           = p;
                            this.WriteAt = q;
                            return(this.Flush(r));
                        }

                        this.codes.Init(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0]);
                    }

                    this.mode = InflateBlockMode.Codes;
                    goto case InflateBlockMode.Codes;

                case InflateBlockMode.Codes:
                    this.Bitb = b;
                    this.Bitk = k;
                    this.Codec.AvailableBytesIn = n;
                    this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                    this.Codec.NextIn           = p;
                    this.WriteAt = q;

                    r = this.codes.Process(this, r);
                    if (r != ZlibConstants.ZStreamEnd)
                    {
                        return(this.Flush(r));
                    }

                    r = ZlibConstants.Zok;
                    p = this.Codec.NextIn;
                    n = this.Codec.AvailableBytesIn;
                    b = this.Bitb;
                    k = this.Bitk;
                    q = this.WriteAt;
                    m = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;

                    if (this.last == 0)
                    {
                        this.mode = InflateBlockMode.Type;
                        break;
                    }

                    this.mode = InflateBlockMode.Dry;
                    goto case InflateBlockMode.Dry;

                case InflateBlockMode.Dry:
                    this.WriteAt = q;
                    r            = this.Flush(r);
                    q            = this.WriteAt;
                    m            = q < this.ReadAt ? this.ReadAt - q - 1 : this.End - q;
                    if (this.ReadAt != this.WriteAt)
                    {
                        this.Bitb = b;
                        this.Bitk = k;
                        this.Codec.AvailableBytesIn = n;
                        this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                        this.Codec.NextIn           = p;
                        this.WriteAt = q;
                        return(this.Flush(r));
                    }

                    this.mode = InflateBlockMode.Done;
                    goto case InflateBlockMode.Done;

                case InflateBlockMode.Done:
                    r         = ZlibConstants.ZStreamEnd;
                    this.Bitb = b;
                    this.Bitk = k;
                    this.Codec.AvailableBytesIn = n;
                    this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                    this.Codec.NextIn           = p;
                    this.WriteAt = q;
                    return(this.Flush(r));

                case InflateBlockMode.Bad:
                    r = ZlibConstants.ZDataError;

                    this.Bitb = b;
                    this.Bitk = k;
                    this.Codec.AvailableBytesIn = n;
                    this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                    this.Codec.NextIn           = p;
                    this.WriteAt = q;
                    return(this.Flush(r));

                default:
                    r = ZlibConstants.ZStreamError;

                    this.Bitb = b;
                    this.Bitk = k;
                    this.Codec.AvailableBytesIn = n;
                    this.Codec.TotalBytesIn    += p - this.Codec.NextIn;
                    this.Codec.NextIn           = p;
                    this.WriteAt = q;
                    return(this.Flush(r));
                }
            }
        }
Example #27
0
 internal void Reset()
 {
     mode = InflateBlockMode.TYPE;
     bitk = 0;
     bitb = 0;
     readAt = writeAt = 0;
 }
        internal void reset(ICompressor z, long[] c)
        {
            if (c != null) c[0] = check;
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
            }

            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            read = write = 0;

            if (checkfn != null)
                z.adler = check = Adler32.adler32(0L, null, 0, 0);
        }
        internal ZLibStatus proc(ICompressor z, ZLibStatus r)
        {
            int t;              // temporary storage
            ZLibStatus tt;
            int b;              // bit buffer
            int k;              // bits in bit buffer
            int p;              // input data pointer
            int n;              // bytes available there
            int q;              // output window write pointer
            int m;
            {              // bytes to end of window or read pointer

                // copy input/output information to locals (UPDATE macro restores)
                p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
            }
            {
                q = write; m = (int)(q < read ? read - q - 1 : end - q);
            }

            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                    case InflateBlockMode.TYPE:

                        while (k < (3))
                        {
                            if (n != 0)
                            {
                                r = ZLibStatus.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                z.avail_in = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write = q;
                                return inflate_flush(z, r);
                            };
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }
                        t = (int)(b & 7);
                        last = t & 1;

                        switch (t >> 1)
                        {
                            case 0:
                                {                         // stored 
                                    b >>= (3); k -= (3);
                                }
                                t = k & 7;
                                {                    // go to byte boundary

                                    b >>= (t); k -= (t);
                                }
                                mode = InflateBlockMode.LENS;                  // get length of stored block
                                break;
                            case 1:
                                {                         // fixed
                                    int[] bl = new int[1];
                                    int[] bd = new int[1];
                                    int[][] tl = new int[1][];
                                    int[][] td = new int[1][];

                                    InflateTree.InflateTreesFixed(bl, bd, tl, td);
                                    codesinit(bl[0], bd[0], tl[0], 0, td[0], 0);
                                }
                                {

                                    b >>= (3); k -= (3);
                                }

                                mode = InflateBlockMode.CODES;
                                break;
                            case 2:
                                {                         // dynamic

                                    b >>= (3); k -= (3);
                                }

                                mode = InflateBlockMode.TABLE;
                                break;
                            case 3:
                                {                         // illegal

                                    b >>= (3); k -= (3);
                                }
                                mode = InflateBlockMode.BAD;
                                z.msg = "invalid block type";
                                r = ZLibStatus.Z_DATA_ERROR;

                                bitb = b; bitk = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write = q;
                                return inflate_flush(z, r);
                        }
                        break;
                    case InflateBlockMode.LENS:

                        while (k < (32))
                        {
                            if (n != 0)
                            {
                                r = ZLibStatus.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                z.avail_in = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write = q;
                                return inflate_flush(z, r);
                            };
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
                        {
                            mode = InflateBlockMode.BAD;
                            z.msg = "invalid stored block lengths";
                            r = ZLibStatus.Z_DATA_ERROR;

                            bitb = b; bitk = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write = q;
                            return inflate_flush(z, r);
                        }
                        left = (b & 0xffff);
                        b = k = 0;                       // dump bits
                        mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                        break;
                    case InflateBlockMode.STORED:
                        if (n == 0)
                        {
                            bitb = b; bitk = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write = q;
                            return inflate_flush(z, r);
                        }

                        if (m == 0)
                        {
                            if (q == end && read != 0)
                            {
                                q = 0; m = (int)(q < read ? read - q - 1 : end - q);
                            }
                            if (m == 0)
                            {
                                write = q;
                                r = inflate_flush(z, r);
                                q = write; m = (int)(q < read ? read - q - 1 : end - q);
                                if (q == end && read != 0)
                                {
                                    q = 0; m = (int)(q < read ? read - q - 1 : end - q);
                                }
                                if (m == 0)
                                {
                                    bitb = b; bitk = k;
                                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    write = q;
                                    return inflate_flush(z, r);
                                }
                            }
                        }
                        r = ZLibStatus.Z_OK;

                        t = left;
                        if (t > n) t = n;
                        if (t > m) t = m;
                        System.Array.Copy(z.next_in, p, window, q, t);
                        p += t; n -= t;
                        q += t; m -= t;
                        if ((left -= t) != 0)
                            break;
                        mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                        break;
                    case InflateBlockMode.TABLE:

                        while (k < (14))
                        {
                            if (n != 0)
                            {
                                r = ZLibStatus.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                z.avail_in = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write = q;
                                return inflate_flush(z, r);
                            };
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        table = t = (b & 0x3fff);
                        if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                        {
                            mode = InflateBlockMode.BAD;
                            z.msg = "too many length or distance symbols";
                            r = ZLibStatus.Z_DATA_ERROR;

                            bitb = b; bitk = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write = q;
                            return inflate_flush(z, r);
                        }
                        t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                        if (blens == null || blens.Length < t)
                        {
                            blens = new int[t];
                        }
                        else
                        {
                            for (int i = 0; i < t; i++) { blens[i] = 0; }
                        }
                        {

                            b >>= (14); k -= (14);
                        }

                        index = 0;
                        mode = InflateBlockMode.BTREE;
                        goto case InflateBlockMode.BTREE;
                    case InflateBlockMode.BTREE:
                        while (index < 4 + (table >> 10))
                        {
                            while (k < (3))
                            {
                                if (n != 0)
                                {
                                    r = ZLibStatus.Z_OK;
                                }
                                else
                                {
                                    bitb = b; bitk = k;
                                    z.avail_in = n;
                                    z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    write = q;
                                    return inflate_flush(z, r);
                                };
                                n--;
                                b |= (z.next_in[p++] & 0xff) << k;
                                k += 8;
                            }

                            blens[border[index++]] = b & 7;
                            {

                                b >>= (3); k -= (3);
                            }
                        }

                        while (index < 19)
                        {
                            blens[border[index++]] = 0;
                        }

                        bb[0] = 7;
                        tt = inftree.InflateTreesBits(blens, bb, tb, hufts, z);
                        if (tt != ZLibStatus.Z_OK)
                        {
                            r = tt;
                            if (r == ZLibStatus.Z_DATA_ERROR)
                            {
                                blens = null;
                                mode = InflateBlockMode.BAD;
                            }

                            bitb = b; bitk = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write = q;
                            return inflate_flush(z, r);
                        }

                        index = 0;
                        mode = InflateBlockMode.DTREE;
                        goto case InflateBlockMode.DTREE;
                    case InflateBlockMode.DTREE:
                        while (true)
                        {
                            t = table;
                            if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                            {
                                break;
                            }

                            int i, j, c;

                            t = bb[0];

                            while (k < (t))
                            {
                                if (n != 0)
                                {
                                    r = ZLibStatus.Z_OK;
                                }
                                else
                                {
                                    bitb = b; bitk = k;
                                    z.avail_in = n;
                                    z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    write = q;
                                    return inflate_flush(z, r);
                                };
                                n--;
                                b |= (z.next_in[p++] & 0xff) << k;
                                k += 8;
                            }

                            if (tb[0] == -1)
                            {
                                //System.err.println("null...");
                            }

                            t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
                            c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];

                            if (c < 16)
                            {
                                b >>= (t); k -= (t);
                                blens[index++] = c;
                            }
                            else
                            { // c == 16..18
                                i = c == 18 ? 7 : c - 14;
                                j = c == 18 ? 11 : 3;

                                while (k < (t + i))
                                {
                                    if (n != 0)
                                    {
                                        r = ZLibStatus.Z_OK;
                                    }
                                    else
                                    {
                                        bitb = b; bitk = k;
                                        z.avail_in = n;
                                        z.total_in += p - z.next_in_index; z.next_in_index = p;
                                        write = q;
                                        return inflate_flush(z, r);
                                    };
                                    n--;
                                    b |= (z.next_in[p++] & 0xff) << k;
                                    k += 8;
                                }

                                b >>= (t); k -= (t);

                                j += (b & inflate_mask[i]);

                                b >>= (i); k -= (i);

                                i = index;
                                t = table;
                                if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
                                    (c == 16 && i < 1))
                                {
                                    blens = null;
                                    mode = InflateBlockMode.BAD;
                                    z.msg = "invalid bit length repeat";
                                    r = ZLibStatus.Z_DATA_ERROR;

                                    bitb = b; bitk = k;
                                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    write = q;
                                    return inflate_flush(z, r);
                                }

                                c = c == 16 ? blens[i - 1] : 0;
                                do
                                {
                                    blens[i++] = c;
                                }
                                while (--j != 0);
                                index = i;
                            }
                        }

                        tb[0] = -1;
                        {
                            int[] bl = new int[1];
                            int[] bd = new int[1];
                            int[] tl = new int[1];
                            int[] td = new int[1];
                            bl[0] = 9;         // must be <= 9 for lookahead assumptions
                            bd[0] = 6;         // must be <= 9 for lookahead assumptions

                            t = table;
                            tt = inftree.InflateTreesDynamic(257 + (t & 0x1f),
                                1 + ((t >> 5) & 0x1f),
                                blens, bl, bd, tl, td, hufts, z);

                            if (tt != ZLibStatus.Z_OK)
                            {
                                if (tt == ZLibStatus.Z_DATA_ERROR)
                                {
                                    blens = null;
                                    mode = InflateBlockMode.BAD;
                                }
                                r = tt;

                                bitb = b; bitk = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write = q;
                                return inflate_flush(z, r);
                            }
                            codesinit(bl[0], bd[0], hufts, tl[0], hufts, td[0]);
                        }
                        mode = InflateBlockMode.CODES;
                        goto case InflateBlockMode.CODES;
                    case InflateBlockMode.CODES:
                        bitb = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write = q;

                        if ((r = codesproc(this, z, r)) != ZLibStatus.Z_STREAM_END)
                        {
                            return inflate_flush(z, r);
                        }
                        r = ZLibStatus.Z_OK;

                        p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
                        q = write; m = (int)(q < read ? read - q - 1 : end - q);

                        if (last == 0)
                        {
                            mode = InflateBlockMode.TYPE;
                            break;
                        }
                        mode = InflateBlockMode.DRY;
                        goto case InflateBlockMode.DRY;
                    case InflateBlockMode.DRY:
                        write = q;
                        r = inflate_flush(z, r);
                        q = write; m = (int)(q < read ? read - q - 1 : end - q);
                        if (read != write)
                        {
                            bitb = b; bitk = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write = q;
                            return inflate_flush(z, r);
                        }
                        mode = InflateBlockMode.DONE;
                        goto case InflateBlockMode.DONE;
                    case InflateBlockMode.DONE:
                        r = ZLibStatus.Z_STREAM_END;

                        bitb = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write = q;
                        return inflate_flush(z, r);
                    case InflateBlockMode.BAD:
                        r = ZLibStatus.Z_DATA_ERROR;

                        bitb = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write = q;
                        return inflate_flush(z, r);

                    default:
                        r = ZLibStatus.Z_STREAM_ERROR;

                        bitb = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write = q;
                        return inflate_flush(z, r);
                }
            }
        }
Example #30
0
 internal InfBlocks(ZStream z, bool needCheck, int w)
 {
     hufts = new int[MANY * 3];
     window = new byte[w];
     end = w;
     this.needCheck = needCheck;
     mode = InflateBlockMode.TYPE;
     reset(z, null);
 }
Example #31
0
        internal int Process(int r)
        {
            int t;                                               // temporary storage
            int nextIn  = _NextIn;                               // input data pointer
            int availIn = _AvailIn;                              // bytes available there
            int bits    = bitb;                                  // bit buffer
            int bitsNum = bitk;                                  // bits in bit buffer
            int q       = writeAt;                               // output window write pointer
            int m       = q < readAt ? readAt - q - 1 : end - q; // bytes to end of window or read pointer

            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:
                    while (bitsNum < 3)
                    {
                        if (availIn != 0)
                        {
                            r = RCode.Okay;
                        }
                        else
                        {
                            return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                        }

                        availIn--;
                        bits    |= InputBuffer[nextIn++] << bitsNum;
                        bitsNum += 8;
                    }

                    last = bits & 0x1;
                    switch ((bits & 0x7) >> 1)
                    {
                    case 0:                                      // stored
                        bits >>= 3; bitsNum -= 3;
                        t      = bitsNum & 7;                    // go to byte boundary
                        bits >>= t; bitsNum -= t;
                        mode   = InflateBlockMode.LENS;          // get length of stored block
                        break;

                    case 1:                                      // fixed
                        int   bl, bd;
                        int[] tl, td;
                        InfTree.InflateTreesFixed(out bl, out bd, out tl, out td);
                        codes.Init(bl, bd, tl, 0, td, 0);
                        bits >>= 3; bitsNum -= 3;
                        mode   = InflateBlockMode.CODES;
                        break;

                    case 2:                                      // dynamic
                        bits >>= 3; bitsNum -= 3;
                        mode   = InflateBlockMode.TABLE;
                        break;

                    case 3:                                      // illegal
                        throw new InvalidDataException("invalid block type");
                    }
                    break;

                case InflateBlockMode.LENS:
                    while (bitsNum < 32)
                    {
                        if (availIn != 0)
                        {
                            r = RCode.Okay;
                        }
                        else
                        {
                            return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                        }
                        availIn--;
                        bits    |= InputBuffer[nextIn++] << bitsNum;
                        bitsNum += 8;
                    }

                    if (((~bits >> 16) & 0xffff) != (bits & 0xffff))
                    {
                        throw new InvalidDataException("invalid stored block lengths");
                    }
                    left = bits & 0xffff;
                    bits = bitsNum = 0;                             // dump bits
                    mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    break;

                case InflateBlockMode.STORED:
                    if (availIn == 0)
                    {
                        return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                    }

                    if (m == 0)
                    {
                        if (q == end && readAt != 0)
                        {
                            q = 0;
                            m = q < readAt ? readAt - q - 1 : end - q;
                        }
                        if (m == 0)
                        {
                            writeAt = q;
                            r       = Flush(r);
                            q       = writeAt;
                            m       = q < readAt ? readAt - q - 1 : end - q;

                            if (q == end && readAt != 0)
                            {
                                q = 0;
                                m = q < readAt ? readAt - q - 1 : end - q;
                            }
                            if (m == 0)
                            {
                                return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                            }
                        }
                    }
                    r = RCode.Okay;

                    t = left;
                    if (t > availIn)
                    {
                        t = availIn;
                    }
                    if (t > m)
                    {
                        t = m;
                    }
                    Array.Copy(InputBuffer, nextIn, window, q, t);
                    nextIn += t; availIn -= t;
                    q      += t; m -= t;
                    if ((left -= t) != 0)
                    {
                        break;
                    }
                    mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                    break;

                case InflateBlockMode.TABLE:
                    while (bitsNum < 14)
                    {
                        if (availIn != 0)
                        {
                            r = RCode.Okay;
                        }
                        else
                        {
                            return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                        }

                        availIn--;
                        bits    |= InputBuffer[nextIn++] << bitsNum;
                        bitsNum += 8;
                    }

                    table = t = (bits & 0x3fff);
                    if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                    {
                        throw new InvalidDataException("too many length or distance symbols");
                    }

                    t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                    if (blens == null || blens.Length < t)
                    {
                        blens = new int[t];
                    }
                    else
                    {
                        Array.Clear(blens, 0, t);
                    }

                    bits   >>= 14;
                    bitsNum -= 14;

                    index = 0;
                    mode  = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;

                case InflateBlockMode.BTREE:
                    while (index < 4 + (table >> 10))
                    {
                        while (bitsNum < 3)
                        {
                            if (availIn != 0)
                            {
                                r = RCode.Okay;
                            }
                            else
                            {
                                return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                            }

                            availIn--;
                            bits    |= InputBuffer[nextIn++] << bitsNum;
                            bitsNum += 8;
                        }

                        blens[border[index++]] = bits & 7;
                        bits >>= 3; bitsNum -= 3;
                    }

                    while (index < 19)
                    {
                        blens[border[index++]] = 0;
                    }

                    bb = 7;
                    inftree.InflateTreeBits(blens, ref bb, ref tb, hufts);
                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;

                case InflateBlockMode.DTREE:
                    while (true)
                    {
                        t = table;
                        if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                        {
                            break;
                        }
                        t = bb;

                        while (bitsNum < t)
                        {
                            if (availIn != 0)
                            {
                                r = RCode.Okay;
                            }
                            else
                            {
                                return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                            }

                            availIn--;
                            bits    |= InputBuffer[nextIn++] << bitsNum;
                            bitsNum += 8;
                        }

                        t = hufts[(tb + (bits & Constants.InflateMask[t])) * 3 + 1];
                        int c = hufts[(tb + (bits & Constants.InflateMask[t])) * 3 + 2];

                        if (c < 16)
                        {
                            bits         >>= t; bitsNum -= t;
                            blens[index++] = c;
                        }
                        else
                        {
                            // c == 16..18
                            int i = c == 18 ? 7 : c - 14;
                            int j = c == 18 ? 11 : 3;

                            while (bitsNum < (t + i))
                            {
                                if (availIn != 0)
                                {
                                    r = RCode.Okay;
                                }
                                else
                                {
                                    return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                                }

                                availIn--;
                                bits    |= InputBuffer[nextIn++] << bitsNum;
                                bitsNum += 8;
                            }

                            bits >>= t; bitsNum -= t;
                            j     += (bits & Constants.InflateMask[i]);
                            bits >>= i; bitsNum -= i;

                            i = index;
                            if (i + j > 258 + (table & 0x1f) + ((table >> 5) & 0x1f) || (c == 16 && i < 1))
                            {
                                throw new InvalidDataException("invalid bit length repeat");
                            }

                            c = (c == 16) ? blens[i - 1] : 0;
                            do
                            {
                                blens[i++] = c;
                            } while (--j != 0);
                            index = i;
                        }
                    }

                    tb = -1;
                    {
                        int bl = 9;                                 // must be <= 9 for lookahead assumptions
                        int bd = 6;                                 // must be <= 9 for lookahead assumptions
                        int tl = 0;
                        int td = 0;
                        inftree.InflateTreesDynamic(257 + (table & 0x1f), 1 + ((table >> 5) & 0x1f), blens,
                                                    ref bl, ref bd, ref tl, ref td, hufts);
                        codes.Init(bl, bd, hufts, tl, hufts, td);
                    }
                    mode = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;

                case InflateBlockMode.CODES:
                    UpdateState(bits, bitsNum, availIn, nextIn, q);

                    r = codes.Process(this, r);
                    if (r != RCode.StreamEnd)
                    {
                        return(Flush(r));
                    }

                    r       = RCode.Okay;
                    nextIn  = _NextIn;
                    availIn = _AvailIn;
                    bits    = bitb;
                    bitsNum = bitk;
                    q       = writeAt;
                    m       = q < readAt ? readAt - q - 1 : end - q;

                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    writeAt = q;
                    r       = Flush(r);
                    q       = writeAt;
                    m       = q < readAt ? readAt - q - 1 : end - q;
                    if (readAt != writeAt)
                    {
                        return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    return(RanOutOfInput(bits, bitsNum, availIn, nextIn, q, RCode.StreamEnd));

                default:
                    throw new InvalidOperationException("Invalid inflate block mode: " + mode);
                }
            }
        }
Example #32
0
        public void Reset(ZStream z, long[] c)
        {
            if (c != null) c[0] = check;
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
            }
            //if (mode == InflateBlockMode.CODES)
            //{
            //    codes.free(z);
            //}
            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            read = write = 0;

            if (checkfn != null)
            {
                //z.adler = check = z.Adler32(0L, null, 0, 0);
                z.UpdateAdler(0L, null, 0, 0);
                check = z.Adler;
            }
        }
Example #33
0
        internal int Process(int r)
        {
            int p = _codec.NextIn;
            int m = _codec.AvailableBytesIn;
            int b = bitb;
            int k = bitk;
            int q = writeAt;
            int l = ((q < readAt) ? (readAt - q - 1) : (end - q));

            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:
                {
                    for (; k < 3; k += 8)
                    {
                        if (m != 0)
                        {
                            r = 0;
                            m--;
                            b |= (_codec.InputBuffer[p++] & 0xFF) << k;
                            continue;
                        }
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    int t = b & 7;
                    last = t & 1;
                    switch ((uint)t >> 1)
                    {
                    case 0u:
                        b  >>= 3;
                        k   -= 3;
                        t    = k & 7;
                        b  >>= t;
                        k   -= t;
                        mode = InflateBlockMode.LENS;
                        break;

                    case 1u:
                    {
                        int[]   bl = new int[1];
                        int[]   bd = new int[1];
                        int[][] tl = new int[1][];
                        int[][] td = new int[1][];
                        InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec);
                        codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                        b  >>= 3;
                        k   -= 3;
                        mode = InflateBlockMode.CODES;
                        break;
                    }

                    case 2u:
                        b  >>= 3;
                        k   -= 3;
                        mode = InflateBlockMode.TABLE;
                        break;

                    case 3u:
                        b                     >>= 3;
                        k                      -= 3;
                        mode                    = InflateBlockMode.BAD;
                        _codec.Message          = "invalid block type";
                        r                       = -3;
                        bitb                    = b;
                        bitk                    = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt                 = q;
                        return(Flush(r));
                    }
                    break;
                }

                case InflateBlockMode.LENS:
                    for (; k < 32; k += 8)
                    {
                        if (m != 0)
                        {
                            r = 0;
                            m--;
                            b |= (_codec.InputBuffer[p++] & 0xFF) << k;
                            continue;
                        }
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    if (((~b >> 16) & 0xFFFF) != (b & 0xFFFF))
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "invalid stored block lengths";
                        r    = -3;
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    left = b & 0xFFFF;
                    b    = (k = 0);
                    mode = ((left != 0) ? InflateBlockMode.STORED : ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE));
                    break;

                case InflateBlockMode.STORED:
                {
                    if (m == 0)
                    {
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    if (l == 0)
                    {
                        if (q == end && readAt != 0)
                        {
                            q = 0;
                            l = ((q < readAt) ? (readAt - q - 1) : (end - q));
                        }
                        if (l == 0)
                        {
                            writeAt = q;
                            r       = Flush(r);
                            q       = writeAt;
                            l       = ((q < readAt) ? (readAt - q - 1) : (end - q));
                            if (q == end && readAt != 0)
                            {
                                q = 0;
                                l = ((q < readAt) ? (readAt - q - 1) : (end - q));
                            }
                            if (l == 0)
                            {
                                bitb = b;
                                bitk = k;
                                _codec.AvailableBytesIn = m;
                                _codec.TotalBytesIn    += p - _codec.NextIn;
                                _codec.NextIn           = p;
                                writeAt = q;
                                return(Flush(r));
                            }
                        }
                    }
                    r = 0;
                    int t = left;
                    if (t > m)
                    {
                        t = m;
                    }
                    if (t > l)
                    {
                        t = l;
                    }
                    Array.Copy(_codec.InputBuffer, p, window, q, t);
                    p += t;
                    m -= t;
                    q += t;
                    l -= t;
                    if ((left -= t) == 0)
                    {
                        mode = ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    }
                    break;
                }

                case InflateBlockMode.TABLE:
                {
                    for (; k < 14; k += 8)
                    {
                        if (m != 0)
                        {
                            r = 0;
                            m--;
                            b |= (_codec.InputBuffer[p++] & 0xFF) << k;
                            continue;
                        }
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    int t = (table = b & 0x3FFF);
                    if ((t & 0x1F) > 29 || ((t >> 5) & 0x1F) > 29)
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "too many length or distance symbols";
                        r    = -3;
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    t = 258 + (t & 0x1F) + ((t >> 5) & 0x1F);
                    if (blens == null || blens.Length < t)
                    {
                        blens = new int[t];
                    }
                    else
                    {
                        Array.Clear(blens, 0, t);
                    }
                    b   >>= 14;
                    k    -= 14;
                    index = 0;
                    mode  = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;
                }

                case InflateBlockMode.BTREE:
                {
                    while (index < 4 + (table >> 10))
                    {
                        for (; k < 3; k += 8)
                        {
                            if (m != 0)
                            {
                                r = 0;
                                m--;
                                b |= (_codec.InputBuffer[p++] & 0xFF) << k;
                                continue;
                            }
                            bitb = b;
                            bitk = k;
                            _codec.AvailableBytesIn = m;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        blens[border[index++]] = b & 7;
                        b >>= 3;
                        k  -= 3;
                    }
                    while (index < 19)
                    {
                        blens[border[index++]] = 0;
                    }
                    bb[0] = 7;
                    int t = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
                    if (t != 0)
                    {
                        r = t;
                        if (r == -3)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;
                }

                case InflateBlockMode.DTREE:
                {
                    int t;
                    while (true)
                    {
                        t = table;
                        if (index >= 258 + (t & 0x1F) + ((t >> 5) & 0x1F))
                        {
                            break;
                        }
                        for (t = bb[0]; k < t; k += 8)
                        {
                            if (m != 0)
                            {
                                r = 0;
                                m--;
                                b |= (_codec.InputBuffer[p++] & 0xFF) << k;
                                continue;
                            }
                            bitb = b;
                            bitk = k;
                            _codec.AvailableBytesIn = m;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1];
                        int c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2];
                        if (c < 16)
                        {
                            b >>= t;
                            k  -= t;
                            blens[index++] = c;
                            continue;
                        }
                        int i = ((c == 18) ? 7 : (c - 14));
                        int j = ((c == 18) ? 11 : 3);
                        for (; k < t + i; k += 8)
                        {
                            if (m != 0)
                            {
                                r = 0;
                                m--;
                                b |= (_codec.InputBuffer[p++] & 0xFF) << k;
                                continue;
                            }
                            bitb = b;
                            bitk = k;
                            _codec.AvailableBytesIn = m;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        b >>= t;
                        k  -= t;
                        j  += b & InternalInflateConstants.InflateMask[i];
                        b >>= i;
                        k  -= i;
                        i   = index;
                        t   = table;
                        if (i + j > 258 + (t & 0x1F) + ((t >> 5) & 0x1F) || (c == 16 && i < 1))
                        {
                            blens          = null;
                            mode           = InflateBlockMode.BAD;
                            _codec.Message = "invalid bit length repeat";
                            r    = -3;
                            bitb = b;
                            bitk = k;
                            _codec.AvailableBytesIn = m;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        c = ((c == 16) ? blens[i - 1] : 0);
                        do
                        {
                            blens[i++] = c;
                        }while (--j != 0);
                        index = i;
                    }
                    tb[0] = -1;
                    int[] bl2 = new int[1]
                    {
                        9
                    };
                    int[] bd2 = new int[1]
                    {
                        6
                    };
                    int[] tl2 = new int[1];
                    int[] td2 = new int[1];
                    t = table;
                    t = inftree.inflate_trees_dynamic(257 + (t & 0x1F), 1 + ((t >> 5) & 0x1F), blens, bl2, bd2, tl2, td2, hufts, _codec);
                    if (t != 0)
                    {
                        if (t == -3)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }
                        r    = t;
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    codes.Init(bl2[0], bd2[0], hufts, tl2[0], hufts, td2[0]);
                    mode = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;
                }

                case InflateBlockMode.CODES:
                    bitb = b;
                    bitk = k;
                    _codec.AvailableBytesIn = m;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    r       = codes.Process(this, r);
                    if (r != 1)
                    {
                        return(Flush(r));
                    }
                    r = 0;
                    p = _codec.NextIn;
                    m = _codec.AvailableBytesIn;
                    b = bitb;
                    k = bitk;
                    q = writeAt;
                    l = ((q < readAt) ? (readAt - q - 1) : (end - q));
                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    writeAt = q;
                    r       = Flush(r);
                    q       = writeAt;
                    l       = ((q < readAt) ? (readAt - q - 1) : (end - q));
                    if (readAt != writeAt)
                    {
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = m;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    r    = 1;
                    bitb = b;
                    bitk = k;
                    _codec.AvailableBytesIn = m;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));

                case InflateBlockMode.BAD:
                    r    = -3;
                    bitb = b;
                    bitk = k;
                    _codec.AvailableBytesIn = m;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));

                default:
                    r    = -2;
                    bitb = b;
                    bitk = k;
                    _codec.AvailableBytesIn = m;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));
                }
            }
        }
Example #34
0
        int tb; // bit length decoding tree

        #endregion Fields

        #region Constructors

        internal InflateBlocks(ZlibCodec codec, int w)
        {
            this.codec = codec;
            hufts = new int[MANY * 3];
            window = new byte[w];
            end = w;
            mode = InflateBlockMode.TYPE;
            Reset();
        }
Example #35
0
        internal int Process(int r)
        {
            int num  = _codec.NextIn;
            int num2 = _codec.AvailableBytesIn;
            int num3 = bitb;
            int i    = bitk;
            int num4 = writeAt;
            int num5 = (num4 >= readAt) ? (end - num4) : (readAt - num4 - 1);

            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:
                {
                    for (; i < 3; i += 8)
                    {
                        if (num2 == 0)
                        {
                            bitb = num3;
                            bitk = i;
                            _codec.AvailableBytesIn = num2;
                            _codec.TotalBytesIn    += num - _codec.NextIn;
                            _codec.NextIn           = num;
                            writeAt = num4;
                            return(Flush(r));
                        }
                        r = 0;
                        num2--;
                        num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
                    }
                    int num7 = num3 & 7;
                    last = (num7 & 1);
                    switch ((uint)num7 >> 1)
                    {
                    case 0u:
                        num3 >>= 3;
                        i     -= 3;
                        num7   = (i & 7);
                        num3 >>= num7;
                        i     -= num7;
                        mode   = InflateBlockMode.LENS;
                        break;

                    case 1u:
                    {
                        int[]   array  = new int[1];
                        int[]   array2 = new int[1];
                        int[][] array3 = new int[1][];
                        int[][] array4 = new int[1][];
                        InfTree.inflate_trees_fixed(array, array2, array3, array4, _codec);
                        codes.Init(array[0], array2[0], array3[0], 0, array4[0], 0);
                        num3 >>= 3;
                        i     -= 3;
                        mode   = InflateBlockMode.CODES;
                        break;
                    }

                    case 2u:
                        num3 >>= 3;
                        i     -= 3;
                        mode   = InflateBlockMode.TABLE;
                        break;

                    case 3u:
                        num3                  >>= 3;
                        i                      -= 3;
                        mode                    = InflateBlockMode.BAD;
                        _codec.Message          = "invalid block type";
                        r                       = -3;
                        bitb                    = num3;
                        bitk                    = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt                 = num4;
                        return(Flush(r));
                    }
                    break;
                }

                case InflateBlockMode.LENS:
                    for (; i < 32; i += 8)
                    {
                        if (num2 == 0)
                        {
                            bitb = num3;
                            bitk = i;
                            _codec.AvailableBytesIn = num2;
                            _codec.TotalBytesIn    += num - _codec.NextIn;
                            _codec.NextIn           = num;
                            writeAt = num4;
                            return(Flush(r));
                        }
                        r = 0;
                        num2--;
                        num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
                    }
                    if (((~num3 >> 16) & 0xFFFF) != (num3 & 0xFFFF))
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "invalid stored block lengths";
                        r    = -3;
                        bitb = num3;
                        bitk = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt = num4;
                        return(Flush(r));
                    }
                    left = (num3 & 0xFFFF);
                    num3 = (i = 0);
                    mode = ((left != 0) ? InflateBlockMode.STORED : ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE));
                    break;

                case InflateBlockMode.STORED:
                {
                    if (num2 == 0)
                    {
                        bitb = num3;
                        bitk = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt = num4;
                        return(Flush(r));
                    }
                    if (num5 == 0)
                    {
                        if (num4 == end && readAt != 0)
                        {
                            num4 = 0;
                            num5 = ((num4 >= readAt) ? (end - num4) : (readAt - num4 - 1));
                        }
                        if (num5 == 0)
                        {
                            writeAt = num4;
                            r       = Flush(r);
                            num4    = writeAt;
                            num5    = ((num4 >= readAt) ? (end - num4) : (readAt - num4 - 1));
                            if (num4 == end && readAt != 0)
                            {
                                num4 = 0;
                                num5 = ((num4 >= readAt) ? (end - num4) : (readAt - num4 - 1));
                            }
                            if (num5 == 0)
                            {
                                bitb = num3;
                                bitk = i;
                                _codec.AvailableBytesIn = num2;
                                _codec.TotalBytesIn    += num - _codec.NextIn;
                                _codec.NextIn           = num;
                                writeAt = num4;
                                return(Flush(r));
                            }
                        }
                    }
                    r = 0;
                    int num7 = left;
                    if (num7 > num2)
                    {
                        num7 = num2;
                    }
                    if (num7 > num5)
                    {
                        num7 = num5;
                    }
                    Array.Copy(_codec.InputBuffer, num, window, num4, num7);
                    num  += num7;
                    num2 -= num7;
                    num4 += num7;
                    num5 -= num7;
                    if ((left -= num7) == 0)
                    {
                        mode = ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    }
                    break;
                }

                case InflateBlockMode.TABLE:
                {
                    for (; i < 14; i += 8)
                    {
                        if (num2 == 0)
                        {
                            bitb = num3;
                            bitk = i;
                            _codec.AvailableBytesIn = num2;
                            _codec.TotalBytesIn    += num - _codec.NextIn;
                            _codec.NextIn           = num;
                            writeAt = num4;
                            return(Flush(r));
                        }
                        r = 0;
                        num2--;
                        num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
                    }
                    int num7 = table = (num3 & 0x3FFF);
                    if ((num7 & 0x1F) > 29 || ((num7 >> 5) & 0x1F) > 29)
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "too many length or distance symbols";
                        r    = -3;
                        bitb = num3;
                        bitk = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt = num4;
                        return(Flush(r));
                    }
                    num7 = 258 + (num7 & 0x1F) + ((num7 >> 5) & 0x1F);
                    if (blens == null || blens.Length < num7)
                    {
                        blens = new int[num7];
                    }
                    else
                    {
                        Array.Clear(blens, 0, num7);
                    }
                    num3 >>= 14;
                    i     -= 14;
                    index  = 0;
                    mode   = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;
                }

                case InflateBlockMode.BTREE:
                {
                    while (index < 4 + (table >> 10))
                    {
                        for (; i < 3; i += 8)
                        {
                            if (num2 == 0)
                            {
                                bitb = num3;
                                bitk = i;
                                _codec.AvailableBytesIn = num2;
                                _codec.TotalBytesIn    += num - _codec.NextIn;
                                _codec.NextIn           = num;
                                writeAt = num4;
                                return(Flush(r));
                            }
                            r = 0;
                            num2--;
                            num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
                        }
                        blens[border[index++]] = (num3 & 7);
                        num3 >>= 3;
                        i     -= 3;
                    }
                    while (index < 19)
                    {
                        blens[border[index++]] = 0;
                    }
                    bb[0] = 7;
                    int num7 = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
                    if (num7 != 0)
                    {
                        r = num7;
                        if (r == -3)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }
                        bitb = num3;
                        bitk = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt = num4;
                        return(Flush(r));
                    }
                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;
                }

                case InflateBlockMode.DTREE:
                {
                    int num7;
                    while (true)
                    {
                        num7 = table;
                        if (index >= 258 + (num7 & 0x1F) + ((num7 >> 5) & 0x1F))
                        {
                            break;
                        }
                        for (num7 = bb[0]; i < num7; i += 8)
                        {
                            if (num2 == 0)
                            {
                                bitb = num3;
                                bitk = i;
                                _codec.AvailableBytesIn = num2;
                                _codec.TotalBytesIn    += num - _codec.NextIn;
                                _codec.NextIn           = num;
                                writeAt = num4;
                                return(Flush(r));
                            }
                            r = 0;
                            num2--;
                            num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
                        }
                        num7 = hufts[(tb[0] + (num3 & InternalInflateConstants.InflateMask[num7])) * 3 + 1];
                        int num11 = hufts[(tb[0] + (num3 & InternalInflateConstants.InflateMask[num7])) * 3 + 2];
                        if (num11 < 16)
                        {
                            num3         >>= num7;
                            i             -= num7;
                            blens[index++] = num11;
                        }
                        else
                        {
                            int num12 = (num11 != 18) ? (num11 - 14) : 7;
                            int num13 = (num11 != 18) ? 3 : 11;
                            for (; i < num7 + num12; i += 8)
                            {
                                if (num2 == 0)
                                {
                                    bitb = num3;
                                    bitk = i;
                                    _codec.AvailableBytesIn = num2;
                                    _codec.TotalBytesIn    += num - _codec.NextIn;
                                    _codec.NextIn           = num;
                                    writeAt = num4;
                                    return(Flush(r));
                                }
                                r = 0;
                                num2--;
                                num3 |= (_codec.InputBuffer[num++] & 0xFF) << i;
                            }
                            num3 >>= num7;
                            i     -= num7;
                            num13 += (num3 & InternalInflateConstants.InflateMask[num12]);
                            num3 >>= num12;
                            i     -= num12;
                            num12  = index;
                            num7   = table;
                            if (num12 + num13 > 258 + (num7 & 0x1F) + ((num7 >> 5) & 0x1F) || (num11 == 16 && num12 < 1))
                            {
                                blens          = null;
                                mode           = InflateBlockMode.BAD;
                                _codec.Message = "invalid bit length repeat";
                                r    = -3;
                                bitb = num3;
                                bitk = i;
                                _codec.AvailableBytesIn = num2;
                                _codec.TotalBytesIn    += num - _codec.NextIn;
                                _codec.NextIn           = num;
                                writeAt = num4;
                                return(Flush(r));
                            }
                            num11 = ((num11 == 16) ? blens[num12 - 1] : 0);
                            do
                            {
                                blens[num12++] = num11;
                            }while (--num13 != 0);
                            index = num12;
                        }
                    }
                    tb[0] = -1;
                    int[] array5 = new int[1]
                    {
                        9
                    };
                    int[] array6 = new int[1]
                    {
                        6
                    };
                    int[] array7 = new int[1];
                    int[] array8 = new int[1];
                    num7 = table;
                    num7 = inftree.inflate_trees_dynamic(257 + (num7 & 0x1F), 1 + ((num7 >> 5) & 0x1F), blens, array5, array6, array7, array8, hufts, _codec);
                    switch (num7)
                    {
                    case -3:
                        blens = null;
                        mode  = InflateBlockMode.BAD;
                        goto default;

                    default:
                        r    = num7;
                        bitb = num3;
                        bitk = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt = num4;
                        return(Flush(r));

                    case 0:
                        break;
                    }
                    codes.Init(array5[0], array6[0], hufts, array7[0], hufts, array8[0]);
                    mode = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;
                }

                case InflateBlockMode.CODES:
                    bitb = num3;
                    bitk = i;
                    _codec.AvailableBytesIn = num2;
                    _codec.TotalBytesIn    += num - _codec.NextIn;
                    _codec.NextIn           = num;
                    writeAt = num4;
                    r       = codes.Process(this, r);
                    if (r != 1)
                    {
                        return(Flush(r));
                    }
                    r    = 0;
                    num  = _codec.NextIn;
                    num2 = _codec.AvailableBytesIn;
                    num3 = bitb;
                    i    = bitk;
                    num4 = writeAt;
                    num5 = ((num4 >= readAt) ? (end - num4) : (readAt - num4 - 1));
                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    writeAt = num4;
                    r       = Flush(r);
                    num4    = writeAt;
                    num5    = ((num4 >= readAt) ? (end - num4) : (readAt - num4 - 1));
                    if (readAt != writeAt)
                    {
                        bitb = num3;
                        bitk = i;
                        _codec.AvailableBytesIn = num2;
                        _codec.TotalBytesIn    += num - _codec.NextIn;
                        _codec.NextIn           = num;
                        writeAt = num4;
                        return(Flush(r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    r    = 1;
                    bitb = num3;
                    bitk = i;
                    _codec.AvailableBytesIn = num2;
                    _codec.TotalBytesIn    += num - _codec.NextIn;
                    _codec.NextIn           = num;
                    writeAt = num4;
                    return(Flush(r));

                case InflateBlockMode.BAD:
                    r    = -3;
                    bitb = num3;
                    bitk = i;
                    _codec.AvailableBytesIn = num2;
                    _codec.TotalBytesIn    += num - _codec.NextIn;
                    _codec.NextIn           = num;
                    writeAt = num4;
                    return(Flush(r));

                default:
                    r    = -2;
                    bitb = num3;
                    bitk = i;
                    _codec.AvailableBytesIn = num2;
                    _codec.TotalBytesIn    += num - _codec.NextIn;
                    _codec.NextIn           = num;
                    writeAt = num4;
                    return(Flush(r));
                }
            }
        }
        internal ZLibStatus proc(ICompressor z, ZLibStatus r)
        {
            int        t;       // temporary storage
            ZLibStatus tt;
            int        b;       // bit buffer
            int        k;       // bits in bit buffer
            int        p;       // input data pointer
            int        n;       // bytes available there
            int        q;       // output window write pointer
            int        m;

            {              // bytes to end of window or read pointer
                // copy input/output information to locals (UPDATE macro restores)
                p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
            }
            {
                q = write; m = (int)(q < read ? read - q - 1 : end - q);
            }

            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:

                    while (k < (3))
                    {
                        if (n != 0)
                        {
                            r = ZLibStatus.Z_OK;
                        }
                        else
                        {
                            bitb        = b; bitk = k;
                            z.avail_in  = n;
                            z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write       = q;
                            return(inflate_flush(z, r));
                        };
                        n--;
                        b |= (z.next_in[p++] & 0xff) << k;
                        k += 8;
                    }
                    t    = (int)(b & 7);
                    last = t & 1;

                    switch (t >> 1)
                    {
                    case 0:
                    {                                     // stored
                        b >>= (3); k -= (3);
                    }
                        t = k & 7;
                        {                            // go to byte boundary
                            b >>= (t); k -= (t);
                        }
                        mode = InflateBlockMode.LENS;                          // get length of stored block
                        break;

                    case 1:
                    {                                     // fixed
                        int[]   bl = new int[1];
                        int[]   bd = new int[1];
                        int[][] tl = new int[1][];
                        int[][] td = new int[1][];

                        InflateTree.InflateTreesFixed(bl, bd, tl, td, z);
                        codesinit(bl[0], bd[0], tl[0], 0, td[0], 0, z);
                    }
                        {
                            b >>= (3); k -= (3);
                        }

                        mode = InflateBlockMode.CODES;
                        break;

                    case 2:
                    {                                     // dynamic
                        b >>= (3); k -= (3);
                    }

                        mode = InflateBlockMode.TABLE;
                        break;

                    case 3:
                    {                                     // illegal
                        b >>= (3); k -= (3);
                    }
                        mode  = InflateBlockMode.BAD;
                        z.msg = "invalid block type";
                        r     = ZLibStatus.Z_DATA_ERROR;

                        bitb       = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write      = q;
                        return(inflate_flush(z, r));
                    }
                    break;

                case InflateBlockMode.LENS:

                    while (k < (32))
                    {
                        if (n != 0)
                        {
                            r = ZLibStatus.Z_OK;
                        }
                        else
                        {
                            bitb        = b; bitk = k;
                            z.avail_in  = n;
                            z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write       = q;
                            return(inflate_flush(z, r));
                        };
                        n--;
                        b |= (z.next_in[p++] & 0xff) << k;
                        k += 8;
                    }

                    if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
                    {
                        mode  = InflateBlockMode.BAD;
                        z.msg = "invalid stored block lengths";
                        r     = ZLibStatus.Z_DATA_ERROR;

                        bitb       = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write      = q;
                        return(inflate_flush(z, r));
                    }
                    left = (b & 0xffff);
                    b    = k = 0;                        // dump bits
                    mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    break;

                case InflateBlockMode.STORED:
                    if (n == 0)
                    {
                        bitb       = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write      = q;
                        return(inflate_flush(z, r));
                    }

                    if (m == 0)
                    {
                        if (q == end && read != 0)
                        {
                            q = 0; m = (int)(q < read ? read - q - 1 : end - q);
                        }
                        if (m == 0)
                        {
                            write = q;
                            r     = inflate_flush(z, r);
                            q     = write; m = (int)(q < read ? read - q - 1 : end - q);
                            if (q == end && read != 0)
                            {
                                q = 0; m = (int)(q < read ? read - q - 1 : end - q);
                            }
                            if (m == 0)
                            {
                                bitb       = b; bitk = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write      = q;
                                return(inflate_flush(z, r));
                            }
                        }
                    }
                    r = ZLibStatus.Z_OK;

                    t = left;
                    if (t > n)
                    {
                        t = n;
                    }
                    if (t > m)
                    {
                        t = m;
                    }
                    System.Array.Copy(z.next_in, p, window, q, t);
                    p += t; n -= t;
                    q += t; m -= t;
                    if ((left -= t) != 0)
                    {
                        break;
                    }
                    mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                    break;

                case InflateBlockMode.TABLE:

                    while (k < (14))
                    {
                        if (n != 0)
                        {
                            r = ZLibStatus.Z_OK;
                        }
                        else
                        {
                            bitb        = b; bitk = k;
                            z.avail_in  = n;
                            z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write       = q;
                            return(inflate_flush(z, r));
                        };
                        n--;
                        b |= (z.next_in[p++] & 0xff) << k;
                        k += 8;
                    }

                    table = t = (b & 0x3fff);
                    if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                    {
                        mode  = InflateBlockMode.BAD;
                        z.msg = "too many length or distance symbols";
                        r     = ZLibStatus.Z_DATA_ERROR;

                        bitb       = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write      = q;
                        return(inflate_flush(z, r));
                    }
                    t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                    if (blens == null || blens.Length < t)
                    {
                        blens = new int[t];
                    }
                    else
                    {
                        for (int i = 0; i < t; i++)
                        {
                            blens[i] = 0;
                        }
                    }
                    {
                        b >>= (14); k -= (14);
                    }

                    index = 0;
                    mode  = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;

                case InflateBlockMode.BTREE:
                    while (index < 4 + (table >> 10))
                    {
                        while (k < (3))
                        {
                            if (n != 0)
                            {
                                r = ZLibStatus.Z_OK;
                            }
                            else
                            {
                                bitb        = b; bitk = k;
                                z.avail_in  = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write       = q;
                                return(inflate_flush(z, r));
                            };
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        blens[border[index++]] = b & 7;
                        {
                            b >>= (3); k -= (3);
                        }
                    }

                    while (index < 19)
                    {
                        blens[border[index++]] = 0;
                    }

                    bb[0] = 7;
                    tt    = inftree.InflateTreesBits(blens, bb, tb, hufts, z);
                    if (tt != ZLibStatus.Z_OK)
                    {
                        r = tt;
                        if (r == ZLibStatus.Z_DATA_ERROR)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }

                        bitb       = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write      = q;
                        return(inflate_flush(z, r));
                    }

                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;

                case InflateBlockMode.DTREE:
                    while (true)
                    {
                        t = table;
                        if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                        {
                            break;
                        }

                        int i, j, c;

                        t = bb[0];

                        while (k < (t))
                        {
                            if (n != 0)
                            {
                                r = ZLibStatus.Z_OK;
                            }
                            else
                            {
                                bitb        = b; bitk = k;
                                z.avail_in  = n;
                                z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write       = q;
                                return(inflate_flush(z, r));
                            };
                            n--;
                            b |= (z.next_in[p++] & 0xff) << k;
                            k += 8;
                        }

                        if (tb[0] == -1)
                        {
                            //System.err.println("null...");
                        }

                        t = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 1];
                        c = hufts[(tb[0] + (b & inflate_mask[t])) * 3 + 2];

                        if (c < 16)
                        {
                            b >>= (t); k -= (t);
                            blens[index++] = c;
                        }
                        else
                        {     // c == 16..18
                            i = c == 18 ? 7 : c - 14;
                            j = c == 18 ? 11 : 3;

                            while (k < (t + i))
                            {
                                if (n != 0)
                                {
                                    r = ZLibStatus.Z_OK;
                                }
                                else
                                {
                                    bitb        = b; bitk = k;
                                    z.avail_in  = n;
                                    z.total_in += p - z.next_in_index; z.next_in_index = p;
                                    write       = q;
                                    return(inflate_flush(z, r));
                                };
                                n--;
                                b |= (z.next_in[p++] & 0xff) << k;
                                k += 8;
                            }

                            b >>= (t); k -= (t);

                            j += (b & inflate_mask[i]);

                            b >>= (i); k -= (i);

                            i = index;
                            t = table;
                            if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) ||
                                (c == 16 && i < 1))
                            {
                                blens = null;
                                mode  = InflateBlockMode.BAD;
                                z.msg = "invalid bit length repeat";
                                r     = ZLibStatus.Z_DATA_ERROR;

                                bitb       = b; bitk = k;
                                z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                                write      = q;
                                return(inflate_flush(z, r));
                            }

                            c = c == 16 ? blens[i - 1] : 0;
                            do
                            {
                                blens[i++] = c;
                            }while (--j != 0);
                            index = i;
                        }
                    }

                    tb[0] = -1;
                    {
                        int[] bl = new int[1];
                        int[] bd = new int[1];
                        int[] tl = new int[1];
                        int[] td = new int[1];
                        bl[0] = 9;             // must be <= 9 for lookahead assumptions
                        bd[0] = 6;             // must be <= 9 for lookahead assumptions

                        t  = table;
                        tt = inftree.InflateTreesDynamic(257 + (t & 0x1f),
                                                         1 + ((t >> 5) & 0x1f),
                                                         blens, bl, bd, tl, td, hufts, z);

                        if (tt != ZLibStatus.Z_OK)
                        {
                            if (tt == ZLibStatus.Z_DATA_ERROR)
                            {
                                blens = null;
                                mode  = InflateBlockMode.BAD;
                            }
                            r = tt;

                            bitb       = b; bitk = k;
                            z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                            write      = q;
                            return(inflate_flush(z, r));
                        }
                        codesinit(bl[0], bd[0], hufts, tl[0], hufts, td[0], z);
                    }
                    mode = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;

                case InflateBlockMode.CODES:
                    bitb       = b; bitk = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    write      = q;

                    if ((r = codesproc(this, z, r)) != ZLibStatus.Z_STREAM_END)
                    {
                        return(inflate_flush(z, r));
                    }
                    r = ZLibStatus.Z_OK;
                    codesfree(z);

                    p = z.next_in_index; n = z.avail_in; b = bitb; k = bitk;
                    q = write; m = (int)(q < read ? read - q - 1 : end - q);

                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    write = q;
                    r     = inflate_flush(z, r);
                    q     = write; m = (int)(q < read ? read - q - 1 : end - q);
                    if (read != write)
                    {
                        bitb       = b; bitk = k;
                        z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                        write      = q;
                        return(inflate_flush(z, r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    r = ZLibStatus.Z_STREAM_END;

                    bitb       = b; bitk = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    write      = q;
                    return(inflate_flush(z, r));

                case InflateBlockMode.BAD:
                    r = ZLibStatus.Z_DATA_ERROR;

                    bitb       = b; bitk = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    write      = q;
                    return(inflate_flush(z, r));

                default:
                    r = ZLibStatus.Z_STREAM_ERROR;

                    bitb       = b; bitk = k;
                    z.avail_in = n; z.total_in += p - z.next_in_index; z.next_in_index = p;
                    write      = q;
                    return(inflate_flush(z, r));
                }
            }
        }
Example #37
0
 internal InflateBlocks(ZlibCodec codec, System.Object checkfn, int w)
 {
     _codec = codec;
     hufts = new int[MANY * 3];
     window = new byte[w];
     end = w;
     this.checkfn = checkfn;
     mode = InflateBlockMode.TYPE;
     Reset();
 }
        internal void reset(ZStream z, long[] c)
        {
            if (c != null) c[0] = check;
            if (mode == InflateBlockMode.BTREE || mode == InflateBlockMode.DTREE)
            {
            }
            if (mode == InflateBlockMode.CODES)
            {
                codesfree(z);
            }
            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            read = write = 0;

            if (checkfn != null)
                z.adler = check = Adler32.adler32(0L, null, 0, 0);
        }
Example #39
0
        internal int Process(int r)
        {
            int t; // temporary storage
            int b; // bit buffer
            int k; // bits in bit buffer
            int p; // input data pointer
            int n; // bytes available there
            int q; // output window write pointer
            int m; // bytes to end of window or read pointer

            // copy input/output information to locals (UPDATE macro restores)

            p = _codec.NextIn;
            n = _codec.AvailableBytesIn;
            b = bitb;
            k = bitk;

            q = writeAt;
            m = (int)(q < readAt ? readAt - q - 1 : end - q);


            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                    case InflateBlockMode.TYPE:

                        while (k < (3))
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn += p - _codec.NextIn;
                                _codec.NextIn = p;
                                writeAt = q;
                                return Flush(r);
                            }

                            n--;
                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }
                        t = (int)(b & 7);
                        last = t & 1;

                        switch ((uint)t >> 1)
                        {
                            case 0:  // stored
                                b >>= 3; k -= (3);
                                t = k & 7; // go to byte boundary
                                b >>= t; k -= t;
                                mode = InflateBlockMode.LENS; // get length of stored block
                                break;

                            case 1:  // fixed
                                int[] bl = new int[1];
                                int[] bd = new int[1];
                                int[][] tl = new int[1][];
                                int[][] td = new int[1][];
                                InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec);
                                codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                                b >>= 3; k -= 3;
                                mode = InflateBlockMode.CODES;
                                break;

                            case 2:  // dynamic
                                b >>= 3; k -= 3;
                                mode = InflateBlockMode.TABLE;
                                break;

                            case 3:  // illegal
                                b >>= 3; k -= 3;
                                mode = InflateBlockMode.BAD;
                                _codec.Message = "invalid block type";
                                r = ZlibConstants.Z_DATA_ERROR;
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn += p - _codec.NextIn;
                                _codec.NextIn = p;
                                writeAt = q;
                                return Flush(r);
                        }
                        break;

                    case InflateBlockMode.LENS:

                        while (k < (32))
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn += p - _codec.NextIn;
                                _codec.NextIn = p;
                                writeAt = q;
                                return Flush(r);
                            }
                            ;
                            n--;
                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
                        {
                            mode = InflateBlockMode.BAD;
                            _codec.Message = "invalid stored block lengths";
                            r = ZlibConstants.Z_DATA_ERROR;

                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn += p - _codec.NextIn;
                            _codec.NextIn = p;
                            writeAt = q;
                            return Flush(r);
                        }
                        left = (b & 0xffff);
                        b = k = 0; // dump bits
                        mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                        break;

                    case InflateBlockMode.STORED:
                        if (n == 0)
                        {
                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn += p - _codec.NextIn;
                            _codec.NextIn = p;
                            writeAt = q;
                            return Flush(r);
                        }

                        if (m == 0)
                        {
                            if (q == end && readAt != 0)
                            {
                                q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                            }
                            if (m == 0)
                            {
                                writeAt = q;
                                r = Flush(r);
                                q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                                if (q == end && readAt != 0)
                                {
                                    q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                                }
                                if (m == 0)
                                {
                                    bitb = b; bitk = k;
                                    _codec.AvailableBytesIn = n;
                                    _codec.TotalBytesIn += p - _codec.NextIn;
                                    _codec.NextIn = p;
                                    writeAt = q;
                                    return Flush(r);
                                }
                            }
                        }
                        r = ZlibConstants.Z_OK;

                        t = left;
                        if (t > n)
                            t = n;
                        if (t > m)
                            t = m;
                        Array.Copy(_codec.InputBuffer, p, window, q, t);
                        p += t; n -= t;
                        q += t; m -= t;
                        if ((left -= t) != 0)
                            break;
                        mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                        break;

                    case InflateBlockMode.TABLE:

                        while (k < (14))
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn += p - _codec.NextIn;
                                _codec.NextIn = p;
                                writeAt = q;
                                return Flush(r);
                            }

                            n--;
                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        table = t = (b & 0x3fff);
                        if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                        {
                            mode = InflateBlockMode.BAD;
                            _codec.Message = "too many length or distance symbols";
                            r = ZlibConstants.Z_DATA_ERROR;

                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn += p - _codec.NextIn;
                            _codec.NextIn = p;
                            writeAt = q;
                            return Flush(r);
                        }
                        t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                        if (blens == null || blens.Length < t)
                        {
                            blens = new int[t];
                        }
                        else
                        {
                            Array.Clear(blens, 0, t);
                            // for (int i = 0; i < t; i++)
                            // {
                            //     blens[i] = 0;
                            // }
                        }

                        b >>= 14;
                        k -= 14;


                        index = 0;
                        mode = InflateBlockMode.BTREE;
                        goto case InflateBlockMode.BTREE;

                    case InflateBlockMode.BTREE:
                        while (index < 4 + (table >> 10))
                        {
                            while (k < (3))
                            {
                                if (n != 0)
                                {
                                    r = ZlibConstants.Z_OK;
                                }
                                else
                                {
                                    bitb = b; bitk = k;
                                    _codec.AvailableBytesIn = n;
                                    _codec.TotalBytesIn += p - _codec.NextIn;
                                    _codec.NextIn = p;
                                    writeAt = q;
                                    return Flush(r);
                                }

                                n--;
                                b |= (_codec.InputBuffer[p++] & 0xff) << k;
                                k += 8;
                            }

                            blens[border[index++]] = b & 7;

                            b >>= 3; k -= 3;
                        }

                        while (index < 19)
                        {
                            blens[border[index++]] = 0;
                        }

                        bb[0] = 7;
                        t = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
                        if (t != ZlibConstants.Z_OK)
                        {
                            r = t;
                            if (r == ZlibConstants.Z_DATA_ERROR)
                            {
                                blens = null;
                                mode = InflateBlockMode.BAD;
                            }

                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn += p - _codec.NextIn;
                            _codec.NextIn = p;
                            writeAt = q;
                            return Flush(r);
                        }

                        index = 0;
                        mode = InflateBlockMode.DTREE;
                        goto case InflateBlockMode.DTREE;

                    case InflateBlockMode.DTREE:
                        while (true)
                        {
                            t = table;
                            if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                            {
                                break;
                            }

                            int i, j, c;

                            t = bb[0];

                            while (k < t)
                            {
                                if (n != 0)
                                {
                                    r = ZlibConstants.Z_OK;
                                }
                                else
                                {
                                    bitb = b; bitk = k;
                                    _codec.AvailableBytesIn = n;
                                    _codec.TotalBytesIn += p - _codec.NextIn;
                                    _codec.NextIn = p;
                                    writeAt = q;
                                    return Flush(r);
                                }

                                n--;
                                b |= (_codec.InputBuffer[p++] & 0xff) << k;
                                k += 8;
                            }

                            t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1];
                            c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2];

                            if (c < 16)
                            {
                                b >>= t; k -= t;
                                blens[index++] = c;
                            }
                            else
                            {
                                // c == 16..18
                                i = c == 18 ? 7 : c - 14;
                                j = c == 18 ? 11 : 3;

                                while (k < (t + i))
                                {
                                    if (n != 0)
                                    {
                                        r = ZlibConstants.Z_OK;
                                    }
                                    else
                                    {
                                        bitb = b; bitk = k;
                                        _codec.AvailableBytesIn = n;
                                        _codec.TotalBytesIn += p - _codec.NextIn;
                                        _codec.NextIn = p;
                                        writeAt = q;
                                        return Flush(r);
                                    }

                                    n--;
                                    b |= (_codec.InputBuffer[p++] & 0xff) << k;
                                    k += 8;
                                }

                                b >>= t; k -= t;

                                j += (b & InternalInflateConstants.InflateMask[i]);

                                b >>= i; k -= i;

                                i = index;
                                t = table;
                                if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
                                {
                                    blens = null;
                                    mode = InflateBlockMode.BAD;
                                    _codec.Message = "invalid bit length repeat";
                                    r = ZlibConstants.Z_DATA_ERROR;

                                    bitb = b; bitk = k;
                                    _codec.AvailableBytesIn = n;
                                    _codec.TotalBytesIn += p - _codec.NextIn;
                                    _codec.NextIn = p;
                                    writeAt = q;
                                    return Flush(r);
                                }

                                c = (c == 16) ? blens[i - 1] : 0;
                                do
                                {
                                    blens[i++] = c;
                                }
                                while (--j != 0);
                                index = i;
                            }
                        }

                        tb[0] = -1;
                        {
                            int[] bl = new int[] { 9 };  // must be <= 9 for lookahead assumptions
                            int[] bd = new int[] { 6 }; // must be <= 9 for lookahead assumptions
                            int[] tl = new int[1];
                            int[] td = new int[1];

                            t = table;
                            t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, _codec);

                            if (t != ZlibConstants.Z_OK)
                            {
                                if (t == ZlibConstants.Z_DATA_ERROR)
                                {
                                    blens = null;
                                    mode = InflateBlockMode.BAD;
                                }
                                r = t;

                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn += p - _codec.NextIn;
                                _codec.NextIn = p;
                                writeAt = q;
                                return Flush(r);
                            }
                            codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]);
                        }
                        mode = InflateBlockMode.CODES;
                        goto case InflateBlockMode.CODES;

                    case InflateBlockMode.CODES:
                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn += p - _codec.NextIn;
                        _codec.NextIn = p;
                        writeAt = q;

                        r = codes.Process(this, r);
                        if (r != ZlibConstants.Z_STREAM_END)
                        {
                            return Flush(r);
                        }

                        r = ZlibConstants.Z_OK;
                        p = _codec.NextIn;
                        n = _codec.AvailableBytesIn;
                        b = bitb;
                        k = bitk;
                        q = writeAt;
                        m = (int)(q < readAt ? readAt - q - 1 : end - q);

                        if (last == 0)
                        {
                            mode = InflateBlockMode.TYPE;
                            break;
                        }
                        mode = InflateBlockMode.DRY;
                        goto case InflateBlockMode.DRY;

                    case InflateBlockMode.DRY:
                        writeAt = q;
                        r = Flush(r);
                        q = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                        if (readAt != writeAt)
                        {
                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn += p - _codec.NextIn;
                            _codec.NextIn = p;
                            writeAt = q;
                            return Flush(r);
                        }
                        mode = InflateBlockMode.DONE;
                        goto case InflateBlockMode.DONE;

                    case InflateBlockMode.DONE:
                        r = ZlibConstants.Z_STREAM_END;
                        bitb = b;
                        bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn += p - _codec.NextIn;
                        _codec.NextIn = p;
                        writeAt = q;
                        return Flush(r);

                    case InflateBlockMode.BAD:
                        r = ZlibConstants.Z_DATA_ERROR;

                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn += p - _codec.NextIn;
                        _codec.NextIn = p;
                        writeAt = q;
                        return Flush(r);


                    default:
                        r = ZlibConstants.Z_STREAM_ERROR;

                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn += p - _codec.NextIn;
                        _codec.NextIn = p;
                        writeAt = q;
                        return Flush(r);
                }
            }
        }
Example #40
0
        //private InfTree inftree = new InfTree();

        public InfBlocks(ZStream z, Object checkfn, int w)
        {
            hufts = new int[MANY * 3];
            window = new byte[w];
            end = w;
            this.checkfn = checkfn;
            mode = InflateBlockMode.TYPE;
            Reset(z, null);
        }
Example #41
0
        internal int Process(int r)
        {
            int t; // temporary storage
            int b; // bit buffer
            int k; // bits in bit buffer
            int p; // input data pointer
            int n; // bytes available there
            int q; // output window write pointer
            int m; // bytes to end of window or read pointer

            // copy input/output information to locals (UPDATE macro restores)

            p = _codec.NextIn;
            n = _codec.AvailableBytesIn;
            b = bitb;
            k = bitk;

            q = writeAt;
            m = (int)(q < readAt ? readAt - q - 1 : end - q);


            // process input based on current state
            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:

                    while (k < (3))
                    {
                        if (n != 0)
                        {
                            r = ZlibConstants.Z_OK;
                        }
                        else
                        {
                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }

                        n--;
                        b |= (_codec.InputBuffer[p++] & 0xff) << k;
                        k += 8;
                    }
                    t    = (int)(b & 7);
                    last = t & 1;

                    switch ((uint)t >> 1)
                    {
                    case 0:                           // stored
                        b  >>= 3; k -= (3);
                        t    = k & 7;                 // go to byte boundary
                        b  >>= t; k -= t;
                        mode = InflateBlockMode.LENS; // get length of stored block
                        break;

                    case 1:          // fixed
                        int[]   bl = new int[1];
                        int[]   bd = new int[1];
                        int[][] tl = new int[1][];
                        int[][] td = new int[1][];
                        InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec);
                        codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                        b  >>= 3; k -= 3;
                        mode = InflateBlockMode.CODES;
                        break;

                    case 2:          // dynamic
                        b  >>= 3; k -= 3;
                        mode = InflateBlockMode.TABLE;
                        break;

                    case 3:          // illegal
                        b                     >>= 3; k -= 3;
                        mode                    = InflateBlockMode.BAD;
                        _codec.Message          = "invalid block type";
                        r                       = ZlibConstants.Z_DATA_ERROR;
                        bitb                    = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt                 = q;
                        return(Flush(r));
                    }
                    break;

                case InflateBlockMode.LENS:

                    while (k < (32))
                    {
                        if (n != 0)
                        {
                            r = ZlibConstants.Z_OK;
                        }
                        else
                        {
                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        ;
                        n--;
                        b |= (_codec.InputBuffer[p++] & 0xff) << k;
                        k += 8;
                    }

                    if ((((~b) >> 16) & 0xffff) != (b & 0xffff))
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "invalid stored block lengths";
                        r = ZlibConstants.Z_DATA_ERROR;

                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    left = (b & 0xffff);
                    b    = k = 0;  // dump bits
                    mode = left != 0 ? InflateBlockMode.STORED : (last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    break;

                case InflateBlockMode.STORED:
                    if (n == 0)
                    {
                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }

                    if (m == 0)
                    {
                        if (q == end && readAt != 0)
                        {
                            q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                        }
                        if (m == 0)
                        {
                            writeAt = q;
                            r       = Flush(r);
                            q       = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                            if (q == end && readAt != 0)
                            {
                                q = 0; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                            }
                            if (m == 0)
                            {
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn    += p - _codec.NextIn;
                                _codec.NextIn           = p;
                                writeAt = q;
                                return(Flush(r));
                            }
                        }
                    }
                    r = ZlibConstants.Z_OK;

                    t = left;
                    if (t > n)
                    {
                        t = n;
                    }
                    if (t > m)
                    {
                        t = m;
                    }
                    Array.Copy(_codec.InputBuffer, p, window, q, t);
                    p += t; n -= t;
                    q += t; m -= t;
                    if ((left -= t) != 0)
                    {
                        break;
                    }
                    mode = last != 0 ? InflateBlockMode.DRY : InflateBlockMode.TYPE;
                    break;

                case InflateBlockMode.TABLE:

                    while (k < (14))
                    {
                        if (n != 0)
                        {
                            r = ZlibConstants.Z_OK;
                        }
                        else
                        {
                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }

                        n--;
                        b |= (_codec.InputBuffer[p++] & 0xff) << k;
                        k += 8;
                    }

                    table = t = (b & 0x3fff);
                    if ((t & 0x1f) > 29 || ((t >> 5) & 0x1f) > 29)
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "too many length or distance symbols";
                        r = ZlibConstants.Z_DATA_ERROR;

                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    t = 258 + (t & 0x1f) + ((t >> 5) & 0x1f);
                    if (blens == null || blens.Length < t)
                    {
                        blens = new int[t];
                    }
                    else
                    {
                        Array.Clear(blens, 0, t);
                        // for (int i = 0; i < t; i++)
                        // {
                        //     blens[i] = 0;
                        // }
                    }

                    b >>= 14;
                    k  -= 14;


                    index = 0;
                    mode  = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;

                case InflateBlockMode.BTREE:
                    while (index < 4 + (table >> 10))
                    {
                        while (k < (3))
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn    += p - _codec.NextIn;
                                _codec.NextIn           = p;
                                writeAt = q;
                                return(Flush(r));
                            }

                            n--;
                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        blens[border[index++]] = b & 7;

                        b >>= 3; k -= 3;
                    }

                    while (index < 19)
                    {
                        blens[border[index++]] = 0;
                    }

                    bb[0] = 7;
                    t     = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
                    if (t != ZlibConstants.Z_OK)
                    {
                        r = t;
                        if (r == ZlibConstants.Z_DATA_ERROR)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }

                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }

                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;

                case InflateBlockMode.DTREE:
                    while (true)
                    {
                        t = table;
                        if (!(index < 258 + (t & 0x1f) + ((t >> 5) & 0x1f)))
                        {
                            break;
                        }

                        int i, j, c;

                        t = bb[0];

                        while (k < t)
                        {
                            if (n != 0)
                            {
                                r = ZlibConstants.Z_OK;
                            }
                            else
                            {
                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn    += p - _codec.NextIn;
                                _codec.NextIn           = p;
                                writeAt = q;
                                return(Flush(r));
                            }

                            n--;
                            b |= (_codec.InputBuffer[p++] & 0xff) << k;
                            k += 8;
                        }

                        t = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 1];
                        c = hufts[(tb[0] + (b & InternalInflateConstants.InflateMask[t])) * 3 + 2];

                        if (c < 16)
                        {
                            b >>= t; k -= t;
                            blens[index++] = c;
                        }
                        else
                        {
                            // c == 16..18
                            i = c == 18 ? 7 : c - 14;
                            j = c == 18 ? 11 : 3;

                            while (k < (t + i))
                            {
                                if (n != 0)
                                {
                                    r = ZlibConstants.Z_OK;
                                }
                                else
                                {
                                    bitb = b; bitk = k;
                                    _codec.AvailableBytesIn = n;
                                    _codec.TotalBytesIn    += p - _codec.NextIn;
                                    _codec.NextIn           = p;
                                    writeAt = q;
                                    return(Flush(r));
                                }

                                n--;
                                b |= (_codec.InputBuffer[p++] & 0xff) << k;
                                k += 8;
                            }

                            b >>= t; k -= t;

                            j += (b & InternalInflateConstants.InflateMask[i]);

                            b >>= i; k -= i;

                            i = index;
                            t = table;
                            if (i + j > 258 + (t & 0x1f) + ((t >> 5) & 0x1f) || (c == 16 && i < 1))
                            {
                                blens          = null;
                                mode           = InflateBlockMode.BAD;
                                _codec.Message = "invalid bit length repeat";
                                r = ZlibConstants.Z_DATA_ERROR;

                                bitb = b; bitk = k;
                                _codec.AvailableBytesIn = n;
                                _codec.TotalBytesIn    += p - _codec.NextIn;
                                _codec.NextIn           = p;
                                writeAt = q;
                                return(Flush(r));
                            }

                            c = (c == 16) ? blens[i - 1] : 0;
                            do
                            {
                                blens[i++] = c;
                            }while (--j != 0);
                            index = i;
                        }
                    }

                    tb[0] = -1;
                    {
                        int[] bl = new int[] { 9 };     // must be <= 9 for lookahead assumptions
                        int[] bd = new int[] { 6 };     // must be <= 9 for lookahead assumptions
                        int[] tl = new int[1];
                        int[] td = new int[1];

                        t = table;
                        t = inftree.inflate_trees_dynamic(257 + (t & 0x1f), 1 + ((t >> 5) & 0x1f), blens, bl, bd, tl, td, hufts, _codec);

                        if (t != ZlibConstants.Z_OK)
                        {
                            if (t == ZlibConstants.Z_DATA_ERROR)
                            {
                                blens = null;
                                mode  = InflateBlockMode.BAD;
                            }
                            r = t;

                            bitb = b; bitk = k;
                            _codec.AvailableBytesIn = n;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        codes.Init(bl[0], bd[0], hufts, tl[0], hufts, td[0]);
                    }
                    mode = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;

                case InflateBlockMode.CODES:
                    bitb = b; bitk = k;
                    _codec.AvailableBytesIn = n;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;

                    r = codes.Process(this, r);
                    if (r != ZlibConstants.Z_STREAM_END)
                    {
                        return(Flush(r));
                    }

                    r = ZlibConstants.Z_OK;
                    p = _codec.NextIn;
                    n = _codec.AvailableBytesIn;
                    b = bitb;
                    k = bitk;
                    q = writeAt;
                    m = (int)(q < readAt ? readAt - q - 1 : end - q);

                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    writeAt = q;
                    r       = Flush(r);
                    q       = writeAt; m = (int)(q < readAt ? readAt - q - 1 : end - q);
                    if (readAt != writeAt)
                    {
                        bitb = b; bitk = k;
                        _codec.AvailableBytesIn = n;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    r    = ZlibConstants.Z_STREAM_END;
                    bitb = b;
                    bitk = k;
                    _codec.AvailableBytesIn = n;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));

                case InflateBlockMode.BAD:
                    r = ZlibConstants.Z_DATA_ERROR;

                    bitb = b; bitk = k;
                    _codec.AvailableBytesIn = n;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));


                default:
                    r = ZlibConstants.Z_STREAM_ERROR;

                    bitb = b; bitk = k;
                    _codec.AvailableBytesIn = n;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));
                }
            }
        }
Example #42
0
        internal int Process(int r)
        {
            int p  = _codec.NextIn;
            int n2 = _codec.AvailableBytesIn;
            int b4 = bitb;
            int k2 = bitk;
            int q  = writeAt;
            int m2 = (q < readAt) ? (readAt - q - 1) : (end - q);

            while (true)
            {
                switch (mode)
                {
                case InflateBlockMode.TYPE:
                {
                    for (; k2 < 3; k2 += 8)
                    {
                        if (n2 != 0)
                        {
                            r = 0;
                            n2--;
                            b4 |= (_codec.InputBuffer[p++] & 0xFF) << k2;
                            continue;
                        }
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    int t12 = b4 & 7;
                    last = (t12 & 1);
                    switch ((uint)t12 >> 1)
                    {
                    case 0u:
                        b4 >>= 3;
                        k2  -= 3;
                        t12  = (k2 & 7);
                        b4 >>= t12;
                        k2  -= t12;
                        mode = InflateBlockMode.LENS;
                        break;

                    case 1u:
                    {
                        int[]   bl = new int[1];
                        int[]   bd = new int[1];
                        int[][] tl = new int[1][];
                        int[][] td = new int[1][];
                        InfTree.inflate_trees_fixed(bl, bd, tl, td, _codec);
                        codes.Init(bl[0], bd[0], tl[0], 0, td[0], 0);
                        b4 >>= 3;
                        k2  -= 3;
                        mode = InflateBlockMode.CODES;
                        break;
                    }

                    case 2u:
                        b4 >>= 3;
                        k2  -= 3;
                        mode = InflateBlockMode.TABLE;
                        break;

                    case 3u:
                        b4           >>= 3;
                        k2            -= 3;
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "invalid block type";
                        r    = -3;
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    break;
                }

                case InflateBlockMode.LENS:
                    for (; k2 < 32; k2 += 8)
                    {
                        if (n2 != 0)
                        {
                            r = 0;
                            n2--;
                            b4 |= (_codec.InputBuffer[p++] & 0xFF) << k2;
                            continue;
                        }
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    if (((~b4 >> 16) & 0xFFFF) != (b4 & 0xFFFF))
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "invalid stored block lengths";
                        r    = -3;
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    left = (b4 & 0xFFFF);
                    b4   = (k2 = 0);
                    mode = ((left != 0) ? InflateBlockMode.STORED : ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE));
                    break;

                case InflateBlockMode.STORED:
                {
                    if (n2 == 0)
                    {
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    if (m2 == 0)
                    {
                        if (q == end && readAt != 0)
                        {
                            q  = 0;
                            m2 = ((q < readAt) ? (readAt - q - 1) : (end - q));
                        }
                        if (m2 == 0)
                        {
                            writeAt = q;
                            r       = Flush(r);
                            q       = writeAt;
                            m2      = ((q < readAt) ? (readAt - q - 1) : (end - q));
                            if (q == end && readAt != 0)
                            {
                                q  = 0;
                                m2 = ((q < readAt) ? (readAt - q - 1) : (end - q));
                            }
                            if (m2 == 0)
                            {
                                bitb = b4;
                                bitk = k2;
                                _codec.AvailableBytesIn = n2;
                                _codec.TotalBytesIn    += p - _codec.NextIn;
                                _codec.NextIn           = p;
                                writeAt = q;
                                return(Flush(r));
                            }
                        }
                    }
                    r = 0;
                    int t12 = left;
                    if (t12 > n2)
                    {
                        t12 = n2;
                    }
                    if (t12 > m2)
                    {
                        t12 = m2;
                    }
                    Array.Copy(_codec.InputBuffer, p, window, q, t12);
                    p  += t12;
                    n2 -= t12;
                    q  += t12;
                    m2 -= t12;
                    if ((left -= t12) == 0)
                    {
                        mode = ((last != 0) ? InflateBlockMode.DRY : InflateBlockMode.TYPE);
                    }
                    break;
                }

                case InflateBlockMode.TABLE:
                {
                    for (; k2 < 14; k2 += 8)
                    {
                        if (n2 != 0)
                        {
                            r = 0;
                            n2--;
                            b4 |= (_codec.InputBuffer[p++] & 0xFF) << k2;
                            continue;
                        }
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    int t12 = table = (b4 & 0x3FFF);
                    if ((t12 & 0x1F) > 29 || ((t12 >> 5) & 0x1F) > 29)
                    {
                        mode           = InflateBlockMode.BAD;
                        _codec.Message = "too many length or distance symbols";
                        r    = -3;
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    t12 = 258 + (t12 & 0x1F) + ((t12 >> 5) & 0x1F);
                    if (blens == null || blens.Length < t12)
                    {
                        blens = new int[t12];
                    }
                    else
                    {
                        Array.Clear(blens, 0, t12);
                    }
                    b4  >>= 14;
                    k2   -= 14;
                    index = 0;
                    mode  = InflateBlockMode.BTREE;
                    goto case InflateBlockMode.BTREE;
                }

                case InflateBlockMode.BTREE:
                {
                    while (index < 4 + (table >> 10))
                    {
                        for (; k2 < 3; k2 += 8)
                        {
                            if (n2 != 0)
                            {
                                r = 0;
                                n2--;
                                b4 |= (_codec.InputBuffer[p++] & 0xFF) << k2;
                                continue;
                            }
                            bitb = b4;
                            bitk = k2;
                            _codec.AvailableBytesIn = n2;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        blens[border[index++]] = (b4 & 7);
                        b4 >>= 3;
                        k2  -= 3;
                    }
                    while (index < 19)
                    {
                        blens[border[index++]] = 0;
                    }
                    bb[0] = 7;
                    int t12 = inftree.inflate_trees_bits(blens, bb, tb, hufts, _codec);
                    if (t12 != 0)
                    {
                        r = t12;
                        if (r == -3)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    index = 0;
                    mode  = InflateBlockMode.DTREE;
                    goto case InflateBlockMode.DTREE;
                }

                case InflateBlockMode.DTREE:
                {
                    int t12;
                    while (true)
                    {
                        t12 = table;
                        if (index >= 258 + (t12 & 0x1F) + ((t12 >> 5) & 0x1F))
                        {
                            break;
                        }
                        for (t12 = bb[0]; k2 < t12; k2 += 8)
                        {
                            if (n2 != 0)
                            {
                                r = 0;
                                n2--;
                                b4 |= (_codec.InputBuffer[p++] & 0xFF) << k2;
                                continue;
                            }
                            bitb = b4;
                            bitk = k2;
                            _codec.AvailableBytesIn = n2;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        t12 = hufts[(tb[0] + (b4 & InternalInflateConstants.InflateMask[t12])) * 3 + 1];
                        int c2 = hufts[(tb[0] + (b4 & InternalInflateConstants.InflateMask[t12])) * 3 + 2];
                        if (c2 < 16)
                        {
                            b4           >>= t12;
                            k2            -= t12;
                            blens[index++] = c2;
                            continue;
                        }
                        int i2 = (c2 == 18) ? 7 : (c2 - 14);
                        int j2 = (c2 == 18) ? 11 : 3;
                        for (; k2 < t12 + i2; k2 += 8)
                        {
                            if (n2 != 0)
                            {
                                r = 0;
                                n2--;
                                b4 |= (_codec.InputBuffer[p++] & 0xFF) << k2;
                                continue;
                            }
                            bitb = b4;
                            bitk = k2;
                            _codec.AvailableBytesIn = n2;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        b4 >>= t12;
                        k2  -= t12;
                        j2  += (b4 & InternalInflateConstants.InflateMask[i2]);
                        b4 >>= i2;
                        k2  -= i2;
                        i2   = index;
                        t12  = table;
                        if (i2 + j2 > 258 + (t12 & 0x1F) + ((t12 >> 5) & 0x1F) || (c2 == 16 && i2 < 1))
                        {
                            blens          = null;
                            mode           = InflateBlockMode.BAD;
                            _codec.Message = "invalid bit length repeat";
                            r    = -3;
                            bitb = b4;
                            bitk = k2;
                            _codec.AvailableBytesIn = n2;
                            _codec.TotalBytesIn    += p - _codec.NextIn;
                            _codec.NextIn           = p;
                            writeAt = q;
                            return(Flush(r));
                        }
                        c2 = ((c2 == 16) ? blens[i2 - 1] : 0);
                        do
                        {
                            blens[i2++] = c2;
                        }while (--j2 != 0);
                        index = i2;
                    }
                    tb[0] = -1;
                    int[] bl2 = new int[1]
                    {
                        9
                    };
                    int[] bd2 = new int[1]
                    {
                        6
                    };
                    int[] tl2 = new int[1];
                    int[] td2 = new int[1];
                    t12 = table;
                    t12 = inftree.inflate_trees_dynamic(257 + (t12 & 0x1F), 1 + ((t12 >> 5) & 0x1F), blens, bl2, bd2, tl2, td2, hufts, _codec);
                    if (t12 != 0)
                    {
                        if (t12 == -3)
                        {
                            blens = null;
                            mode  = InflateBlockMode.BAD;
                        }
                        r    = t12;
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    codes.Init(bl2[0], bd2[0], hufts, tl2[0], hufts, td2[0]);
                    mode = InflateBlockMode.CODES;
                    goto case InflateBlockMode.CODES;
                }

                case InflateBlockMode.CODES:
                    bitb = b4;
                    bitk = k2;
                    _codec.AvailableBytesIn = n2;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    r       = codes.Process(this, r);
                    if (r != 1)
                    {
                        return(Flush(r));
                    }
                    r  = 0;
                    p  = _codec.NextIn;
                    n2 = _codec.AvailableBytesIn;
                    b4 = bitb;
                    k2 = bitk;
                    q  = writeAt;
                    m2 = ((q < readAt) ? (readAt - q - 1) : (end - q));
                    if (last == 0)
                    {
                        mode = InflateBlockMode.TYPE;
                        break;
                    }
                    mode = InflateBlockMode.DRY;
                    goto case InflateBlockMode.DRY;

                case InflateBlockMode.DRY:
                    writeAt = q;
                    r       = Flush(r);
                    q       = writeAt;
                    m2      = ((q < readAt) ? (readAt - q - 1) : (end - q));
                    if (readAt != writeAt)
                    {
                        bitb = b4;
                        bitk = k2;
                        _codec.AvailableBytesIn = n2;
                        _codec.TotalBytesIn    += p - _codec.NextIn;
                        _codec.NextIn           = p;
                        writeAt = q;
                        return(Flush(r));
                    }
                    mode = InflateBlockMode.DONE;
                    goto case InflateBlockMode.DONE;

                case InflateBlockMode.DONE:
                    r    = 1;
                    bitb = b4;
                    bitk = k2;
                    _codec.AvailableBytesIn = n2;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));

                case InflateBlockMode.BAD:
                    r    = -3;
                    bitb = b4;
                    bitk = k2;
                    _codec.AvailableBytesIn = n2;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));

                default:
                    r    = -2;
                    bitb = b4;
                    bitk = k2;
                    _codec.AvailableBytesIn = n2;
                    _codec.TotalBytesIn    += p - _codec.NextIn;
                    _codec.NextIn           = p;
                    writeAt = q;
                    return(Flush(r));
                }
            }
        }
Example #43
-1
        internal uint Reset()
        {
            uint oldCheck = check;
            mode = InflateBlockMode.TYPE;
            bitk = 0;
            bitb = 0;
            readAt = writeAt = 0;

            if (checkfn != null)
                _codec._Adler32 = check = Adler.Adler32(0, null, 0, 0);
            return oldCheck;
        }