/// <summary>
 /// Reads the next symbol from input.  The symbol is encoded using the
 /// huffman tree.
 /// </summary>
 /// <param name="input">
 /// input the input source.
 /// </param>
 /// <returns>
 /// the next symbol, or -1 if not enough input is available.
 /// </returns>
 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;
         }
     }
 }
示例#2
0
 /// <summary>
 /// Creates a new inflater.
 /// </summary>
 /// <param name="noHeader">
 /// True if no RFC1950/Zlib header and footer fields are expected in the input data
 /// 
 /// This is used for GZIPed/Zipped input.
 /// 
 /// For compatibility with
 /// Sun JDK you should provide one byte of input more than needed in
 /// this case.
 /// </param>
 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
        /// <summary>
        /// Copy from input manipulator to internal window
        /// </summary>
        /// <param name="input">source of data</param>
        /// <param name="length">length of data to copy</param>
        /// <returns>the number of bytes copied</returns>
        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;
        }