Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8264514: HexFormat implementation tweaks #3381

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter
Filter file types
Jump to
Jump to file
Failed to load files.

Always

Just for now

@@ -150,28 +150,32 @@
};
// Analysis has shown that generating the whole array allows the JIT to generate
// better code compared to a slimmed down array, such as one cutting off after 'f'
private static final byte[] DIGITS = new byte[] {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1,
-1, -1, -1, -1, -1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 10, 11, 12,
13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
private static final byte[] DIGITS = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
/**
* Format each byte of an array as a pair of hexadecimal digits.
* The hexadecimal characters are from lowercase alpha digits.
*/
private static final HexFormat HEX_FORMAT =
new HexFormat("", "", "", LOWERCASE_DIGITS);

private static final byte[] EMPTY_BYTES = new byte[0];
private static final byte[] EMPTY_BYTES = {};

private final String delimiter;
private final String prefix;
@@ -191,7 +195,7 @@ private HexFormat(String delimiter, String prefix, String suffix, byte[] digits)
this.delimiter = Objects.requireNonNull(delimiter, "delimiter");
this.prefix = Objects.requireNonNull(prefix, "prefix");
this.suffix = Objects.requireNonNull(suffix, "suffix");
this.digits = Objects.requireNonNull(digits, "digits");
this.digits = digits;
}

/**
@@ -468,7 +472,8 @@ private String formatOptDelimiter(byte[] bytes, int fromIndex, int toIndex) {
}

/**
* Checked that the requested size for the result string is less than the max array size.
* Checked that the requested size for the result string is
* less than or equal to the max array size.
*
* @param length the requested size of a byte array.
* @return the length
@@ -526,15 +531,15 @@ private static int checkMaxArraySize(long length) {
string = string.subSequence(fromIndex, toIndex);
}

if (string.length() == 0)
if (string.isEmpty())
return EMPTY_BYTES;
if (delimiter.isEmpty() && prefix.isEmpty() && suffix.isEmpty())
return parseNoDelimiter(string);

// avoid overflow for max length prefix or suffix
long valueChars = prefix.length() + 2L + suffix.length();
long stride = valueChars + delimiter.length();
if (string.length() < valueChars || (string.length() - valueChars) % stride != 0)
if ((string.length() - valueChars) % stride != 0)
throw new IllegalArgumentException("extra or missing delimiters " +
"or values consisting of prefix, two hexadecimal digits, and suffix");

@@ -545,16 +550,10 @@ private static int checkMaxArraySize(long length) {
byte[] bytes = new byte[len];
int i, offset;
for (i = 0, offset = prefix.length(); i < len - 1; i++, offset += 2 + between.length()) {
int v = fromHexDigits(string, offset);
if (v < 0)
throw new IllegalArgumentException("input contains non-hexadecimal characters");
bytes[i] = (byte) v;
bytes[i] = (byte) fromHexDigits(string, offset);
checkLiteral(string, offset + 2, between);
}
int v = fromHexDigits(string, offset);
if (v < 0)
throw new IllegalArgumentException("input contains non-hexadecimal characters");
bytes[i] = (byte) v;
bytes[i] = (byte) fromHexDigits(string, offset);

return bytes;
}
@@ -830,21 +829,15 @@ public String toHexDigits(long value, int digits) {
* @throws IllegalArgumentException if the string length is not valid or
* the string contains non-hexadecimal characters
*/
private byte[] parseNoDelimiter(CharSequence string) {
private static byte[] parseNoDelimiter(CharSequence string) {
if ((string.length() & 1) != 0)
throw new IllegalArgumentException("string length not even: " +
string.length());

byte[] bytes = new byte[string.length() / 2];
int illegal = 0; // Accumulate logical-or of all bytes
for (int i = 0; i < bytes.length; i++) {
int v = fromHexDigits(string, i * 2);
bytes[i] = (byte) v;
illegal |= v;
bytes[i] = (byte) fromHexDigits(string, i * 2);
}
// check if any character was an illegal character
if (illegal < 0)
throw new IllegalArgumentException("input contains non-hexadecimal characters");

return bytes;
}
@@ -916,7 +909,6 @@ public static int fromHexDigit(int ch) {
* for the {@code CharSequence}
*/
private static int fromHexDigits(CharSequence string, int index) {
Objects.requireNonNull(string, "string");
int high = fromHexDigit(string.charAt(index));
int low = fromHexDigit(string.charAt(index + 1));
return (high << 4) | low;
@@ -933,7 +925,8 @@ private static int fromHexDigits(CharSequence string, int index) {
* {@link Integer#parseUnsignedInt(String, int) Integer.parseUnsignedInt(s, 16)}
* are similar but allow all Unicode hexadecimal digits defined by
* {@link Character#digit(char, int) Character.digit(ch, 16)}.
* {@code HexFormat} uses only hexadecimal characters "0-9, "A-F", and "a-f".
* {@code HexFormat} uses only hexadecimal characters
* {@code "0-9"}, {@code "A-F"} and {@code "a-f"}.
* Signed hexadecimal strings can be parsed with {@link Integer#parseInt(String, int)}.
*
* @param string a CharSequence containing up to eight hexadecimal characters
@@ -942,13 +935,7 @@ private static int fromHexDigits(CharSequence string, int index) {
* if any of the characters is not a hexadecimal character
*/
public static int fromHexDigits(CharSequence string) {
Objects.requireNonNull(string, "string");
int length = checkDigitCount(0, string.length(), 8);
int value = 0;
for (int i = 0; i < length; i++) {
value = (value << 4) + fromHexDigit(string.charAt(i));
}
return value;
return fromHexDigits(string, 0, string.length());
}

/**
@@ -964,7 +951,8 @@ public static int fromHexDigits(CharSequence string) {
* {@link Integer#parseUnsignedInt(String, int) Integer.parseUnsignedInt(s, 16)}
* are similar but allow all Unicode hexadecimal digits defined by
* {@link Character#digit(char, int) Character.digit(ch, 16)}.
* {@code HexFormat} uses only hexadecimal characters "0-9, "A-F", and "a-f".
* {@code HexFormat} uses only hexadecimal characters
* {@code "0-9"}, {@code "A-F"} and {@code "a-f"}.
* Signed hexadecimal strings can be parsed with {@link Integer#parseInt(String, int)}.
*
* @param string a CharSequence containing the characters
@@ -998,7 +986,8 @@ public static int fromHexDigits(CharSequence string, int fromIndex, int toIndex)
* {@link Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s, 16)}
* are similar but allow all Unicode hexadecimal digits defined by
* {@link Character#digit(char, int) Character.digit(ch, 16)}.
* {@code HexFormat} uses only hexadecimal characters "0-9, "A-F", and "a-f".
* {@code HexFormat} uses only hexadecimal characters
* {@code "0-9"}, {@code "A-F"} and {@code "a-f"}.
* Signed hexadecimal strings can be parsed with {@link Long#parseLong(String, int)}.
*
* @param string a CharSequence containing up to sixteen hexadecimal characters
@@ -1007,13 +996,7 @@ public static int fromHexDigits(CharSequence string, int fromIndex, int toIndex)
* if any of the characters is not a hexadecimal character
*/
public static long fromHexDigitsToLong(CharSequence string) {
Objects.requireNonNull(string, "string");
int length = checkDigitCount(0, string.length(), 16);
long value = 0L;
for (int i = 0; i < length; i++) {
value = (value << 4) + fromHexDigit(string.charAt(i));
}
return value;
return fromHexDigitsToLong(string, 0, string.length());
}

/**
@@ -1029,7 +1012,8 @@ public static long fromHexDigitsToLong(CharSequence string) {
* {@link Long#parseUnsignedLong(String, int) Long.parseUnsignedLong(s, 16)}
* are similar but allow all Unicode hexadecimal digits defined by
* {@link Character#digit(char, int) Character.digit(ch, 16)}.
* {@code HexFormat} uses only hexadecimal characters "0-9, "A-F", and "a-f".
* {@code HexFormat} uses only hexadecimal characters
* {@code "0-9"}, {@code "A-F"} and {@code "a-f"}.
* Signed hexadecimal strings can be parsed with {@link Long#parseLong(String, int)}.
*
* @param string a CharSequence containing the characters
@@ -1068,10 +1052,10 @@ public boolean equals(Object o) {
if (o == null || getClass() != o.getClass())
return false;
HexFormat otherHex = (HexFormat) o;
return delimiter.equals(otherHex.delimiter) &&
return Arrays.equals(digits, otherHex.digits) &&
delimiter.equals(otherHex.delimiter) &&
prefix.equals(otherHex.prefix) &&
suffix.equals(otherHex.suffix) &&
Arrays.equals(digits, otherHex.digits);
suffix.equals(otherHex.suffix);
}

/**
ProTip! Use n and p to navigate between commits in a pull request.