28package com.jogamp.common.util;
30import java.io.BufferedInputStream;
31import java.io.BufferedOutputStream;
32import java.io.IOException;
33import java.io.InputStream;
34import java.io.OutputStream;
35import java.nio.ByteBuffer;
36import java.util.Locale;
38import jogamp.common.Debug;
52 private static final boolean DEBUG = Debug.debug(
"Bitstream");
55 public static final int EOS = -1;
75 void close() throws IOException;
81 void flush() throws IOException;
114 long position(
long newPosition) throws UnsupportedOperationException, IllegalArgumentException;
122 long skip(final
long n) throws IOException;
129 void mark(final
int readLimit) throws UnsupportedOperationException;
140 void reset() throws UnsupportedOperationException, IllegalStateException, IOException;
151 int read() throws UnsupportedOperationException, IOException;
162 int write(final
byte val) throws UnsupportedOperationException, IOException;
172 private byte[] media;
209 public long position(
final long newPosition)
throws UnsupportedOperationException, IllegalArgumentException {
210 if( newPosition >= media.length ) {
213 pos = (int)newPosition;
214 if( posMark > pos ) {
221 public long skip(
final long n) {
224 final int remaining = media.length - pos;
225 skip = Math.min(remaining, (
int)n);
227 final int n2 = (int)n * -1;
228 skip = -1 * Math.min(pos, n2);
235 public void mark(
final int readLimit) {
240 public void reset() throws IllegalStateException {
242 throw new IllegalStateException(
"markpos not set");
244 if(DEBUG) { System.err.println(
"rewind: "+pos+
" -> "+posMark); }
251 if( media.length > pos ) {
252 r = 0xff & media[pos++];
258 System.err.println(
"u8["+(pos-1)+
"] -> "+
toHexBinString(
true, r, 8));
260 System.err.println(
"u8["+(pos-0)+
"] -> EOS");
269 if( media.length > pos ) {
277 System.err.println(
"u8["+(pos-1)+
"] <- "+
toHexBinString(
true, r, 8));
279 System.err.println(
"u8["+(pos-0)+
"] <- EOS");
293 private ByteBuffer media;
330 public long position(
final long newPosition)
throws UnsupportedOperationException, IllegalArgumentException {
331 if( newPosition >= media.limit() ) {
334 media.position((
int)newPosition);
335 pos = (int)newPosition;
336 if( posMark > pos ) {
343 public long skip(
final long n) {
346 final int remaining = media.limit() - pos;
347 skip = Math.min(remaining, (
int)n);
349 final int n2 = (int)n * -1;
350 skip = -1 * Math.min(pos, n2);
357 public void mark(
final int readLimit) {
362 public void reset() throws IllegalStateException {
364 throw new IllegalStateException(
"markpos not set");
366 if(DEBUG) { System.err.println(
"rewind: "+pos+
" -> "+posMark); }
367 media.position(posMark);
374 if( media.limit() > pos ) {
375 r = 0xff & media.get(pos++);
381 System.err.println(
"u8["+(pos-1)+
"] -> "+
toHexBinString(
true, r, 8));
383 System.err.println(
"u8["+(pos-0)+
"] -> EOS");
392 if( media.limit() > pos ) {
393 media.put(pos++, val);
400 System.err.println(
"u8["+(pos-1)+
"] <- "+
toHexBinString(
true, r, 8));
402 System.err.println(
"u8["+(pos-0)+
"] <- EOS");
416 private BufferedInputStream media;
418 private long posMark;
426 if( stream instanceof BufferedInputStream ) {
427 media = (BufferedInputStream) stream;
428 }
else if(
null != stream ) {
429 media =
new BufferedInputStream(stream);
441 public void close() throws IOException {
442 if(
null != media ) {
462 public long position(
final long newPosition)
throws UnsupportedOperationException, IllegalArgumentException {
463 throw new UnsupportedOperationException(
"N/a for "+getClass().getCanonicalName());
467 public long skip(
final long n)
throws IOException {
468 final long skip = media.skip(n);
474 public void mark(
final int readLimit) {
475 media.mark(readLimit);
480 public void reset() throws IllegalStateException, IOException {
482 throw new IllegalStateException(
"markpos not set");
484 if(DEBUG) { System.err.println(
"rewind: "+pos+
" -> "+posMark); }
490 public int read() throws IOException {
491 final int r = media.read();
496 System.err.println(
"u8["+pos+
"] -> EOS");
506 public int write(
final byte val)
throws UnsupportedOperationException {
507 throw new UnsupportedOperationException(
"not allowed with input stream");
518 private BufferedOutputStream media;
519 private long pos = 0;
527 if( stream instanceof BufferedOutputStream ) {
528 media = (BufferedOutputStream) stream;
529 }
else if(
null != stream ) {
530 media =
new BufferedOutputStream(stream);
538 public void close() throws IOException {
539 if(
null != media ) {
545 public void flush() throws IOException {
546 if(
null != media ) {
561 public long position(
final long newPosition)
throws UnsupportedOperationException, IllegalArgumentException {
562 throw new UnsupportedOperationException(
"N/a for "+getClass().getCanonicalName());
566 public long skip(
final long n)
throws IOException {
572 final long skip = n-i;
581 public void mark(
final int readLimit)
throws UnsupportedOperationException {
582 throw new UnsupportedOperationException(
"not allowed with output stream");
586 public void reset() throws UnsupportedOperationException {
587 throw new UnsupportedOperationException(
"not allowed with output stream");
591 public int read() throws UnsupportedOperationException {
592 throw new UnsupportedOperationException(
"not allowed with output stream");
596 public int write(
final byte val)
throws IOException {
597 final int r = 0xff & val;
607 private ByteStream<T> bytes;
609 private int bitBuffer;
610 private int bitsDataMark;
613 private int bitCount;
614 private int bitsCountMark;
616 private boolean outputMode;
617 private boolean throwIOExceptionOnEOF;
626 this.outputMode = outputMode;
629 throwIOExceptionOnEOF =
false;
632 private final void resetLocal() {
638 private final void validateMode() throws IllegalArgumentException {
640 throw new IllegalArgumentException(
"stream can neither input nor output: "+
this);
643 throw new IllegalArgumentException(
"stream cannot output as requested: "+
this);
646 throw new IllegalArgumentException(
"stream cannot input as requested: "+
this);
657 throwIOExceptionOnEOF = enable;
672 public final void setStream(
final T stream,
final boolean outputMode)
throws IllegalArgumentException, IOException {
673 if(
null != bytes && this.outputMode ) {
676 this.bytes.setStream(stream);
677 this.outputMode = outputMode;
701 public final void close() throws IOException {
702 if(
null != bytes && this.outputMode ) {
720 public final int flush() throws IllegalStateException, IOException {
721 if( !outputMode ||
null == bytes ) {
722 throw new IllegalStateException(
"not in output-mode: "+
this);
725 if( 0 != bitCount ) {
726 final int r = bytes.write((
byte)bitBuffer);
730 if( throwIOExceptionOnEOF ) {
731 throw new IOException(
"EOS "+
this);
740 public final boolean canInput() {
return null != bytes ? bytes.canInput() :
false; }
743 public final boolean canOutput() {
return null != bytes ? bytes.canOutput() :
false; }
750 public final void mark(
final int readLimit)
throws IllegalStateException {
751 if( outputMode ||
null == bytes ) {
752 throw new IllegalStateException(
"not in input-mode: "+
this);
754 bytes.mark(readLimit);
755 bitsDataMark = bitBuffer;
756 bitsCountMark = bitCount;
768 public final void reset() throws IllegalStateException, IOException {
769 if( outputMode ||
null == bytes ) {
770 throw new IllegalStateException(
"not in input-mode: "+
this);
772 if( 0 > bitsCountMark ) {
773 throw new IllegalStateException(
"markpos not set: "+
this);
776 bitBuffer = bitsDataMark;
777 bitCount = bitsCountMark;
810 if( 0 == bitCount ) {
829 if(
null == bytes ) {
831 }
else if( 0 == bitCount ) {
832 return bytes.position() << 3;
834 final long bytePos = bytes.position() - ( outputMode ? 0 : 1 );
835 return ( bytePos << 3 ) + 8 - bitCount;
861 public final long position(
final long newPosition)
throws UnsupportedOperationException, IllegalArgumentException, IllegalStateException, IOException {
862 if( 0 > newPosition ) {
863 throw new IllegalArgumentException(
"new position not positive: "+newPosition);
867 if( newPosition >
skip(newPosition) ) {
879 public final int readBit(
final boolean msbFirst)
throws UnsupportedOperationException, IllegalStateException, IOException {
880 if( outputMode ||
null == bytes ) {
881 throw new IllegalStateException(
"not in input-mode: "+
this);
883 if ( 0 < bitCount ) {
886 return ( bitBuffer >>> bitCount ) & 0x01;
888 return ( bitBuffer >>> ( 7 - bitCount ) ) & 0x01;
891 bitBuffer = bytes.read();
892 if(
EOS == bitBuffer ) {
893 if( throwIOExceptionOnEOF ) {
894 throw new IOException(
"EOS "+
this);
900 return bitBuffer >>> 7;
902 return bitBuffer & 0x01;
915 public final int writeBit(
final boolean msbFirst,
final int bit)
throws IllegalStateException, IOException {
916 if( !outputMode ||
null == bytes ) {
917 throw new IllegalStateException(
"not in output-mode: "+
this);
919 if ( 0 < bitCount ) {
922 bitBuffer |= ( 0x01 & bit ) << bitCount;
924 bitBuffer |= ( 0x01 & bit ) << ( 7 - bitCount );
926 if( 0 == bitCount ) {
927 final int r = bytes.write((
byte)bitBuffer);
928 if( throwIOExceptionOnEOF &&
EOS == r ) {
929 throw new IOException(
"EOS "+
this);
936 bitBuffer = ( 0x01 & bit ) << 7;
938 bitBuffer = 0x01 & bit;
952 public long skip(
final long n)
throws IllegalStateException, IOException {
953 if(
null == bytes ) {
954 throw new IllegalStateException(
"closed: "+
this);
957 System.err.println(
"Bitstream.skip.0: "+n+
" - "+
toStringImpl());
960 if( n <= bitCount ) {
963 System.err.println(
"Bitstream.skip.F_N1: "+n+
" - "+
toStringImpl());
969 if(
EOS == bytes.write((
byte)bitBuffer) ) {
975 final long n2 = n - bitCount;
976 final long n3 = n2 >>> 3;
977 final long n4 = bytes.skip(n3);
978 final int n5 = (int) ( n2 - ( n3 << 3 ) );
979 final long nX = ( n4 << 3 ) + n5 + bitCount;
989 System.err.println(
"Bitstream.skip.F_EOS: "+n+
" - "+
toStringImpl());
991 if( throwIOExceptionOnEOF ) {
992 throw new IOException(
"EOS "+
this);
996 bitCount = ( 8 - n5 ) & 7;
998 if( !outputMode && 0 < bitCount ) {
999 bitBuffer = bytes.read();
1000 if(
EOS == bitBuffer ) {
1001 notReadBits = bitCount;
1006 System.err.println(
"Bitstream.skip.F_N2: "+n+
", notReadBits "+notReadBits+
" - "+
toStringImpl());
1008 return nX - notReadBits;
1017 private static final boolean useFastPathStream =
true;
1018 private static final boolean useFastPathTypes =
true;
1031 public int readBits31(
final int n)
throws IllegalArgumentException, IOException {
1033 throw new IllegalArgumentException(
"n > 31: "+n);
1035 if( outputMode ||
null == bytes ) {
1036 throw new IllegalStateException(
"not in input-mode: "+
this);
1041 if( !useFastPathStream ) {
1044 for(
int i=0; i < n; i++) {
1045 final int b =
readBit(
false );
1047 if( throwIOExceptionOnEOF ) {
1048 throw new IOException(
"EOS "+
this);
1058 final int n1 = Math.min(n, bitCount);
1061 final int m1 = ( 1 << n1 ) - 1;
1062 final int s1 = 7 - bitCount + 1;
1066 r = ( m1 & ( bitBuffer >>> s1 ) );
1073 assert( 0 == bitCount );
1076 bitBuffer = bytes.read();
1077 if(
EOS == bitBuffer ) {
1078 if( throwIOExceptionOnEOF ) {
1079 throw new IOException(
"EOS "+
this);
1083 final int n2 = Math.min(c, 8);
1084 final int m2 = ( 1 << n2 ) - 1;
1088 r |= ( m2 & bitBuffer ) << s;
1108 public int writeBits31(
final int n,
final int bits)
throws IllegalStateException, IllegalArgumentException, IOException {
1110 throw new IllegalArgumentException(
"n > 31: "+n);
1112 if( !outputMode ||
null == bytes ) {
1113 throw new IllegalStateException(
"not in output-mode: "+
this);
1116 if( !useFastPathStream ) {
1118 for(
int i=0; i < n; i++) {
1119 final int b =
writeBit(
false , ( bits >>> i ) & 0x1);
1127 final int n1 = Math.min(n, bitCount);
1129 final int m1 = ( 1 << n1 ) - 1;
1130 final int s1 = 7 - bitCount + 1;
1134 bitBuffer |= ( m1 & bits ) << s1 ;
1135 if( 0 == bitCount ) {
1136 if(
EOS == bytes.write((
byte)bitBuffer) ) {
1137 if( throwIOExceptionOnEOF ) {
1138 throw new IOException(
"EOS "+
this);
1147 assert( 0 == bitCount );
1150 final int n2 = Math.min(c, 8);
1151 final int m2 = ( 1 << n2 ) - 1;
1155 bitBuffer = ( m2 & ( bits >>> s ) );
1157 if( 0 == bitCount ) {
1158 if(
EOS == bytes.write((
byte)bitBuffer) ) {
1159 if( throwIOExceptionOnEOF ) {
1160 throw new IOException(
"EOS "+
this);
1181 public final int readUInt8() throws IllegalStateException, IOException {
1182 if( 0 == bitCount && useFastPathTypes ) {
1184 if( outputMode ||
null == bytes ) {
1185 throw new IllegalStateException(
"not in input-mode: "+
this);
1187 final int r = bytes.read();
1188 if( throwIOExceptionOnEOF &&
EOS == r ) {
1189 throw new IOException(
"EOS "+
this);
1203 public final int writeInt8(
final byte int8)
throws IllegalStateException, IOException {
1204 if( 0 == bitCount && useFastPathTypes ) {
1206 if( !outputMode ||
null == bytes ) {
1207 throw new IllegalStateException(
"not in output-mode: "+
this);
1209 final int r = bytes.write(int8);
1210 if( throwIOExceptionOnEOF &&
EOS == r ) {
1211 throw new IOException(
"EOS "+
this);
1231 public final int readUInt16(
final boolean bigEndian)
throws IllegalStateException, IOException {
1232 if( 0 == bitCount && useFastPathTypes ) {
1234 if( outputMode ||
null == bytes ) {
1235 throw new IllegalStateException(
"not in input-mode: "+
this);
1237 final int b1 = bytes.read();
1238 final int b2 =
EOS != b1 ? bytes.read() :
EOS;
1240 if( throwIOExceptionOnEOF ) {
1241 throw new IOException(
"EOS "+
this);
1244 }
else if( bigEndian ) {
1245 return b1 << 8 | b2;
1247 return b2 << 8 | b1;
1253 }
else if( bigEndian ) {
1254 final int b1 = 0xff & ( i16 >>> 8 );
1255 final int b2 = 0xff & i16;
1256 return b2 << 8 | b1;
1272 public static final int readUInt16(
final boolean bigEndian,
final byte[] bytes,
final int offset)
throws IndexOutOfBoundsException {
1275 final int b1 = bytes[offset] & 0xff;
1276 final int b2 = bytes[offset+1] & 0xff;
1278 return b1 << 8 | b2;
1280 return b2 << 8 | b1;
1292 public final int writeInt16(
final boolean bigEndian,
final short int16)
throws IllegalStateException, IOException {
1293 if( 0 == bitCount && useFastPathTypes ) {
1295 if( !outputMode ||
null == bytes ) {
1296 throw new IllegalStateException(
"not in output-mode: "+
this);
1298 final byte hi = (byte) ( 0xff & ( int16 >>> 8 ) );
1299 final byte lo = (byte) ( 0xff & int16 );
1308 if(
EOS != bytes.write(b1) ) {
1309 if(
EOS != bytes.write(b2) ) {
1313 if( throwIOExceptionOnEOF ) {
1314 throw new IOException(
"EOS "+
this);
1317 }
else if( bigEndian ) {
1318 final int b1 = 0xff & ( int16 >>> 8 );
1319 final int b2 = 0xff & int16;
1338 public final long readUInt32(
final boolean bigEndian)
throws IllegalStateException, IOException {
1339 if( 0 == bitCount && useFastPathTypes ) {
1341 if( outputMode ||
null == bytes ) {
1342 throw new IllegalStateException(
"not in input-mode: "+
this);
1344 final int b1 = bytes.read();
1345 final int b2 =
EOS != b1 ? bytes.read() :
EOS;
1346 final int b3 =
EOS != b2 ? bytes.read() :
EOS;
1347 final int b4 =
EOS != b3 ? bytes.read() :
EOS;
1349 if( throwIOExceptionOnEOF ) {
1350 throw new IOException(
"EOS "+
this);
1353 }
else if( bigEndian ) {
1354 return 0xffffffffL & ( b1 << 24 | b2 << 16 | b3 << 8 | b4 );
1356 return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 );
1363 }
else if( bigEndian ) {
1364 final int b1 = 0xff & ( i16b >>> 8 );
1365 final int b2 = 0xff & i16b;
1366 final int b3 = 0xff & ( i16a >>> 8 );
1367 final int b4 = 0xff & i16a;
1368 return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 );
1370 return 0xffffffffL & ( i16b << 16 | i16a );
1384 public static final long readUInt32(
final boolean bigEndian,
final byte[] bytes,
final int offset)
throws IndexOutOfBoundsException {
1386 final int b1 = bytes[offset];
1387 final int b2 = bytes[offset+1];
1388 final int b3 = bytes[offset+2];
1389 final int b4 = bytes[offset+3];
1391 return 0xffffffffL & ( b1 << 24 | b2 << 16 | b3 << 8 | b4 );
1393 return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 );
1405 public final int writeInt32(
final boolean bigEndian,
final int int32)
throws IllegalStateException, IOException {
1406 if( 0 == bitCount && useFastPathTypes ) {
1408 if( !outputMode ||
null == bytes ) {
1409 throw new IllegalStateException(
"not in output-mode: "+
this);
1411 final byte p1 = (byte) ( 0xff & ( int32 >>> 24 ) );
1412 final byte p2 = (byte) ( 0xff & ( int32 >>> 16 ) );
1413 final byte p3 = (byte) ( 0xff & ( int32 >>> 8 ) );
1414 final byte p4 = (byte) ( 0xff & int32 );
1415 final byte b1, b2, b3, b4;
1427 if(
EOS != bytes.write(b1) ) {
1428 if(
EOS != bytes.write(b2) ) {
1429 if(
EOS != bytes.write(b3) ) {
1430 if(
EOS != bytes.write(b4) ) {
1436 if( throwIOExceptionOnEOF ) {
1437 throw new IOException(
"EOS "+
this);
1440 }
else if( bigEndian ) {
1441 final int p1 = 0xff & ( int32 >>> 24 );
1442 final int p2 = 0xff & ( int32 >>> 16 );
1443 final int p3 = 0xff & ( int32 >>> 8 );
1444 final int p4 = 0xff & int32 ;
1452 final int hi = 0x0000ffff & ( int32 >>> 16 );
1453 final int lo = 0x0000ffff & int32 ;
1471 return 0xffffffffL & int32;
1490 if( Integer.MAX_VALUE >= uint32 ) {
1504 if(
null == bytes ) {
1508 mode = outputMode ?
"output" :
"input";
1509 bpos = bytes.position();
1511 return String.format((Locale)
null,
"%s, pos %d [byteP %d, bitCnt %d], bitbuf %s",
1515 private static final String strZeroPadding=
"0000000000000000000000000000000000000000000000000000000000000000";
1516 public static String
toBinString(
final boolean msbFirst,
final int v,
final int bitCount) {
1517 if( 0 == bitCount ) {
1521 final int mask = (int) ( ( 1L << bitCount ) - 1L );
1522 final String s0 = Integer.toBinaryString( mask & v );
1523 return strZeroPadding.substring(0, bitCount-s0.length())+s0;
1525 final char[] c =
new char[32];
1526 for(
int i=0; i<bitCount; i++) {
1527 c[i] = 0 != ( v & ( 1 << i ) ) ?
'1' :
'0';
1529 final String s0 =
new String(c, 0, bitCount);
1530 return s0+strZeroPadding.substring(0, bitCount-s0.length());
1533 public static String
toHexBinString(
final boolean msbFirst,
final int v,
final int bitCount) {
1534 final int nibbles = 0 == bitCount ? 2 : ( bitCount + 3 ) / 4;
1535 return String.format((Locale)
null,
"[0x%0"+nibbles+
"X, msbFirst %b, %s]", v, msbFirst,
toBinString(msbFirst, v, bitCount));
1537 public static final String
toHexBinString(
final boolean msbFirst,
final byte[] data,
final int offset,
final int len) {
1538 final StringBuilder sb =
new StringBuilder();
1540 for(
int i=0; i<len; i++) {
1541 final int v = 0xFF & data[offset+i];
1545 return sb.toString();
1547 public static final String
toHexBinString(
final boolean msbFirst,
final ByteBuffer data,
final int offset,
final int len) {
1548 final StringBuilder sb =
new StringBuilder();
1550 for(
int i=0; i<len; i++) {
1551 final int v = 0xFF & data.get(offset+i);
1555 return sb.toString();
1558 public static void checkBounds(
final byte[] sb,
final int offset,
final int remaining)
throws IndexOutOfBoundsException {
1559 if( offset + remaining > sb.length ) {
1560 throw new IndexOutOfBoundsException(
"Buffer of size "+sb.length+
" cannot hold offset "+offset+
" + remaining "+remaining);
int write(final byte val)
void setStream(final byte[] stream)
void mark(final int readLimit)
long position(final long newPosition)
ByteArrayStream(final byte[] stream)
void setStream(final ByteBuffer stream)
long position(final long newPosition)
int write(final byte val)
ByteBufferStream(final ByteBuffer stream)
void mark(final int readLimit)
void mark(final int readLimit)
void setStream(final OutputStream stream)
ByteOutputStream(final OutputStream stream)
int write(final byte val)
long position(final long newPosition)
Versatile Bitstream implementation supporting:
final int getBitBuffer()
Returns the current bit buffer.
final int writeInt32(final boolean bigEndian, final int int32)
Write the given 32 bits via writeBits31(int, int) LSB-first as little-endian, hence bytes are swapped...
final int flush()
Synchronizes all underlying output stream operations, or do nothing.
long skip(final long n)
It is implementation dependent, whether backward skip giving a negative number is supported or not.
final boolean getThrowIOExceptionOnEOF()
Returns true if I/O methods throw an IOException if EOS appears, otherwise false (default).
final int writeInt8(final byte int8)
Write the given 8 bits via writeBits31(int, int).
static final int readUInt16(final boolean bigEndian, final byte[] bytes, final int offset)
Return incoming uint16_t value and swap bytes according to bigEndian.
static final String toHexBinString(final boolean msbFirst, final byte[] data, final int offset, final int len)
static final long readUInt32(final boolean bigEndian, final byte[] bytes, final int offset)
Return incoming uint32_t and swap bytes according to bigEndian.
static String toHexBinString(final boolean msbFirst, final int v, final int bitCount)
int readBits31(final int n)
Return incoming bits as read via readBit(boolean) LSB-first as little-endian.
static final int uint32LongToInt(final long uint32)
Returns the given uint32_t value long value as int if ≤ Integer#MAX_VALUE.
static String toBinString(final boolean msbFirst, final int v, final int bitCount)
int writeBits31(final int n, final int bits)
Write the given bits via writeBit(boolean, int) LSB-first as little-endian.
final int writeBit(final boolean msbFirst, final int bit)
final int readUInt8()
Return incoming uint8_t as read via readBits31(int).
static void checkBounds(final byte[] sb, final int offset, final int remaining)
final T getSubStream()
Returns the currently used ByteStream's ByteStream#getStream().
static final String toHexBinString(final boolean msbFirst, final ByteBuffer data, final int offset, final int len)
final int getBitPosition()
Return the next bit number to be read or write counting from [0..7].
final int getBitCount()
Number of remaining bits in cache to read before next byte-read (input mode) or number of remaining b...
final int writeInt16(final boolean bigEndian, final short int16)
Write the given 16 bits via writeBits31(int, int) LSB-first as little-endian, hence bytes are swapped...
final boolean canOutput()
Return true if stream can handle output, i.e.
final int getLastBitPos()
Return the last bit number read or written counting from [0..7].
final ByteStream< T > getStream()
Returns the currently used ByteStream.
final void setStream(final T stream, final boolean outputMode)
Sets the underlying stream, without close()ing the previous one.
final void reset()
Reset stream position to markpos as set via mark(int).
Bitstream(final ByteStream< T > stream, final boolean outputMode)
static final long toUInt32Long(final int int32)
Reinterpret the given int32_t value as uint32_t, i.e.
final void setThrowIOExceptionOnEOF(final boolean enable)
Enables or disables throwing an IOException in case EOS appears.
static final int toUInt32Int(final int int32)
Returns the reinterpreted given int32_t value as uint32_t if ≤ Integer#MAX_VALUE as within an int sto...
final int readUInt16(final boolean bigEndian)
Return incoming uint16_t as read via readBits31(int) LSB-first as little-endian, hence bytes are swap...
final int readBit(final boolean msbFirst)
final long position(final long newPosition)
Sets this stream's bit position.
final void mark(final int readLimit)
Set markpos to current position, allowing the stream to be reset().
final long position()
Returns the bit position in the stream.
final long readUInt32(final boolean bigEndian)
Return incoming uint32_t as read via readBits31(int) LSB-first as little-endian, hence bytes are swap...
final boolean canInput()
Return true if stream can handle input, i.e.
final void close()
Closing the underlying stream, implies flush().
static final int EOS
End of stream marker, {@value} or 0xFFFFFFFF.
int read()
Reads one byte from the stream.
boolean canInput()
Return true if stream can handle input, i.e.
void flush()
Synchronizes all underlying output stream operations, or do nothing.
boolean canOutput()
Return true if stream can handle output, i.e.
void setStream(final T stream)
Sets the underlying stream, without close()ing the previous one.
void reset()
Reset stream position to markpos as set via mark(int).
void close()
Closing the underlying stream, implies flush().
long skip(final long n)
It is implementation dependent, whether backward skip giving a negative number is supported or not.
void mark(final int readLimit)
Set markpos to current position, allowing the stream to be reset().
long position()
Returns the byte position in the stream.
int write(final byte val)
Writes one byte, to the stream.
T getStream()
Returns the underlying stream.