1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.commons.compress.utils;
20
21 import static org.junit.jupiter.api.Assertions.assertEquals;
22 import static org.junit.jupiter.api.Assertions.assertThrows;
23
24 import java.io.ByteArrayInputStream;
25 import java.io.IOException;
26 import java.nio.ByteOrder;
27
28 import org.junit.jupiter.api.Test;
29
30 public class BitInputStreamTest {
31
32 private ByteArrayInputStream getStream() {
33 return new ByteArrayInputStream(new byte[] { (byte) 0xF8,
34 0x40,
35 0x01,
36 0x2F });
37 }
38
39 @Test
40 public void testAlignWithByteBoundaryWhenAtBoundary() throws Exception {
41 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
42 assertEquals(0xF8, bis.readBits(8));
43 bis.alignWithByteBoundary();
44 assertEquals(0, bis.readBits(4));
45 }
46 }
47
48 @Test
49 public void testAlignWithByteBoundaryWhenNotAtBoundary() throws Exception {
50 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
51 assertEquals(0x08, bis.readBits(4));
52 assertEquals(4, bis.bitsCached());
53 bis.alignWithByteBoundary();
54 assertEquals(0, bis.bitsCached());
55 assertEquals(0, bis.readBits(4));
56 }
57 }
58
59 @Test
60 public void testAvailableWithCache() throws Exception {
61 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
62 assertEquals(0x08, bis.readBits(4));
63 assertEquals(28, bis.bitsAvailable());
64 }
65 }
66
67 @Test
68 public void testAvailableWithoutCache() throws Exception {
69 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
70 assertEquals(32, bis.bitsAvailable());
71 }
72 }
73
74 @Test
75 public void testBigEndianWithOverflow() throws Exception {
76 final ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 87,
77 45,
78 66,
79 15,
80 90,
81 29,
82 88,
83 61,
84 33,
85 74
86 });
87 try (BitInputStream bin = new BitInputStream(in, ByteOrder.BIG_ENDIAN)) {
88 assertEquals(10,
89 bin.readBits(5));
90 assertEquals(8274274654740644818L,
91 bin.readBits(63));
92 assertEquals(330,
93 bin.readBits(12));
94 assertEquals(-1, bin.readBits(1));
95 }
96 }
97
98 @Test
99 public void testClearBitCache() throws IOException {
100 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
101 assertEquals(0x08, bis.readBits(4));
102 bis.clearBitCache();
103 assertEquals(0, bis.readBits(1));
104 }
105 }
106
107 @Test
108 public void testEOF() throws IOException {
109 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
110 assertEquals(0x2f0140f8, bis.readBits(30));
111 assertEquals(-1, bis.readBits(3));
112 }
113 }
114
115
116
117
118 @Test
119 public void testLittleEndianWithOverflow() throws Exception {
120 final ByteArrayInputStream in = new ByteArrayInputStream(new byte[] { 87,
121 45,
122 66,
123 15,
124 90,
125 29,
126 88,
127 61,
128 33,
129 74
130 });
131 try (BitInputStream bin = new BitInputStream(in, ByteOrder.LITTLE_ENDIAN)) {
132 assertEquals(23,
133 bin.readBits(5));
134 assertEquals(714595605644185962L,
135 bin.readBits(63));
136 assertEquals(1186,
137 bin.readBits(12));
138 assertEquals(-1, bin.readBits(1));
139 }
140 }
141
142 @Test
143 public void testReading17BitsInBigEndian() throws IOException {
144 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.BIG_ENDIAN)) {
145
146 assertEquals(0x0001f080, bis.readBits(17));
147 }
148 }
149
150 @Test
151 public void testReading17BitsInLittleEndian() throws IOException {
152 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
153 assertEquals(0x000140f8, bis.readBits(17));
154 }
155 }
156
157 @Test
158 public void testReading24BitsInBigEndian() throws IOException {
159 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.BIG_ENDIAN)) {
160 assertEquals(0x00f84001, bis.readBits(24));
161 }
162 }
163
164 @Test
165 public void testReading24BitsInLittleEndian() throws IOException {
166 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
167 assertEquals(0x000140f8, bis.readBits(24));
168 }
169 }
170
171 @Test
172 public void testReading30BitsInBigEndian() throws IOException {
173 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.BIG_ENDIAN)) {
174
175 assertEquals(0x3e10004b, bis.readBits(30));
176 }
177 }
178
179 @Test
180 public void testReading30BitsInLittleEndian() throws IOException {
181 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
182 assertEquals(0x2f0140f8, bis.readBits(30));
183 }
184 }
185
186 @Test
187 public void testReading31BitsInBigEndian() throws IOException {
188 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.BIG_ENDIAN)) {
189
190 assertEquals(0x7c200097, bis.readBits(31));
191 }
192 }
193
194 @Test
195 public void testReading31BitsInLittleEndian() throws IOException {
196 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
197 assertEquals(0x2f0140f8, bis.readBits(31));
198 }
199 }
200
201 @Test
202 public void testShouldNotAllowReadingOfANegativeAmountOfBits() throws IOException {
203 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
204 assertThrows(IOException.class, () -> bis.readBits(-1));
205 }
206 }
207
208 @Test
209 public void testShouldNotAllowReadingOfMoreThan63BitsAtATime() throws IOException {
210 try (BitInputStream bis = new BitInputStream(getStream(), ByteOrder.LITTLE_ENDIAN)) {
211 assertThrows(IOException.class, () -> bis.readBits(64));
212 }
213 }
214
215 }