jaulib v1.4.0-2-g788cf73
Jau Support Library (C++, Java, ..)
Loading...
Searching...
No Matches
TestBitstream01.java
Go to the documentation of this file.
1/**
2 * Author: Sven Gothel <sgothel@jausoft.com>
3 * Copyright (c) 2021 Gothel Software e.K.
4 * Copyright (c) 2014 Gothel Software e.K.
5 * Copyright (c) 2014 JogAmp Community.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining
8 * a copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sublicense, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25 */
26
27package jau.test.util;
28
29import static jau.test.util.BitDemoData.*;
30
31import java.io.IOException;
32import java.nio.ByteBuffer;
33
34import org.jau.io.Bitstream;
35import org.junit.Assert;
36import org.junit.Test;
37import org.junit.FixMethodOrder;
38import org.junit.runners.MethodSorters;
39
40import jau.test.junit.util.JunitTracer;
41
42/**
43 * Test {@link Bitstream} w/ raw linear and bulk read/write access w/o semantics:
44 * <ul>
45 * <li>{@link Bitstream#readBit(boolean)}</li>
46 * <li>{@link Bitstream#writeBit(boolean, int)}</li>
47 * <li>{@link Bitstream#mark(int)}</li>
48 * <li>{@link Bitstream#reset()}</li>
49 * <li>{@link Bitstream#flush()}</li>
50 * <li>{@link Bitstream#readBits31(int)}</li>
51 * <li>{@link Bitstream#writeBits31(int, int)}</li>
52 * </ul>
53 */
54@FixMethodOrder(MethodSorters.NAME_ASCENDING)
55public class TestBitstream01 extends JunitTracer {
56
57 Bitstream<ByteBuffer> getTestStream(final boolean msbFirstData, final boolean msbFirstWrite,
58 final int preBits, final int skipBits, final int postBits) throws IOException {
59 final int bitCount = preBits+skipBits+postBits;
60 final int byteCount = ( bitCount + 7 ) / 8;
61 final ByteBuffer bbTest = ByteBuffer.allocate(byteCount);
62 final Bitstream.ByteBufferStream bbsTest = new Bitstream.ByteBufferStream(bbTest);
63 final Bitstream<ByteBuffer> bsTest = new Bitstream<ByteBuffer>(bbsTest, true /* outputMode */);
64 final String sTest0;
65 if( msbFirstData ) {
66 sTest0 = testStringMSB.substring(0, preBits+skipBits+postBits);
67 } else {
68 sTest0 = testStringLSB.substring(0, preBits+skipBits+postBits);
69 }
70 if( msbFirstData == msbFirstWrite ) {
71 for(int i=0; i<bitCount; i++) {
72 final int bit = Integer.valueOf(sTest0.substring(i, i+1));
73 bsTest.writeBit(msbFirstWrite, bit);
74 }
75 } else {
76 for(int i=bitCount-1; i >= 0; i--) {
77 final int bit = Integer.valueOf(sTest0.substring(i, i+1));
78 bsTest.writeBit(msbFirstWrite, bit);
79 }
80 }
81 System.err.printf("TestData: msbFirst[data %b, write %b], bits[pre %d, skip %d, post %d = %d]: <%s>%n",
82 msbFirstData, msbFirstWrite, preBits, skipBits, postBits, bitCount, sTest0);
83 Assert.assertEquals(preBits+skipBits+postBits, bsTest.position());
84 bsTest.setStream(bsTest.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush()
85 dumpData("TestData: ", bsTest.getSubStream(), 0, bsTest.getSubStream().limit());
86 return bsTest;
87 }
88
89 String getTestStreamResultAsString(final boolean msbFirstData, final boolean msbFirstAssemble,
90 final int preBits, final int skipBits, final int postBits) {
91 final String pre, post;
92 if( msbFirstData ) {
93 if( msbFirstAssemble ) {
94 pre = testStringMSB.substring(0, preBits);
95 post = testStringMSB.substring(preBits+skipBits, preBits+skipBits+postBits);
96 } else {
97 pre = testStringMSB.substring(postBits+skipBits, postBits+skipBits+preBits);
98 post = testStringMSB.substring(0, postBits);
99 }
100 } else {
101 if( msbFirstAssemble ) {
102 pre = testStringLSB.substring(0, preBits);
103 post = testStringLSB.substring(preBits+skipBits, preBits+skipBits+postBits);
104 } else {
105 pre = testStringLSB.substring(postBits+skipBits, postBits+skipBits+preBits);
106 post = testStringLSB.substring(0, postBits);
107 }
108 }
109 final String r = msbFirstAssemble ? pre + post : post + pre;
110 System.err.println("ResultExp: <"+pre+"> + <"+post+"> = <"+r+">");
111 return r;
112 }
113
114 @Test
115 public void test01LinearBitsMSBFirst() throws IOException {
116 testLinearBitsImpl(true /* msbFirst */);
117 }
118 @Test
119 public void test02LinearBitsLSBFirst() throws IOException {
120 testLinearBitsImpl(false /* msbFirst */);
121 }
122 void testLinearBitsImpl(final boolean msbFirst) throws IOException {
123 testLinearBitsImpl(msbFirst, 0, 0, 1);
124 testLinearBitsImpl(msbFirst, 0, 0, 3);
125 testLinearBitsImpl(msbFirst, 0, 0, 8);
126 testLinearBitsImpl(msbFirst, 0, 0, 10);
127 testLinearBitsImpl(msbFirst, 0, 0, 30);
128 testLinearBitsImpl(msbFirst, 0, 0, 32);
129
130 testLinearBitsImpl(msbFirst, 3, 0, 3);
131 testLinearBitsImpl(msbFirst, 8, 0, 3);
132 testLinearBitsImpl(msbFirst, 9, 0, 3);
133
134 testLinearBitsImpl(msbFirst, 0, 1, 1);
135 testLinearBitsImpl(msbFirst, 0, 1, 3);
136 testLinearBitsImpl(msbFirst, 0, 2, 8);
137 testLinearBitsImpl(msbFirst, 0, 8, 10);
138 testLinearBitsImpl(msbFirst, 0, 12, 20);
139 testLinearBitsImpl(msbFirst, 0, 23, 9);
140
141 testLinearBitsImpl(msbFirst, 1, 1, 1);
142 testLinearBitsImpl(msbFirst, 2, 1, 3);
143 testLinearBitsImpl(msbFirst, 7, 2, 8);
144 testLinearBitsImpl(msbFirst, 8, 8, 8);
145 testLinearBitsImpl(msbFirst, 15, 12, 5);
146 testLinearBitsImpl(msbFirst, 16, 11, 5);
147 }
148
149 String readBits(final boolean msbFirst, final Bitstream<?> copy, final Bitstream<?> input, final int preCount, final int count) throws IOException {
150 final StringBuilder sbRead = new StringBuilder();
151 int i = 0;
152 while( i < count ) {
153 final int bit = input.readBit(msbFirst);
154 if( Bitstream.EOS == bit ) {
155 System.err.printf(" EOS");
156 break;
157 } else {
158 sbRead.append( ( 0 != bit ) ? '1' : '0' );
159 i++;
160 Assert.assertEquals(i+preCount, input.position());
161 if( null != copy ) {
162 copy.writeBit(msbFirst, bit);
163 Assert.assertEquals(i+preCount, copy.position());
164 }
165 }
166 }
167 Assert.assertEquals(i+preCount, input.position());
168 if( null != copy ) {
169 Assert.assertEquals(i+preCount, copy.position());
170 }
171 return sbRead.toString();
172 }
173
174 void testLinearBitsImpl(final boolean msbFirst, final int preBits, final int skipBits, final int postBits) throws IOException {
175 final int totalBits = preBits+skipBits+postBits;
176 System.err.println("XXX TestLinearBits: msbFirst "+msbFirst+", preBits "+preBits+", skipBits "+skipBits+", postBits "+postBits+", totalBits "+totalBits);
177
178 // prepare bitstream
179 System.err.println("Prepare bitstream");
180 final Bitstream<ByteBuffer> bsTest = getTestStream(msbFirst, msbFirst, preBits, skipBits, postBits);
181 final String sTest = getTestStreamResultAsString(msbFirst, true, preBits, skipBits, postBits);
182
183 // init copy-bitstream
184 final int byteCount = ( totalBits + 7 ) / 8;
185 final ByteBuffer bbCopy = ByteBuffer.allocate(byteCount);
186 final Bitstream.ByteBufferStream bbsCopy = new Bitstream.ByteBufferStream(bbCopy);
187 final Bitstream<ByteBuffer> bsCopy = new Bitstream<ByteBuffer>(bbsCopy, true /* outputMode */);
188
189 // read-bitstream .. and copy bits while reading
190 System.err.println("Reading bitstream: "+bsTest);
191 {
192 final String sReadPre = readBits(msbFirst, bsCopy, bsTest, 0, preBits);
193 {
194 final int skippedBits = (int) bsTest.skip(skipBits);
195 Assert.assertEquals(skipBits, skippedBits);
196 }
197 {
198 final int skippedBits = (int) bsCopy.skip(skipBits);
199 Assert.assertEquals(skipBits, skippedBits);
200 }
201 final String sReadPost = readBits(msbFirst, bsCopy, bsTest, preBits+skipBits, postBits);
202 final String sRead = sReadPre + sReadPost;
203 System.err.println("Read.Test: <"+sReadPre+"> + <"+sReadPost+"> = <"+sRead+">");
204 Assert.assertEquals(sTest, sRead);
205 Assert.assertEquals(totalBits, bsTest.position());
206 Assert.assertEquals(totalBits, bsCopy.position());
207 }
208
209 // read copy ..
210 bsCopy.setStream(bsCopy.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush()
211 dumpData("Copy", bbCopy, 0, bbCopy.limit());
212 System.err.println("Reading copy-bitstream: "+bsCopy);
213 bsCopy.mark(0); // mark at beginning
214 Assert.assertEquals(0, bsCopy.position());
215 {
216 final String sReadPre1 = readBits(msbFirst, null, bsCopy, 0, preBits);
217 {
218 final int skippedBits = (int) bsCopy.skip(skipBits);
219 Assert.assertEquals(skipBits, skippedBits);
220 }
221 final String sReadPost1 = readBits(msbFirst, null, bsCopy, preBits+skipBits, postBits);
222 final String sRead1 = sReadPre1 + sReadPost1;
223 System.err.println("Read.Copy.1: <"+sReadPre1+"> + <"+sReadPost1+"> = <"+sRead1+">");
224 Assert.assertEquals(sTest, sRead1);
225
226 bsCopy.reset();
227 final String sReadPre2 = readBits(msbFirst, null, bsCopy, 0, preBits);
228 Assert.assertEquals(sReadPre1, sReadPre2);
229 {
230 final int skippedBits = (int) bsCopy.skip(skipBits);
231 Assert.assertEquals(skipBits, skippedBits);
232 }
233 final String sReadPost2 = readBits(msbFirst, null, bsCopy, preBits+skipBits, postBits);
234 Assert.assertEquals(sReadPost1, sReadPost2);
235 final String sRead2 = sReadPre2 + sReadPost2;
236 System.err.println("Read.Copy.2: <"+sReadPre2+"> + <"+sReadPost2+"> = <"+sRead2+">");
237 Assert.assertEquals(sTest, sRead2);
238 Assert.assertEquals(totalBits, bsCopy.position());
239 }
240 }
241
242 @Test
243 public void test03BulkBits() throws IOException {
244 testBulkBitsImpl(0, 0, 1);
245 testBulkBitsImpl(0, 0, 3);
246 testBulkBitsImpl(0, 0, 8);
247 testBulkBitsImpl(0, 0, 10);
248 testBulkBitsImpl(0, 0, 30);
249 testBulkBitsImpl(0, 0, 31);
250
251 testBulkBitsImpl(3, 0, 3);
252 testBulkBitsImpl(8, 0, 3);
253 testBulkBitsImpl(9, 0, 3);
254 testBulkBitsImpl(5, 0, 6);
255 testBulkBitsImpl(5, 0, 8);
256
257 testBulkBitsImpl(0, 1, 1);
258 testBulkBitsImpl(3, 6, 4);
259
260 testBulkBitsImpl(0, 1, 3);
261 testBulkBitsImpl(0, 2, 8);
262 testBulkBitsImpl(0, 8, 10);
263 testBulkBitsImpl(0, 12, 20);
264 testBulkBitsImpl(0, 23, 9);
265 testBulkBitsImpl(0, 1, 31);
266
267 testBulkBitsImpl(1, 1, 1);
268 testBulkBitsImpl(2, 1, 3);
269 testBulkBitsImpl(7, 2, 8);
270 testBulkBitsImpl(8, 8, 8);
271 testBulkBitsImpl(15, 12, 5);
272 testBulkBitsImpl(16, 11, 5);
273 testBulkBitsImpl(5, 6, 5);
274 testBulkBitsImpl(5, 6, 8);
275 }
276
277 void testBulkBitsImpl(final int preBits, final int skipBits, final int postBits) throws IOException {
278 final int totalBits = preBits+skipBits+postBits;
279 System.err.println("XXX TestBulkBits: preBits "+preBits+", skipBits "+skipBits+", postBits "+postBits+", totalBits "+totalBits);
280
281 // prepare bitstream
282 System.err.println("Prepare bitstream");
283 final Bitstream<ByteBuffer> bsTest = getTestStream(true, false, preBits, skipBits, postBits);
284 final String sTest = getTestStreamResultAsString(true, false, preBits, skipBits, postBits);
285
286 // init copy-bitstream
287 final int byteCount = ( totalBits + 7 ) / 8;
288 final ByteBuffer bbCopy = ByteBuffer.allocate(byteCount);
289 final Bitstream.ByteBufferStream bbsCopy = new Bitstream.ByteBufferStream(bbCopy);
290 final Bitstream<ByteBuffer> bsCopy = new Bitstream<ByteBuffer>(bbsCopy, true /* outputMode */);
291
292 // read-bitstream .. and copy bits while reading
293 System.err.println("Reading bitstream: "+bsTest);
294 {
295 final int readBitsPre = bsTest.readBits31(preBits);
296 Assert.assertEquals(readBitsPre, bsCopy.writeBits31(preBits, readBitsPre));
297
298 final int skippedReadBits = (int) bsTest.skip(skipBits);
299 final int skippedBitsCopy = (int) bsCopy.skip(skipBits);
300
301 final int readBitsPost = bsTest.readBits31(postBits);
302 Assert.assertEquals(readBitsPost, bsCopy.writeBits31(postBits, readBitsPost));
303 final String sReadPreLo = toBinaryString(readBitsPre, preBits);
304 final String sReadPostHi = toBinaryString(readBitsPost, postBits);
305 final String sRead = sReadPostHi + sReadPreLo;
306 System.err.println("Read.Test: <"+sReadPreLo+"> + <"+sReadPostHi+"> = <"+sRead+">");
307
308 Assert.assertEquals(skipBits, skippedReadBits);
309 Assert.assertEquals(sTest, sRead);
310 Assert.assertEquals(totalBits, bsTest.position());
311 Assert.assertEquals(skipBits, skippedBitsCopy);
312 }
313
314 // read copy ..
315 bsCopy.setStream(bsCopy.getSubStream(), false /* outputMode */); // switch to input-mode, implies flush()
316 dumpData("Copy", bbCopy, 0, bbCopy.limit());
317 System.err.println("Reading copy-bitstream: "+bsCopy);
318 Assert.assertEquals(0, bsCopy.position());
319 {
320 final int copyBitsPre = bsCopy.readBits31(preBits);
321
322 final int skippedCopyBits = (int) bsCopy.skip(skipBits);
323
324 final int copyBitsPost = bsCopy.readBits31(postBits);
325 final String sCopyPreLo = toBinaryString(copyBitsPre, preBits);
326 final String sCopyPostHi = toBinaryString(copyBitsPost, postBits);
327 final String sCopy = sCopyPostHi + sCopyPreLo;
328 System.err.println("Copy.Test: <"+sCopyPreLo+"> + <"+sCopyPostHi+"> = <"+sCopy+">");
329
330 Assert.assertEquals(skipBits, skippedCopyBits);
331 Assert.assertEquals(sTest, sCopy);
332 Assert.assertEquals(totalBits, bsCopy.position());
333 }
334 }
335
336 @Test
337 public void test05ErrorHandling() throws IOException {
338 // prepare bitstream
339 final Bitstream<ByteBuffer> bsTest = getTestStream(false, false, 0, 0, 0);
340 System.err.println("01a: "+bsTest);
341 bsTest.close();
342 System.err.println("01b: "+bsTest);
343
344 try {
345 bsTest.readBit(false);
346 } catch (final Exception e) {
347 Assert.assertNotNull(e);
348 }
349 try {
350 bsTest.writeBit(false, 1);
351 } catch (final Exception e) {
352 Assert.assertNotNull(e);
353 }
354 }
355
356 public static void main(final String args[]) throws IOException {
357 final String tstname = TestBitstream01.class.getName();
358 org.junit.runner.JUnitCore.main(tstname);
359 }
360
361}
Test Bitstream w/ raw linear and bulk read/write access w/o semantics:
static void main(final String args[])
Versatile Bitstream implementation supporting:
int readBits31(final int n)
Return incoming bits as read via readBit(boolean) LSB-first as little-endian.
int writeBits31(final int n, final int bits)
Write the given bits via writeBit(boolean, int) LSB-first as little-endian.
final void setStream(final T stream, final boolean writeMode)
Sets the underlying stream, without close()ing the previous one.
final long position()
Returns the bit position in the stream.
long skip(final long n)
It is implementation dependent, whether backward skip giving a negative number is supported or not.
final int readBit(final boolean msbFirst)
final void close()
Closing the underlying stream, implies flush().
final boolean writeBit(final boolean msbFirst, final int bit)
final T getSubStream()
Returns the currently used ByteStream's ByteStream#getStream().