This class allows us to retrieve a specified number of bits from the input buffer, as well as copy big byte blocks. It uses an int buffer to store up to 31 bits for direct manipulation. This guarantees that we can get at least 16 bits, but we only need at most 15, so this is all safe. There are some optimizations in this class, for example, you must never peek more than 8 bits more than needed, and you must first peek bits before you may drop them. This is not a general purpose class but optimized for the behaviour of the Inflater. authors of the original java version : John Leuner, Jochen Hoenicke
예제 #1
0
 public Inflater(bool noHeader)
 {
     this.noHeader = noHeader;
     this.adler = new Adler32();
     this.input = new StreamManipulator();
     this.outputWindow = new OutputWindow();
     this.mode = noHeader ? 2 : 0;
 }
예제 #2
0
 public Inflater(bool noHeader)
 {
     this.noHeader = noHeader;
     this.adler = new Adler32();
     input = new StreamManipulator();
     outputWindow = new OutputWindow();
     mode = noHeader ? DECODE_BLOCKS : DECODE_HEADER;
 }
예제 #3
0
        public int CopyStored(StreamManipulator input, int length)
        {
            length = Math.Min(Math.Min(length, WindowSize - windowFilled), input.AvailableBytes);
            int copied;

            int tailLen = WindowSize - windowEnd;
            if (length > tailLen) {
                copied = input.CopyBytes(window, windowEnd, tailLen);
                if (copied == tailLen) {
                    copied += input.CopyBytes(window, 0, length - tailLen);
                }
            } else {
                copied = input.CopyBytes(window, windowEnd, length);
            }

            windowEnd = (windowEnd + copied) & WindowMask;
            windowFilled += copied;
            return copied;
        }
예제 #4
0
 public int CopyStored(StreamManipulator input, int length)
 {
     int num;
     length = Math.Min(Math.Min(length, 0x8000 - this.windowFilled), input.AvailableBytes);
     int num2 = 0x8000 - this.windowEnd;
     if (length > num2)
     {
         num = input.CopyBytes(this.window, this.windowEnd, num2);
         if (num == num2)
         {
             num += input.CopyBytes(this.window, 0, length - num2);
         }
     }
     else
     {
         num = input.CopyBytes(this.window, this.windowEnd, length);
     }
     this.windowEnd = (this.windowEnd + num) & 0x7fff;
     this.windowFilled += num;
     return num;
 }
예제 #5
0
 public int CopyStored(StreamManipulator input, int length)
 {
     length = Math.Min(Math.Min(length, 32768 - this.windowFilled), input.AvailableBytes);
     int num = 32768 - this.windowEnd;
     int num2;
     if (length > num)
     {
         num2 = input.CopyBytes(this.window, this.windowEnd, num);
         if (num2 == num)
         {
             num2 += input.CopyBytes(this.window, 0, length - num);
         }
     }
     else
     {
         num2 = input.CopyBytes(this.window, this.windowEnd, length);
     }
     this.windowEnd = (this.windowEnd + num2 & 32767);
     this.windowFilled += num2;
     return num2;
 }
 public int GetSymbol(StreamManipulator input)
 {
     int lookahead, symbol;
     if ((lookahead = input.PeekBits(9)) >= 0) {
         if ((symbol = tree[lookahead]) >= 0) {
             input.DropBits(symbol & 15);
             return symbol >> 4;
         }
         int subtree = -(symbol >> 4);
         int bitlen = symbol & 15;
         if ((lookahead = input.PeekBits(bitlen)) >= 0) {
             symbol = tree[subtree | (lookahead >> 9)];
             input.DropBits(symbol & 15);
             return symbol >> 4;
         } else {
             int bits = input.AvailableBits;
             lookahead = input.PeekBits(bits);
             symbol = tree[subtree | (lookahead >> 9)];
             if ((symbol & 15) <= bits) {
                 input.DropBits(symbol & 15);
                 return symbol >> 4;
             } else {
                 return -1;
             }
         }
     } else {
         int bits = input.AvailableBits;
         lookahead = input.PeekBits(bits);
         symbol = tree[lookahead];
         if (symbol >= 0 && (symbol & 15) <= bits) {
             input.DropBits(symbol & 15);
             return symbol >> 4;
         } else {
             return -1;
         }
     }
 }
예제 #7
0
		public bool Decode(StreamManipulator input)
		{
			decode_loop:
				for (;;) {
					switch (mode) {
						case LNUM:
							lnum = input.PeekBits(5);
							if (lnum < 0) {
								return false;
							}
							lnum += 257;
							input.DropBits(5);
							//  	    System.err.println("LNUM: "+lnum);
							mode = DNUM;
							goto case DNUM; // fall through
						case DNUM:
							dnum = input.PeekBits(5);
							if (dnum < 0) {
								return false;
							}
							dnum++;
							input.DropBits(5);
							//  	    System.err.println("DNUM: "+dnum);
							num = lnum+dnum;
							litdistLens = new byte[num];
							mode = BLNUM;
							goto case BLNUM; // fall through
						case BLNUM:
							blnum = input.PeekBits(4);
							if (blnum < 0) {
								return false;
							}
							blnum += 4;
							input.DropBits(4);
							blLens = new byte[19];
							ptr = 0;
							//  	    System.err.println("BLNUM: "+blnum);
							mode = BLLENS;
							goto case BLLENS; // fall through
						case BLLENS:
							while (ptr < blnum) {
								int len = input.PeekBits(3);
								if (len < 0) {
									return false;
								}
								input.DropBits(3);
								//  		System.err.println("blLens["+BL_ORDER[ptr]+"]: "+len);
								blLens[BL_ORDER[ptr]] = (byte) len;
								ptr++;
							}
							blTree = new InflaterHuffmanTree(blLens);
							blLens = null;
							ptr = 0;
							mode = LENS;
							goto case LENS; // fall through
						case LENS: 
						{
							int symbol;
							while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) {
								/* Normal case: symbol in [0..15] */
							
								//  		  System.err.println("litdistLens["+ptr+"]: "+symbol);
								litdistLens[ptr++] = lastLen = (byte)symbol;
							
								if (ptr == num) {
									/* Finished */
									return true;
								}
							}
						
							/* need more input ? */
							if (symbol < 0) {
								return false;
							}
						
							/* otherwise repeat code */
							if (symbol >= 17) {
								/* repeat zero */
								//  		  System.err.println("repeating zero");
								lastLen = 0;
							} else {
								if (ptr == 0) {
									throw new SharpZipBaseException();
								}
							}
							repSymbol = symbol-16;
						}
							mode = REPS;
							goto case REPS; // fall through
						case REPS:
						{
							int bits = repBits[repSymbol];
							int count = input.PeekBits(bits);
							if (count < 0) {
								return false;
							}
							input.DropBits(bits);
							count += repMin[repSymbol];
							//  	      System.err.println("litdistLens repeated: "+count);
							
							if (ptr + count > num) {
								throw new SharpZipBaseException();
							}
							while (count-- > 0) {
								litdistLens[ptr++] = lastLen;
							}
							
							if (ptr == num) {
								/* Finished */
								return true;
							}
						}
							mode = LENS;
							goto decode_loop;
					}
				}
		}
        public bool Decode(StreamManipulator input)
        {
            decode_loop:
                for (;;) {
                    switch (mode) {
                        case LNUM:
                            lnum = input.PeekBits(5);
                            if (lnum < 0) {
                                return false;
                            }
                            lnum += 257;
                            input.DropBits(5);

                            mode = DNUM;
                            goto case DNUM;
                        case DNUM:
                            dnum = input.PeekBits(5);
                            if (dnum < 0) {
                                return false;
                            }
                            dnum++;
                            input.DropBits(5);
                            num = lnum+dnum;
                            litdistLens = new byte[num];
                            mode = BLNUM;
                            goto case BLNUM;
                        case BLNUM:
                            blnum = input.PeekBits(4);
                            if (blnum < 0) {
                                return false;
                            }
                            blnum += 4;
                            input.DropBits(4);
                            blLens = new byte[19];
                            ptr = 0;
                            mode = BLLENS;
                            goto case BLLENS;
                        case BLLENS:
                            while (ptr < blnum) {
                                int len = input.PeekBits(3);
                                if (len < 0) {
                                    return false;
                                }
                                input.DropBits(3);

                                blLens[BL_ORDER[ptr]] = (byte) len;
                                ptr++;
                            }
                            blTree = new InflaterHuffmanTree(blLens);
                            blLens = null;
                            ptr = 0;
                            mode = LENS;
                            goto case LENS;
                        case LENS:
                        {
                            int symbol;
                            while (((symbol = blTree.GetSymbol(input)) & ~15) == 0) {

                                litdistLens[ptr++] = lastLen = (byte)symbol;

                                if (ptr == num) {
                                    return true;
                                }
                            }

                            if (symbol < 0) {
                                return false;
                            }

                            if (symbol >= 17) {

                                lastLen = 0;
                            } else {
                                if (ptr == 0) {
                                    throw new SharpZipBaseException();
                                }
                            }
                            repSymbol = symbol-16;
                        }
                            mode = REPS;
                            goto case REPS;
                        case REPS:
                        {
                            int bits = repBits[repSymbol];
                            int count = input.PeekBits(bits);
                            if (count < 0) {
                                return false;
                            }
                            input.DropBits(bits);
                            count += repMin[repSymbol];

                            if (ptr + count > num) {
                                throw new SharpZipBaseException();
                            }
                            while (count-- > 0) {
                                litdistLens[ptr++] = lastLen;
                            }

                            if (ptr == num) {

                                return true;
                            }
                        }
                            mode = LENS;
                            goto decode_loop;
                    }
                }
        }
예제 #9
0
        public bool Decode(StreamManipulator input)
        {
            int num2;
            int num3;
        Label_0000:
            switch (this.mode)
            {
                case 0:
                    this.lnum = input.PeekBits(5);
                    if (this.lnum >= 0)
                    {
                        this.lnum += 0x101;
                        input.DropBits(5);
                        this.mode = 1;
                        break;
                    }
                    return false;

                case 1:
                    break;

                case 2:
                    goto Label_00B9;

                case 3:
                    goto Label_013B;

                case 4:
                    goto Label_01A8;

                case 5:
                    goto Label_01EE;

                default:
                    goto Label_0000;
            }
            this.dnum = input.PeekBits(5);
            if (this.dnum < 0)
            {
                return false;
            }
            this.dnum++;
            input.DropBits(5);
            this.num = this.lnum + this.dnum;
            this.litdistLens = new byte[this.num];
            this.mode = 2;
        Label_00B9:
            this.blnum = input.PeekBits(4);
            if (this.blnum < 0)
            {
                return false;
            }
            this.blnum += 4;
            input.DropBits(4);
            this.blLens = new byte[0x13];
            this.ptr = 0;
            this.mode = 3;
        Label_013B:
            while (this.ptr < this.blnum)
            {
                int num = input.PeekBits(3);
                if (num < 0)
                {
                    return false;
                }
                input.DropBits(3);
                this.blLens[BL_ORDER[this.ptr]] = (byte) num;
                this.ptr++;
            }
            this.blTree = new InflaterHuffmanTree(this.blLens);
            this.blLens = null;
            this.ptr = 0;
            this.mode = 4;
        Label_01A8:
            while (((num2 = this.blTree.GetSymbol(input)) & -16) == 0)
            {
                this.litdistLens[this.ptr++] = this.lastLen = (byte) num2;
                if (this.ptr == this.num)
                {
                    return true;
                }
            }
            if (num2 < 0)
            {
                return false;
            }
            if (num2 >= 0x11)
            {
                this.lastLen = 0;
            }
            else if (this.ptr == 0)
            {
                throw new SharpZipBaseException();
            }
            this.repSymbol = num2 - 0x10;
            this.mode = 5;
        Label_01EE:
            num3 = repBits[this.repSymbol];
            int num4 = input.PeekBits(num3);
            if (num4 < 0)
            {
                return false;
            }
            input.DropBits(num3);
            num4 += repMin[this.repSymbol];
            if ((this.ptr + num4) > this.num)
            {
                throw new SharpZipBaseException();
            }
            while (num4-- > 0)
            {
                this.litdistLens[this.ptr++] = this.lastLen;
            }
            if (this.ptr == this.num)
            {
                return true;
            }
            this.mode = 4;
            goto Label_0000;
        }
예제 #10
0
		/// <summary>
		/// Copy from input manipulator to internal window
		/// </summary>
		/// <param name="input">source of data</param>
		/// <param name="len">length of data to copy</param>
		/// <returns>the number of bytes copied</returns>
		public int CopyStored(StreamManipulator input, int len)
		{
			len = Math.Min(Math.Min(len, WINDOW_SIZE - windowFilled), input.AvailableBytes);
			int copied;
			
			int tailLen = WINDOW_SIZE - windowEnd;
			if (len > tailLen) {
				copied = input.CopyBytes(window, windowEnd, tailLen);
				if (copied == tailLen) {
					copied += input.CopyBytes(window, 0, len - tailLen);
				}
			} else {
				copied = input.CopyBytes(window, windowEnd, len);
			}
			
			windowEnd = (windowEnd + copied) & WINDOW_MASK;
			windowFilled += copied;
			return copied;
		}
예제 #11
0
 public int GetSymbol(StreamManipulator input)
 {
     int num2;
     int index = input.PeekBits(9);
     if (index >= 0)
     {
         num2 = this.tree[index];
         if (num2 >= 0)
         {
             input.DropBits(num2 & 15);
             return (num2 >> 4);
         }
         int num3 = -(num2 >> 4);
         int bitCount = num2 & 15;
         index = input.PeekBits(bitCount);
         if (index >= 0)
         {
             num2 = this.tree[num3 | (index >> 9)];
             input.DropBits(num2 & 15);
             return (num2 >> 4);
         }
         int num5 = input.AvailableBits;
         index = input.PeekBits(num5);
         num2 = this.tree[num3 | (index >> 9)];
         if ((num2 & 15) <= num5)
         {
             input.DropBits(num2 & 15);
             return (num2 >> 4);
         }
         return -1;
     }
     int availableBits = input.AvailableBits;
     index = input.PeekBits(availableBits);
     num2 = this.tree[index];
     if ((num2 >= 0) && ((num2 & 15) <= availableBits))
     {
         input.DropBits(num2 & 15);
         return (num2 >> 4);
     }
     return -1;
 }