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));
        }
Beispiel #2
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));
                }
            }
        }
Beispiel #3
0
        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;

            while (true)
            {
                switch (this.mode)
                {
                case InflateBlocks.InflateBlockMode.TYPE:
                    while (i < 3)
                    {
                        if (num2 == 0)
                        {
                            goto IL_A7;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & 255) << 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_1FB;
                    }
                    continue;

                case InflateBlocks.InflateBlockMode.LENS:
                    while (i < 32)
                    {
                        if (num2 == 0)
                        {
                            goto IL_28F;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & 255) << 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_612;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & 255) << i;
                        i    += 8;
                    }
                    num6 = (this.table = (num3 & 16383));
                    if ((num6 & 31) > 29 || (num6 >> 5 & 31) > 29)
                    {
                        goto IL_6C4;
                    }
                    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_79D;

                case InflateBlocks.InflateBlockMode.BTREE:
                    goto IL_79D;

                case InflateBlocks.InflateBlockMode.DTREE:
                    goto IL_971;

                case InflateBlocks.InflateBlockMode.CODES:
                    goto IL_DB8;

                case InflateBlocks.InflateBlockMode.DRY:
                    goto IL_EA2;

                case InflateBlocks.InflateBlockMode.DONE:
                    goto IL_F57;

                case InflateBlocks.InflateBlockMode.BAD:
                    goto IL_FB1;
                }
                break;
                while (true)
                {
IL_971:
                    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_9B6;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & 255) << 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_AEF;
                            }
                            r = 0;
                            num2--;
                            num3 |= (int)(this._codec.InputBuffer[num++] & 255) << 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_BDE;
                        }
                        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_DB8;
                continue;
IL_DB8:
                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_E96;
IL_79D:
                while (this.index < 4 + (this.table >> 10))
                {
                    while (i < 3)
                    {
                        if (num2 == 0)
                        {
                            goto IL_7B6;
                        }
                        r = 0;
                        num2--;
                        num3 |= (int)(this._codec.InputBuffer[num++] & 255) << 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_971;
            }
            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_A7:
            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_1FB:
            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_28F:
            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_612:
            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_6C4:
            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_7B6:
            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_9B6:
            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_AEF:
            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_BDE:
            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_E96:
            this.mode = InflateBlocks.InflateBlockMode.DRY;
IL_EA2:
            this.writeAt = num4;
            r            = this.Flush(r);
            num4         = this.writeAt;
            int arg_EE1_0 = (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_F57:
            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_FB1:
            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));
        }