Skip to content

Commit 0611f40

Browse files
committed
changed default behavior for missing data when reading bit fields at the end of a stream
1 parent 92e48df commit 0611f40

File tree

2 files changed

+129
-36
lines changed

2 files changed

+129
-36
lines changed

jbbp/src/main/java/com/igormaznitsa/jbbp/io/JBBPBitInputStream.java

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,25 @@ public boolean[] readBoolArray(final int items,
198198

199199
@Override
200200
public int read(final byte[] array, final int offset, final int length) throws IOException {
201+
return this.read(array, offset, length, true);
202+
}
203+
204+
/**
205+
* Reads up to {@code len} bytes of data from this input stream
206+
* into an array of bytes. If {@code len} is not zero, the method
207+
* blocks until some input is available; otherwise, no
208+
* bytes are read and {@code 0} is returned.
209+
*
210+
* @param array target array
211+
* @param offset offset in the target array
212+
* @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.
214+
* @return number of read bytes from the wrapped input stream
215+
* @throws IOException thrown if any transport error
216+
* @since 3.0.1
217+
*/
218+
public int read(final byte[] array, final int offset, final int length,
219+
final boolean allowEofForMissingBitData) throws IOException {
201220
if (this.bitsInBuffer == 0) {
202221
int readBytes = 0;
203222
int tempOffset = offset;
@@ -229,7 +248,7 @@ public int read(final byte[] array, final int offset, final int length) throws I
229248
int count = length;
230249
int i = offset;
231250
while (count > 0) {
232-
final int nextByte = this.readBits(JBBPBitNumber.BITS_8);
251+
final int nextByte = this.readBits(JBBPBitNumber.BITS_8, allowEofForMissingBitData);
233252
if (nextByte < 0) {
234253
break;
235254
}
@@ -364,7 +383,7 @@ private byte[] internalReadArray(
364383
byte[] buffer = new byte[INITIAL_ARRAY_BUFFER_SIZE];
365384
// till end
366385
while (true) {
367-
final int next = readByteArray ? read() : readBits(bitNumber);
386+
final int next = readByteArray ? read() : this.readBits(bitNumber, true);
368387
if (next < 0) {
369388
break;
370389
}
@@ -396,7 +415,7 @@ private byte[] internalReadArray(
396415
}
397416
} else {
398417
for (int i = 0; i < items; i++) {
399-
final int next = readBits(bitNumber);
418+
final int next = this.readBits(bitNumber, true);
400419
if (next < 0) {
401420
throw new EOFException("Have read only " + i + " bit portions instead of " + items);
402421
}
@@ -932,7 +951,7 @@ public JBBPBitOrder getBitOrder() {
932951
* @since 1.3.0
933952
*/
934953
public byte readBitField(final JBBPBitNumber numOfBitsToRead) throws IOException {
935-
final int value = this.readBits(numOfBitsToRead);
954+
final int value = this.readBits(numOfBitsToRead, true);
936955
if (value < 0) {
937956
throw new EOFException("Can't read bits from stream [" + numOfBitsToRead + ']');
938957
}
@@ -951,7 +970,23 @@ public byte readBitField(final JBBPBitNumber numOfBitsToRead) throws IOException
951970
* @throws IOException it will be thrown for transport errors to be read
952971
* @throws NullPointerException if number of bits to be read is null
953972
*/
954-
public int readBits(final JBBPBitNumber numOfBitsToRead)
973+
public int readBits(final JBBPBitNumber numOfBitsToRead) throws IOException {
974+
return this.readBits(numOfBitsToRead, false);
975+
}
976+
977+
/**
978+
* Read number of bits from the input stream. It reads bits from input stream
979+
* since 0 bit and make reversion to return bits in the order according the thread mode.
980+
* 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.
981+
*
982+
* @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
984+
* @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.
985+
* @throws IOException it will be thrown for transport errors to be read
986+
* @throws NullPointerException if number of bits to be read is null
987+
* @since 3.0.1
988+
*/
989+
public int readBits(final JBBPBitNumber numOfBitsToRead, final boolean allowEofForMissingBitData)
955990
throws IOException {
956991
int result;
957992

@@ -993,7 +1028,13 @@ public int readBits(final JBBPBitNumber numOfBitsToRead)
9931028
if (i == numOfBitsAsNumber) {
9941029
return nextByte;
9951030
} else {
996-
break;
1031+
if (allowEofForMissingBitData) {
1032+
this.bitBuffer = 0;
1033+
this.bitsInBuffer = 0;
1034+
return -1;
1035+
} else {
1036+
break;
1037+
}
9971038
}
9981039
} else {
9991040
theBitBuffer = nextByte;
@@ -1017,7 +1058,13 @@ public int readBits(final JBBPBitNumber numOfBitsToRead)
10171058
if (i == numOfBitsAsNumber) {
10181059
return nextByte;
10191060
} else {
1020-
break;
1061+
if (allowEofForMissingBitData) {
1062+
this.bitBuffer = 0;
1063+
this.bitsInBuffer = 0;
1064+
return -1;
1065+
} else {
1066+
break;
1067+
}
10211068
}
10221069
} else {
10231070
theBitBuffer = nextByte;

0 commit comments

Comments
 (0)