📄 outputbitstream.java
字号:
* java.nio.channels.FileChannel#position(long) position(position / 8)} on * the byte stream. Currently there is no clean, working way of supporting * out-of-byte-boundary positioning. * * @param position the new position expressed as a bit offset; it must be byte-aligned. * @throws IllegalArgumentException when trying to position outside of byte boundaries. * @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 ( ( position & 7 ) != 0 ) throw new IllegalArgumentException( "Not a byte-aligned position: " + position ); if ( wrapping ) { if ( position > buffer.length ) throw new IllegalArgumentException( "Illegal position: " + position ); flush(); free = 8; pos = (int)position; avail = buffer.length - pos; } else if ( repositionableStream != null ) { flush(); if ( position >> 3 != this.position ) repositionableStream.position( this.position = position >> 3 ); } else if ( fileChannel != null ) { flush(); if ( position >> 3 != this.position ) fileChannel.position( this.position = position >> 3 ); } else throw new UnsupportedOperationException( "position() can only be called if the underlying byte stream implements the RepositionableStream interface or if the getChannel() method of the underlying byte stream exists and returns a FileChannel" ); } /** Writes a sequence of bits. * * Bits will be written 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 a vector containing the bits to be written. * @param len a bit length. * @return the number of bits written (<code>len</code>). * @deprecated As of MG4J 1.2, replaced by {@link #write(byte[], long)}. */ @Deprecated public int write( final byte[] bits, final int len ) throws IOException { return (int)writeByteOffset( bits, 0, len ); } /** Writes a sequence of bits, starting from a given offset. * * Bits will be written 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 a vector containing the bits to be written. * @param offset a bit offset from which to start to write. * @param len a bit length. * @return the number of bits written (<code>len</code>). * @deprecated As of MG4J 1.2, replaced by {@link #write(byte[], long, long)}. */ @Deprecated public int write( final byte[] bits, final int offset, final int len ) throws IOException { return (int)write( bits, offset, (long)len ); } /** Writes a sequence of bits. * * Bits will be written 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 a vector containing the bits to be written. * @param len a bit length. * @return the number of bits written (<code>len</code>). */ public long write( final byte[] bits, final long len ) throws IOException { return writeByteOffset( bits, 0, len ); } /** Writes a sequence of bits, starting from a given offset. * * Bits will be written 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 a vector containing the bits to be written. * @param offset a bit offset from which to start to write. * @param len a bit length. * @return the number of bits written (<code>len</code>). */ public long write( final byte[] bits, final long offset, final long len ) throws IOException { final int initial = (int)( 8 - ( offset & 0x7 ) ); if ( initial == 8 ) return writeByteOffset( bits, (int)offset / 8, len ); if ( len <= initial ) return writeInt( ( 0xFF & bits[ (int)( offset / 8 ) ] ) >>> ( initial - len ), (int)len ); return writeInt( bits[ (int)( offset / 8 ) ], initial ) + writeByteOffset( bits, (int)(offset / 8 + 1), len - initial ); } /** Writes a sequence of bits, starting from a given byte offset. * * Bits will be written 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. * * <p>This method is used to support methods such as {@link #write(byte[], long, long)}. * * @param bits a vector containing the bits to be written. * @param offset an offset, expressed in <strong>bytes</strong>. * @param len a bit length. * @return the number of bits written (<code>len</code>). */ protected long writeByteOffset( final byte[] bits, final int offset, long len ) throws IOException { if ( len == 0 ) return 0; if ( len <= free ) { return writeInCurrent( bits[ offset ] >>> 8 - len, (int)len ); } else { final int shift = free; int i, j; writeInCurrent( bits[ offset ] >>> 8 - shift, shift ); len -= shift; j = offset; i = (int)( len >> 3 ); while( i-- != 0 ) { write( bits[ j ] << shift | ( bits[ j + 1 ] & 0xFF ) >>> 8 - shift ); writtenBits += 8; j++; } final int queue = (int)( len & 7 ); if ( queue != 0 ) { if ( queue <= 8 - shift ) { writeInCurrent( bits[ j ] >>> 8 - shift - queue, queue ); } else { writeInCurrent( bits[ j ], 8 - shift ); writeInCurrent( bits[ j + 1 ] >>> 16 - queue - shift, queue + shift - 8 ); } } return len + shift; } } /** Writes a bit. * * @param bit a bit. * @return the number of bits written. */ public int writeBit( final boolean bit ) throws IOException { return writeInCurrent( bit ? 1 : 0, 1 ); } /** Writes a bit. * * @param bit a bit. * @return the number of bits written. */ public int writeBit( final int bit ) throws IOException { if ( bit < 0 || bit > 1 ) throw new IllegalArgumentException( "The argument " + bit + " is not a bit." ); return writeInCurrent( bit, 1 ); } /** Writes a sequence of bits emitted by a boolean iterator. * * <P>If the iterator throws an exception, it is catched, * and the return value is given by the number of bits written * increased by one and with the sign changed. * * @param i a boolean iterator. * @return if <code>i</code> did not throw a runtime exception, * the number of bits written; otherwise, the number of bits written, * plus one, with the sign changed. */ public int write( final BooleanIterator i ) throws IOException { int count = 0; boolean bit; while( i.hasNext() ) { try { bit = i.nextBoolean(); } catch( RuntimeException hide ) { return -count - 1; } writeBit( bit ); count++; } return count; } /** Writes a fixed number of bits from an integer. * * @param x an integer. * @param len a bit length; this many lower bits of the first argument will be written * (the most significant bit first). * @return the number of bits written (<code>len</code>). */ public int writeInt( int x, final int len ) throws IOException { if ( len < 0 || len > 32 ) throw new IllegalArgumentException( "You cannot write " + len + " bits to an integer." ); if ( len <= free ) return writeInCurrent( x, len ); int i = len - free; final int queue = i & 7; if ( free != 0 ) writeInCurrent( x >>> i, free ); // Dirty trick: since queue < 8, we pre-write the last bits in the bit buffer. if ( queue != 0 ) { i -= queue; writeInCurrent( x, queue ); x >>>= queue; } if ( i == 32 ) write( x >>> 24 ); if ( i > 23 ) write( x >>> 16 ); if ( i > 15 ) write( x >>> 8 ); if ( i > 7 ) write( x ); writtenBits += i; return len; } /** Writes a fixed number of bits from a long. * * @param x a long. * @param len a bit length; this many lower bits of the first argument will be written * (the most significant bit first). * @return the number of bits written (<code>len</code>). */ public int writeLong( long x, final int len ) throws IOException { if ( len < 0 || len > 64 ) throw new IllegalArgumentException( "You cannot write " + len + " bits to a long." ); if ( len <= free ) return writeInCurrent( (int)x, len ); int i = len - free; final int queue = i & 7; if ( free != 0 ) writeInCurrent( (int)(x >>> i), free ); // Dirty trick: since queue < 8, we pre-write the last bits in the bit buffer. if ( queue != 0 ) { i -= queue; writeInCurrent( (int)x, queue ); x >>>= queue; } if ( i == 64 ) write( (int)(x >>> 56) ); if ( i > 55 ) write( (int)(x >>> 48) ); if ( i > 47 ) write( (int)(x >>> 40) ); if ( i > 39 ) write( (int)(x >>> 32) ); if ( i > 31 ) write( (int)x >>> 24 ); if ( i > 23 ) write( (int)x >>> 16 ); if ( i > 15 ) write( (int)x >>> 8 ); if ( i > 7 ) write( (int)x ); writtenBits += i; return len; } /** Writes a natural number in unary coding. * * <p>The unary coding of a natural number <var>n</var> is given * by 0<sup><var>n</var></sup>1. * * @param x a natural number. * @return the number of bits written. * @throws IllegalArgumentException if you try to write a negative number. */ public int writeUnary( int x ) throws IOException { if ( x < 0 ) throw new IllegalArgumentException( "The argument " + x + " is negative" ); if ( x < free ) return writeInCurrent( 1, x + 1 ); final int shift = free; x -= shift; writtenBits += shift; write( current ); free = 8; current = 0; int i = x >> 3; writtenBits += ( x & 0x7FFFFFF8 ); while( i-- != 0 ) write( 0 ); writeInCurrent( 1, ( x & 7 ) + 1 ); return x + shift + 1; } /** Writes a long natural number in unary coding. * * @param x a long natural number. * @return the number of bits written. * @throws IllegalArgumentException if you try to write a negative number. * @see #writeUnary(int) */ public long writeLongUnary( long x ) throws IOException { if ( x < 0 ) throw new IllegalArgumentException( "The argument " + x + " is negative" ); if ( x < free ) return writeInCurrent( 1, (int)x + 1 ); final int shift = free; x -= shift; writtenBits += shift; write( current ); free = 8; current = 0; long i = x >> 3; writtenBits += ( x & 0x7FFFFFFFFFFFFFF8L ); while( i-- != 0 ) write( 0 ); writeInCurrent( 1, (int)( x & 7 ) + 1 ); return x + shift + 1; } /** Writes a natural number in γ coding. * * <P>The γ coding of a positive number of <var>k</var> bits is * obtained writing <var>k</var>-1 in unary, followed by the lower * <var>k</var>-1 bits of the number. The coding of a natural number is * obtained by adding one and coding. * * @param x a natural number. * @return the number of bits written. * @throws IllegalArgumentException if you try to write a negative number. */ public int writeGamma( int x ) throws IOException { if ( x < 0 ) throw new IllegalArgumentException( "The argument " + x + " is negative" ); if ( x < MAX_PRECOMPUTED ) return writeInt( GAMMA[ x ], GAMMA[ x ] >>> 26 ); final int msb = Fast.mostSignificantBit( ++x ); // TODO: Can't we eliminate this variable? Is it advantageous? final int l = writeUnary( msb ); return l + ( msb != 0 ? writeInt( x, msb ) : 0 ); } /** Writes a long natural number in γ coding. * * @param x a long natural number. * @return the number of bits written. * @throws IllegalArgumentException if you try to write a negative number. * @see #writeGamma(int) */ public int writeLongGamma( long x ) throws IOException { if ( x < 0 ) throw new IllegalArgumentException( "The argument " + x + " is negative" ); if ( x < MAX_PRECOMPUTED ) return writeInt( GAMMA[ (int)x ], GAMMA[ (int)x ] >>> 26 ); final int msb = Fast.mostSignificantBit( ++x ); final int l = writeUnary( msb ); return l + ( msb != 0 ? writeLong( x, msb ) : 0 ); } /** Writes a natural number in shifted γ coding. * * The shifted γ coding of 0 is 1. The coding of a positive number * of <var>k</var> bits is * obtained writing <var>k</var> in unary, followed by the lower * <var>k</var>-1 bits of the number (equivalently, by writing * <var>k</var> zeroes followed by the number). * * @param x a natural number. * @return the number of bits written. * @throws IllegalArgumentException if you try to write a negative number. */ public int writeShiftedGamma( int x ) throws IOException { if ( x < 0 ) throw new IllegalArgumentException( "The argument " + x + " is negative" );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -