Skip to content
Permalink
Browse files
8263754: HexFormat 'fromHex' methods should be static
Reviewed-by: redestad, naoto, chegar
  • Loading branch information
Roger Riggs committed Mar 29, 2021
1 parent a5d7de2 commit 8cf1c62c345ce91208549294192944a1efe717cf
@@ -877,7 +877,7 @@ private static int checkDigitCount(int fromIndex, int toIndex, int limit) {
* @return {@code true} if the character is valid a hexadecimal character,
* otherwise {@code false}
*/
public boolean isHexDigit(int ch) {
public static boolean isHexDigit(int ch) {
return ((ch >>> 8) == 0 && DIGITS[ch] >= 0);
}

@@ -889,13 +889,12 @@ public boolean isHexDigit(int ch) {
* <li>{@code (ch - 'A' + 10)} for {@code 'A'} through {@code 'F'} inclusive, and
* <li>{@code (ch - 'a' + 10)} for {@code 'a'} through {@code 'f'} inclusive.
* </ul>
* The delimiter, prefix, suffix, and uppercase parameters are not used.
*
* @param ch a character or codepoint
* @return the value {@code 0-15}
* @throws NumberFormatException if the codepoint is not a hexadecimal character
*/
public int fromHexDigit(int ch) {
public static int fromHexDigit(int ch) {
int value;
if ((ch >>> 8) == 0 && (value = DIGITS[ch]) >= 0) {
return value;
@@ -907,7 +906,6 @@ public int fromHexDigit(int ch) {
* Returns a value parsed from two hexadecimal characters in a string.
* The characters in the range from {@code index} to {@code index + 1},
* inclusive, must be valid hex digits according to {@link #fromHexDigit(int)}.
* The delimiter, prefix, suffix, and uppercase parameters are not used.
*
* @param string a CharSequence containing the characters
* @param index the index of the first character of the range
@@ -917,7 +915,7 @@ public int fromHexDigit(int ch) {
* @throws IndexOutOfBoundsException if the range is out of bounds
* for the {@code CharSequence}
*/
private int fromHexDigits(CharSequence string, int index) {
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));
@@ -929,7 +927,6 @@ private int fromHexDigits(CharSequence string, int index) {
* The hexadecimal characters are parsed from most significant to least significant
* using {@link #fromHexDigit(int)} to form an unsigned value.
* The value is zero extended to 32 bits and is returned as an {@code int}.
* The delimiter, prefix, suffix, and uppercase parameters are not used.
*
* @apiNote
* {@link Integer#parseInt(String, int) Integer.parseInt(s, 16)} and
@@ -944,7 +941,7 @@ private int fromHexDigits(CharSequence string, int index) {
* @throws IllegalArgumentException if the string length is greater than eight (8) or
* if any of the characters is not a hexadecimal character
*/
public int fromHexDigits(CharSequence string) {
public static int fromHexDigits(CharSequence string) {
Objects.requireNonNull(string, "string");
int length = checkDigitCount(0, string.length(), 8);
int value = 0;
@@ -961,7 +958,6 @@ public int fromHexDigits(CharSequence string) {
* are parsed from most significant to least significant
* using {@link #fromHexDigit(int)} to form an unsigned value.
* The value is zero extended to 32 bits and is returned as an {@code int}.
* The delimiter, prefix, suffix, and uppercase parameters are not used.
*
* @apiNote
* {@link Integer#parseInt(String, int) Integer.parseInt(s, 16)} and
@@ -980,7 +976,7 @@ public int fromHexDigits(CharSequence string) {
* @throws IllegalArgumentException if length of the range is greater than eight (8) or
* if any of the characters is not a hexadecimal character
*/
public int fromHexDigits(CharSequence string, int fromIndex, int toIndex) {
public static int fromHexDigits(CharSequence string, int fromIndex, int toIndex) {
Objects.requireNonNull(string, "string");
Objects.checkFromToIndex(fromIndex, toIndex, string.length());
int length = checkDigitCount(fromIndex, toIndex, 8);
@@ -996,7 +992,6 @@ public int fromHexDigits(CharSequence string, int fromIndex, int toIndex) {
* The hexadecimal characters are parsed from most significant to least significant
* using {@link #fromHexDigit(int)} to form an unsigned value.
* The value is zero extended to 64 bits and is returned as a {@code long}.
* The delimiter, prefix, suffix, and uppercase parameters are not used.
*
* @apiNote
* {@link Long#parseLong(String, int) Long.parseLong(s, 16)} and
@@ -1011,7 +1006,7 @@ public int fromHexDigits(CharSequence string, int fromIndex, int toIndex) {
* @throws IllegalArgumentException if the string length is greater than sixteen (16) or
* if any of the characters is not a hexadecimal character
*/
public long fromHexDigitsToLong(CharSequence string) {
public static long fromHexDigitsToLong(CharSequence string) {
Objects.requireNonNull(string, "string");
int length = checkDigitCount(0, string.length(), 16);
long value = 0L;
@@ -1028,7 +1023,6 @@ public long fromHexDigitsToLong(CharSequence string) {
* are parsed from most significant to least significant
* using {@link #fromHexDigit(int)} to form an unsigned value.
* The value is zero extended to 64 bits and is returned as a {@code long}.
* The delimiter, prefix, suffix, and uppercase parameters are not used.
*
* @apiNote
* {@link Long#parseLong(String, int) Long.parseLong(s, 16)} and
@@ -1047,7 +1041,7 @@ public long fromHexDigitsToLong(CharSequence string) {
* @throws IllegalArgumentException if the length of the range is greater than sixteen (16) or
* if any of the characters is not a hexadecimal character
*/
public long fromHexDigitsToLong(CharSequence string, int fromIndex, int toIndex) {
public static long fromHexDigitsToLong(CharSequence string, int fromIndex, int toIndex) {
Objects.requireNonNull(string, "string");
Objects.checkFromToIndex(fromIndex, toIndex, string.length());
int length = checkDigitCount(fromIndex, toIndex, 16);
@@ -815,11 +815,10 @@ private void checkOCSP(X509Certificate cert,
* Removes any non-hexadecimal characters from a string.
*/
private static String stripOutSeparators(String value) {
HexFormat hex = HexFormat.of();
char[] chars = value.toCharArray();
StringBuilder hexNumber = new StringBuilder();
for (int i = 0; i < chars.length; i++) {
if (hex.isHexDigit(chars[i])) {
if (HexFormat.isHexDigit(chars[i])) {
hexNumber.append(chars[i]);
}
}
@@ -40,7 +40,6 @@

import java.security.interfaces.ECKey;
import java.security.interfaces.EdECKey;
import java.security.spec.AlgorithmParameterSpec;
import java.security.spec.ECParameterSpec;
import java.text.Collator;
import java.text.MessageFormat;
@@ -4574,16 +4573,15 @@ private CertificateExtensions createV3Extensions(
break;
case -1:
ObjectIdentifier oid = ObjectIdentifier.of(name);
HexFormat hexFmt = HexFormat.of();
byte[] data = null;
if (value != null) {
data = new byte[value.length() / 2 + 1];
int pos = 0;
for (char c: value.toCharArray()) {
if (!hexFmt.isHexDigit(c)) {
if (!HexFormat.isHexDigit(c)) {
continue;
}
int hex = hexFmt.fromHexDigit(c);
int hex = HexFormat.fromHexDigit(c);
if (pos % 2 == 0) {
data[pos/2] = (byte)(hex << 4);
} else {
@@ -29,7 +29,6 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.security.AccessController;
import java.text.Normalizer;
import java.util.*;

@@ -251,7 +250,6 @@ public String getValueString() {

private static DerValue parseHexString
(Reader in, int format) throws IOException {
HexFormat hex = HexFormat.of();
int c;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte b = 0;
@@ -263,7 +261,7 @@ public String getValueString() {
break;
}
try {
int cVal = hex.fromHexDigit(c); // throws on invalid character
int cVal = HexFormat.fromHexDigit(c); // throws on invalid character
if ((cNdx % 2) == 1) {
b = (byte)((b * 16) + (byte)(cVal));
baos.write(b);
@@ -502,14 +500,13 @@ public String getValueString() {
private static Byte getEmbeddedHexPair(int c1, Reader in)
throws IOException {

HexFormat hex = HexFormat.of();
if (hex.isHexDigit(c1)) {
if (HexFormat.isHexDigit(c1)) {
int c2 = readChar(in, "unexpected EOF - " +
"escaped hex value must include two valid digits");

if (hex.isHexDigit(c2)) {
int hi = hex.fromHexDigit(c1);
int lo = hex.fromHexDigit(c2);
if (HexFormat.isHexDigit(c2)) {
int hi = HexFormat.fromHexDigit(c1);
int lo = HexFormat.fromHexDigit(c2);
return (byte)((hi<<4) + lo);
} else {
throw new IOException
@@ -153,7 +153,7 @@ static void testToHexDigits() {
HexFormat hex = HexFormat.of();
for (int i = 0; i < 256; i++) {
String actual = hex.toHexDigits((byte)i);
int expected = hex.fromHexDigits(actual);
int expected = HexFormat.fromHexDigits(actual);
assertEquals(expected, i, "fromHexDigits");
assertEquals(actual.charAt(0), hex.toHighHexDigit((byte)i),
"first char mismatch");
@@ -164,33 +164,30 @@ static void testToHexDigits() {

@Test
static void testIsHexDigit() {
HexFormat hex = HexFormat.of();
for (int i = 0; i < 0x3ff; i++) {
boolean actual = hex.isHexDigit(i);
boolean actual = HexFormat.isHexDigit(i);
boolean expected = Character.digit(i, 16) >= 0;
assertEquals(actual, expected, "isHexDigit: " + i);
}
}

@Test
static void testFromHexDigit() {
HexFormat hex = HexFormat.of();
String chars = "0123456789ABCDEF0123456789abcdef";
for (int i = 0; i < chars.length(); i++) {
int v = hex.fromHexDigit(chars.charAt(i));
int v = HexFormat.fromHexDigit(chars.charAt(i));
assertEquals(v, i & 0xf, "fromHex decode");
}
}

@Test
static void testFromHexInvalid() {
HexFormat hex = HexFormat.of();
for (int i = 0; i < 65536; i++) {
char ch = (char)i;
if (ch > 0xff || Character.digit(ch, 16) < 0) {
assertFalse(hex.isHexDigit(ch), "isHexDigit incorrect for '" + ch + "' = " + i);
assertFalse(HexFormat.isHexDigit(ch), "isHexDigit incorrect for '" + ch + "' = " + i);
expectThrows(NumberFormatException.class,
() -> hex.fromHexDigit(ch));
() -> HexFormat.fromHexDigit(ch));

}
}
@@ -208,7 +205,7 @@ static void testAppendHexByteWithStringBuilder() {
assertEquals(sb.charAt(0), hex.toHighHexDigit((byte)i), "MSB converted wrong");
assertEquals(sb.charAt(1), hex.toLowHexDigit((byte)i), "LSB converted wrong");

assertEquals(hex.fromHexDigits(sb), i, "hex.format(sb, byte) wrong");
assertEquals(HexFormat.fromHexDigits(sb), i, "hex.format(sb, byte) wrong");
}
}

@@ -244,7 +241,7 @@ static void testFromHexPairInvalid() {
for (int i = 0; i < chars.length(); i += 2) {
final int ndx = i;
Throwable ex = expectThrows(NumberFormatException.class,
() -> hex.fromHexDigits(chars.subSequence(ndx, ndx+2)));
() -> HexFormat.fromHexDigits(chars.subSequence(ndx, ndx+2)));
System.out.println(ex);
}
}
@@ -289,10 +286,10 @@ static void testParseHexNPE() {

@Test
static void testFromHexNPE() {
assertThrows(NPE, () -> HexFormat.of().fromHexDigits(null));
assertThrows(NPE, () -> HexFormat.of().fromHexDigits(null, 0, 0));
assertThrows(NPE, () -> HexFormat.of().fromHexDigitsToLong(null));
assertThrows(NPE, () -> HexFormat.of().fromHexDigitsToLong(null, 0, 0));
assertThrows(NPE, () -> HexFormat.fromHexDigits(null));
assertThrows(NPE, () -> HexFormat.fromHexDigits(null, 0, 0));
assertThrows(NPE, () -> HexFormat.fromHexDigitsToLong(null));
assertThrows(NPE, () -> HexFormat.fromHexDigitsToLong(null, 0, 0));
}

@Test
@@ -314,23 +311,23 @@ static void badParseHex(String string, int offset, int length,
static void badFromHexDigits(String string, int fromIndex, int toIndex,
Class<? extends Throwable> exClass) {
assertThrows(exClass,
() -> HexFormat.of().fromHexDigits(string, fromIndex, toIndex));
() -> HexFormat.fromHexDigits(string, fromIndex, toIndex));
assertThrows(exClass,
() -> HexFormat.of().fromHexDigitsToLong(string, fromIndex, toIndex));
() -> HexFormat.fromHexDigitsToLong(string, fromIndex, toIndex));
}

// Verify IAE for strings that are too long for the target primitive type
// or the number of requested digits is too large.
@Test
static void wrongNumberDigits() {
assertThrows(IllegalArgumentException.class,
() -> HexFormat.of().fromHexDigits("9876543210"));
() -> HexFormat.fromHexDigits("9876543210"));
assertThrows(IllegalArgumentException.class,
() -> HexFormat.of().fromHexDigits("9876543210", 0, 9));
() -> HexFormat.fromHexDigits("9876543210", 0, 9));
assertThrows(IllegalArgumentException.class,
() -> HexFormat.of().fromHexDigitsToLong("98765432109876543210"));
() -> HexFormat.fromHexDigitsToLong("98765432109876543210"));
assertThrows(IllegalArgumentException.class,
() -> HexFormat.of().fromHexDigitsToLong("98765432109876543210", 0, 17));
() -> HexFormat.fromHexDigitsToLong("98765432109876543210", 0, 17));
}

@Test(dataProvider="HexFormattersParsers")
@@ -572,7 +569,7 @@ static void testfromHexDigitsToInt() {
final int orig = 0x76543210;
for (int digits = 0; digits <= 8; digits++) {
String s = hex.toHexDigits(orig, digits);
long actual = hex.fromHexDigits(s, 0, digits);
long actual = HexFormat.fromHexDigits(s, 0, digits);
System.out.printf(" digits: %2d, formatted: \"%s\", parsed as: 0x%08x%n",
digits, s, actual);
assertEquals(s, allHex.substring(8 - digits, 8));
@@ -589,7 +586,7 @@ static void testfromHexDigitsToLong() {
final long orig = 0xfedcba9876543210L;
for (int digits = 0; digits <= 16; digits++) {
String s = hex.toHexDigits(orig, digits);
long actual = hex.fromHexDigitsToLong(s, 0, digits);
long actual = HexFormat.fromHexDigitsToLong(s, 0, digits);
System.out.printf(" digits: %2d, formatted: \"%s\", parsed as: 0x%016xL%n",
digits, s, actual);
assertEquals(s, allHex.substring(16 - digits, 16));
@@ -605,7 +602,7 @@ static void testToHexDigitsLong() {
String allHex = "fedcba9876543210";
final long expected = 0xfedcba9876543210L;
String s = hex.toHexDigits(expected);
long actual = hex.fromHexDigitsToLong(s);
long actual = HexFormat.fromHexDigitsToLong(s);
System.out.printf(" formatted: \"%s\", parsed as: 0x%016xL%n", s, actual);
assertEquals(s, allHex);
assertEquals(actual, expected);
@@ -667,7 +664,7 @@ private static void samples() {
String byteStr = hex.toHexDigits(b);
System.out.println(" " + byteStr);

byte byteVal = (byte)hex.fromHexDigits(byteStr);
byte byteVal = (byte) HexFormat.fromHexDigits(byteStr);
assert(byteStr.equals("7f"));
assert(b == byteVal);
assertTrue(byteStr.equals("7f"));
@@ -677,20 +674,20 @@ private static void samples() {
char c = 'A';
String charStr = hex.toHexDigits(c);
System.out.println(" " + charStr);
int charVal = hex.fromHexDigits(charStr);
int charVal = HexFormat.fromHexDigits(charStr);
assert(c == charVal);
assertTrue(c == charVal);

int i = 12345;
String intStr = hex.toHexDigits(i);
System.out.println(" " + intStr);
int intVal = hex.fromHexDigits(intStr);
int intVal = HexFormat.fromHexDigits(intStr);
assert(i == intVal);
assertTrue(i == intVal);

long l = Long.MAX_VALUE;
String longStr = hex.toHexDigits(l, 16);
long longVal = hex.fromHexDigitsToLong(longStr, 0, 16);
long longVal = HexFormat.fromHexDigitsToLong(longStr, 0, 16);
System.out.println(" " + longStr + ", " + longVal);
assert(l == longVal);
assertTrue(l == longVal);

1 comment on commit 8cf1c62

@openjdk-notifier

This comment has been minimized.

Copy link

@openjdk-notifier openjdk-notifier bot commented on 8cf1c62 Mar 29, 2021

Please sign in to comment.