Skip to content

Commit 27a2b0c

Browse files
committed
Add clear method and fix issue with Integer/Long max and min value
1 parent badde3a commit 27a2b0c

File tree

3 files changed

+123
-56
lines changed

3 files changed

+123
-56
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Bit-lib4j [![Build Status](https://travis-ci.org/devnied/Bit-lib4j.png?branch=ma
44
Bit-Lib4j is an useful library to handle bytes or bits in Java.<br/>
55
With this library you can read/write data in a byte array with a custom size for Java primitive types.
66

7-
<b>Current version : 1.4.11</b>
7+
<b>Current version : 1.4.12</b>
88

99
##Simple API
1010

@@ -44,7 +44,7 @@ More documentation into the [wiki](https://github.com/devnied/Bit-lib4j/wiki)
4444
<dependency>
4545
<groupId>com.github.devnied</groupId>
4646
<artifactId>bit-lib4j</artifactId>
47-
<version>1.4.11</version>
47+
<version>1.4.12</version>
4848
</dependency>
4949
```
5050

src/main/java/fr/devnied/bitlib/BitUtils.java

Lines changed: 75 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import java.nio.charset.Charset;
55
import java.text.ParseException;
66
import java.text.SimpleDateFormat;
7+
import java.util.Arrays;
78
import java.util.Date;
89

910
import org.slf4j.Logger;
@@ -150,8 +151,10 @@ public boolean getNextBoolean() {
150151
}
151152

152153
/**
153-
* Method used to get the next byte and shift read data to the beginning of the array.<br>
154-
* (Ex 00110000b if we start read 2 bit at index 2 the data returned will be 11000000b)
154+
* Method used to get the next byte and shift read data to the beginning of
155+
* the array.<br>
156+
* (Ex 00110000b if we start read 2 bit at index 2 the data returned will be
157+
* 11000000b)
155158
*
156159
* @param pSize
157160
* the size in bit to read
@@ -167,10 +170,13 @@ public byte[] getNextByte(final int pSize) {
167170
* @param pSize
168171
* the size in bit to read
169172
* @param pShift
170-
* boolean to indicate if the data read will be shift to the left.<br>
173+
* boolean to indicate if the data read will be shift to the
174+
* left.<br>
171175
* <ul>
172-
* <li>if true : (Ex 10110000b if we start read 2 bit at index 2 the returned data will be 11000000b)</li>
173-
* <li>if false : (Ex 10110000b if we start read 2 bit at index 2 the returned data will be 00110000b)</li>
176+
* <li>if true : (Ex 10110000b if we start read 2 bit at index 2
177+
* the returned data will be 11000000b)</li>
178+
* <li>if false : (Ex 10110000b if we start read 2 bit at index 2
179+
* the returned data will be 00110000b)</li>
174180
* </ul>
175181
* @return a byte array
176182
*/
@@ -267,7 +273,6 @@ public String getNextHexaString(final int pSize) {
267273
return BytesUtils.bytesToStringNoSpace(getNextByte(pSize, true));
268274
}
269275

270-
271276
/**
272277
* This method is used to get an long with the specified size
273278
*
@@ -278,38 +283,38 @@ public String getNextHexaString(final int pSize) {
278283
* @return an long
279284
*/
280285
public long getNextLong(final int pLength) {
281-
// allocate Size of Integer
282-
ByteBuffer buffer = ByteBuffer.allocate(BYTE_SIZE * 2);
283-
// final value
284-
long finalValue = 0;
285-
// Incremental value
286-
long currentValue = 0;
287-
// Size to read
288-
int readSize = pLength;
289-
// length max of the index
290-
int max = currentBitIndex + pLength;
291-
while (currentBitIndex < max) {
292-
int mod = currentBitIndex % BYTE_SIZE;
293-
// apply the mask to the selected byte
294-
currentValue = byteTab[currentBitIndex / BYTE_SIZE] & getMask(mod, readSize) & DEFAULT_VALUE;
295-
// Shift right the read value
296-
int dec = Math.max(BYTE_SIZE - (mod + readSize), 0);
297-
currentValue = (currentValue & DEFAULT_VALUE) >>> dec & DEFAULT_VALUE;
298-
// Shift left the previously read value and add the current value
299-
finalValue = finalValue << Math.min(readSize, BYTE_SIZE) | currentValue;
300-
// calculate read value size
301-
int val = BYTE_SIZE - mod;
302-
// Decrease the size left
303-
readSize = readSize - val;
304-
currentBitIndex = Math.min(currentBitIndex + val, max);
305-
}
306-
buffer.putLong(finalValue);
307-
// reset the current bytebuffer index to 0
308-
buffer.rewind();
309-
// return integer
310-
return buffer.getLong();
286+
// allocate Size of Integer
287+
ByteBuffer buffer = ByteBuffer.allocate(BYTE_SIZE * 2);
288+
// final value
289+
long finalValue = 0;
290+
// Incremental value
291+
long currentValue = 0;
292+
// Size to read
293+
int readSize = pLength;
294+
// length max of the index
295+
int max = currentBitIndex + pLength;
296+
while (currentBitIndex < max) {
297+
int mod = currentBitIndex % BYTE_SIZE;
298+
// apply the mask to the selected byte
299+
currentValue = byteTab[currentBitIndex / BYTE_SIZE] & getMask(mod, readSize) & DEFAULT_VALUE;
300+
// Shift right the read value
301+
int dec = Math.max(BYTE_SIZE - (mod + readSize), 0);
302+
currentValue = (currentValue & DEFAULT_VALUE) >>> dec & DEFAULT_VALUE;
303+
// Shift left the previously read value and add the current value
304+
finalValue = finalValue << Math.min(readSize, BYTE_SIZE) | currentValue;
305+
// calculate read value size
306+
int val = BYTE_SIZE - mod;
307+
// Decrease the size left
308+
readSize = readSize - val;
309+
currentBitIndex = Math.min(currentBitIndex + val, max);
310+
}
311+
buffer.putLong(finalValue);
312+
// reset the current bytebuffer index to 0
313+
buffer.rewind();
314+
// return integer
315+
return buffer.getLong();
311316
}
312-
317+
313318
/**
314319
* This method is used to get an integer with the specified size
315320
*
@@ -324,7 +329,8 @@ public int getNextInteger(final int pLength) {
324329
}
325330

326331
/**
327-
* This method is used to get the next String with the specified size with the charset ASCII
332+
* This method is used to get the next String with the specified size with
333+
* the charset ASCII
328334
*
329335
* @param pSize
330336
* the length of the string in bit
@@ -363,6 +369,14 @@ public void reset() {
363369
setCurrentBitIndex(0);
364370
}
365371

372+
/**
373+
* Method used to clear data and reset current bit index
374+
*/
375+
public void clear() {
376+
Arrays.fill(byteTab, (byte) 0);
377+
reset();
378+
}
379+
366380
/**
367381
* Set to 0 the next N bits
368382
*
@@ -423,7 +437,7 @@ public void setNextByte(final byte[] pValue, final int pLength) {
423437
* @param pLength
424438
* the length of the data in bits
425439
* @param pPadBefore
426-
* if true pad with 0
440+
* if true pad with 0
427441
*/
428442
public void setNextByte(final byte[] pValue, final int pLength, final boolean pPadBefore) {
429443
int totalSize = (int) Math.ceil(pLength / BYTE_SIZE_F);
@@ -510,14 +524,14 @@ public void setNextDate(final Date pValue, final String pPattern, final boolean
510524
public void setNextHexaString(final String pValue, final int pLength) {
511525
setNextByte(BytesUtils.fromString(pValue), pLength);
512526
}
513-
527+
514528
/**
515529
* Add Long to the current position with the specified size
516530
*
517531
* Be careful with java long bit sign
518532
*
519533
* @param pValue
520-
* the value to set
534+
* the value to set
521535
*
522536
* @param pLength
523537
* the length of the long
@@ -528,19 +542,25 @@ public void setNextLong(final long pValue, final int pLength) {
528542
throw new IllegalArgumentException("Long overflow with length > 64");
529543
}
530544

531-
setNextValue(pValue, pLength);
545+
setNextValue(pValue, pLength, Long.SIZE - 1);
532546
}
533-
547+
534548
/**
535549
* Add Value to the current position with the specified size
536-
* @param pValue value to add
537-
* @param pLength length of the value
550+
*
551+
* @param pValue
552+
* value to add
553+
* @param pLength
554+
* length of the value
555+
* @param pMaxSize
556+
* max size in bits
538557
*/
539-
protected void setNextValue(final long pValue, final int pLength){
558+
protected void setNextValue(final long pValue, final int pLength, final int pMaxSize) {
540559
long value = pValue;
541560
// Set to max value if pValue cannot be stored on pLength bits.
542-
if (pValue >= 1 << pLength) {
543-
value = (1 << pLength) - 1;
561+
long bitMax = (long) Math.pow(2, Math.min(pLength, pMaxSize));
562+
if (pValue > bitMax) {
563+
value = bitMax - 1;
544564
}
545565
// size to wrote
546566
int writeSize = pLength;
@@ -568,6 +588,9 @@ protected void setNextValue(final long pValue, final int pLength){
568588
*
569589
* Be careful with java integer bit sign
570590
*
591+
* @param pValue
592+
* the value to set
593+
*
571594
* @param pLength
572595
* the length of the integer
573596
*/
@@ -577,14 +600,17 @@ public void setNextInteger(final int pValue, final int pLength) {
577600
throw new IllegalArgumentException("Integer overflow with length > 32");
578601
}
579602

580-
setNextValue(pValue, pLength);
603+
setNextValue(pValue, pLength, Integer.SIZE - 1);
581604
}
582605

583606
/**
584607
* Method to write String
585608
*
586609
* @param pValue
587610
* the string to write
611+
*
612+
* @param pLength
613+
* the length of the integer
588614
*/
589615
public void setNextString(final String pValue, final int pLength) {
590616
setNextString(pValue, pLength, true);

src/test/java/fr/devnied/bitlib/BitUtilsTest.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -291,23 +291,47 @@ public void testSetInteger() {
291291
Assertions.assertThat(bit.getNextInteger(1)).isEqualTo(0);
292292
Assertions.assertThat(bit.getNextInteger(1)).isEqualTo(1);
293293

294-
bit.reset();
294+
bit.clear();
295295
try {
296296
bit.setNextInteger(500, 33);
297297
Assert.fail();
298298
} catch (IllegalArgumentException iae) {
299299
}
300+
bit.clear();
301+
bit.setNextInteger(127, 5);
302+
bit.reset();
303+
Assertions.assertThat(bit.getNextInteger(5)).isEqualTo(31);
300304
}
301305

302306
@Test
303-
public void testMaxMinValue(){
307+
public void testOverflowValueInSize() {
304308
BitUtils bit = new BitUtils(64);
305-
bit.setNextHexaString("FFFFFFFF", 32);
309+
bit.setNextInteger(Integer.MAX_VALUE, 3);
310+
bit.reset();
311+
Assertions.assertThat(bit.getNextInteger(3)).isEqualTo(7);
312+
313+
bit.clear();
314+
bit.setNextLong(Long.MAX_VALUE, 40);
306315
bit.reset();
307-
Assertions.assertThat(bit.getNextInteger(32)).isEqualTo(-1);
316+
Assertions.assertThat(bit.getNextLong(40)).isEqualTo(1099511627775L);
308317
}
309-
310318

319+
@Test
320+
public void testMaxMinValueInteger() {
321+
BitUtils bit = new BitUtils(64);
322+
bit.setNextInteger(Integer.MIN_VALUE, 32);
323+
bit.reset();
324+
Assertions.assertThat(bit.getNextHexaString(32)).isEqualTo("80000000");
325+
bit.reset();
326+
Assertions.assertThat(bit.getNextInteger(32)).isEqualTo(Integer.MIN_VALUE);
327+
328+
bit.clear();
329+
bit.setNextInteger(Integer.MAX_VALUE, 32);
330+
bit.reset();
331+
Assertions.assertThat(bit.getNextHexaString(32)).isEqualTo("7FFFFFFF");
332+
bit.reset();
333+
Assertions.assertThat(bit.getNextInteger(32)).isEqualTo(Integer.MAX_VALUE);
334+
}
311335

312336
/**
313337
* Test the method to set an long
@@ -380,6 +404,23 @@ public void testSetLong() {
380404
}
381405
}
382406

407+
@Test
408+
public void testMaxMinValueLong() {
409+
BitUtils bit = new BitUtils(64);
410+
bit.setNextLong(Long.MIN_VALUE, 64);
411+
bit.reset();
412+
Assertions.assertThat(bit.getNextHexaString(64)).isEqualTo("8000000000000000");
413+
bit.reset();
414+
Assertions.assertThat(bit.getNextLong(64)).isEqualTo(Long.MIN_VALUE);
415+
416+
bit.clear();
417+
bit.setNextLong(Long.MAX_VALUE, 64);
418+
bit.reset();
419+
Assertions.assertThat(bit.getNextHexaString(64)).isEqualTo("7FFFFFFFFFFFFFFF");
420+
bit.reset();
421+
Assertions.assertThat(bit.getNextLong(64)).isEqualTo(Long.MAX_VALUE);
422+
}
423+
383424
@Test
384425
public void testLongMaxMinValue(){
385426
BitUtils bit = new BitUtils(64);

0 commit comments

Comments
 (0)