internal InflateBlocks(ZlibCodec codec, object checkfn, int w)
 {
     this._codec  = codec;
     this.hufts   = new int[4320];
     this.window  = new byte[w];
     this.end     = w;
     this.checkfn = checkfn;
     this.mode    = InflateBlocks.InflateBlockMode.TYPE;
     this.Reset();
 }
        internal uint Reset()
        {
            uint result = this.check;

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

            this.mode   = InflateBlocks.InflateBlockMode.TYPE;
            this.bitk   = 0;
            this.bitb   = 0;
            this.readAt = this.writeAt = 0;
            if (this.checkfn != null)
            {
                this._codec._Adler32 = this.check = Adler.Adler32(0U, (byte[])null, 0, 0);
            }
            return(num);
        }
        internal int Process(int r)
        {
            int num  = this._codec.NextIn;
            int num2 = this._codec.AvailableBytesIn;
            int num3 = this.bitb;
            int i    = this.bitk;
            int num4 = this.writeAt;
            int num5 = (num4 >= this.readAt) ? (this.end - num4) : (this.readAt - num4 - 1);
            int num6;

            for (;;)
            {
                switch (this.mode)
                {
                case InflateBlocks.InflateBlockMode.TYPE:
                    while (i < 3)
                    {
                        if (num2 == 0)
                        {
                            goto IL_AD;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & byte.MaxValue) << i;
                        i    += 8;
                    }
                    num6      = (num3 & 7);
                    this.last = (num6 & 1);
                    switch ((uint)num6 >> 1)
                    {
                    case 0u:
                        num3    >>= 3;
                        i        -= 3;
                        num6      = (i & 7);
                        num3    >>= num6;
                        i        -= num6;
                        this.mode = InflateBlocks.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;
                        i        -= 3;
                        this.mode = InflateBlocks.InflateBlockMode.CODES;
                        break;
                    }

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

                    case 3u:
                        goto IL_206;
                    }
                    continue;

                case InflateBlocks.InflateBlockMode.LENS:
                    while (i < 32)
                    {
                        if (num2 == 0)
                        {
                            goto IL_2A3;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & byte.MaxValue) << i;
                        i    += 8;
                    }
                    if ((~num3 >> 16 & 65535) != (num3 & 65535))
                    {
                        goto Block_8;
                    }
                    this.left = (num3 & 65535);
                    i         = (num3 = 0);
                    this.mode = ((this.left == 0) ? ((this.last == 0) ? InflateBlocks.InflateBlockMode.TYPE : InflateBlocks.InflateBlockMode.DRY) : InflateBlocks.InflateBlockMode.STORED);
                    continue;

                case InflateBlocks.InflateBlockMode.STORED:
                    if (num2 == 0)
                    {
                        goto Block_11;
                    }
                    if (num5 == 0)
                    {
                        if (num4 == this.end && this.readAt != 0)
                        {
                            num4 = 0;
                            num5 = ((num4 >= this.readAt) ? (this.end - num4) : (this.readAt - num4 - 1));
                        }
                        if (num5 == 0)
                        {
                            this.writeAt = num4;
                            r            = this.Flush(r);
                            num4         = this.writeAt;
                            num5         = ((num4 >= this.readAt) ? (this.end - num4) : (this.readAt - num4 - 1));
                            if (num4 == this.end && this.readAt != 0)
                            {
                                num4 = 0;
                                num5 = ((num4 >= this.readAt) ? (this.end - num4) : (this.readAt - num4 - 1));
                            }
                            if (num5 == 0)
                            {
                                goto Block_21;
                            }
                        }
                    }
                    r    = 0;
                    num6 = this.left;
                    if (num6 > num2)
                    {
                        num6 = num2;
                    }
                    if (num6 > num5)
                    {
                        num6 = num5;
                    }
                    Array.Copy(this._codec.InputBuffer, num, this.window, num4, num6);
                    num  += num6;
                    num2 -= num6;
                    num4 += num6;
                    num5 -= num6;
                    if ((this.left -= num6) != 0)
                    {
                        continue;
                    }
                    this.mode = ((this.last == 0) ? InflateBlocks.InflateBlockMode.TYPE : InflateBlocks.InflateBlockMode.DRY);
                    continue;

                case InflateBlocks.InflateBlockMode.TABLE:
                    while (i < 14)
                    {
                        if (num2 == 0)
                        {
                            goto IL_64B;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & byte.MaxValue) << i;
                        i    += 8;
                    }
                    num6 = (this.table = (num3 & 16383));
                    if ((num6 & 31) > 29 || (num6 >> 5 & 31) > 29)
                    {
                        goto IL_702;
                    }
                    num6 = 258 + (num6 & 31) + (num6 >> 5 & 31);
                    if (this.blens == null || this.blens.Length < num6)
                    {
                        this.blens = new int[num6];
                    }
                    else
                    {
                        Array.Clear(this.blens, 0, num6);
                    }
                    num3     >>= 14;
                    i         -= 14;
                    this.index = 0;
                    this.mode  = InflateBlocks.InflateBlockMode.BTREE;
                    goto IL_7E6;

                case InflateBlocks.InflateBlockMode.BTREE:
                    goto IL_7E6;

                case InflateBlocks.InflateBlockMode.DTREE:
                    goto IL_9CF;

                case InflateBlocks.InflateBlockMode.CODES:
                    goto IL_E42;

                case InflateBlocks.InflateBlockMode.DRY:
                    goto IL_F34;

                case InflateBlocks.InflateBlockMode.DONE:
                    goto IL_FF0;

                case InflateBlocks.InflateBlockMode.BAD:
                    goto IL_1050;
                }
                break;
                for (;;)
                {
IL_9CF:
                    num6 = this.table;
                    if (this.index >= 258 + (num6 & 31) + (num6 >> 5 & 31))
                    {
                        break;
                    }
                    num6 = this.bb[0];
                    while (i < num6)
                    {
                        if (num2 == 0)
                        {
                            goto IL_A1A;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & byte.MaxValue) << i;
                        i    += 8;
                    }
                    num6 = this.hufts[(this.tb[0] + (num3 & InternalInflateConstants.InflateMask[num6])) * 3 + 1];
                    int num7 = this.hufts[(this.tb[0] + (num3 & InternalInflateConstants.InflateMask[num6])) * 3 + 2];
                    if (num7 < 16)
                    {
                        num3 >>= num6;
                        i     -= num6;
                        this.blens[this.index++] = num7;
                    }
                    else
                    {
                        int num8 = (num7 != 18) ? (num7 - 14) : 7;
                        int num9 = (num7 != 18) ? 3 : 11;
                        while (i < num6 + num8)
                        {
                            if (num2 == 0)
                            {
                                goto IL_B5E;
                            }
                            r = 0;
                            num2--;
                            num3 |= (int)(this._codec.InputBuffer[num++] & byte.MaxValue) << i;
                            i    += 8;
                        }
                        num3 >>= num6;
                        i     -= num6;
                        num9  += (num3 & InternalInflateConstants.InflateMask[num8]);
                        num3 >>= num8;
                        i     -= num8;
                        num8   = this.index;
                        num6   = this.table;
                        if (num8 + num9 > 258 + (num6 & 31) + (num6 >> 5 & 31) || (num7 == 16 && num8 < 1))
                        {
                            goto IL_C52;
                        }
                        num7 = ((num7 != 16) ? 0 : this.blens[num8 - 1]);
                        do
                        {
                            this.blens[num8++] = num7;
                        }while (--num9 != 0);
                        this.index = num8;
                    }
                }
                this.tb[0] = -1;
                int[] array5 = new int[]
                {
                    9
                };
                int[] array6 = new int[]
                {
                    6
                };
                int[] array7 = new int[1];
                int[] array8 = new int[1];
                num6 = this.table;
                num6 = this.inftree.inflate_trees_dynamic(257 + (num6 & 31), 1 + (num6 >> 5 & 31), this.blens, array5, array6, array7, array8, this.hufts, this._codec);
                if (num6 != 0)
                {
                    goto Block_48;
                }
                this.codes.Init(array5[0], array6[0], this.hufts, array7[0], this.hufts, array8[0]);
                this.mode = InflateBlocks.InflateBlockMode.CODES;
                goto IL_E42;
                continue;
IL_E42:
                this.bitb = num3;
                this.bitk = i;
                this._codec.AvailableBytesIn = num2;
                this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
                this._codec.NextIn           = num;
                this.writeAt = num4;
                r            = this.codes.Process(this, r);
                if (r != 1)
                {
                    goto Block_50;
                }
                r    = 0;
                num  = this._codec.NextIn;
                num2 = this._codec.AvailableBytesIn;
                num3 = this.bitb;
                i    = this.bitk;
                num4 = this.writeAt;
                num5 = ((num4 >= this.readAt) ? (this.end - num4) : (this.readAt - num4 - 1));
                if (this.last == 0)
                {
                    this.mode = InflateBlocks.InflateBlockMode.TYPE;
                    continue;
                }
                goto IL_F28;
IL_7E6:
                while (this.index < 4 + (this.table >> 10))
                {
                    while (i < 3)
                    {
                        if (num2 == 0)
                        {
                            goto IL_803;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & byte.MaxValue) << i;
                        i    += 8;
                    }
                    this.blens[InflateBlocks.border[this.index++]] = (num3 & 7);
                    num3 >>= 3;
                    i     -= 3;
                }
                while (this.index < 19)
                {
                    this.blens[InflateBlocks.border[this.index++]] = 0;
                }
                this.bb[0] = 7;
                num6       = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, this._codec);
                if (num6 != 0)
                {
                    goto Block_34;
                }
                this.index = 0;
                this.mode  = InflateBlocks.InflateBlockMode.DTREE;
                goto IL_9CF;
            }
            r         = -2;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

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

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

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

Block_8:
            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "invalid stored block lengths";
            r         = -3;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

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

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

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

IL_702:
            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "too many length or distance symbols";
            r         = -3;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

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

Block_34:
            r = num6;
            if (r == -3)
            {
                this.blens = null;
                this.mode  = InflateBlocks.InflateBlockMode.BAD;
            }
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

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

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

IL_C52:
            this.blens          = null;
            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "invalid bit length repeat";
            r         = -3;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

Block_48:
            if (num6 == -3)
            {
                this.blens = null;
                this.mode  = InflateBlocks.InflateBlockMode.BAD;
            }
            r         = num6;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

Block_50:
            return(this.Flush(r));

IL_F28:
            this.mode = InflateBlocks.InflateBlockMode.DRY;
IL_F34:
            this.writeAt = num4;
            r            = this.Flush(r);
            num4         = this.writeAt;
            int num10 = (num4 >= this.readAt) ? (this.end - num4) : (this.readAt - num4 - 1);

            if (this.readAt != this.writeAt)
            {
                this.bitb = num3;
                this.bitk = i;
                this._codec.AvailableBytesIn = num2;
                this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
                this._codec.NextIn           = num;
                this.writeAt = num4;
                return(this.Flush(r));
            }
            this.mode = InflateBlocks.InflateBlockMode.DONE;
IL_FF0:
            r         = 1;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));

IL_1050:
            r         = -3;
            this.bitb = num3;
            this.bitk = i;
            this._codec.AvailableBytesIn = num2;
            this._codec.TotalBytesIn    += (long)(num - this._codec.NextIn);
            this._codec.NextIn           = num;
            this.writeAt = num4;
            return(this.Flush(r));
        }
Exemple #5
0
        internal int Process(int r)
        {
            int sourceIndex      = this._codec.NextIn;
            int num1             = this._codec.AvailableBytesIn;
            int num2             = this.bitb;
            int num3             = this.bitk;
            int destinationIndex = this.writeAt;
            int num4             = destinationIndex < this.readAt ? this.readAt - destinationIndex - 1 : this.end - destinationIndex;
            int num5;
            int num6;

            while (true)
            {
                bool flag = true;
                switch (this.mode)
                {
                case InflateBlocks.InflateBlockMode.TYPE:
                    while (num3 < 3)
                    {
                        if (num1 != 0)
                        {
                            r = 0;
                            --num1;
                            num2 |= ((int)this._codec.InputBuffer[sourceIndex++] & (int)byte.MaxValue) << num3;
                            num3 += 8;
                        }
                        else
                        {
                            this.bitb = num2;
                            this.bitk = num3;
                            this._codec.AvailableBytesIn = num1;
                            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                            this._codec.NextIn           = sourceIndex;
                            this.writeAt = destinationIndex;
                            return(this.Flush(r));
                        }
                    }
                    int num7 = num2 & 7;
                    this.last = num7 & 1;
                    switch ((uint)num7 >> 1)
                    {
                    case 0:
                        int num8  = num2 >> 3;
                        int num9  = num3 - 3;
                        int num10 = num9 & 7;
                        num2      = num8 >> num10;
                        num3      = num9 - num10;
                        this.mode = InflateBlocks.InflateBlockMode.LENS;
                        break;

                    case 1:
                        int[]   bl1 = new int[1];
                        int[]   bd1 = new int[1];
                        int[][] tl1 = new int[1][];
                        int[][] td1 = new int[1][];
                        InfTree.inflate_trees_fixed(bl1, bd1, tl1, td1, this._codec);
                        this.codes.Init(bl1[0], bd1[0], tl1[0], 0, td1[0], 0);
                        num2    >>= 3;
                        num3     -= 3;
                        this.mode = InflateBlocks.InflateBlockMode.CODES;
                        break;

                    case 2:
                        num2    >>= 3;
                        num3     -= 3;
                        this.mode = InflateBlocks.InflateBlockMode.TABLE;
                        break;

                    case 3:
                        goto label_9;
                    }
                    break;

                case InflateBlocks.InflateBlockMode.LENS:
                    while (num3 < 32)
                    {
                        if (num1 != 0)
                        {
                            r = 0;
                            --num1;
                            num2 |= ((int)this._codec.InputBuffer[sourceIndex++] & (int)byte.MaxValue) << num3;
                            num3 += 8;
                        }
                        else
                        {
                            this.bitb = num2;
                            this.bitk = num3;
                            this._codec.AvailableBytesIn = num1;
                            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                            this._codec.NextIn           = sourceIndex;
                            this.writeAt = destinationIndex;
                            return(this.Flush(r));
                        }
                    }
                    if ((~num2 >> 16 & (int)ushort.MaxValue) == (num2 & (int)ushort.MaxValue))
                    {
                        this.left = num2 & (int)ushort.MaxValue;
                        num2      = num3 = 0;
                        this.mode = this.left != 0 ? InflateBlocks.InflateBlockMode.STORED : (this.last != 0 ? InflateBlocks.InflateBlockMode.DRY : InflateBlocks.InflateBlockMode.TYPE);
                        break;
                    }
                    goto label_15;

                case InflateBlocks.InflateBlockMode.STORED:
                    if (num1 != 0)
                    {
                        if (num4 == 0)
                        {
                            if (destinationIndex == this.end && this.readAt != 0)
                            {
                                destinationIndex = 0;
                                num4             = destinationIndex < this.readAt ? this.readAt - destinationIndex - 1 : this.end - destinationIndex;
                            }
                            if (num4 == 0)
                            {
                                this.writeAt     = destinationIndex;
                                r                = this.Flush(r);
                                destinationIndex = this.writeAt;
                                num4             = destinationIndex < this.readAt ? this.readAt - destinationIndex - 1 : this.end - destinationIndex;
                                if (destinationIndex == this.end && this.readAt != 0)
                                {
                                    destinationIndex = 0;
                                    num4             = destinationIndex < this.readAt ? this.readAt - destinationIndex - 1 : this.end - destinationIndex;
                                }
                                if (num4 == 0)
                                {
                                    goto label_26;
                                }
                            }
                        }
                        r = 0;
                        int length = this.left;
                        if (length > num1)
                        {
                            length = num1;
                        }
                        if (length > num4)
                        {
                            length = num4;
                        }
                        Array.Copy((Array)this._codec.InputBuffer, sourceIndex, (Array)this.window, destinationIndex, length);
                        sourceIndex      += length;
                        num1             -= length;
                        destinationIndex += length;
                        num4             -= length;
                        if ((this.left -= length) == 0)
                        {
                            this.mode = this.last != 0 ? InflateBlocks.InflateBlockMode.DRY : InflateBlocks.InflateBlockMode.TYPE;
                            break;
                        }
                        break;
                    }
                    goto label_18;

                case InflateBlocks.InflateBlockMode.TABLE:
                    while (num3 < 14)
                    {
                        if (num1 != 0)
                        {
                            r = 0;
                            --num1;
                            num2 |= ((int)this._codec.InputBuffer[sourceIndex++] & (int)byte.MaxValue) << num3;
                            num3 += 8;
                        }
                        else
                        {
                            this.bitb = num2;
                            this.bitk = num3;
                            this._codec.AvailableBytesIn = num1;
                            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                            this._codec.NextIn           = sourceIndex;
                            this.writeAt = destinationIndex;
                            return(this.Flush(r));
                        }
                    }
                    int num11;
                    this.table = num11 = num2 & 16383;
                    if ((num11 & 31) <= 29 && (num11 >> 5 & 31) <= 29)
                    {
                        int length = 258 + (num11 & 31) + (num11 >> 5 & 31);
                        if (this.blens == null || this.blens.Length < length)
                        {
                            this.blens = new int[length];
                        }
                        else
                        {
                            Array.Clear((Array)this.blens, 0, length);
                        }
                        num2     >>= 14;
                        num3      -= 14;
                        this.index = 0;
                        this.mode  = InflateBlocks.InflateBlockMode.BTREE;
                        goto case InflateBlocks.InflateBlockMode.BTREE;
                    }
                    else
                    {
                        goto label_39;
                    }

                case InflateBlocks.InflateBlockMode.BTREE:
                    while (this.index < 4 + (this.table >> 10))
                    {
                        while (num3 < 3)
                        {
                            if (num1 != 0)
                            {
                                r = 0;
                                --num1;
                                num2 |= ((int)this._codec.InputBuffer[sourceIndex++] & (int)byte.MaxValue) << num3;
                                num3 += 8;
                            }
                            else
                            {
                                this.bitb = num2;
                                this.bitk = num3;
                                this._codec.AvailableBytesIn = num1;
                                this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                                this._codec.NextIn           = sourceIndex;
                                this.writeAt = destinationIndex;
                                return(this.Flush(r));
                            }
                        }
                        this.blens[InflateBlocks.border[this.index++]] = num2 & 7;
                        num2 >>= 3;
                        num3  -= 3;
                    }
                    while (this.index < 19)
                    {
                        this.blens[InflateBlocks.border[this.index++]] = 0;
                    }
                    this.bb[0] = 7;
                    num5       = this.inftree.inflate_trees_bits(this.blens, this.bb, this.tb, this.hufts, this._codec);
                    if (num5 == 0)
                    {
                        this.index = 0;
                        this.mode  = InflateBlocks.InflateBlockMode.DTREE;
                        goto case InflateBlocks.InflateBlockMode.DTREE;
                    }
                    else
                    {
                        goto label_53;
                    }

                case InflateBlocks.InflateBlockMode.DTREE:
                    while (true)
                    {
                        flag = true;
                        int num12 = this.table;
                        if (this.index < 258 + (num12 & 31) + (num12 >> 5 & 31))
                        {
                            int index1 = this.bb[0];
                            while (num3 < index1)
                            {
                                if (num1 != 0)
                                {
                                    r = 0;
                                    --num1;
                                    num2 |= ((int)this._codec.InputBuffer[sourceIndex++] & (int)byte.MaxValue) << num3;
                                    num3 += 8;
                                }
                                else
                                {
                                    this.bitb = num2;
                                    this.bitk = num3;
                                    this._codec.AvailableBytesIn = num1;
                                    this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                                    this._codec.NextIn           = sourceIndex;
                                    this.writeAt = destinationIndex;
                                    return(this.Flush(r));
                                }
                            }
                            int index2 = this.hufts[(this.tb[0] + (num2 & InternalInflateConstants.InflateMask[index1])) * 3 + 1];
                            int num13  = this.hufts[(this.tb[0] + (num2 & InternalInflateConstants.InflateMask[index2])) * 3 + 2];
                            if (num13 < 16)
                            {
                                num2 >>= index2;
                                num3  -= index2;
                                this.blens[this.index++] = num13;
                            }
                            else
                            {
                                int index3 = num13 == 18 ? 7 : num13 - 14;
                                int num14  = num13 == 18 ? 11 : 3;
                                while (num3 < index2 + index3)
                                {
                                    if (num1 != 0)
                                    {
                                        r = 0;
                                        --num1;
                                        num2 |= ((int)this._codec.InputBuffer[sourceIndex++] & (int)byte.MaxValue) << num3;
                                        num3 += 8;
                                    }
                                    else
                                    {
                                        this.bitb = num2;
                                        this.bitk = num3;
                                        this._codec.AvailableBytesIn = num1;
                                        this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                                        this._codec.NextIn           = sourceIndex;
                                        this.writeAt = destinationIndex;
                                        return(this.Flush(r));
                                    }
                                }
                                int num15 = num2 >> index2;
                                int num16 = num3 - index2;
                                int num17 = num14 + (num15 & InternalInflateConstants.InflateMask[index3]);
                                num2 = num15 >> index3;
                                num3 = num16 - index3;
                                int num18 = this.index;
                                int num19 = this.table;
                                if (num18 + num17 <= 258 + (num19 & 31) + (num19 >> 5 & 31) && (num13 != 16 || num18 >= 1))
                                {
                                    int num20 = num13 == 16 ? this.blens[num18 - 1] : 0;
                                    do
                                    {
                                        this.blens[num18++] = num20;
                                    }while (--num17 != 0);
                                    this.index = num18;
                                }
                                else
                                {
                                    goto label_70;
                                }
                            }
                        }
                        else
                        {
                            break;
                        }
                    }
                    this.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];
                    int   num21 = this.table;
                    num6 = this.inftree.inflate_trees_dynamic(257 + (num21 & 31), 1 + (num21 >> 5 & 31), this.blens, bl2, bd2, tl2, td2, this.hufts, this._codec);
                    switch (num6)
                    {
                    case 0:
                        this.codes.Init(bl2[0], bd2[0], this.hufts, tl2[0], this.hufts, td2[0]);
                        this.mode = InflateBlocks.InflateBlockMode.CODES;
                        goto label_80;

                    case -3:
                        goto label_77;

                    default:
                        goto label_78;
                    }

                case InflateBlocks.InflateBlockMode.CODES:
label_80:
                    this.bitb = num2;
                    this.bitk = num3;
                    this._codec.AvailableBytesIn = num1;
                    this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                    this._codec.NextIn           = sourceIndex;
                    this.writeAt = destinationIndex;
                    r            = this.codes.Process(this, r);
                    if (r == 1)
                    {
                        r                = 0;
                        sourceIndex      = this._codec.NextIn;
                        num1             = this._codec.AvailableBytesIn;
                        num2             = this.bitb;
                        num3             = this.bitk;
                        destinationIndex = this.writeAt;
                        num4             = destinationIndex < this.readAt ? this.readAt - destinationIndex - 1 : this.end - destinationIndex;
                        if (this.last == 0)
                        {
                            this.mode = InflateBlocks.InflateBlockMode.TYPE;
                            break;
                        }
                        goto label_84;
                    }
                    else
                    {
                        goto label_81;
                    }

                case InflateBlocks.InflateBlockMode.DRY:
                    goto label_85;

                case InflateBlocks.InflateBlockMode.DONE:
                    goto label_88;

                case InflateBlocks.InflateBlockMode.BAD:
                    goto label_89;

                default:
                    goto label_90;
                }
            }
label_9:
            int num22 = num2 >> 3;
            int num23 = num3 - 3;

            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "invalid block type";
            r         = -3;
            this.bitb = num22;
            this.bitk = num23;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_15:
            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "invalid stored block lengths";
            r         = -3;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_18:
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_26:
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_39:
            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "too many length or distance symbols";
            r         = -3;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_53:
            r = num5;
            if (r == -3)
            {
                this.blens = (int[])null;
                this.mode  = InflateBlocks.InflateBlockMode.BAD;
            }
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_70:
            this.blens          = (int[])null;
            this.mode           = InflateBlocks.InflateBlockMode.BAD;
            this._codec.Message = "invalid bit length repeat";
            r         = -3;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_77:
            this.blens = (int[])null;
            this.mode  = InflateBlocks.InflateBlockMode.BAD;
label_78:
            r         = num6;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_81:
            return(this.Flush(r));

label_84:
            this.mode = InflateBlocks.InflateBlockMode.DRY;
label_85:
            this.writeAt     = destinationIndex;
            r                = this.Flush(r);
            destinationIndex = this.writeAt;
            int num24 = destinationIndex < this.readAt ? this.readAt - destinationIndex - 1 : this.end - destinationIndex;

            if (this.readAt != this.writeAt)
            {
                this.bitb = num2;
                this.bitk = num3;
                this._codec.AvailableBytesIn = num1;
                this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
                this._codec.NextIn           = sourceIndex;
                this.writeAt = destinationIndex;
                return(this.Flush(r));
            }
            this.mode = InflateBlocks.InflateBlockMode.DONE;
label_88:
            r         = 1;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_89:
            r         = -3;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));

label_90:
            r         = -2;
            this.bitb = num2;
            this.bitk = num3;
            this._codec.AvailableBytesIn = num1;
            this._codec.TotalBytesIn    += (long)(sourceIndex - this._codec.NextIn);
            this._codec.NextIn           = sourceIndex;
            this.writeAt = destinationIndex;
            return(this.Flush(r));
        }