@@ -40,6 +40,11 @@ public class JBBPBitInputStream extends FilterInputStream implements JBBPCountab
4040 */
4141 protected static final int INITIAL_ARRAY_BUFFER_SIZE =
4242 JBBPSystemProperty .PROPERTY_INPUT_INITIAL_ARRAY_BUFFER_SIZE .getAsInteger (32 );
43+ /**
44+ * Allow return accumulated data during met end of stream and missing part of bits field data.
45+ * @since 3.1.0
46+ */
47+ private final boolean returnAccumulatedForBitReadInEof ;
4348 /**
4449 * Contains bit mode for bit operations.
4550 */
@@ -68,7 +73,6 @@ public class JBBPBitInputStream extends FilterInputStream implements JBBPCountab
6873 * Internal temp variable to keep the byte counter temporarily.
6974 */
7075 private long markedByteCounter ;
71- 7276 /**
7377 * Internal flag shows that read stopped for whole stream array read limit reach.
7478 *
@@ -77,48 +81,84 @@ public class JBBPBitInputStream extends FilterInputStream implements JBBPCountab
7781 private boolean detectedArrayLimit ;
7882
7983 /**
80- * Flag shows that read of array was stopped for array limiter restrictions.
81- *
82- * @return true if array limiter restrictions detected, false otherwise
83- * @see JBBPArraySizeLimiter
84- * @since 2.1.0
85- */
86- public boolean isDetectedArrayLimit () {
87- return this .detectedArrayLimit ;
88- }
89- 90- /**
91- * Set value for array limit detected flag. It is important to set the flag for correct processing of parsing.
84+ * A Constructor, the LSB0 bit order will be used by default.
85+ * <b>By default, if missing part of bit field in the end of stream then current accumulated data will be returned.</b>
9286 *
93- * @param value true or false.
94- * @see com.igormaznitsa.jbbp.JBBPParser
95- * @since 2.1.0
87+ * @param in an input stream to be filtered.
9688 */
97- public void setDetectedArrayLimit (final boolean value ) {
98- this . detectedArrayLimit = value ;
89+ public JBBPBitInputStream (final InputStream in ) {
90+ this ( in , JBBPBitOrder . LSB0 ) ;
9991 }
10092
10193 /**
10294 * A Constructor, the LSB0 bit order will be used by default.
10395 *
104- * @param in an input stream to be filtered.
96+ * @param in an input stream to be filtered.
97+ * @param returnAccumulatedForBitReadInEof if true then end of stream during bit read and some data missing returns accumulated data.
10598 */
106- public JBBPBitInputStream (final InputStream in ) {
107- this (in , JBBPBitOrder .LSB0 );
99+ public JBBPBitInputStream (final InputStream in , final boolean returnAccumulatedForBitReadInEof ) {
100+ this (in , JBBPBitOrder .LSB0 , returnAccumulatedForBitReadInEof );
108101 }
109102
110103 /**
111104 * 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>
112106 *
113107 * @param in an input stream to be filtered.
114108 * @param order a bit order mode for the filter.
115109 * @see JBBPBitOrder#LSB0
116110 * @see JBBPBitOrder#MSB0
117111 */
118112 public JBBPBitInputStream (final InputStream in , final JBBPBitOrder order ) {
113+ this (in , order , true );
114+ }
115+ 116+ /**
117+ * Create wrapping bit input stream.
118+ *
119+ * @param in the base input stream, must not be null
120+ * @param order a bit order mode for the filter.
121+ * @param returnAccumulatedForBitReadInEof if true then end of stream during bit read and some data missing returns accumulated data.
122+ * @since 3.1.0
123+ */
124+ public JBBPBitInputStream (final InputStream in , final JBBPBitOrder order ,
125+ final boolean returnAccumulatedForBitReadInEof ) {
119126 super (in );
120127 this .bitsInBuffer = 0 ;
121128 this .bitOrderMode = order ;
129+ this .returnAccumulatedForBitReadInEof = returnAccumulatedForBitReadInEof ;
130+ }
131+ 132+ /**
133+ * 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.
134+ *
135+ * @return boolean flag for the behavior, true if allowed
136+ * @since 3.1.0
137+ */
138+ public boolean isReturnAccumulatedForBitReadInEof () {
139+ return this .returnAccumulatedForBitReadInEof ;
140+ }
141+ 142+ /**
143+ * Flag shows that read of array was stopped for array limiter restrictions.
144+ *
145+ * @return true if array limiter restrictions detected, false otherwise
146+ * @see JBBPArraySizeLimiter
147+ * @since 2.1.0
148+ */
149+ public boolean isDetectedArrayLimit () {
150+ return this .detectedArrayLimit ;
151+ }
152+ 153+ /**
154+ * Set value for array limit detected flag. It is important to set the flag for correct processing of parsing.
155+ *
156+ * @param value true or false.
157+ * @see com.igormaznitsa.jbbp.JBBPParser
158+ * @since 2.1.0
159+ */
160+ public void setDetectedArrayLimit (final boolean value ) {
161+ this .detectedArrayLimit = value ;
122162 }
123163
124164 /**
@@ -198,7 +238,7 @@ public boolean[] readBoolArray(final int items,
198238
199239 @ Override
200240 public int read (final byte [] array , final int offset , final int length ) throws IOException {
201- return this .read (array , offset , length , true );
241+ return this .read (array , offset , length , this . returnAccumulatedForBitReadInEof );
202242 }
203243
204244 /**
@@ -210,13 +250,13 @@ public int read(final byte[] array, final int offset, final int length) throws I
210250 * @param array target array
211251 * @param offset offset in the target array
212252 * @param length the length of data portion to be read
213- * @param allowEofForMissingBitData if true then allow to stop read if missing data for non-complete read bits operation .
253+ * @param returnAccumulatedForBitReadInEof if true then return accumulated data if end of stream during bit read, return -1 otherwise .
214254 * @return number of read bytes from the wrapped input stream
215255 * @throws IOException thrown if any transport error
216- * @since 3.0.1
256+ * @since 3.1.0
217257 */
218258 public int read (final byte [] array , final int offset , final int length ,
219- final boolean allowEofForMissingBitData ) throws IOException {
259+ final boolean returnAccumulatedForBitReadInEof ) throws IOException {
220260 if (this .bitsInBuffer == 0 ) {
221261 int readBytes = 0 ;
222262 int tempOffset = offset ;
@@ -248,7 +288,7 @@ public int read(final byte[] array, final int offset, final int length,
248288 int count = length ;
249289 int i = offset ;
250290 while (count > 0 ) {
251- final int nextByte = this .readBits (JBBPBitNumber .BITS_8 , allowEofForMissingBitData );
291+ final int nextByte = this .readBits (JBBPBitNumber .BITS_8 , returnAccumulatedForBitReadInEof );
252292 if (nextByte < 0 ) {
253293 break ;
254294 }
@@ -383,7 +423,7 @@ private byte[] internalReadArray(
383423 byte [] buffer = new byte [INITIAL_ARRAY_BUFFER_SIZE ];
384424 // till end
385425 while (true ) {
386- final int next = readByteArray ? read () : this .readBits (bitNumber , true );
426+ final int next = readByteArray ? read () : this .readBits (bitNumber , this . returnAccumulatedForBitReadInEof );
387427 if (next < 0 ) {
388428 break ;
389429 }
@@ -415,7 +455,7 @@ private byte[] internalReadArray(
415455 }
416456 } else {
417457 for (int i = 0 ; i < items ; i ++) {
418- final int next = this .readBits (bitNumber , true );
458+ final int next = this .readBits (bitNumber , this . returnAccumulatedForBitReadInEof );
419459 if (next < 0 ) {
420460 throw new EOFException ("Have read only " + i + " bit portions instead of " + items );
421461 }
@@ -951,7 +991,7 @@ public JBBPBitOrder getBitOrder() {
951991 * @since 1.3.0
952992 */
953993 public byte readBitField (final JBBPBitNumber numOfBitsToRead ) throws IOException {
954- final int value = this .readBits (numOfBitsToRead , true );
994+ final int value = this .readBits (numOfBitsToRead , this . returnAccumulatedForBitReadInEof );
955995 if (value < 0 ) {
956996 throw new EOFException ("Can't read bits from stream [" + numOfBitsToRead + ']' );
957997 }
@@ -971,7 +1011,7 @@ public byte readBitField(final JBBPBitNumber numOfBitsToRead) throws IOException
9711011 * @throws NullPointerException if number of bits to be read is null
9721012 */
9731013 public int readBits (final JBBPBitNumber numOfBitsToRead ) throws IOException {
974- return this .readBits (numOfBitsToRead , false );
1014+ return this .readBits (numOfBitsToRead , this . returnAccumulatedForBitReadInEof );
9751015 }
9761016
9771017 /**
@@ -980,13 +1020,13 @@ public int readBits(final JBBPBitNumber numOfBitsToRead) throws IOException {
9801020 * Behaviour in case of missing bit data can be tuned by the special argument flag and if it is true then -1 returned otherwise current accumulated bit data returned.
9811021 *
9821022 * @param numOfBitsToRead the number of bits to be read, must be 1..8
983- * @param allowEofForMissingBitData if false then returned current accumulated data as stream ended with missing bits, -1 otherwise
1023+ * @param returnAccumulatedForBitReadInEof if false then returned current accumulated data as stream ended with missing bits, -1 otherwise
9841024 * @return the read bits as integer, -1 if the end of stream has been reached or if allowed end of stream flag and not all bits read.
9851025 * @throws IOException it will be thrown for transport errors to be read
9861026 * @throws NullPointerException if number of bits to be read is null
9871027 * @since 3.0.1
9881028 */
989- public int readBits (final JBBPBitNumber numOfBitsToRead , final boolean allowEofForMissingBitData )
1029+ public int readBits (final JBBPBitNumber numOfBitsToRead , final boolean returnAccumulatedForBitReadInEof )
9901030 throws IOException {
9911031 int result ;
9921032
@@ -1028,12 +1068,12 @@ public int readBits(final JBBPBitNumber numOfBitsToRead, final boolean allowEofF
10281068 if (i == numOfBitsAsNumber ) {
10291069 return nextByte ;
10301070 } else {
1031- if (allowEofForMissingBitData ) {
1071+ if (returnAccumulatedForBitReadInEof ) {
1072+ break ;
1073+ } else {
10321074 this .bitBuffer = 0 ;
10331075 this .bitsInBuffer = 0 ;
10341076 return -1 ;
1035- } else {
1036- break ;
10371077 }
10381078 }
10391079 } else {
@@ -1058,12 +1098,12 @@ public int readBits(final JBBPBitNumber numOfBitsToRead, final boolean allowEofF
10581098 if (i == numOfBitsAsNumber ) {
10591099 return nextByte ;
10601100 } else {
1061- if (allowEofForMissingBitData ) {
1101+ if (returnAccumulatedForBitReadInEof ) {
1102+ break ;
1103+ } else {
10621104 this .bitBuffer = 0 ;
10631105 this .bitsInBuffer = 0 ;
10641106 return -1 ;
1065- } else {
1066- break ;
10671107 }
10681108 }
10691109 } else {
0 commit comments