Skip to content

Commit 86152ec

Browse files
committed
Add bit switch feature
1 parent c6c0f06 commit 86152ec

File tree

4 files changed

+60
-0
lines changed

4 files changed

+60
-0
lines changed

CHANGELOG

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
* better type hierarchy with read-only and mutable types
66
* add validator feature
7+
* add bit switch feature
78

89
## v0.2.0
910

src/main/java/at/favre/lib/bytes/Bytes.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -689,6 +689,17 @@ public Bytes resize(int newByteLength) {
689689
return transform(new BytesTransformer.ResizeTransformer(newByteLength));
690690
}
691691

692+
/**
693+
* Returns a Byte whose value is equivalent to this Byte with the designated bit switched to newBitValue. Bits start to count from the LSB (ie. Bytes.from(0).switchBit(0,true) == 1)
694+
*
695+
* @param bitPosition not to confuse with byte position
696+
* @param newBitValue if true set to 1, 0 otherwise
697+
* @return instance with bit switched
698+
*/
699+
public Bytes switchBit(int bitPosition, boolean newBitValue) {
700+
return transform(new BytesTransformer.BitSwitchTransformer(bitPosition, newBitValue));
701+
}
702+
692703
/**
693704
* Generic transformation of this instance.
694705
* <p>

src/main/java/at/favre/lib/bytes/BytesTransformer.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -284,4 +284,35 @@ public byte[] transform(byte[] currentArray, boolean inPlace) {
284284
return resizedArray;
285285
}
286286
}
287+
288+
/**
289+
* Switches bits on specific position of an array
290+
*/
291+
class BitSwitchTransformer implements BytesTransformer {
292+
private final int position;
293+
private final boolean newBitValue;
294+
295+
BitSwitchTransformer(int position, boolean newBitValue) {
296+
this.position = position;
297+
this.newBitValue = newBitValue;
298+
}
299+
300+
@Override
301+
public byte[] transform(byte[] currentArray, boolean inPlace) {
302+
byte[] out = inPlace ? currentArray : Bytes.from(currentArray).array();
303+
304+
if (position < 0 || position >= 8 * currentArray.length) {
305+
throw new IllegalArgumentException("bit index " + (position * 8) + " out of bounds");
306+
}
307+
308+
309+
int bytePosition = currentArray.length - 1 - position / 8;
310+
if (newBitValue) {
311+
out[bytePosition] ^= (1 << position % 8);
312+
} else {
313+
out[bytePosition] &= ~(1 << position % 8);
314+
}
315+
return out;
316+
}
317+
}
287318
}

src/test/java/at/favre/lib/bytes/BytesTransformTest.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
import org.junit.Test;
2525

26+
import java.math.BigInteger;
2627
import java.nio.ByteBuffer;
2728
import java.security.SecureRandom;
2829
import java.util.Comparator;
@@ -241,6 +242,22 @@ public void rightShift() throws Exception {
241242
assertArrayEquals(new byte[1], Bytes.from(example_bytes_two).rightShift(16).array());
242243
}
243244

245+
@Test
246+
public void bitSwitch() throws Exception {
247+
assertEquals(1, Bytes.from(0).switchBit(0, true).toInt());
248+
249+
for (int i = 0; i < 63; i++) {
250+
for (long j = 1; j < 33; j++) {
251+
assertEquals("bit position " + i + " is wrong",
252+
BigInteger.valueOf(j).flipBit(i).longValue(),
253+
Bytes.from(j).switchBit(i, true).toLong());
254+
assertEquals("bit position " + i + " is wrong",
255+
BigInteger.valueOf(j).clearBit(i).longValue(),
256+
Bytes.from(j).switchBit(i, false).toLong());
257+
}
258+
}
259+
}
260+
244261
@Test
245262
public void transform() throws Exception {
246263
assertArrayEquals(example_bytes_two, Bytes.from(example_bytes_two).transform(new BytesTransformer() {

0 commit comments

Comments
 (0)