28import java.io.BufferedInputStream;
 
   29import java.io.BufferedOutputStream;
 
   30import java.io.IOException;
 
   31import java.io.InputStream;
 
   32import java.io.OutputStream;
 
   33import java.nio.ByteBuffer;
 
   34import java.util.Locale;
 
   36import org.jau.sys.Debug;
 
   50    private static final boolean DEBUG = 
Debug.
debug(
"Bitstream");
 
   53    public static final int EOS = -1;
 
   73        void close() throws IOException;
 
   79        void flush() throws IOException;
 
  112        long position(
long newPosition) throws UnsupportedOperationException, IllegalArgumentException;
 
  120        long skip(final 
long n) throws IOException;
 
  127        void mark(final 
int readLimit) throws UnsupportedOperationException;
 
  138        void reset() throws UnsupportedOperationException, IllegalStateException, IOException;
 
  149        int read() throws UnsupportedOperationException, IOException;
 
  160        int write(final 
byte val) throws UnsupportedOperationException, IOException;
 
 
  170        private byte[] media;
 
  207        public long position(
final long newPosition) 
throws UnsupportedOperationException, IllegalArgumentException {
 
  208            if( newPosition >= media.length ) {
 
  211            pos = (int)newPosition;
 
  212            if( posMark > pos ) {
 
 
  219        public long skip(
final long n) {
 
  222                final int remaining = media.length - pos;
 
  223                skip = Math.min(remaining, (
int)n);
 
  225                final int n2 = (int)n * -1;
 
  226                skip = -1 * Math.min(pos, n2);
 
 
  233        public void mark(
final int readLimit) {
 
 
  238        public void reset() throws IllegalStateException {
 
  240                throw new IllegalStateException(
"markpos not set");
 
  242            if(DEBUG) { System.err.println(
"rewind: "+pos+
" -> "+posMark); }
 
 
  249            if( media.length > pos ) {
 
  250                r = 0xff & media[pos++];
 
  256                    System.err.println(
"u8["+(pos-1)+
"] -> "+
toHexBinString(
true, r, 8));
 
  258                    System.err.println(
"u8["+(pos-0)+
"] -> EOS");
 
 
  267            if( media.length > pos ) {
 
  275                    System.err.println(
"u8["+(pos-1)+
"] <- "+
toHexBinString(
true, r, 8));
 
  277                    System.err.println(
"u8["+(pos-0)+
"] <- EOS");
 
 
 
  291        private ByteBuffer media;
 
  328        public long position(
final long newPosition) 
throws UnsupportedOperationException, IllegalArgumentException {
 
  329            if( newPosition >= media.limit() ) {
 
  332            media.position((
int)newPosition);
 
  333            pos = (int)newPosition;
 
  334            if( posMark > pos ) {
 
 
  341        public long skip(
final long n) {
 
  344                final int remaining = media.limit() - pos;
 
  345                skip = Math.min(remaining, (
int)n);
 
  347                final int n2 = (int)n * -1;
 
  348                skip = -1 * Math.min(pos, n2);
 
 
  355        public void mark(
final int readLimit) {
 
 
  360        public void reset() throws IllegalStateException {
 
  362                throw new IllegalStateException(
"markpos not set");
 
  364            if(DEBUG) { System.err.println(
"rewind: "+pos+
" -> "+posMark); }
 
  365            media.position(posMark);
 
 
  372            if( media.limit() > pos ) {
 
  373                r = 0xff & media.get(pos++);
 
  379                    System.err.println(
"u8["+(pos-1)+
"] -> "+
toHexBinString(
true, r, 8));
 
  381                    System.err.println(
"u8["+(pos-0)+
"] -> EOS");
 
 
  390            if( media.limit() > pos ) {
 
  391                media.put(pos++, val);
 
  398                    System.err.println(
"u8["+(pos-1)+
"] <- "+
toHexBinString(
true, r, 8));
 
  400                    System.err.println(
"u8["+(pos-0)+
"] <- EOS");
 
 
 
  414        private BufferedInputStream media;
 
  416        private long posMark;
 
  424            if( stream instanceof BufferedInputStream ) {
 
  425                media = (BufferedInputStream) stream;
 
  426            } 
else if( 
null != stream ) {
 
  427                media = 
new BufferedInputStream(stream);
 
 
  439        public void close() throws IOException {
 
  440            if( 
null != media ) {
 
 
  460        public long position(
final long newPosition) 
throws UnsupportedOperationException, IllegalArgumentException {
 
  461            throw new UnsupportedOperationException(
"N/a for "+getClass().getCanonicalName());
 
 
  465        public long skip(
final long n) 
throws IOException {
 
  466            final long skip = media.skip(n);
 
 
  472        public void mark(
final int readLimit) {
 
  473            media.mark(readLimit);
 
 
  478        public void reset() throws IllegalStateException, IOException {
 
  480                throw new IllegalStateException(
"markpos not set");
 
  482            if(DEBUG) { System.err.println(
"rewind: "+pos+
" -> "+posMark); }
 
 
  488        public int read() throws IOException {
 
  489            final int r = media.read();
 
  494                    System.err.println(
"u8["+pos+
"] -> EOS");
 
 
  504        public int write(
final byte val) 
throws UnsupportedOperationException {
 
  505            throw new UnsupportedOperationException(
"not allowed with input stream");
 
 
 
  516        private BufferedOutputStream media;
 
  517        private long pos = 0;
 
  525            if( stream instanceof BufferedOutputStream ) {
 
  526                media = (BufferedOutputStream) stream;
 
  527            } 
else if( 
null != stream ) {
 
  528                media = 
new BufferedOutputStream(stream);
 
 
  536        public void close() throws IOException {
 
  537            if( 
null != media ) {
 
 
  543        public void flush() throws IOException {
 
  544            if( 
null != media ) {
 
 
  559        public long position(
final long newPosition) 
throws UnsupportedOperationException, IllegalArgumentException {
 
  560            throw new UnsupportedOperationException(
"N/a for "+getClass().getCanonicalName());
 
 
  564        public long skip(
final long n) 
throws IOException {
 
  570            final long skip = n-i; 
 
 
  579        public void mark(
final int readLimit) 
throws UnsupportedOperationException {
 
  580            throw new UnsupportedOperationException(
"not allowed with output stream");
 
 
  584        public void reset() throws UnsupportedOperationException {
 
  585            throw new UnsupportedOperationException(
"not allowed with output stream");
 
 
  589        public int read() throws UnsupportedOperationException {
 
  590            throw new UnsupportedOperationException(
"not allowed with output stream");
 
 
  594        public int write(
final byte val) 
throws IOException {
 
  595            final int r = 0xff & val;
 
 
 
  605    private ByteStream<T> m_bytes;
 
  607    private int m_bitCache;
 
  608    private int m_bitsDataMark;
 
  611    private int m_bitCount;
 
  612    private int m_bitsCountMark;
 
  614    private boolean m_writeMode;
 
  615    private boolean m_throwIOExceptionOnEOF;
 
  623        this.m_bytes = stream;
 
  624        this.m_writeMode = outputMode;
 
  627        m_throwIOExceptionOnEOF = 
false;
 
 
  630    private final void resetLocal() {
 
  634        m_bitsCountMark = -1;
 
  636    private final boolean canInput0() { 
return null != m_bytes ? m_bytes.canInput() : 
false; }
 
  637    private final boolean canOutput0() { 
return null != m_bytes ? m_bytes.canOutput() : 
false; }
 
  638    private final void validateMode() throws IllegalArgumentException {
 
  639        if( !canInput0() && !canOutput0() ) {
 
  640            throw new IllegalArgumentException(
"stream can neither input nor output: "+
this);
 
  642        if( m_writeMode && !canOutput0() ) {
 
  643            throw new IllegalArgumentException(
"stream cannot output as requested: "+
this);
 
  645        if( !m_writeMode && !canInput0() ) {
 
  646            throw new IllegalArgumentException(
"stream cannot input as requested: "+
this);
 
  657        m_throwIOExceptionOnEOF = enable;
 
 
  672    public final void setStream(
final T stream, 
final boolean writeMode) 
throws IllegalArgumentException, IOException {
 
  673        if( 
null != m_bytes && this.m_writeMode ) {
 
  676        this.m_bytes.setStream(stream);
 
  677        this.m_writeMode = writeMode;
 
 
  691    public final void setWriteMode(
final boolean writeMode) 
throws IllegalArgumentException, IOException {
 
  692        if( this.m_writeMode ) {
 
  695        this.m_writeMode = writeMode;
 
 
  719    public final void close() throws IOException {
 
  720        if( 
null != m_bytes && this.m_writeMode ) {
 
 
  738    public final int flush() throws IllegalStateException, IOException {
 
  739        if( !m_writeMode || 
null == m_bytes ) {
 
  740            throw new IllegalStateException(
"not in output-mode: "+
this);
 
  743        if( 0 != m_bitCount ) {
 
  744            final int r = m_bytes.write((
byte)m_bitCache);
 
  748                if( m_throwIOExceptionOnEOF ) {
 
  749                    throw new IOException(
"EOS "+
this);
 
 
  758    public final boolean canWrite() { 
return m_writeMode; }
 
  765    public final void mark(
final int readLimit) 
throws IllegalStateException {
 
  766        if( m_writeMode || 
null == m_bytes ) {
 
  767            throw new IllegalStateException(
"not in input-mode: "+
this);
 
  769        m_bytes.mark(readLimit);
 
  770        m_bitsDataMark = m_bitCache;
 
  771        m_bitsCountMark = m_bitCount;
 
 
  783    public final void reset() throws IllegalStateException, IOException {
 
  784        if( m_writeMode || 
null == m_bytes ) {
 
  785            throw new IllegalStateException(
"not in input-mode: "+
this);
 
  787        if( 0 > m_bitsCountMark ) {
 
  788            throw new IllegalStateException(
"markpos not set: "+
this);
 
  791        m_bitCache = m_bitsDataMark;
 
  792        m_bitCount = m_bitsCountMark;
 
 
  821        return 0 == m_bitCount ? 0 : 8 - m_bitCount;
 
 
  834        if( 
null == m_bytes ) {
 
  836        } 
else if( 0 == m_bitCount ) {
 
  837            return m_bytes.position() << 3;
 
  839            final long bytePos = m_bytes.position() - ( m_writeMode ? 0 : 1 );
 
  840            return ( bytePos << 3 ) + 8 - m_bitCount;
 
 
  866    public final long position(
final long newPosition) 
throws UnsupportedOperationException, IllegalArgumentException, IllegalStateException, IOException {
 
  867        if( 0 > newPosition ) {
 
  868            throw new IllegalArgumentException(
"new position not positive: "+newPosition);
 
  871        final long diff = newPosition - pos0;
 
  874        } 
else if( diff > 0 ) {
 
  875            if( diff > 
skip(diff) ) {
 
  881                if( 0 < m_bitCount && 
EOS == m_bytes.write((
byte)m_bitCache) ) {
 
  886            if( 0 != m_bytes.position(0) ) { 
 
  889            if( newPosition > 
skip(newPosition) ) {
 
 
  902    public final int readBit(
final boolean msbFirst) 
throws UnsupportedOperationException, IllegalStateException, IOException {
 
  903        if( m_writeMode || 
null == m_bytes ) {
 
  904            throw new IllegalStateException(
"not in input-mode: "+
this);
 
  906        if ( 0 < m_bitCount ) {
 
  909                return  ( m_bitCache >>> m_bitCount ) & 0x01;
 
  911                return  ( m_bitCache >>> ( 7 - m_bitCount ) ) & 0x01;
 
  914            m_bitCache = m_bytes.read();
 
  915            if( 
EOS == m_bitCache ) {
 
  916                if( m_throwIOExceptionOnEOF ) {
 
  917                    throw new IOException(
"EOS "+
this);
 
  923                    return m_bitCache >>> m_bitCount;
 
  925                    return m_bitCache & 0x01;
 
 
  938    public final boolean writeBit(
final boolean msbFirst, 
final int bit) 
throws IllegalStateException, IOException {
 
  939        if( !m_writeMode || 
null == m_bytes ) {
 
  940            throw new IllegalStateException(
"not in output-mode: "+
this);
 
  942        if ( 0 < m_bitCount ) {
 
  945                m_bitCache |= ( 0x01 & bit ) << m_bitCount;
 
  947                m_bitCache |= ( 0x01 & bit ) << ( 7 - m_bitCount );
 
  949            if( 0 == m_bitCount ) {
 
  950                final int r = m_bytes.write((
byte)m_bitCache);
 
  951                if( m_throwIOExceptionOnEOF && 
EOS == r ) {
 
  952                    throw new IOException(
"EOS "+
this);
 
  959                m_bitCache = ( 0x01 & bit ) << m_bitCount;
 
  961                m_bitCache = 0x01 & bit;
 
 
  975    public long skip(
final long n) 
throws IllegalStateException, IOException {
 
  976        if( 
null == m_bytes ) {
 
  977            throw new IllegalStateException(
"closed: "+
this);
 
  980            System.err.println(
"Bitstream.skip.0: "+n+
" - "+
toStringImpl());
 
  983            if( n <= m_bitCount ) {
 
  984                m_bitCount -= (int)n;
 
  986                    System.err.println(
"Bitstream.skip.F_N1: "+n+
" - "+
toStringImpl());
 
  991                    if( 0 < m_bitCount && 
EOS == m_bytes.write((
byte)m_bitCache) ) {
 
  996                final long n2 = n - m_bitCount;                
 
  997                final long n3 = n2 >>> 3;                    
 
  998                final long n4 = m_bytes.skip(n3);              
 
  999                final int n5 = (int) ( n2 - ( n3 << 3 ) );   
 
 1000                final long nX = ( n4 << 3 ) + n5 + m_bitCount; 
 
 1010                        System.err.println(
"Bitstream.skip.F_EOS: "+n+
" - "+
toStringImpl());
 
 1012                    if( m_throwIOExceptionOnEOF ) {
 
 1013                        throw new IOException(
"EOS "+
this);
 
 1017                int notReadBits = 0;
 
 1018                if( !m_writeMode && 0 < n5 ) {
 
 1019                    m_bitCache = m_bytes.read();
 
 1020                    if( 
EOS == m_bitCache ) {
 
 1022                        notReadBits = m_bitCount;
 
 1024                        m_bitCount = 8 - n5;
 
 1027                    m_bitCount = ( 8 - n5 ) & 7; 
 
 1030                    System.err.println(
"Bitstream.skip.F_N2: "+n+
", notReadBits "+notReadBits+
" - "+
toStringImpl());
 
 1032                return nX - notReadBits;
 
 
 1041    private static final boolean useFastPathStream = 
true;
 
 1042    private static final boolean useFastPathTypes = 
true;
 
 1055    public int readBits31(
final int n) 
throws IllegalArgumentException, IOException {
 
 1057            throw new IllegalArgumentException(
"n > 31: "+n);
 
 1059        if( m_writeMode || 
null == m_bytes ) {
 
 1060            throw new IllegalStateException(
"not in input-mode: "+
this);
 
 1065            if( !useFastPathStream ) {
 
 1068                for(
int i=0; i < n; i++) {
 
 1069                    final int b = 
readBit(
false );
 
 1071                        if( m_throwIOExceptionOnEOF ) {
 
 1072                            throw new IOException(
"EOS "+
this);
 
 1082                final int n1 = Math.min(n, m_bitCount); 
 
 1085                    final int m1 = ( 1 << n1 ) - 1;
 
 1086                    final int s1 = 7 - m_bitCount + 1; 
 
 1090                    r = ( m1 & ( m_bitCache >>> s1 ) ); 
 
 1097                assert( 0 == m_bitCount );
 
 1100                    m_bitCache = m_bytes.read();
 
 1101                    if( 
EOS == m_bitCache ) {
 
 1102                        if( m_throwIOExceptionOnEOF ) {
 
 1103                            throw new IOException(
"EOS "+
this);
 
 1107                    final int n2 = Math.min(c, 8); 
 
 1108                    final int m2 = ( 1 << n2 ) - 1;
 
 1109                    m_bitCount = 8 - n2;
 
 1112                    r |= ( m2 & m_bitCache ) << s; 
 
 
 1132    public int writeBits31(
final int n, 
final int bits) 
throws IllegalStateException, IllegalArgumentException, IOException {
 
 1134            throw new IllegalArgumentException(
"n > 31: "+n);
 
 1136        if( !m_writeMode || 
null == m_bytes ) {
 
 1137            throw new IllegalStateException(
"not in output-mode: "+
this);
 
 1140            if( !useFastPathStream ) {
 
 1142                for(
int i=0; i < n; i++) {
 
 1143                    if( !
writeBit(
false , ( bits >>> i ) & 0x1) ) {
 
 1150                final int n1 = Math.min(n, m_bitCount); 
 
 1152                    final int m1 = ( 1 << n1 ) - 1;
 
 1153                    final int s1 = 7 - m_bitCount + 1; 
 
 1157                    m_bitCache |= ( m1 & bits ) << s1 ; 
 
 1158                    if( 0 == m_bitCount ) {
 
 1159                        if( 
EOS == m_bytes.write((
byte)m_bitCache) ) {
 
 1160                            if( m_throwIOExceptionOnEOF ) {
 
 1161                                throw new IOException(
"EOS "+
this);
 
 1170                assert( 0 == m_bitCount );
 
 1173                    final int n2 = Math.min(c, 8); 
 
 1174                    final int m2 = ( 1 << n2 ) - 1;
 
 1175                    m_bitCount = 8 - n2;
 
 1178                    m_bitCache = ( m2 & ( bits >>> s ) ); 
 
 1180                    if( 0 == m_bitCount ) {
 
 1181                        if( 
EOS == m_bytes.write((
byte)m_bitCache) ) {
 
 1182                            if( m_throwIOExceptionOnEOF ) {
 
 1183                                throw new IOException(
"EOS "+
this);
 
 
 1204    public final int readUInt8() throws IllegalStateException, IOException {
 
 1205        if( 0 == m_bitCount && useFastPathTypes ) {
 
 1207            if( m_writeMode || 
null == m_bytes ) {
 
 1208                throw new IllegalStateException(
"not in input-mode: "+
this);
 
 1210            final int r = m_bytes.read();
 
 1211            if( m_throwIOExceptionOnEOF && 
EOS == r ) {
 
 1212                throw new IOException(
"EOS "+
this);
 
 
 1226    public final int writeInt8(
final byte int8) 
throws IllegalStateException, IOException {
 
 1227        if( 0 == m_bitCount && useFastPathTypes  ) {
 
 1229            if( !m_writeMode || 
null == m_bytes ) {
 
 1230                throw new IllegalStateException(
"not in output-mode: "+
this);
 
 1232            final int r = m_bytes.write(int8);
 
 1233            if( m_throwIOExceptionOnEOF && 
EOS == r ) {
 
 1234                throw new IOException(
"EOS "+
this);
 
 
 1254    public final int readUInt16(
final boolean bigEndian) 
throws IllegalStateException, IOException {
 
 1255        if( 0 == m_bitCount && useFastPathTypes ) {
 
 1257            if( m_writeMode || 
null == m_bytes ) {
 
 1258                throw new IllegalStateException(
"not in input-mode: "+
this);
 
 1260            final int b1 = m_bytes.read();
 
 1261            final int b2 = 
EOS != b1 ? m_bytes.read() : 
EOS;
 
 1263                if( m_throwIOExceptionOnEOF ) {
 
 1264                    throw new IOException(
"EOS "+
this);
 
 1267            } 
else if( bigEndian ) {
 
 1268                return b1 << 8 | b2;
 
 1270                return b2 << 8 | b1;
 
 1276            } 
else if( bigEndian ) {
 
 1277                final int b1 = 0xff & ( i16 >>> 8 );
 
 1278                final int b2 = 0xff &   i16;
 
 1279                return b2 << 8 | b1;
 
 
 1295    public static final int readUInt16(
final boolean bigEndian, 
final byte[] bytes, 
final int offset) 
throws IndexOutOfBoundsException {
 
 1298        final int b1 = bytes[offset] & 0xff;
 
 1299        final int b2 = bytes[offset+1] & 0xff;
 
 1301            return b1 << 8 | b2;
 
 1303            return b2 << 8 | b1;
 
 
 1315    public final int writeInt16(
final boolean bigEndian, 
final short int16) 
throws IllegalStateException, IOException {
 
 1316        if( 0 == m_bitCount && useFastPathTypes ) {
 
 1318            if( !m_writeMode || 
null == m_bytes ) {
 
 1319                throw new IllegalStateException(
"not in output-mode: "+
this);
 
 1321            final byte hi = (byte) ( 0xff & ( int16 >>> 8 ) );
 
 1322            final byte lo = (byte) ( 0xff &   int16         );
 
 1331            if( 
EOS != m_bytes.write(b1) ) {
 
 1332                if( 
EOS != m_bytes.write(b2) ) {
 
 1336            if( m_throwIOExceptionOnEOF ) {
 
 1337                throw new IOException(
"EOS "+
this);
 
 1340        } 
else if( bigEndian ) {
 
 1341            final int b1 = 0xff & ( int16 >>> 8 );
 
 1342            final int b2 = 0xff &   int16;
 
 
 1361    public final long readUInt32(
final boolean bigEndian) 
throws IllegalStateException, IOException {
 
 1362        if( 0 == m_bitCount && useFastPathTypes ) {
 
 1364            if( m_writeMode || 
null == m_bytes ) {
 
 1365                throw new IllegalStateException(
"not in input-mode: "+
this);
 
 1367            final int b1 = m_bytes.read();
 
 1368            final int b2 = 
EOS != b1 ? m_bytes.read() : 
EOS;
 
 1369            final int b3 = 
EOS != b2 ? m_bytes.read() : 
EOS;
 
 1370            final int b4 = 
EOS != b3 ? m_bytes.read() : 
EOS;
 
 1372                if( m_throwIOExceptionOnEOF ) {
 
 1373                    throw new IOException(
"EOS "+
this);
 
 1376            } 
else if( bigEndian ) {
 
 1377                return 0xffffffffL & ( b1 << 24 | b2 << 16 | b3 << 8 | b4 );
 
 1379                return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 );
 
 1386            } 
else if( bigEndian ) {
 
 1387                final int b1 = 0xff & ( i16b >>> 8 );
 
 1388                final int b2 = 0xff &   i16b;
 
 1389                final int b3 = 0xff & ( i16a >>> 8 );
 
 1390                final int b4 = 0xff &   i16a;
 
 1391                return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 );
 
 1393                return 0xffffffffL & ( i16b << 16 | i16a );
 
 
 1407    public static final long readUInt32(
final boolean bigEndian, 
final byte[] bytes, 
final int offset) 
throws IndexOutOfBoundsException {
 
 1409        final int b1 = bytes[offset];
 
 1410        final int b2 = bytes[offset+1];
 
 1411        final int b3 = bytes[offset+2];
 
 1412        final int b4 = bytes[offset+3];
 
 1414            return 0xffffffffL & ( b1 << 24 | b2 << 16 | b3 << 8 | b4 );
 
 1416            return 0xffffffffL & ( b4 << 24 | b3 << 16 | b2 << 8 | b1 );
 
 
 1428    public final int writeInt32(
final boolean bigEndian, 
final int int32) 
throws IllegalStateException, IOException {
 
 1429        if( 0 == m_bitCount && useFastPathTypes ) {
 
 1431            if( !m_writeMode || 
null == m_bytes ) {
 
 1432                throw new IllegalStateException(
"not in output-mode: "+
this);
 
 1434            final byte p1 = (byte) ( 0xff & ( int32 >>> 24 ) );
 
 1435            final byte p2 = (byte) ( 0xff & ( int32 >>> 16 ) );
 
 1436            final byte p3 = (byte) ( 0xff & ( int32 >>>  8 ) );
 
 1437            final byte p4 = (byte) ( 0xff &   int32          );
 
 1438            final byte b1, b2, b3, b4;
 
 1450            if( 
EOS != m_bytes.write(b1) ) {
 
 1451                if( 
EOS != m_bytes.write(b2) ) {
 
 1452                    if( 
EOS != m_bytes.write(b3) ) {
 
 1453                        if( 
EOS != m_bytes.write(b4) ) {
 
 1459            if( m_throwIOExceptionOnEOF ) {
 
 1460                throw new IOException(
"EOS "+
this);
 
 1463        } 
else if( bigEndian ) {
 
 1464            final int p1 = 0xff & ( int32 >>> 24 );
 
 1465            final int p2 = 0xff & ( int32 >>> 16 );
 
 1466            final int p3 = 0xff & ( int32 >>>  8 );
 
 1467            final int p4 = 0xff &   int32         ;
 
 1475            final int hi = 0x0000ffff & ( int32 >>> 16 );
 
 1476            final int lo = 0x0000ffff &   int32 ;
 
 
 1494        return 0xffffffffL & int32;
 
 
 1513        if( Integer.MAX_VALUE >= uint32 ) {
 
 
 1527        if( 
null == m_bytes ) {
 
 1531            mode = m_writeMode ? 
"output" : 
"input";
 
 1532            bpos = m_bytes.position();
 
 1534        return String.format((Locale)
null, 
"%s, pos %d [byteP %d, bitCnt %d], bitbuf %s",
 
 
 1538    private static final String strZeroPadding= 
"0000000000000000000000000000000000000000000000000000000000000000"; 
 
 1539    public static String 
toBinString(
final boolean msbFirst, 
final int v, 
final int bitCount) {
 
 1540        if( 0 == bitCount ) {
 
 1544            final int mask = (int) ( ( 1L << bitCount ) - 1L );
 
 1545            final String s0 = Integer.toBinaryString( mask & v );
 
 1546            return strZeroPadding.substring(0, bitCount-s0.length())+s0;
 
 1548            final char[] c = 
new char[32];
 
 1549            for(
int i=0; i<bitCount; i++) {
 
 1550                c[i] = 0 != ( v & ( 1 << i ) ) ? 
'1' : 
'0';
 
 1552            final String s0 = 
new String(c, 0, bitCount);
 
 1553            return s0+strZeroPadding.substring(0, bitCount-s0.length());
 
 
 1556    public static String 
toHexBinString(
final boolean msbFirst, 
final int v, 
final int bitCount) {
 
 1557        final int nibbles = 0 == bitCount ? 2 : ( bitCount + 3 ) / 4;
 
 1558        return String.format((Locale)
null, 
"[0x%0"+nibbles+
"X, msbFirst %b, %s]", v, msbFirst, 
toBinString(msbFirst, v, bitCount));
 
 
 1560    public static final String 
toHexBinString(
final boolean msbFirst, 
final byte[] data, 
final int offset, 
final int len) {
 
 1561        final StringBuilder sb = 
new StringBuilder();
 
 1563        for(
int i=0; i<len; i++) {
 
 1564            final int v = 0xFF & data[offset+i];
 
 1568        return sb.toString();
 
 
 1570    public static final String 
toHexBinString(
final boolean msbFirst, 
final ByteBuffer data, 
final int offset, 
final int len) {
 
 1571        final StringBuilder sb = 
new StringBuilder();
 
 1573        for(
int i=0; i<len; i++) {
 
 1574            final int v = 0xFF & data.get(offset+i);
 
 1578        return sb.toString();
 
 
 1581    public static void checkBounds(
final byte[] sb, 
final int offset, 
final int remaining) 
throws IndexOutOfBoundsException {
 
 1582        if( offset + remaining > sb.length ) {
 
 1583            throw new IndexOutOfBoundsException(
"Buffer of size "+sb.length+
" cannot hold offset "+offset+
" + remaining "+remaining);
 
 
 
long position(final long newPosition)
 
void setStream(final byte[] stream)
 
ByteArrayStream(final byte[] stream)
 
void mark(final int readLimit)
 
int write(final byte val)
 
int write(final byte val)
 
void setStream(final ByteBuffer stream)
 
void mark(final int readLimit)
 
ByteBufferStream(final ByteBuffer stream)
 
long position(final long newPosition)
 
void setStream(final OutputStream stream)
 
void mark(final int readLimit)
 
int write(final byte val)
 
long position(final long newPosition)
 
ByteOutputStream(final OutputStream stream)
 
int readBits31(final int n)
Return incoming bits as read via readBit(boolean) LSB-first as little-endian.
 
final int getCachedBitCount()
Number of remaining bits cached to read before next byte-read (input mode) or number of remaining bit...
 
final void mark(final int readLimit)
Set markpos to current position, allowing the stream to be reset().
 
final ByteStream< T > getStream()
Returns the currently used ByteStream.
 
final int flush()
Synchronizes all underlying output stream operations, or do nothing.
 
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 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.
 
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 void reset()
Reset stream position to markpos as set via mark(int).
 
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 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...
 
static String toHexBinString(final boolean msbFirst, final int v, final int bitCount)
 
static final int uint32LongToInt(final long uint32)
Returns the given uint32_t value long value as int if ≤ Integer#MAX_VALUE.
 
final long position()
Returns the bit position in the stream.
 
final int getCachedPos()
Return the next cached bit position to be read or written counting from [0..7].
 
static final long readUInt32(final boolean bigEndian, final byte[] bytes, final int offset)
Return incoming uint32_t 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 toUInt32Long(final int int32)
Reinterpret the given int32_t value as uint32_t, i.e.
 
final boolean getThrowIOExceptionOnEOF()
Returns true if I/O methods throw an IOException if EOS appears, otherwise false (default).
 
final void setWriteMode(final boolean writeMode)
Sets the output-mode of this stream.
 
long skip(final long n)
It is implementation dependent, whether backward skip giving a negative number is supported or not.
 
final long position(final long newPosition)
Sets this stream's bit position.
 
final boolean canWrite()
Returns true in case stream is in write mode, false if in read mode.
 
final void setThrowIOExceptionOnEOF(final boolean enable)
Enables or disables throwing an IOException in case EOS appears.
 
final int readBit(final boolean msbFirst)
 
Bitstream(final ByteStream< T > stream, final boolean outputMode)
 
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 int getLastCachedPos()
Return the last cached bit position read or written counting from [0..7].
 
final void close()
Closing the underlying stream, implies flush().
 
final boolean writeBit(final boolean msbFirst, final int bit)
 
static String toBinString(final boolean msbFirst, final int v, final int bitCount)
 
static final String toHexBinString(final boolean msbFirst, final ByteBuffer data, final int offset, final int len)
 
final T getSubStream()
Returns the currently used ByteStream's ByteStream#getStream().
 
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...
 
static final int EOS
End of stream marker, {@value} or 0xFFFFFFFF.
 
final int getBitCache()
Returns the current bit cache.
 
static void checkBounds(final byte[] sb, final int offset, final int remaining)
 
final int readUInt8()
Return incoming uint8_t as read via readBits31(int).
 
Helper routines for logging and debugging.
 
static final boolean debug(final String subcomponent)
 
long skip(final long n)
It is implementation dependent, whether backward skip giving a negative number is supported or not.
 
void flush()
Synchronizes all underlying output stream operations, or do nothing.
 
void reset()
Reset stream position to markpos as set via mark(int).
 
boolean canOutput()
Return true if stream can handle output, i.e.
 
void close()
Closing the underlying stream, implies flush().
 
int read()
Reads one byte from the stream.
 
long position()
Returns the byte position in the stream.
 
void setStream(final T stream)
Sets the underlying stream, without close()ing the previous one.
 
void mark(final int readLimit)
Set markpos to current position, allowing the stream to be reset().
 
boolean canInput()
Return true if stream can handle input, i.e.
 
T getStream()
Returns the underlying stream.
 
int write(final byte val)
Writes one byte, to the stream.