You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2022/05/27 15:19:55 UTC
[commons-lang] 01/03: Rewrite method to be the same as binaryToHexDigit but working from the end of the array backwards.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-lang.git
commit cf7c9522aa99d0d180e54ac5abe849f19d153d25
Author: Arturo Bernal <ar...@gmail.com>
AuthorDate: Thu Apr 7 10:48:49 2022 +0200
Rewrite method to be the same as binaryToHexDigit but working from the end of the array backwards.
---
.../java/org/apache/commons/lang3/Conversion.java | 50 +++++++++++-----------
.../org/apache/commons/lang3/ConversionTest.java | 28 ++++++++++++
2 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/src/main/java/org/apache/commons/lang3/Conversion.java b/src/main/java/org/apache/commons/lang3/Conversion.java
index e71070131..47b1a5799 100644
--- a/src/main/java/org/apache/commons/lang3/Conversion.java
+++ b/src/main/java/org/apache/commons/lang3/Conversion.java
@@ -435,39 +435,41 @@ public class Conversion {
* @return a hexadecimal digit representing the selected bits
* @throws IllegalArgumentException if {@code src} is empty
* @throws NullPointerException if {@code src} is {@code null}
+ * @throws IndexOutOfBoundsException if {@code srcPos} is outside the array.
*/
public static char binaryBeMsb0ToHexDigit(boolean[] src, int srcPos) {
- if (src.length == 0) {
- throw new IllegalArgumentException("Cannot convert an empty array.");
- }
- final int beSrcPos = src.length - 1 - srcPos;
- final int srcLen = Math.min(4, beSrcPos + 1);
- final boolean[] paddedSrc = new boolean[4];
- System.arraycopy(src, beSrcPos + 1 - srcLen, paddedSrc, 4 - srcLen, srcLen);
- src = paddedSrc;
- srcPos = 0;
- if (src[srcPos]) {
- if (src.length > srcPos + 1 && src[srcPos + 1]) {
- if (src.length > srcPos + 2 && src[srcPos + 2]) {
- return src.length > srcPos + 3 && src[srcPos + 3] ? 'f' : 'e';
+ // JDK 9: Objects.checkIndex(int index, int length)
+ if (Integer.compareUnsigned(srcPos, src.length) >= 0) {
+ // Throw the correct exception
+ if (src.length == 0) {
+ throw new IllegalArgumentException("Cannot convert an empty array.");
+ }
+ throw new IndexOutOfBoundsException(srcPos + " is not within array length " + src.length);
+ }
+ // Little-endian bit 0 position
+ final int pos = src.length - 1 - srcPos;
+ if (3 <= pos && src[pos - 3]) {
+ if (src[pos - 2]) {
+ if (src[pos - 1]) {
+ return src[pos] ? 'f' : 'e';
}
- return src.length > srcPos + 3 && src[srcPos + 3] ? 'd' : 'c';
+ return src[pos] ? 'd' : 'c';
}
- if (src.length > srcPos + 2 && src[srcPos + 2]) {
- return src.length > srcPos + 3 && src[srcPos + 3] ? 'b' : 'a';
+ if (src[pos - 1]) {
+ return src[pos] ? 'b' : 'a';
}
- return src.length > srcPos + 3 && src[srcPos + 3] ? '9' : '8';
+ return src[pos] ? '9' : '8';
}
- if (src.length > srcPos + 1 && src[srcPos + 1]) {
- if (src.length > srcPos + 2 && src[srcPos + 2]) {
- return src.length > srcPos + 3 && src[srcPos + 3] ? '7' : '6';
+ if (2 <= pos && src[pos - 2]) {
+ if (src[pos - 1]) {
+ return src[pos] ? '7' : '6';
}
- return src.length > srcPos + 3 && src[srcPos + 3] ? '5' : '4';
+ return src[pos] ? '5' : '4';
}
- if (src.length > srcPos + 2 && src[srcPos + 2]) {
- return src.length > srcPos + 3 && src[srcPos + 3] ? '3' : '2';
+ if (1 <= pos && src[pos - 1]) {
+ return src[pos] ? '3' : '2';
}
- return src.length > srcPos + 3 && src[srcPos + 3] ? '1' : '0';
+ return src[pos] ? '1' : '0';
}
/**
diff --git a/src/test/java/org/apache/commons/lang3/ConversionTest.java b/src/test/java/org/apache/commons/lang3/ConversionTest.java
index 59b372bd6..ec104e6dd 100644
--- a/src/test/java/org/apache/commons/lang3/ConversionTest.java
+++ b/src/test/java/org/apache/commons/lang3/ConversionTest.java
@@ -20,9 +20,13 @@ import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import java.util.Arrays;
+import java.util.SplittableRandom;
import java.util.UUID;
import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
/**
@@ -413,6 +417,30 @@ public class ConversionTest {
}
+ @Test
+ public void testBinaryToHexDigitReverse() {
+ final SplittableRandom rng = new SplittableRandom();
+ final boolean[] x = new boolean[8];
+ for (int i = 0; i < 100; i++) {
+ Conversion.longToBinary(rng.nextLong(), 0, x, 0, 8);
+ for (int j = 1; j <= 8; j++) {
+ final boolean[] a = Arrays.copyOf(x, j);
+ final boolean[] b = a.clone();
+ ArrayUtils.reverse(b);
+ for (int k = 0; k < j; k++) {
+ assertEquals(Conversion.binaryToHexDigit(a, k),
+ Conversion.binaryBeMsb0ToHexDigit(b, k));
+ }
+ }
+ }
+ }
+
+ @ParameterizedTest
+ @ValueSource(ints = {-1, 8, 99})
+ public void binaryBeMsb0ToHexDigitPosOutsideArray(int index) {
+ assertThrows(IndexOutOfBoundsException.class,
+ () -> Conversion.binaryBeMsb0ToHexDigit(new boolean[8], index));
+ }
/**
* Tests {@link Conversion#intToHexDigit(int)}.
*/