public class OutputBitStream extends Object implements Flushable, Closeable
This class wraps any OutputStream
so that you can treat it as
bit stream. Constructors and methods closely resemble those of
OutputStream
. Data can be added to such a stream in several ways:
writing an integer or long in fixedwidth, unary, γ, δ, ζ and Golomb
coding, or providing a vector of bytes.
This class can also wrap a byte
array; this is much more lightweight than wrapping a FastByteArrayOutputStream
wrapping the array, but overflowing the array
will cause an IOException
.
Note that when writing using a vector of bytes bits are written in the natural way: the first bit is bit 7 of the first byte, the eighth bit is bit 0 of the first byte, the ninth bit is bit 7 of the second byte and so on. When writing integers using some coding, instead, the lower bits are considered for coding (in the fixedwidth case, the given number of bits, otherwise the lower bits starting from the most significant one).
The bit streams written by this class are big endian. That is, the first bit of the stream 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.
Blocks of bits (such as coded integers) are written starting from the
most significant bit. In other words, if you take the first bytes of a stream
and print them in binary you will see exactly the sequence of bits you have
written. In particular, if you write 32bit integers you will get a stream
which is identical to the one produced by a DataOutput
.
Additional features:
java.io
, this class provides a flush()
method that bytealigns the streams, flushes to the underlying byte stream
all data and resets the internal state. At this point, you can safely reposition
the underlying stream and write again afterwards. For instance, this is safe
and will perform as expected:
FileOutputStream fos = new FileOutputStream(...); OutputBitStream obs = new OutputBitStream(fos); ... write operations on obs ... obs.flush(); fos.getChannel().position(...); ... other write operations on obs ...
As a commodity, an instance of this class will try to cast the underlying
byte stream to a RepositionableStream
and to fetch by reflection the
FileChannel
underlying the given output stream, in
this order. If either reference can be successfully fetched, you can use
directly the position()
method with argument
pos
with the same semantics of a flush()
, followed by
a call to position(pos / 8)
(where the latter method belongs
either to the underlying stream or to its underlying file channel). The
specified position must be byte aligned, as there is no clean way of reading
a fraction of a byte with the current APIs. However, since the reflective checks are quite
heavy they can be disabled using a suitable constructor.
This class is not synchronised. If multiple threads access an instance of this class concurrently, they must be synchronised externally.
OutputStream
,
InputBitStream
Modifier and Type  Field and Description 

protected int 
avail
Current number of bytes available in the byte buffer.

protected byte[] 
buffer
The stream buffer.

static int 
DEFAULT_BUFFER_SIZE
The default size of the byte buffer in bytes (16Ki).

static int[] 
DELTA 
protected FileChannel 
fileChannel
The cached file channel underlying
os . 
protected int 
free
Current number of free bits in the bit buffer (the bits in the buffer are stored high).

static int[] 
GAMMA 
static int 
MAX_PRECOMPUTED 
protected OutputStream 
os
The underlying
OutputStream . 
protected int 
pos
Current position in the byte buffer.

protected long 
position
Current position of the underlying output stream.

protected RepositionableStream 
repositionableStream
os cast to a positionable stream. 
static int[] 
SHIFTED_GAMMA 
protected boolean 
wrapping
True if we are wrapping an array.

static int[] 
ZETA_3 
Modifier  Constructor and Description 

protected 
OutputBitStream()
This (nonpublic) constructor exists just to provide fake initialisation for classes such as
DebugOutputBitStream . 

OutputBitStream(byte[] a)
Creates a new output bit stream wrapping a given byte array.


OutputBitStream(File file)
Creates a new output bit stream writing to a file.


OutputBitStream(File file,
int bufSize)
Creates a new output bit stream writing to file.


OutputBitStream(FileOutputStream os)
Creates a new output bit stream wrapping a given file output stream using a buffer of size
DEFAULT_BUFFER_SIZE . 

OutputBitStream(FileOutputStream os,
int bufSize)
Creates a new output bit stream wrapping a given file output stream with a specified buffer size.


OutputBitStream(OutputStream os)
Creates a new output bit stream wrapping a given output stream using a buffer of size
DEFAULT_BUFFER_SIZE . 

OutputBitStream(OutputStream os,
boolean testForPosition)
Creates a new output bit stream wrapping a given output stream using a buffer of size
DEFAULT_BUFFER_SIZE . 

OutputBitStream(OutputStream os,
int bufSize)
Creates a new output bit stream wrapping a given output stream with a specified buffer size.


OutputBitStream(OutputStream os,
int bufSize,
boolean testForPosition)
Creates a new output bit stream wrapping a given output stream with a specified buffer size.


OutputBitStream(String name)
Creates a new output bit stream writing to a file.


OutputBitStream(String name,
int bufSize)
Creates a new output bit stream writing to file.

Modifier and Type  Method and Description 

int 
align()
Aligns the stream.

void 
close()
Closes the bit stream.

void 
copyFrom(InputBitStream ibs,
long length)
Copies a given number of bits from a given input bit stream into this output bit stream.

void 
flush()
Flushes the bit stream.

void 
position(long position)
Sets this stream bit position, if it is based on a
RepositionableStream or on a FileChannel . 
int 
write(BooleanIterator i)
Writes a sequence of bits emitted by a boolean iterator.

long 
write(byte[] bits,
long len)
Writes a sequence of bits.

long 
write(byte[] bits,
long offset,
long len)
Writes a sequence of bits, starting from a given offset.

int 
writeBit(boolean bit)
Writes a bit.

int 
writeBit(int bit)
Writes a bit.

protected long 
writeByteOffset(byte[] bits,
int offset,
long len)
Writes a sequence of bits, starting from a given byte offset.

int 
writeDelta(int x)
Writes a natural number in δ coding.

long 
writeDeltas(int[] a,
int count)
Writes a given amount of natural numbers in δ coding.

int 
writeGamma(int x)
Writes a natural number in γ coding.

long 
writeGammas(int[] a,
int count)
Writes a given amount of natural numbers in γ coding.

int 
writeGolomb(int x,
int b)
Writes a natural number in Golomb coding.

int 
writeGolomb(int x,
int b,
int log2b)
Writes a natural number in Golomb coding.

int 
writeInt(int x,
int len)
Writes a fixed number of bits from an integer.

int 
writeLong(long x,
int len)
Writes a fixed number of bits from a long.

int 
writeLongDelta(long x)
Writes a long natural number in δ coding.

int 
writeLongGamma(long x)
Writes a long natural number in γ coding.

long 
writeLongGolomb(long x,
long b)
Writes a long natural number in Golomb coding.

long 
writeLongGolomb(long x,
long b,
int log2b)
Writes a long natural number in Golomb coding.

int 
writeLongMinimalBinary(long x,
long b)
Writes a long natural number in a limited range using a minimal binary coding.

int 
writeLongMinimalBinary(long x,
long b,
int log2b)
Writes a long natural number in a limited range using a minimal binary coding.

int 
writeLongNibble(long x)
Writes a long natural number in variablelength nibble coding.

int 
writeLongShiftedGamma(long x)
Writes a long natural number in shifted γ coding.

long 
writeLongSkewedGolomb(long x,
long b)
Writes a long natural number in skewed Golomb coding.

long 
writeLongUnary(long x)
Writes a long natural number in unary coding.

int 
writeLongZeta(long x,
int k)
Writes a long natural number in ζ coding.

int 
writeMinimalBinary(int x,
int b)
Writes a natural number in a limited range using a minimal binary coding.

int 
writeMinimalBinary(int x,
int b,
int log2b)
Writes a natural number in a limited range using a minimal binary coding.

int 
writeNibble(int x)
Writes a natural number in variablelength nibble coding.

int 
writeShiftedGamma(int x)
Writes a natural number in shifted γ coding.

long 
writeShiftedGammas(int[] a,
int count)
Writes a given amount of natural numbers in shifted γ coding.

int 
writeSkewedGolomb(int x,
int b)
Writes a natural number in skewed Golomb coding.

int 
writeUnary(int x)
Writes a natural number in unary coding.

int 
writeZeta(int x,
int k)
Writes a natural number in ζ coding.

long 
writtenBits()
Returns the number of bits written to this bit stream.

void 
writtenBits(long writtenBits)
Sets the number of bits written to this bit stream.

public static final int MAX_PRECOMPUTED
public static final int[] GAMMA
public static final int[] DELTA
public static final int[] ZETA_3
public static final int[] SHIFTED_GAMMA
public static final int DEFAULT_BUFFER_SIZE
protected final OutputStream os
OutputStream
.protected byte[] buffer
protected int free
protected int pos
protected long position
protected int avail
protected final FileChannel fileChannel
os
.protected final RepositionableStream repositionableStream
os
cast to a positionable stream.protected final boolean wrapping
protected OutputBitStream()
DebugOutputBitStream
.public OutputBitStream(OutputStream os)
DEFAULT_BUFFER_SIZE
.
This constructor performs the reflective tests that are necessary to support position(long)
.
os
 the output stream to wrap.public OutputBitStream(OutputStream os, boolean testForPosition)
DEFAULT_BUFFER_SIZE
.os
 the output stream to wrap.testForPosition
 if false, the reflective test that is necessary to support position(long)
in case os
does not support RepositionableStream
will not be performed.public OutputBitStream(OutputStream os, int bufSize)
This constructor performs the reflective tests that are necessary to support position(long)
.
os
 the output stream to wrap.bufSize
 the size in byte of the buffer; it may be 0, denoting no buffering.public OutputBitStream(OutputStream os, int bufSize, boolean testForPosition)
os
 the output stream to wrap.bufSize
 the size in byte of the buffer; it may be 0, denoting no buffering.testForPosition
 if false, the reflective test that is necessary to support position(long)
in case os
does not support RepositionableStream
will not be performed.public OutputBitStream(FileOutputStream os)
DEFAULT_BUFFER_SIZE
.
This constructor invokes directly FileOutputStream.getChannel()
to support position(long)
.
os
 the output stream to wrap.public OutputBitStream(FileOutputStream os, int bufSize)
This constructor invokes directly FileOutputStream.getChannel()
to support position(long)
.
os
 the output stream to wrap.bufSize
 the size in byte of the buffer; it may be 0, denoting no buffering.public OutputBitStream(byte[] a)
a
 the byte array to wrap.public OutputBitStream(String name, int bufSize) throws FileNotFoundException
name
 the name of the file.bufSize
 the size in byte of the buffer; it may be 0, denoting no buffering.FileNotFoundException
public OutputBitStream(String name) throws FileNotFoundException
name
 the name of the file.FileNotFoundException
public OutputBitStream(File file, int bufSize) throws FileNotFoundException
file
 the file.bufSize
 the size in byte of the buffer; it may be 0, denoting no buffering.FileNotFoundException
public OutputBitStream(File file) throws FileNotFoundException
file
 the file.FileNotFoundException
public void flush() throws IOException
This method will align the stream, write the bit buffer, empty the
byte buffer and delegate to the OutputStream.flush()
method of
the underlying output stream.
This method is provided so that users of this class can easily wrap
repositionable streams (for instance, filebased streams, which can be
repositioned using the underlying FileChannel
).
It is guaranteed that after calling this method the underlying stream can be repositioned, and that the next write to the underlying output stream will start with the content of the first write method called afterwards.
flush
in interface Flushable
IOException
public void close() throws IOException
close
in interface Closeable
close
in interface AutoCloseable
IOException
public long writtenBits()
public void writtenBits(long writtenBits)
This method is provided so that, for instance, the
user can reset via writtenBits(0)
the writtenbits count
after a flush()
.
writtenBits
 the new value for the number of bits written so far.public int align() throws IOException
IOException
public void position(long position) throws IOException
RepositionableStream
or on a FileChannel
.
Given an underlying stream that implements RepositionableStream
or that can provide a FileChannel
via the getChannel()
method,
a call to this method has the same semantics of a flush()
,
followed by a call to position(position / 8)
on
the byte stream. Currently there is no clean, working way of supporting
outofbyteboundary positioning.
position
 the new position expressed as a bit offset; it must be bytealigned.IllegalArgumentException
 when trying to position outside of byte boundaries.UnsupportedOperationException
 if the underlying byte stream does not implement
RepositionableStream
and if the channel it returns is not a FileChannel
.IOException
FileChannel.position(long)
public long write(byte[] bits, long len) throws IOException
bits
 a vector containing the bits to be written.len
 a bit length.len
).IOException
public long write(byte[] bits, long offset, long len) throws IOException
bits
 a vector containing the bits to be written.offset
 a bit offset from which to start to write.len
 a bit length.len
).IOException
protected long writeByteOffset(byte[] bits, int offset, long len) throws IOException
This method is used to support methods such as write(byte[], long, long)
.
bits
 a vector containing the bits to be written.offset
 an offset, expressed in bytes.len
 a bit length.len
).IOException
public int writeBit(boolean bit) throws IOException
bit
 a bit.IOException
public int writeBit(int bit) throws IOException
bit
 a bit.IOException
public int write(BooleanIterator i) throws IOException
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.
i
 a boolean iterator.i
did not throw a runtime exception,
the number of bits written; otherwise, the number of bits written,
plus one, with the sign changed.IOException
public int writeInt(int x, int len) throws IOException
x
 an integer.len
 a bit length; this many lower bits of the first argument will be written
(the most significant bit first).len
).IOException
public int writeLong(long x, int len) throws IOException
x
 a long.len
 a bit length; this many lower bits of the first argument will be written
(the most significant bit first).len
).IOException
public int writeUnary(int x) throws IOException
The unary coding of a natural number n is given by 0^{n}1.
x
 a natural number.IllegalArgumentException
 if you try to write a negative number.IOException
public long writeLongUnary(long x) throws IOException
x
 a long natural number.IllegalArgumentException
 if you try to write a negative number.IOException
writeUnary(int)
public int writeGamma(int x) throws IOException
The γ coding of a positive number of k bits is obtained writing k1 in unary, followed by the lower k1 bits of the number. The coding of a natural number is obtained by adding one and coding.
x
 a natural number.IllegalArgumentException
 if you try to write a negative number.IOException
public long writeGammas(int[] a, int count) throws IOException
a
 an array at least count
natural numbers.count
 the number of elements of a
to be written.IllegalArgumentException
 if you try to write a negative number.IOException
writeGamma(int)
public int writeLongGamma(long x) throws IOException
x
 a long natural number.IllegalArgumentException
 if you try to write a negative number.IOException
writeGamma(int)
public int writeShiftedGamma(int x) throws IOException
x
 a natural number.IllegalArgumentException
 if you try to write a negative number.IOException
public int writeLongShiftedGamma(long x) throws IOException
x
 a natural number.IllegalArgumentException
 if you try to write a negative number.IOException
writeShiftedGamma(int)
public long writeShiftedGammas(int[] a, int count) throws IOException
a
 an array at least count
natural numbers.count
 the number of elements of a
to be written.IllegalArgumentException
 if you try to write a negative number.IOException
writeShiftedGamma(int)
public int writeDelta(int x) throws IOException
x
 a natural number.IllegalArgumentException
 if you try to write a negative number.IOException
public int writeLongDelta(long x) throws IOException
x
 a long natural number.IllegalArgumentException
 if you try to write a negative number.IOException
writeDelta(int)
public long writeDeltas(int[] a, int count) throws IOException
a
 an array at least count
natural numbers.count
 the number of elements of a
to be written.IllegalArgumentException
 if you try to write a negative number.IOException
writeDelta(int)
public int writeMinimalBinary(int x, int b) throws IOException
A minimal binary code is an optimal code for the uniform distribution. This method uses an optimal code in which shorter words are assigned to smaller integers.
x
 a natural number.b
 a strict upper bound for x
.IllegalArgumentException
 if you try to write a negative number or use a nonpositive base.IOException
public int writeMinimalBinary(int x, int b, int log2b) throws IOException
writeMinimalBinary(int,int)
because it does not
have to compute log2b
.x
 a natural number.b
 a strict upper bound for x
.log2b
 the floor of the base2 logarithm of the bound.IllegalArgumentException
 if you try to write a negative number or use a nonpositive base.IOException
writeMinimalBinary(int, int)
public int writeLongMinimalBinary(long x, long b) throws IOException
x
 a natural number.b
 a strict upper bound for x
.IllegalArgumentException
 if you try to write a negative number or use a nonpositive base.IOException
writeMinimalBinary(int, int)
public int writeLongMinimalBinary(long x, long b, int log2b) throws IOException
writeLongMinimalBinary(long,long)
because it does not
have to compute log2b
.x
 a long natural number.b
 a strict upper bound for x
.log2b
 the floor of the base2 logarithm of the bound.IllegalArgumentException
 if you try to write a negative number or use a nonpositive base.IOException
writeMinimalBinary(int, int)
public int writeGolomb(int x, int b) throws IOException
Golomb coding with modulo b writes a natural number x as the quotient of the division of x and b in unary, followed by the remainder in minimal binary code.
This method implements also the case in which b
is 0: in this case,
the argument x
may only be zero, and nothing will be written.
x
 a natural number.b
 the modulus for the coding.IllegalArgumentException
 if you try to write a negative number or use a negative modulus.IOException
public int writeGolomb(int x, int b, int log2b) throws IOException
writeGolomb(int,int)
because it does not
have to compute log2b
.x
 a natural number.b
 the modulus for the coding.log2b
 the floor of the base2 logarithm of the coding modulus (it is irrelevant when b
is zero).IllegalArgumentException
 if you try to write a negative number or use a negative modulus.IOException
writeGolomb(int, int)
public long writeLongGolomb(long x, long b) throws IOException
x
 a long natural number.b
 the modulus for the coding.IllegalArgumentException
 if you try to write a negative number or use a negative modulus.IOException
writeGolomb(int, int)
public long writeLongGolomb(long x, long b, int log2b) throws IOException
writeLongGolomb(long,long)
because it does not
have to compute log2b
.x
 a long natural number.b
 the modulus for the coding.log2b
 the floor of the base2 logarithm of the coding modulus (it is irrelevant when b
is zero).IllegalArgumentException
 if you try to write a negative number or use a negative modulus.IOException
writeGolomb(int, int)
public int writeSkewedGolomb(int x, int b) throws IOException
This method implements also the case in which b
is 0: in this case,
the argument x
may only be zero, and nothing will be written.
x
 a natural number.b
 the modulus for the coding.IllegalArgumentException
 if you try to write a negative number or use a negative modulus.IOException
public long writeLongSkewedGolomb(long x, long b) throws IOException
This method implements also the case in which b
is 0: in this case,
the argument x
may only be zero, and nothing will be written.
x
 a long natural number.b
 the modulus for the coding.IllegalArgumentException
 if you try to write a negative number or use a negative modulus.IOException
writeSkewedGolomb(int, int)
public int writeZeta(int x, int k) throws IOException
ζ coding (with modulo k) records positive numbers in the intervals [1,2^{k}1],[2^{k},2^{k+1}1],…,[2^{hk},2^{(h+1)k}1] by coding h in unary, followed by a minimal binary coding of the offset in the interval. The coding of a natural number is obtained by adding one and coding.
ζ codes were defined by Paolo Boldi and Sebastiano Vigna in “Codes for the World−Wide Web”, Internet Math., 2(4):405427, 2005. The paper contains also a detailed analysis.
x
 a natural number.k
 the shrinking factor.IllegalArgumentException
 if you try to write a negative number or use a nonpositive shrinking factor.IOException
public int writeLongZeta(long x, int k) throws IOException
x
 a long natural number.k
 the shrinking factor.IllegalArgumentException
 if you try to write a negative number or use a nonpositive shrinking factor.IOException
writeZeta(int, int)
public int writeNibble(int x) throws IOException
Variablelength nibble coding records a natural number by padding its binary representation to the left using zeroes, until its length is a multiple of three. Then, the resulting string is broken in blocks of 3 bits, and each block is prefixed with a bit, which is zero for all blocks except for the last one.
x
 a natural number.IllegalArgumentException
 if you try to write a negative number.IOException
public int writeLongNibble(long x) throws IOException
x
 a long natural number.IllegalArgumentException
 if you try to write a negative number.IOException
writeNibble(int)
public void copyFrom(InputBitStream ibs, long length) throws IOException
ibs
 an input bit stream.length
 the number of bits to copy.EOFException
 if there are not enough bits to copy.IOException