⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 inputbitstream.java

📁 MG4J (Managing Gigabytes for Java) is a free full-text search engine for large document collections
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
	}	/** Feeds 16 more bits into {@link #current}, assuming that {@link #fill} is less than 16.	 * 	 * <p>This method will never throw an {@link EOFException}&mdash;simply, it will refill less than 16 bits.	 * 	 * @return {@link #fill}.	 */ 		private final int refill() throws IOException {		if ( ASSERTS ) assert fill < 16;						if ( avail > 1 ) {			// If there is a byte in the buffer, we use it directly.			avail -= 2;			current = current << 16 | ( buffer[ pos++ ] & 0xFF ) << 8 | buffer[ pos++ ] & 0xFF;			return fill += 16;		}		try{			current = ( current << 8 ) | read();			fill += 8;			current = ( current << 8 ) | read();			fill += 8;		}		catch( EOFException dontCare ) {}				return fill;	}	/** Reads bits from the bit buffer, possibly refilling it.	 *	 * <P>This method is the basic mean for extracting bits from the underlying stream.	 * 	 * <P>You cannot read more than {@link #fill} bits with this method (unless {@link #fill} is 0,	 * and <code>len</code> is nonzero, in which case the buffer will be refilled for you with 8 bits), and if you	 * read exactly {@link #fill} bits the buffer will be empty afterwards. In particular,	 * there will never be 8 bits in the buffer.	 *	 * <P>The bit buffer stores its content in the lower {@link #fill} bits. The content	 * of the remaining bits is undefined.	 *	 * <P>This method updates {@link #readBits}.	 *	 * @param len the number of bits to read.	 * @return the bits read (in the <strong>lower</strong> positions).	 * @throws AssertionError if one tries to read more bits than available in the buffer and assertions are enabled.	 */	private final int readFromCurrent( final int len ) throws IOException {		if ( len == 0 ) return 0;		if ( fill == 0 ) {			current = read();			fill = 8;		}		if ( ASSERTS ) assert len <= fill : len + " bit(s) requested, " + fill + " available";		readBits += len;		return current >>> ( fill -= len ) & ( 1 << len ) - 1;	}	/** Aligns the stream.	 *	 * After a call to this function, the stream is byte aligned. Bits that have been	 * read to align are discarded.	 */	public void align() {		if ( ( fill & 7 ) == 0 ) return;		readBits += fill & 7;		fill &= ~7;	}	/** Reads a sequence of bits. 	 *	 * Bits will be read in the natural way: the first bit is bit 7 of the	 * first byte, the eightth bit is bit 0 of the first byte, the ninth bit is	 * bit 7 of the second byte and so on.	 *	 * @param bits an array of bytes to store the result.	 * @param len the number of bits to read.	 */	public void read( final byte[] bits, int len ) throws IOException {		if ( ASSERTS ) assert fill < 32 : fill + " >= " + 32;				if ( len <= fill ) {			if ( len <= 8 ) {				bits[ 0 ] = (byte)( readFromCurrent( len ) << 8 - len );				return;			}			else if ( len <= 16 ){				bits[ 0 ] = (byte)( readFromCurrent( 8 ) );				bits[ 1 ] = (byte)( readFromCurrent( len - 8 ) << 16 - len );				return;			}			else if ( len <= 24 ) {				bits[ 0 ] = (byte)( readFromCurrent( 8 ) );				bits[ 1 ] = (byte)( readFromCurrent( 8 ) );				bits[ 2 ] = (byte)( readFromCurrent( len - 16 ) << 24 - len );				return;			}			else {				bits[ 0 ] = (byte)( readFromCurrent( 8 ) );				bits[ 1 ] = (byte)( readFromCurrent( 8 ) );				bits[ 2 ] = (byte)( readFromCurrent( 8 ) );				bits[ 3 ] = (byte)( readFromCurrent( len - 24 ) << 32 - len );				return;			}		}		else {			int i, j = 0, b;			if ( fill >= 24 ) {				bits[ j++ ] = (byte)( readFromCurrent( 8 ) );				bits[ j++ ] = (byte)( readFromCurrent( 8 ) );				bits[ j++ ] = (byte)( readFromCurrent( 8 ) );				len -= 24;			} 			else if ( fill >= 16 ) {				bits[ j++ ] = (byte)( readFromCurrent( 8 ) );				bits[ j++ ] = (byte)( readFromCurrent( 8 ) );				len -= 16;			} 			else if ( fill >= 8 ) {				bits[ j++ ] = (byte)( readFromCurrent( 8 ) );				len -= 8;			} 			final int shift = fill;						if ( shift != 0 ) {				bits[ j ] = (byte)( readFromCurrent( shift ) << 8 - shift );				len -= shift;				i = len >> 3;				while( i-- != 0 ) {					b = read();					bits[ j ] |= ( b & 0xFF ) >>> shift;					bits[ ++j ] = (byte)( b << 8 - shift );				}			}			else {				i = len >> 3;				while( i-- != 0 ) bits[ j++ ] = (byte)read();			}			readBits += len & ~7;			len &= 7;			if ( len != 0 ) {				if ( shift == 0 ) bits[ j ] = 0; // We must zero the next byte before OR'ing stuff in				if ( len <= 8 - shift ) {					bits[ j ] |= (byte)( readFromCurrent( len ) << 8 - shift - len );				}				else {					bits[ j ] |= (byte)( readFromCurrent( 8 - shift ) );					bits[ j + 1 ] = (byte)( readFromCurrent( len + shift - 8 ) << 16 - shift - len );				}			}		}	}	/** Reads a bit.	 *	 * @return the next bit from the stream.	 */	public int readBit() throws IOException {		return readFromCurrent( 1 );	}	/** Reads a fixed number of bits into an integer.	 *	 * @param len a bit length.	 * @return an integer whose lower <code>len</code> bits are taken from the stream; the rest is zeroed.	 */	public int readInt( int len ) throws IOException {		int i, x = 0;		if ( len < 0 || len > 32 ) throw new IllegalArgumentException( "You cannot read " + len + " bits into an integer." );		if ( fill < 16 ) refill();		if ( len <= fill ) return readFromCurrent( len );		len -= fill;		x = readFromCurrent( fill );				i = len >> 3;		while( i-- != 0 ) x = x << 8 | read();		readBits += len & ~7;		len &= 7;		return ( x << len ) | readFromCurrent( len );	}	/** Reads a fixed number of bits into a long.	 *	 * @param len a bit length.	 * @return a long whose lower <code>len</code> bits are taken from the stream; the rest is zeroed.	 */	public long readLong( int len ) throws IOException {		int i;		long x = 0;		if ( len < 0 || len > 64 ) throw new IllegalArgumentException( "You cannot read " + len + " bits into a long." );		if ( fill < 16 ) refill();		if ( len <= fill ) return readFromCurrent( len );		len -= fill;		x = readFromCurrent( fill );		i = len >> 3;		while( i-- != 0 ) x = x << 8 | read();		readBits += len & ~7;		len &= 7;		return ( x << len ) | readFromCurrent( len );	}	/** Skips the given number of bits. 	 *	 * @param n the number of bits to skip.	 * @return the actual number of skipped bits.	 */	public long skip( long n ) throws IOException {		if ( n <= fill ) {			if ( n < 0 ) throw new IllegalArgumentException( "Negative bit skip value: " + n );			fill -= n;			readBits += n;			return n;		}		else {			final long prevReadBits = readBits;			n -= fill;			readBits += fill;			fill = 0;			long nb = n >> 3;			// TODO: A real evaluation of the usefulness of this block of code			if ( buffer != null && nb > avail && nb < avail + buffer.length  ) {				/* If we can skip by simply filling the buffer and skipping some bytes,				   we do it. Usually the next block has already been fetched by a read-ahead logic. */				readBits += ( avail + 1 ) << 3;				n -= ( avail + 1 ) << 3;				nb -= avail + 1;				position += pos + avail;				pos = avail = 0;				read();			}			if ( nb <= avail ) {				// We skip bytes directly inside the buffer.				pos += (int)nb;				avail -= (int)nb;				readBits += n & ~7;			}			else {				// No way, we have to pass the byte skip to the underlying stream.				n -= avail << 3;				readBits += avail << 3;				final long toSkip = nb - avail;				// ALERT: the semantics of skip is flawed--this should be somehow fixed.				final long skipped = is.skip( toSkip );				if ( skipped < toSkip ) throw new IOException( "skip() has skipped " + skipped + " instead of " + toSkip + " bytes" );								position += ( avail + pos ) + skipped;				pos = 0;				avail = 0;				readBits += skipped << 3;				if ( skipped != toSkip ) return readBits - prevReadBits;			}						final int residual = (int)( n & 7 );			if ( residual != 0 ) {				current = read();				fill = 8 - residual;				readBits += residual;			}			return readBits - prevReadBits;		}	}	/** Sets this stream bit position, if it is based on a {@link RepositionableStream} or on a {@link java.nio.channels.FileChannel}. 	 *	 * <P>Given an underlying stream that implements {@link	 * RepositionableStream} or that can provide a {@link	 * java.nio.channels.FileChannel} via the <code>getChannel()</code> method,	 * a call to this method has the same semantics of a {@link #flush()},	 * followed by a call to {@link	 * java.nio.channels.FileChannel#position(long) position(position / 8)} on	 * the byte stream, followed by a {@link #skip(long) skip(position % 8)}.	 *	 * @param position the new position expressed as a bit offset.	 * @throws UnsupportedOperationException if the underlying byte stream does not implement	 * {@link RepositionableStream} and if the channel it returns is not a {@link java.nio.channels.FileChannel}.	 * @see FileChannel#position(long)	 */    public void position( final long position ) throws IOException {		if ( position < 0 ) throw new IllegalArgumentException( "Illegal position: " + position );		/*if ( wrapping ) {			final long bitDelta = ( pos << 3 ) - position;			if ( bitDelta >= 0 && bitDelta <= fill ) {				//System.err.println( "Bit positioning... position: " + position + " this.position: " + this.position + " pos: " + pos + " bitDelta: " + bitDelta + " fill: " + fill );				fill = (int)bitDelta;				//System.err.println( "Post: " + position + " fill: " + fill );				return;			}			pos = (int)( position >> 3 );			avail = buffer.length - pos;			fill = 0;			final int residual = (int)( position & 7 );			if ( residual != 0 ) {				current = read();				fill = 8 - residual;			}			return;		}*/				final long bitDelta = ( ( this.position + pos ) << 3 ) - position;		if ( bitDelta >= 0 && bitDelta <= fill ) {			//System.err.println( "Bit positioning... position: " + position + " this.position: " + this.position + " pos: " + pos + " bitDelta: " + bitDelta + " fill: " + fill );			fill = (int)bitDelta;			//System.err.println( "Post: " + position + " fill: " + fill );			return;		}				final long delta = ( position >> 3 ) - ( this.position + pos );		if ( DEBUG ) System.err.println( this + ".position(" + position + "); curr: " + this.position + " delta: " + delta + " pos: " + pos + " avail: " + avail );		// TODO: check for delta < number of bits in current				if ( delta <= avail && delta >= - pos ) {			// We can reposition just by moving into the buffer.			avail -= delta;			pos += delta;			fill = 0;			if ( DEBUG ) System.err.println( this + ": moved internally; pos: " + pos + " avail: " + avail );		}		else if ( repositionableStream != null ) {			flush();			repositionableStream.position( this.position = position >> 3 );		}		else if ( fileChannel != null ) {			flush();			fileChannel.position( this.position = position >> 3 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -