Esempio n. 1
0
        internal int Process(InflaterBlocks s, CompressionStream z, int r)
        {
            int inputIndex      = z.InputIndex;
            int inputCount      = z.InputCount;
            int number          = s.BitBuffer;
            int bitBufferLength = s.BitBufferLength;
            int num1            = s.WindowWrite;
            int num2            = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;

            while (true)
            {
                switch (this.mode)
                {
                case 0:
                    if (num2 >= 258 && inputCount >= 10)
                    {
                        s.BitBuffer       = number;
                        s.BitBufferLength = bitBufferLength;
                        z.InputCount      = inputCount;
                        z.InputTotal     += (long)(inputIndex - z.InputIndex);
                        z.InputIndex      = inputIndex;
                        s.WindowWrite     = num1;
                        r               = this.InflateFast((int)this.lbits, (int)this.dbits, this.ltree, this.ltreeIndex, this.dtree, this.dtreeIndex, s, z);
                        inputIndex      = z.InputIndex;
                        inputCount      = z.InputCount;
                        number          = s.BitBuffer;
                        bitBufferLength = s.BitBufferLength;
                        num1            = s.WindowWrite;
                        num2            = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                        int num3;
                        switch (r)
                        {
                        case 0:
                            goto label_6;

                        case 1:
                            num3 = 7;
                            break;

                        default:
                            num3 = 9;
                            break;
                        }
                        this.mode = num3;
                        break;
                    }
label_6:
                    this.need      = (int)this.lbits;
                    this.tree      = this.ltree;
                    this.treeIndex = this.ltreeIndex;
                    this.mode      = 1;
                    goto case 1;

                case 1:
                    int need1;
                    for (need1 = this.need; bitBufferLength < need1; bitBufferLength += 8)
                    {
                        if (inputCount != 0)
                        {
                            r = 0;
                            --inputCount;
                            number |= ((int)z.Input[inputIndex++] & (int)byte.MaxValue) << bitBufferLength;
                        }
                        else
                        {
                            s.BitBuffer       = number;
                            s.BitBufferLength = bitBufferLength;
                            z.InputCount      = inputCount;
                            z.InputTotal     += (long)(inputIndex - z.InputIndex);
                            z.InputIndex      = inputIndex;
                            s.WindowWrite     = num1;
                            return(s.InflateFlush(z, r));
                        }
                    }
                    int index1 = (this.treeIndex + (number & InflaterCodes.inflateMask[need1])) * 3;
                    number           = Utils.ShiftRight(number, this.tree[index1 + 1]);
                    bitBufferLength -= this.tree[index1 + 1];
                    int num4 = this.tree[index1];
                    if (num4 == 0)
                    {
                        this.lit  = this.tree[index1 + 2];
                        this.mode = 6;
                        break;
                    }
                    if ((num4 & 16) != 0)
                    {
                        this.getBits = num4 & 15;
                        this.len     = this.tree[index1 + 2];
                        this.mode    = 2;
                        break;
                    }
                    if ((num4 & 64) == 0)
                    {
                        this.need      = num4;
                        this.treeIndex = index1 / 3 + this.tree[index1 + 2];
                        break;
                    }
                    if ((num4 & 32) != 0)
                    {
                        this.mode = 7;
                        break;
                    }
                    goto label_20;

                case 2:
                    int getBits1;
                    for (getBits1 = this.getBits; bitBufferLength < getBits1; bitBufferLength += 8)
                    {
                        if (inputCount != 0)
                        {
                            r = 0;
                            --inputCount;
                            number |= ((int)z.Input[inputIndex++] & (int)byte.MaxValue) << bitBufferLength;
                        }
                        else
                        {
                            s.BitBuffer       = number;
                            s.BitBufferLength = bitBufferLength;
                            z.InputCount      = inputCount;
                            z.InputTotal     += (long)(inputIndex - z.InputIndex);
                            z.InputIndex      = inputIndex;
                            s.WindowWrite     = num1;
                            return(s.InflateFlush(z, r));
                        }
                    }
                    this.len        += number & InflaterCodes.inflateMask[getBits1];
                    number         >>= getBits1;
                    bitBufferLength -= getBits1;
                    this.need        = (int)this.dbits;
                    this.tree        = this.dtree;
                    this.treeIndex   = this.dtreeIndex;
                    this.mode        = 3;
                    goto case 3;

                case 3:
                    int need2;
                    for (need2 = this.need; bitBufferLength < need2; bitBufferLength += 8)
                    {
                        if (inputCount != 0)
                        {
                            r = 0;
                            --inputCount;
                            number |= ((int)z.Input[inputIndex++] & (int)byte.MaxValue) << bitBufferLength;
                        }
                        else
                        {
                            s.BitBuffer       = number;
                            s.BitBufferLength = bitBufferLength;
                            z.InputCount      = inputCount;
                            z.InputTotal     += (long)(inputIndex - z.InputIndex);
                            z.InputIndex      = inputIndex;
                            s.WindowWrite     = num1;
                            return(s.InflateFlush(z, r));
                        }
                    }
                    int index2 = (this.treeIndex + (number & InflaterCodes.inflateMask[need2])) * 3;
                    number         >>= this.tree[index2 + 1];
                    bitBufferLength -= this.tree[index2 + 1];
                    int num5 = this.tree[index2];
                    if ((num5 & 16) != 0)
                    {
                        this.getBits = num5 & 15;
                        this.dist    = this.tree[index2 + 2];
                        this.mode    = 4;
                        break;
                    }
                    if ((num5 & 64) == 0)
                    {
                        this.need      = num5;
                        this.treeIndex = index2 / 3 + this.tree[index2 + 2];
                        break;
                    }
                    goto label_36;

                case 4:
                    int getBits2;
                    for (getBits2 = this.getBits; bitBufferLength < getBits2; bitBufferLength += 8)
                    {
                        if (inputCount != 0)
                        {
                            r = 0;
                            --inputCount;
                            number |= ((int)z.Input[inputIndex++] & (int)byte.MaxValue) << bitBufferLength;
                        }
                        else
                        {
                            s.BitBuffer       = number;
                            s.BitBufferLength = bitBufferLength;
                            z.InputCount      = inputCount;
                            z.InputTotal     += (long)(inputIndex - z.InputIndex);
                            z.InputIndex      = inputIndex;
                            s.WindowWrite     = num1;
                            return(s.InflateFlush(z, r));
                        }
                    }
                    this.dist       += number & InflaterCodes.inflateMask[getBits2];
                    number         >>= getBits2;
                    bitBufferLength -= getBits2;
                    this.mode        = 5;
                    goto case 5;

                case 5:
                    int num6 = num1 - this.dist;
                    while (num6 < 0)
                    {
                        num6 += s.WindowEnd;
                    }
                    for (; this.len != 0; --this.len)
                    {
                        if (num2 == 0)
                        {
                            if (num1 == s.WindowEnd && s.WindowRead != 0)
                            {
                                num1 = 0;
                                num2 = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                            }
                            if (num2 == 0)
                            {
                                s.WindowWrite = num1;
                                r             = s.InflateFlush(z, r);
                                num1          = s.WindowWrite;
                                num2          = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                                if (num1 == s.WindowEnd && s.WindowRead != 0)
                                {
                                    num1 = 0;
                                    num2 = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                                }
                                if (num2 == 0)
                                {
                                    s.BitBuffer       = number;
                                    s.BitBufferLength = bitBufferLength;
                                    z.InputCount      = inputCount;
                                    z.InputTotal     += (long)(inputIndex - z.InputIndex);
                                    z.InputIndex      = inputIndex;
                                    s.WindowWrite     = num1;
                                    return(s.InflateFlush(z, r));
                                }
                            }
                        }
                        s.Window[num1++] = s.Window[num6++];
                        --num2;
                        if (num6 == s.WindowEnd)
                        {
                            num6 = 0;
                        }
                    }
                    this.mode = 0;
                    break;

                case 6:
                    if (num2 == 0)
                    {
                        if (num1 == s.WindowEnd && s.WindowRead != 0)
                        {
                            num1 = 0;
                            num2 = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                        }
                        if (num2 == 0)
                        {
                            s.WindowWrite = num1;
                            r             = s.InflateFlush(z, r);
                            num1          = s.WindowWrite;
                            num2          = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                            if (num1 == s.WindowEnd && s.WindowRead != 0)
                            {
                                num1 = 0;
                                num2 = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;
                            }
                            if (num2 == 0)
                            {
                                goto label_67;
                            }
                        }
                    }
                    r = 0;
                    s.Window[num1++] = (byte)this.lit;
                    --num2;
                    this.mode = 0;
                    break;

                case 7:
                    goto label_70;

                case 8:
                    goto label_75;

                case 9:
                    goto label_76;

                default:
                    goto label_77;
                }
            }
label_20:
            this.mode      = 9;
            z.ErrorMessage = "invalid literal/length code";
            r                 = -3;
            s.BitBuffer       = number;
            s.BitBufferLength = bitBufferLength;
            z.InputCount      = inputCount;
            z.InputTotal     += (long)(inputIndex - z.InputIndex);
            z.InputIndex      = inputIndex;
            s.WindowWrite     = num1;
            return(s.InflateFlush(z, r));

label_36:
            this.mode      = 9;
            z.ErrorMessage = "invalid distance code";
            r                 = -3;
            s.BitBuffer       = number;
            s.BitBufferLength = bitBufferLength;
            z.InputCount      = inputCount;
            z.InputTotal     += (long)(inputIndex - z.InputIndex);
            z.InputIndex      = inputIndex;
            s.WindowWrite     = num1;
            return(s.InflateFlush(z, r));

label_67:
            s.BitBuffer       = number;
            s.BitBufferLength = bitBufferLength;
            z.InputCount      = inputCount;
            z.InputTotal     += (long)(inputIndex - z.InputIndex);
            z.InputIndex      = inputIndex;
            s.WindowWrite     = num1;
            return(s.InflateFlush(z, r));

label_70:
            if (bitBufferLength > 7)
            {
                bitBufferLength -= 8;
                ++inputCount;
                --inputIndex;
            }
            s.WindowWrite = num1;
            r             = s.InflateFlush(z, r);
            num1          = s.WindowWrite;
            int num7 = num1 < s.WindowRead ? s.WindowRead - num1 - 1 : s.WindowEnd - num1;

            if (s.WindowRead != s.WindowWrite)
            {
                s.BitBuffer       = number;
                s.BitBufferLength = bitBufferLength;
                z.InputCount      = inputCount;
                z.InputTotal     += (long)(inputIndex - z.InputIndex);
                z.InputIndex      = inputIndex;
                s.WindowWrite     = num1;
                return(s.InflateFlush(z, r));
            }
            this.mode = 8;
label_75:
            r                 = 1;
            s.BitBuffer       = number;
            s.BitBufferLength = bitBufferLength;
            z.InputCount      = inputCount;
            z.InputTotal     += (long)(inputIndex - z.InputIndex);
            z.InputIndex      = inputIndex;
            s.WindowWrite     = num1;
            return(s.InflateFlush(z, r));

label_76:
            r                 = -3;
            s.BitBuffer       = number;
            s.BitBufferLength = bitBufferLength;
            z.InputCount      = inputCount;
            z.InputTotal     += (long)(inputIndex - z.InputIndex);
            z.InputIndex      = inputIndex;
            s.WindowWrite     = num1;
            return(s.InflateFlush(z, r));

label_77:
            r                 = -2;
            s.BitBuffer       = number;
            s.BitBufferLength = bitBufferLength;
            z.InputCount      = inputCount;
            z.InputTotal     += (long)(inputIndex - z.InputIndex);
            z.InputIndex      = inputIndex;
            s.WindowWrite     = num1;
            return(s.InflateFlush(z, r));
        }