Skip to content

Commit 2799f49

Browse files
committed
added flag isDetectedPartlyReadBitField into JBBPInputStream to detect that only part of data read during last read operation
1 parent 1526228 commit 2799f49

File tree

2 files changed

+56
-21
lines changed

2 files changed

+56
-21
lines changed

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

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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;

jbbp/src/test/java/com/igormaznitsa/jbbp/io/JBBPBitInputStreamTest.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1622,7 +1622,9 @@ public void testReadNotFullByteArrayAfterBitReading_disableAccumulatedBitsOnEof(
16221622
assertEquals(0, in.getCounter());
16231623

16241624
final byte[] readArray = new byte[6];
1625+
assertFalse(in.isDetectedPartlyReadBitField());
16251626
final int read = in.read(readArray, 0, readArray.length);
1627+
assertTrue(in.isDetectedPartlyReadBitField());
16261628
assertEquals(3, read);
16271629
assertEquals(4, in.getCounter());
16281630

@@ -1644,7 +1646,9 @@ public void testReadNotFullByteArrayAfterBitReading_MSB0_disableAccumulatedBitsO
16441646
assertEquals(0, in.getCounter());
16451647

16461648
final byte[] readArray = new byte[6];
1649+
assertFalse(in.isDetectedPartlyReadBitField());
16471650
final int read = in.read(readArray, 0, readArray.length);
1651+
assertTrue(in.isDetectedPartlyReadBitField());
16481652
assertEquals(3, read);
16491653
assertEquals(4, in.getCounter());
16501654

@@ -1665,7 +1669,9 @@ public void testReadNotFullByteArrayAfterBitReading()
16651669
assertEquals(0, in.getCounter());
16661670

16671671
final byte[] readarray = new byte[6];
1672+
assertFalse(in.isDetectedPartlyReadBitField());
16681673
final int read = in.read(readarray, 0, readarray.length, true);
1674+
assertTrue(in.isDetectedPartlyReadBitField());
16691675
assertEquals(4, read);
16701676
assertEquals(4, in.getCounter());
16711677
assertArrayEquals(new byte[] {(byte) 0x41, (byte) 0x63, (byte) 0xD5, (byte) 0x0D, 0, 0},
@@ -1681,8 +1687,9 @@ public void testReadNotFullByteArrayAfterBitReading_MSB0()
16811687
assertEquals(0x8, in.readBits(BITS_4));
16821688

16831689
final byte[] readarray = new byte[6];
1690+
assertFalse(in.isDetectedPartlyReadBitField());
16841691
final int read = in.read(readarray, 0, readarray.length);
1685-
1692+
assertTrue(in.isDetectedPartlyReadBitField());
16861693
assertEquals(4, read);
16871694
assertEquals(4, in.getCounter());
16881695

0 commit comments

Comments
 (0)