@@ -42,7 +42,7 @@ public class JBBPBitInputStream extends FilterInputStream implements JBBPCountab
4242 JBBPSystemProperty .PROPERTY_INPUT_INITIAL_ARRAY_BUFFER_SIZE .getAsInteger (32 );
4343 /**
4444 * Allow return accumulated data during met end of stream and missing part of bits field data.
45- * @since 3.1.0
45+ * @since 3.0.1
4646 */
4747 private final boolean returnAccumulatedForBitReadInEof ;
4848 /**
@@ -80,6 +80,28 @@ public class JBBPBitInputStream extends FilterInputStream implements JBBPCountab
8080 */
8181 private boolean detectedArrayLimit ;
8282
83+ /**
84+ * Flag shows that during last read some bit field was not fully read.
85+ *
86+ * @see JBBPBitInputStream#isReturnAccumulatedForBitReadInEof()
87+ * @since 3.0.1
88+ */
89+ private boolean detectedPartlyReadBitField ;
90+ 91+ /**
92+ * A Constructor.
93+ * <b>By default, if missing part of bit field in the end of stream then current accumulated data will be returned.</b>
94+ *
95+ * @param in an input stream to be filtered.
96+ * @param order a bit order mode for the filter.
97+ * @see JBBPBitOrder#LSB0
98+ * @see JBBPBitOrder#MSB0
99+ * @see JBBPBitOrder#MSB0_DIRECT
100+ */
101+ public JBBPBitInputStream (final InputStream in , final JBBPBitOrder order ) {
102+ this (in , order , true );
103+ }
104+ 83105 /**
84106 * A Constructor, the LSB0 bit order will be used by default.
85107 * <b>By default, if missing part of bit field in the end of stream then current accumulated data will be returned.</b>
@@ -100,26 +122,13 @@ public JBBPBitInputStream(final InputStream in, final boolean returnAccumulatedF
100122 this (in , JBBPBitOrder .LSB0 , returnAccumulatedForBitReadInEof );
101123 }
102124
103- /**
104- * A Constructor.
105- * <b>By default, if missing part of bit field in the end of stream then current accumulated data will be returned.</b>
106- *
107- * @param in an input stream to be filtered.
108- * @param order a bit order mode for the filter.
109- * @see JBBPBitOrder#LSB0
110- * @see JBBPBitOrder#MSB0
111- */
112- public JBBPBitInputStream (final InputStream in , final JBBPBitOrder order ) {
113- this (in , order , true );
114- }
115- 116125 /**
117126 * Create wrapping bit input stream.
118127 *
119128 * @param in the base input stream, must not be null
120129 * @param order a bit order mode for the filter.
121130 * @param returnAccumulatedForBitReadInEof if true then end of stream during bit read and some data missing returns accumulated data.
122- * @since 3.1.0
131+ * @since 3.0.1
123132 */
124133 public JBBPBitInputStream (final InputStream in , final JBBPBitOrder order ,
125134 final boolean returnAccumulatedForBitReadInEof ) {
@@ -129,11 +138,21 @@ public JBBPBitInputStream(final InputStream in, final JBBPBitOrder order,
129138 this .returnAccumulatedForBitReadInEof = returnAccumulatedForBitReadInEof ;
130139 }
131140
141+ /**
142+ * Shows that during last read some bit field was not fully read.
143+ *
144+ * @see JBBPBitInputStream#isReturnAccumulatedForBitReadInEof()
145+ * @since 3.0.1
146+ */
147+ public boolean isDetectedPartlyReadBitField () {
148+ return this .detectedPartlyReadBitField ;
149+ }
150+ 132151 /**
133152 * If true then the bit stream returns currently accumulated data for bit read if end of stream and not whole bit data read, -1 otherwise.
134153 *
135154 * @return boolean flag for the behavior, true if allowed
136- * @since 3.1.0
155+ * @since 3.0.1
137156 */
138157 public boolean isReturnAccumulatedForBitReadInEof () {
139158 return this .returnAccumulatedForBitReadInEof ;
@@ -253,10 +272,11 @@ public int read(final byte[] array, final int offset, final int length) throws I
253272 * @param returnAccumulatedForBitReadInEof if true then return accumulated data if end of stream during bit read, return -1 otherwise.
254273 * @return number of read bytes from the wrapped input stream
255274 * @throws IOException thrown if any transport error
256- * @since 3.1.0
275+ * @since 3.0.1
257276 */
258277 public int read (final byte [] array , final int offset , final int length ,
259278 final boolean returnAccumulatedForBitReadInEof ) throws IOException {
279+ this .detectedPartlyReadBitField = false ;
260280 if (this .bitsInBuffer == 0 ) {
261281 int readBytes = 0 ;
262282 int tempOffset = offset ;
@@ -287,14 +307,17 @@ public int read(final byte[] array, final int offset, final int length,
287307 } else {
288308 int count = length ;
289309 int i = offset ;
310+ boolean partlyReadBits = false ;
290311 while (count > 0 ) {
291312 final int nextByte = this .readBits (JBBPBitNumber .BITS_8 , returnAccumulatedForBitReadInEof );
313+ partlyReadBits |= this .detectedPartlyReadBitField ;
292314 if (nextByte < 0 ) {
293315 break ;
294316 }
295317 count --;
296318 array [i ++] = (byte ) nextByte ;
297319 }
320+ this .detectedPartlyReadBitField = partlyReadBits ;
298321 return length - count ;
299322 }
300323 }
@@ -416,6 +439,7 @@ private byte[] internalReadArray(
416439 final JBBPBitNumber bitNumber ,
417440 final JBBPArraySizeLimiter streamLimiter
418441 ) throws IOException {
442+ this .detectedPartlyReadBitField = false ;
419443 final boolean readByteArray = bitNumber == null ;
420444 this .setDetectedArrayLimit (false );
421445 int pos = 0 ;
@@ -976,6 +1000,7 @@ public int getBufferedBitsNumber() {
9761000 * @return the bit order parameter
9771001 * @see JBBPBitOrder#LSB0
9781002 * @see JBBPBitOrder#MSB0
1003+ * @see JBBPBitOrder#MSB0_DIRECT
9791004 */
9801005 @ Override
9811006 public JBBPBitOrder getBitOrder () {
@@ -992,7 +1017,7 @@ public JBBPBitOrder getBitOrder() {
9921017 */
9931018 public byte readBitField (final JBBPBitNumber numOfBitsToRead ) throws IOException {
9941019 final int value = this .readBits (numOfBitsToRead , this .returnAccumulatedForBitReadInEof );
995- if (value < 0 ) {
1020+ if (value < 0 || this . isDetectedPartlyReadBitField () ) {
9961021 throw new EOFException ("Can't read bits from stream [" + numOfBitsToRead + ']' );
9971022 }
9981023 return (byte ) value ;
@@ -1029,7 +1054,7 @@ public int readBits(final JBBPBitNumber numOfBitsToRead) throws IOException {
10291054 public int readBits (final JBBPBitNumber numOfBitsToRead , final boolean returnAccumulatedForBitReadInEof )
10301055 throws IOException {
10311056 int result ;
1032- 1057+ this . detectedPartlyReadBitField = false ;
10331058 final int numOfBitsAsNumber = numOfBitsToRead .getBitNumber ();
10341059
10351060 if (this .bitsInBuffer == 0 && numOfBitsAsNumber == 8 ) {
@@ -1068,6 +1093,7 @@ public int readBits(final JBBPBitNumber numOfBitsToRead, final boolean returnAcc
10681093 if (i == numOfBitsAsNumber ) {
10691094 return nextByte ;
10701095 } else {
1096+ this .detectedPartlyReadBitField = true ;
10711097 if (returnAccumulatedForBitReadInEof ) {
10721098 break ;
10731099 } else {
@@ -1098,6 +1124,7 @@ public int readBits(final JBBPBitNumber numOfBitsToRead, final boolean returnAcc
10981124 if (i == numOfBitsAsNumber ) {
10991125 return nextByte ;
11001126 } else {
1127+ this .detectedPartlyReadBitField = true ;
11011128 if (returnAccumulatedForBitReadInEof ) {
11021129 break ;
11031130 } else {
@@ -1282,12 +1309,13 @@ public long skip(final long numOfBytes) throws IOException {
12821309 }
12831310
12841311 /**
1285- * Inside method to read a byte from stream.
1312+ * Internal method to read a byte from wrapped stream.
12861313 *
12871314 * @return the read byte or -1 if the end of the stream has been reached
12881315 * @throws IOException it will be thrown for transport errors
12891316 */
12901317 private int readByteFromStream () throws IOException {
1318+ this .detectedPartlyReadBitField = false ;
12911319 int result = this .in .read ();
12921320 if (result >= 0 && this .bitOrderMode == JBBPBitOrder .MSB0 ) {
12931321 result = JBBPUtils .reverseBitsInByte ((byte ) result ) & 0xFF ;
0 commit comments