Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
*/
public final class DataConverter {

private static final char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

/** Private constructor to prevent instantiation of this utility class. */
private DataConverter() {
super();
Expand Down Expand Up @@ -313,7 +315,7 @@ public static String bytesToHexString(
if (array == null) {
throw new IllegalArgumentException("Input byte array must not be null");
}
StringBuilder result = new StringBuilder();
StringBuilder result = new StringBuilder(array.length * (usePrettyPrinting ? 4 : 3) + 1);
if (initialNewLine && usePrettyPrinting) {
result.append("\n");
}
Expand All @@ -328,8 +330,7 @@ public static String bytesToHexString(
result.append(" ");
}
}
byte b = array[i];
result.append(String.format("%02X", b));
appendHex(result, array[i]);
}
return result.toString();
}
Expand Down Expand Up @@ -422,13 +423,17 @@ public static String bytesToRawHexString(byte[] array) {
if (array == null) {
throw new IllegalArgumentException("Input byte array must not be null");
}
StringBuilder result = new StringBuilder();
StringBuilder result = new StringBuilder(array.length * 2);
for (byte b : array) {
result.append(String.format("%02X", b));
appendHex(result, b);
}
return result.toString();
}

private static void appendHex(StringBuilder sb, byte b) {
sb.append(HEX_DIGITS[(b >> 4) & 0x0F]).append(HEX_DIGITS[b & 0x0F]);
}

/**
* Concatenates multiple arrays of the same type into a single array.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ public UnformattedByteArrayAdapter() {
*/
@Override
public byte[] unmarshal(String value) {
value = value.replaceAll("\\s", "");
return DataConverter.hexStringToByteArray(value);
return DataConverter.hexStringToByteArray(removeWhitespace(value));
}

/**
Expand All @@ -77,4 +76,23 @@ public byte[] unmarshal(String value) {
public String marshal(byte[] value) {
return DataConverter.bytesToHexString(value, false, false);
}

/** Same as {@code value.replaceAll("\\s", "")}, without compiling a pattern per call. */
private static String removeWhitespace(String value) {
StringBuilder builder = null;
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
boolean whitespace =
c == ' ' || c == '\t' || c == '\n' || c == '\u000B' || c == '\f' || c == '\r';
if (whitespace) {
if (builder == null) {
builder = new StringBuilder(value.length());
builder.append(value, 0, i);
}
} else if (builder != null) {
builder.append(c);
}
}
return builder == null ? value : builder.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,4 +77,34 @@ void testUnmarshalOnlyWhitespace() throws Exception {

assertArrayEquals(expected, adapter.unmarshal(input));
}

@Test
void testUnmarshalStripsWhitespaceLikeRegex() {
java.util.Random random = new java.util.Random(7);
char[] alphabet = {
'0', 'a', 'F', ' ', '\t', '\n', '\u000B', '\f', '\r', '\u00A0', '\u2028'
};
for (int n = 0; n < 2000; n++) {
StringBuilder raw = new StringBuilder();
int length = random.nextInt(40);
for (int i = 0; i < length; i++) {
char c = alphabet[random.nextInt(alphabet.length)];
raw.append(c);
}
String expectedInput = raw.toString().replaceAll("\\s", "");
byte[] expected;
try {
expected = DataConverter.hexStringToByteArray(expectedInput);
} catch (RuntimeException e) {
expected = null;
}
byte[] actual;
try {
actual = adapter.unmarshal(raw.toString());
} catch (RuntimeException e) {
actual = null;
}
assertArrayEquals(expected, actual, raw.toString());
}
}
}