Skip to content

Commit ef3d5d9

Browse files
committed
Add ArrayUtils.startsWith()
1 parent 4d77a45 commit ef3d5d9

File tree

3 files changed

+65
-0
lines changed

3 files changed

+65
-0
lines changed

src/changes/changes.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ The <action> type attribute can be add,update,fix,remove.
8787
<action type="add" dev="ggregory" due-to="Gary Gregory">Add SystemUtils.IS_OS_MAC_OSX_SEQUOIA.</action>
8888
<action type="add" dev="ggregory" due-to="Gary Gregory">Add BasicThreadFactory.builder() and deprecate BasicThreadFactory.Builder().</action>
8989
<action type="add" dev="ggregory" due-to="Gary Gregory">Add BasicThreadFactory.daemon().</action>
90+
<action type="add" dev="ggregory" due-to="Gary Gregory">Add ArrayUtils.startsWith.</action>
9091
<!-- UPDATE -->
9192
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">Bump org.apache.commons:commons-parent from 73 to 78 #1267, #1277, #1283, #1288, #1302.</action>
9293
<action type="update" dev="ggregory" due-to="Gary Gregory, Dependabot">[site] Bump org.codehaus.mojo:taglist-maven-plugin from 3.1.0 to 3.2.1 #1300.</action>

src/main/java/org/apache/commons/lang3/ArrayUtils.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7842,6 +7842,41 @@ public static void shuffle(final short[] array, final Random random) {
78427842
}
78437843
}
78447844

7845+
/**
7846+
* Tests whether the given data array starts with an expected array, for example, signature bytes.
7847+
* <p>
7848+
* If both arrays are null, the method returns true. The method return false when one array is null and the other not.
7849+
* </p>
7850+
*
7851+
* @param data The data to search, maybe larger than the expected data.
7852+
* @param expected The expected data to find.
7853+
* @return whether a match was found.
7854+
* @since 3.18.0
7855+
*/
7856+
public static boolean startsWith(final byte[] data, final byte[] expected) {
7857+
if (data == expected) {
7858+
return true;
7859+
}
7860+
if (data == null || expected == null) {
7861+
return false;
7862+
}
7863+
final int dataLen = data.length;
7864+
if (expected.length > dataLen) {
7865+
return false;
7866+
}
7867+
if (expected.length == dataLen) {
7868+
// delegate to Arrays.equals() which has optimizations on Java > 8
7869+
return Arrays.equals(data, expected);
7870+
}
7871+
// Once we are on Java 9+ we can delegate to Arrays here as well (or not).
7872+
for (int i = 0; i < expected.length; i++) {
7873+
if (data[i] != expected[i]) {
7874+
return false;
7875+
}
7876+
}
7877+
return true;
7878+
}
7879+
78457880
/**
78467881
* Produces a new {@code boolean} array containing the elements
78477882
* between the start and end indices.

src/test/java/org/apache/commons/lang3/ArrayUtilsTest.java

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import java.lang.annotation.ElementType;
3232
import java.lang.reflect.Constructor;
3333
import java.lang.reflect.Modifier;
34+
import java.nio.charset.StandardCharsets;
3435
import java.util.Arrays;
3536
import java.util.BitSet;
3637
import java.util.Collections;
@@ -5176,6 +5177,34 @@ public void testShuffleShort() {
51765177
}
51775178
}
51785179

5180+
@Test
5181+
public void testStartsWith() {
5182+
// edge cases
5183+
assertTrue(ArrayUtils.startsWith(null, null));
5184+
assertFalse(ArrayUtils.startsWith(ArrayUtils.EMPTY_BYTE_ARRAY, null));
5185+
assertFalse(ArrayUtils.startsWith(null, ArrayUtils.EMPTY_BYTE_ARRAY));
5186+
assertTrue(ArrayUtils.startsWith(ArrayUtils.EMPTY_BYTE_ARRAY, ArrayUtils.EMPTY_BYTE_ARRAY));
5187+
assertTrue(ArrayUtils.startsWith(new byte[0], new byte[0]));
5188+
// normal cases
5189+
assertTrue(ArrayUtils.startsWith(new byte[10], new byte[10]));
5190+
assertTrue(ArrayUtils.startsWith(new byte[10], new byte[9]));
5191+
assertTrue(ArrayUtils.startsWith(new byte[10], new byte[1]));
5192+
final byte[] sig = "Signature".getBytes(StandardCharsets.US_ASCII);
5193+
final byte[] data = new byte[1024];
5194+
// data is 0
5195+
assertFalse(ArrayUtils.startsWith(data, sig));
5196+
// data is 1 short for expected at the end
5197+
System.arraycopy(sig, 0, data, 0, sig.length - 1);
5198+
assertFalse(ArrayUtils.startsWith(data, sig));
5199+
// data is mimatched at the start
5200+
System.arraycopy(sig, 0, data, 0, sig.length);
5201+
data[0] = 0;
5202+
assertFalse(ArrayUtils.startsWith(data, sig));
5203+
// data is as expected
5204+
System.arraycopy(sig, 0, data, 0, sig.length);
5205+
assertTrue(ArrayUtils.startsWith(data, sig));
5206+
}
5207+
51795208
@Test
51805209
public void testSubarrayBoolean() {
51815210
final boolean[] nullArray = null;

0 commit comments

Comments
 (0)