コード例 #1
0
 private void ProcessTypeStored(InflaterBlocksContext state)
 {
     state.ShiftRight(3);
     state.Temp = state.Bits & 7;
     state.ShiftRight(state.Temp);
     this.mode = 1;
 }
コード例 #2
0
 private int ProcessLens(CompressionStream zip, InflaterBlocksContext state, ref int res)
 {
     for (; state.Bits < 32; state.Bits += 8)
     {
         if (state.BytesCount != 0)
         {
             res = 0;
             --state.BytesCount;
             state.BitBuf |= ((int)zip.Input[state.Input++] & (int)byte.MaxValue) << state.Bits;
         }
         else
         {
             this.TransferBlocksState(zip, state);
             state.IsReturn = true;
             return(this.InflateFlush(zip, res));
         }
     }
     if ((Utils.ShiftRight(~state.BitBuf, 16) & (int)ushort.MaxValue) != (state.BitBuf & (int)ushort.MaxValue))
     {
         this.mode        = 9;
         zip.ErrorMessage = "invalid stored block lengths";
         res = -3;
         this.TransferBlocksState(zip, state);
         state.IsReturn = true;
         return(this.InflateFlush(zip, res));
     }
     this.left    = state.BitBuf & (int)ushort.MaxValue;
     state.BitBuf = state.Bits = 0;
     this.mode    = this.left == 0 ? (this.last == 0 ? 0 : 7) : 2;
     return(0);
 }
コード例 #3
0
 private void TransferBlocksState(CompressionStream zip, InflaterBlocksContext state)
 {
     this.BitBuffer       = state.BitBuf;
     this.BitBufferLength = state.Bits;
     zip.InputCount       = state.BytesCount;
     zip.InputTotal      += (long)(state.Input - zip.InputIndex);
     zip.InputIndex       = state.Input;
     this.WindowWrite     = state.Output;
 }
コード例 #4
0
 private void ProcessTypeFixed(CompressionStream zip, InflaterBlocksContext state)
 {
     int[]   bl = new int[1];
     int[]   bd = new int[1];
     int[][] tl = new int[1][];
     int[][] td = new int[1][];
     InflaterTree.InflateTreeFixed(bl, bd, tl, td, zip);
     this.codes = new InflaterCodes(bl[0], bd[0], tl[0], td[0], zip);
     state.ShiftRight(3);
     this.mode = 6;
 }
コード例 #5
0
 private int ProcessStored(CompressionStream zip, InflaterBlocksContext state, int res)
 {
     if (state.BytesCount == 0)
     {
         this.TransferBlocksState(zip, state);
         state.IsReturn = true;
         return(this.InflateFlush(zip, res));
     }
     if (state.EndBytes == 0)
     {
         if (state.Output == this.WindowEnd && this.WindowRead != 0)
         {
             state.Output   = 0;
             state.EndBytes = this.GetEndBytes(state);
         }
         if (state.EndBytes == 0)
         {
             this.WindowWrite = state.Output;
             res            = this.InflateFlush(zip, res);
             state.Output   = this.WindowWrite;
             state.EndBytes = this.GetEndBytes(state);
             if (state.Output == this.WindowEnd && this.WindowRead != 0)
             {
                 state.Output   = 0;
                 state.EndBytes = this.GetEndBytes(state);
             }
             if (state.EndBytes == 0)
             {
                 this.TransferBlocksState(zip, state);
                 state.IsReturn = true;
                 return(this.InflateFlush(zip, res));
             }
         }
     }
     res        = 0;
     state.Temp = this.left;
     if (state.Temp > state.BytesCount)
     {
         state.Temp = state.BytesCount;
     }
     if (state.Temp > state.EndBytes)
     {
         state.Temp = state.EndBytes;
     }
     Array.Copy((Array)zip.Input, state.Input, (Array)this.Window, state.Output, state.Temp);
     state.Input      += state.Temp;
     state.BytesCount -= state.Temp;
     state.Output     += state.Temp;
     state.EndBytes   -= state.Temp;
     return(0);
 }
コード例 #6
0
 private int ProcessTable(CompressionStream zip, InflaterBlocksContext state, int res)
 {
     for (; state.Bits < 14; state.Bits += 8)
     {
         if (state.BytesCount != 0)
         {
             res = 0;
             --state.BytesCount;
             state.BitBuf |= ((int)zip.Input[state.Input++] & (int)byte.MaxValue) << state.Bits;
         }
         else
         {
             this.TransferBlocksState(zip, state);
             state.IsReturn = true;
             return(this.InflateFlush(zip, res));
         }
     }
     this.table = state.Temp = state.BitBuf & 16383;
     if ((state.Temp & 31) > 29 || (state.Temp >> 5 & 31) > 29)
     {
         this.mode        = 9;
         zip.ErrorMessage = "too many length or distance symbols";
         res = -3;
         this.TransferBlocksState(zip, state);
         state.IsReturn = true;
         return(this.InflateFlush(zip, res));
     }
     state.Temp = 258 + (state.Temp & 31) + (state.Temp >> 5 & 31);
     this.blens = new int[state.Temp];
     if (this.blens == null || this.blens.Length < state.Temp)
     {
         this.blens = new int[state.Temp];
     }
     else
     {
         for (int index = 0; index < state.Temp; ++index)
         {
             this.blens[index] = 0;
         }
     }
     state.ShiftRight(14);
     this.index = 0;
     this.mode  = 4;
     return(0);
 }
コード例 #7
0
 private int ProcessBTree(CompressionStream zip, InflaterBlocksContext state, int res)
 {
     while (this.index < 4 + Utils.ShiftRight(this.table, 10))
     {
         for (; state.Bits < 3; state.Bits += 8)
         {
             if (state.BytesCount != 0)
             {
                 res = 0;
                 --state.BytesCount;
                 state.BitBuf |= ((int)zip.Input[state.Input++] & (int)byte.MaxValue) << state.Bits;
             }
             else
             {
                 this.TransferBlocksState(zip, state);
                 state.IsReturn = true;
                 return(this.InflateFlush(zip, res));
             }
         }
         this.blens[InflaterBlocks.border[this.index++]] = state.BitBuf & 7;
         state.ShiftRight(3);
     }
     while (this.index < 19)
     {
         this.blens[InflaterBlocks.border[this.index++]] = 0;
     }
     this.bitLengthTreeDepth[0] = 7;
     state.Temp = InflaterTree.InflateTreeBits(this.blens, this.bitLengthTreeDepth, this.bitLengthDecodeTree, this.hufts, zip);
     if (state.Temp != 0)
     {
         res = state.Temp;
         if (res == -3)
         {
             this.blens = (int[])null;
             this.mode  = 9;
         }
         this.TransferBlocksState(zip, state);
         state.IsReturn = true;
         return(this.InflateFlush(zip, res));
     }
     this.index = 0;
     this.mode  = 5;
     return(0);
 }
コード例 #8
0
        private int ProcessType(CompressionStream zip, InflaterBlocksContext state, int res)
        {
            for (; state.Bits < 3; state.Bits += 8)
            {
                if (state.BytesCount != 0)
                {
                    res = 0;
                    --state.BytesCount;
                    state.BitBuf |= ((int)zip.Input[state.Input++] & (int)byte.MaxValue) << state.Bits;
                }
                else
                {
                    this.TransferBlocksState(zip, state);
                    state.IsReturn = true;
                    return(this.InflateFlush(zip, res));
                }
            }
            state.Temp = state.BitBuf & 7;
            this.last  = state.Temp & 1;
            switch (Utils.ShiftRight(state.Temp, 1))
            {
            case 0:
                this.ProcessTypeStored(state);
                break;

            case 1:
                this.ProcessTypeFixed(zip, state);
                break;

            case 2:
                this.ProcessTypeDynamic(state);
                break;

            case 3:
                state.ShiftRight(3);
                this.mode        = 9;
                zip.ErrorMessage = "invalid block type";
                res = -3;
                this.TransferBlocksState(zip, state);
                state.IsReturn = true;
                return(this.InflateFlush(zip, res));
            }
            return(0);
        }
コード例 #9
0
 private void ProcessTypeDynamic(InflaterBlocksContext state)
 {
     state.ShiftRight(3);
     this.mode = 3;
 }
コード例 #10
0
        internal int Process(CompressionStream zip, int res)
        {
            InflaterBlocksContext state = new InflaterBlocksContext()
            {
                Input      = zip.InputIndex,
                BytesCount = zip.InputCount,
                BitBuf     = this.BitBuffer,
                Bits       = this.BitBufferLength,
                Output     = this.WindowWrite
            };

            state.EndBytes = this.GetEndBytes(state);
            int num1;
            int num2;
            int num3;
            int num4;
            int num5;
            int num6;

            while (true)
            {
                switch (this.mode)
                {
                case 0:
                    state.IsReturn = false;
                    num1           = this.ProcessType(zip, state, res);
                    if (!state.IsReturn)
                    {
                        break;
                    }
                    goto label_2;

                case 1:
                    state.IsReturn = false;
                    num2           = this.ProcessLens(zip, state, ref res);
                    if (!state.IsReturn)
                    {
                        break;
                    }
                    goto label_4;

                case 2:
                    state.IsReturn = false;
                    num3           = this.ProcessStored(zip, state, res);
                    if (!state.IsReturn)
                    {
                        if ((this.left -= state.Temp) == 0)
                        {
                            this.mode = this.last == 0 ? 0 : 7;
                            break;
                        }
                        break;
                    }
                    goto label_6;

                case 3:
                    state.IsReturn = false;
                    num4           = this.ProcessTable(zip, state, res);
                    if (!state.IsReturn)
                    {
                        goto case 4;
                    }
                    else
                    {
                        goto label_10;
                    }

                case 4:
                    state.IsReturn = false;
                    num5           = this.ProcessBTree(zip, state, res);
                    if (!state.IsReturn)
                    {
                        goto case 5;
                    }
                    else
                    {
                        goto label_12;
                    }

                case 5:
                    state.IsReturn = false;
                    num6           = this.ProcessDTree(zip, state, res);
                    if (!state.IsReturn)
                    {
                        goto case 6;
                    }
                    else
                    {
                        goto label_14;
                    }

                case 6:
                    this.TransferBlocksState(zip, state);
                    if ((res = this.codes.Process(this, zip, res)) == 1)
                    {
                        res = 0;
                        this.codes.Free(zip);
                        state.Input      = zip.InputIndex;
                        state.BytesCount = zip.InputCount;
                        state.BitBuf     = this.BitBuffer;
                        state.Bits       = this.BitBufferLength;
                        state.Output     = this.WindowWrite;
                        state.EndBytes   = this.GetEndBytes(state);
                        if (this.last == 0)
                        {
                            this.mode = 0;
                            break;
                        }
                        goto label_19;
                    }
                    else
                    {
                        goto label_16;
                    }

                case 7:
                    goto label_20;

                case 8:
                    goto label_23;

                case 9:
                    goto label_24;

                default:
                    goto label_25;
                }
            }
label_2:
            return(num1);

label_4:
            return(num2);

label_6:
            return(num3);

label_10:
            return(num4);

label_12:
            return(num5);

label_14:
            return(num6);

label_16:
            return(this.InflateFlush(zip, res));

label_19:
            this.mode = 7;
label_20:
            this.WindowWrite = state.Output;
            res            = this.InflateFlush(zip, res);
            state.Output   = this.WindowWrite;
            state.EndBytes = this.GetEndBytes(state);
            if (this.WindowRead != this.WindowWrite)
            {
                this.TransferBlocksState(zip, state);
                return(this.InflateFlush(zip, res));
            }
            this.mode = 8;
label_23:
            res = 1;
            this.TransferBlocksState(zip, state);
            return(this.InflateFlush(zip, res));

label_24:
            res = -3;
            this.TransferBlocksState(zip, state);
            return(this.InflateFlush(zip, res));

label_25:
            res = -2;
            this.TransferBlocksState(zip, state);
            return(this.InflateFlush(zip, res));
        }
コード例 #11
0
        private int ProcessDTree(CompressionStream zip, InflaterBlocksContext state, int res)
        {
            while (true)
            {
                state.Temp = this.table;
                if (this.index < 258 + (state.Temp & 31) + (state.Temp >> 5 & 31))
                {
                    for (state.Temp = this.bitLengthTreeDepth[0]; state.Bits < state.Temp; state.Bits += 8)
                    {
                        if (state.BytesCount != 0)
                        {
                            res = 0;
                            --state.BytesCount;
                            state.BitBuf |= ((int)zip.Input[state.Input++] & (int)byte.MaxValue) << state.Bits;
                        }
                        else
                        {
                            this.TransferBlocksState(zip, state);
                            state.IsReturn = true;
                            return(this.InflateFlush(zip, res));
                        }
                    }
                    state.Temp = this.hufts[(this.bitLengthDecodeTree[0] + (state.BitBuf & InflaterBlocks.inflateMask[state.Temp])) * 3 + 1];
                    int huft = this.hufts[(this.bitLengthDecodeTree[0] + (state.BitBuf & InflaterBlocks.inflateMask[state.Temp])) * 3 + 2];
                    if (huft < 16)
                    {
                        state.ShiftRight(state.Temp);
                        this.blens[this.index++] = huft;
                    }
                    else
                    {
                        int v    = huft == 18 ? 7 : huft - 14;
                        int num1 = huft == 18 ? 11 : 3;
                        for (; state.Bits < state.Temp + v; state.Bits += 8)
                        {
                            if (state.BytesCount != 0)
                            {
                                res = 0;
                                --state.BytesCount;
                                state.BitBuf |= ((int)zip.Input[state.Input++] & (int)byte.MaxValue) << state.Bits;
                            }
                            else
                            {
                                this.TransferBlocksState(zip, state);
                                state.IsReturn = true;
                                return(this.InflateFlush(zip, res));
                            }
                        }
                        state.ShiftRight(state.Temp);
                        int num2 = num1 + (state.BitBuf & InflaterBlocks.inflateMask[v]);
                        state.ShiftRight(v);
                        int index = this.index;
                        state.Temp = this.table;
                        if (index + num2 <= 258 + (state.Temp & 31) + (state.Temp >> 5 & 31) && (huft != 16 || index >= 1))
                        {
                            int num3 = huft == 16 ? this.blens[index - 1] : 0;
                            do
                            {
                                this.blens[index++] = num3;
                            }while (--num2 != 0);
                            this.index = index;
                        }
                        else
                        {
                            break;
                        }
                    }
                }
                else
                {
                    goto label_20;
                }
            }
            this.blens       = (int[])null;
            this.mode        = 9;
            zip.ErrorMessage = "invalid bit length repeat";
            res = -3;
            this.TransferBlocksState(zip, state);
            state.IsReturn = true;
            return(this.InflateFlush(zip, res));

label_20:
            this.bitLengthDecodeTree[0] = -1;
            int[] bl = new int[1];
            int[] bd = new int[1];
            int[] tl = new int[1];
            int[] td = new int[1];
            bl[0]      = 9;
            bd[0]      = 6;
            state.Temp = this.table;
            state.Temp = InflaterTree.InflateTreeDynamic(257 + (state.Temp & 31), 1 + (state.Temp >> 5 & 31), this.blens, bl, bd, tl, td, this.hufts, zip);
            if (state.Temp != 0)
            {
                if (state.Temp == -3)
                {
                    this.blens = (int[])null;
                    this.mode  = 9;
                }
                res = state.Temp;
                this.TransferBlocksState(zip, state);
                state.IsReturn = true;
                return(this.InflateFlush(zip, res));
            }
            this.codes = new InflaterCodes(bl[0], bd[0], this.hufts, tl[0], this.hufts, td[0], zip);
            this.mode  = 6;
            return(0);
        }
コード例 #12
0
 private int GetEndBytes(InflaterBlocksContext state)
 {
     return(state.Output < this.WindowRead ? this.WindowRead - state.Output - 1 : this.WindowEnd - state.Output);
 }