-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBitOutputStream.java
More file actions
56 lines (41 loc) · 1.7 KB
/
Copy pathBitOutputStream.java
File metadata and controls
56 lines (41 loc) · 1.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
package nayuki.arithcode;
import java.io.IOException;
import java.io.OutputStream;
/**
* A stream where bits can be written to. Because they are written to an underlying byte stream, the end of the stream is padded with 0's up to a multiple of 8 bits. The bits are written in big endian.
*/
public final class BitOutputStream {
// Underlying byte stream to write to.
private OutputStream output;
// The accumulated bits for the current byte. Always in the range 0x00 to 0xFF.
private byte currentByte;
// The number of accumulated bits in the current byte. Always between 0 and 7 (inclusive).
private int numBitsInCurrentByte;
// Creates a bit output stream based on the given byte output stream.
public BitOutputStream(OutputStream out) {
if (out == null)
throw new NullPointerException("Argument is null");
output = out;
currentByte = (byte) 0;
numBitsInCurrentByte = 0;
}
// Writes a bit to the stream. The specified bit must be 0 or 1.
public void write(byte b) throws IOException {
if (!(b == 0 || b == 1))
throw new IllegalArgumentException("Argument must be 0 or 1");
currentByte = (byte)(currentByte << 1 | b); // shift will implicitly convert byte to int!!!
numBitsInCurrentByte++;
if (numBitsInCurrentByte == 8) {
output.write(currentByte);
numBitsInCurrentByte = 0;
currentByte = (byte) 0;
}
}
// Closes this stream and the underlying OutputStream. If called when this bit stream is not at a byte boundary,
// then the minimum number of "0" bits (between 0 and 7 of them) are written as padding to reach the next byte boundary.
public void close() throws IOException {
while (numBitsInCurrentByte != 0)
write((byte)0);
output.close();
}
}