Add wuffs_base__hexadecimal__decodeN
diff --git a/internal/cgen/base/strconv-impl.c b/internal/cgen/base/strconv-impl.c
index 1d4dbef..74e990b 100644
--- a/internal/cgen/base/strconv-impl.c
+++ b/internal/cgen/base/strconv-impl.c
@@ -1104,6 +1104,46 @@
} while (0);
}
+// ---------------- Hexadecimal
+
+size_t //
+wuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src) {
+ size_t src_len2 = src.len / 2;
+ size_t len = dst.len < src_len2 ? dst.len : src_len2;
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ *d = (wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
+ (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F);
+ d += 1;
+ s += 2;
+ }
+
+ return len;
+}
+
+size_t //
+wuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src) {
+ size_t src_len4 = src.len / 4;
+ size_t len = dst.len < src_len4 ? dst.len : src_len4;
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ *d = (wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
+ (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F);
+ d += 1;
+ s += 4;
+ }
+
+ return len;
+}
+
// ---------------- Unicode and UTF-8
size_t //
diff --git a/internal/cgen/base/strconv-public.h b/internal/cgen/base/strconv-public.h
index 65c60ec..c6f7ad6 100644
--- a/internal/cgen/base/strconv-public.h
+++ b/internal/cgen/base/strconv-public.h
@@ -120,7 +120,35 @@
return f;
}
- // ---------------- Unicode and UTF-8
+// ---------------- Hexadecimal
+
+// wuffs_base__hexadecimal__decode2 converts "6A6b" to "jk", where e.g. 'j' is
+// U+006A. There are 2 source bytes for every destination byte.
+//
+// It returns the number of dst bytes written: the minimum of dst.len and
+// (src.len / 2). Excess source bytes are ignored.
+//
+// It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
+// repeated. It may write nonsense bytes if not, although it will not read or
+// write out of bounds.
+size_t //
+wuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src);
+
+// wuffs_base__hexadecimal__decode4 converts "\\x6A\\x6b" to "jk", where e.g.
+// 'j' is U+006A. There are 4 source bytes for every destination byte.
+//
+// It returns the number of dst bytes written: the minimum of dst.len and
+// (src.len / 4). Excess source bytes are ignored.
+//
+// It assumes that the src bytes are two ignored bytes and then two hexadecimal
+// digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
+// although it will not read or write out of bounds.
+size_t //
+wuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src);
+
+// ---------------- Unicode and UTF-8
#define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
#define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
diff --git a/internal/cgen/data.go b/internal/cgen/data.go
index e745d8b..dac8f33 100644
--- a/internal/cgen/data.go
+++ b/internal/cgen/data.go
@@ -114,6 +114,8 @@
"man2 >> 52) == 0) {\n exp2 = bias;\n }\n\n // Pack the bits and return.\n uint64_t exp2_bits = (uint64_t)((exp2 - bias) & 0x07FF); // (1 << 11) - 1.\n uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.\n (exp2_bits << 52) | //\n (h.negative ? 0x8000000000000000 : 0); // (1 << 63).\n\n wuffs_base__result_f64 ret;\n ret.status.repr = NULL;\n ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n return ret;\n } while (0);\n\nzero:\n do {\n uint64_t bits = h.negative ? 0x8000000000000000 : 0;\n\n wuffs_base__result_f64 ret;\n ret.status.repr = NULL;\n ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n return ret;\n } while (0);\n\ninfinity:\n do {\n uint64_t bits = h.negative ? 0xFFF0000000000000 : 0x7FF0000000000000;\n\n wuffs_base__result_f64 ret;\n ret.status.repr = NULL;\n ret.value = wuffs_base__ieee_754_bit_representation__to_f64(bits);\n return ret;\n } whi" +
"le (0);\n}\n\n" +
"" +
+ "// ---------------- Hexadecimal\n\nsize_t //\nwuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 src) {\n size_t src_len2 = src.len / 2;\n size_t len = dst.len < src_len2 ? dst.len : src_len2;\n uint8_t* d = dst.ptr;\n uint8_t* s = src.ptr;\n size_t n = len;\n\n while (n--) {\n *d = (wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |\n (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F);\n d += 1;\n s += 2;\n }\n\n return len;\n}\n\nsize_t //\nwuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 src) {\n size_t src_len4 = src.len / 4;\n size_t len = dst.len < src_len4 ? dst.len : src_len4;\n uint8_t* d = dst.ptr;\n uint8_t* s = src.ptr;\n size_t n = len;\n\n while (n--) {\n *d = (wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |\n (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F);\n d += 1;\n s += 4;\n }\n\n return len;\n}\n\n" +
+ "" +
"// ---------------- Unicode and UTF-8\n\nsize_t //\nwuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {\n if (code_point <= 0x7F) {\n if (dst.len >= 1) {\n dst.ptr[0] = (uint8_t)(code_point);\n return 1;\n }\n\n } else if (code_point <= 0x07FF) {\n if (dst.len >= 2) {\n dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));\n dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));\n return 2;\n }\n\n } else if (code_point <= 0xFFFF) {\n if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {\n dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));\n dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));\n dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));\n return 3;\n }\n\n } else if (code_point <= 0x10FFFF) {\n if (dst.len >= 4) {\n dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));\n dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));\n dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3" +
"F));\n dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));\n return 4;\n }\n }\n\n return 0;\n}\n\n// wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a\n// UTF-8 encoded code point, based on the encoding's initial byte.\n// - 0x00 is 1-byte UTF-8 (ASCII).\n// - 0x01 is the start of 2-byte UTF-8.\n// - 0x02 is the start of 3-byte UTF-8.\n// - 0x03 is the start of 4-byte UTF-8.\n// - 0x40 is a UTF-8 tail byte.\n// - 0x80 is invalid UTF-8.\n//\n// RFC 3629 (UTF-8) gives this grammar for valid UTF-8:\n// UTF8-1 = %x00-7F\n// UTF8-2 = %xC2-DF UTF8-tail\n// UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /\n// %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )\n// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /\n// %xF4 %x80-8F 2( UTF8-tail )\n// UTF8-tail = %x80-BF\nstatic const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {\n // 0 1 2 3 4 5 6 7\n // 8 9" +
" A B C D E F\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F.\n\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.\n 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 .." +
@@ -329,7 +331,10 @@
"" +
"// ---------------- IEEE 754 Floating Point\n\n// wuffs_base__parse_number_f64 parses the floating point number in s. For\n// example, if s contains the bytes \"1.5\" then it will return the double 1.5.\n//\n// It returns an error if s does not contain a floating point number.\n//\n// It does not necessarily return an error if the conversion is lossy, e.g. if\n// s is \"0.3\", which double-precision floating point cannot represent exactly.\n//\n// Similarly, the returned value may be infinite (and no error returned) even\n// if s was not \"inf\", when the input is nominally finite but sufficiently\n// larger than DBL_MAX, about 1.8e+308.\n//\n// It is similar to the C standard library's strtod function, but:\n// - Errors are returned in-band (in a result type), not out-of-band (errno).\n// - It takes a slice (a pointer and length), not a NUL-terminated C string.\n// - It does not take an optional endptr argument. It does not allow a partial\n// parse: it returns an error unless all of s is consumed.\n// - It does not allow whi" +
"tespace, leading or otherwise.\n// - It does not allow unnecessary leading zeroes (\"0\" is valid and its sole\n// zero is necessary). All of \"00\", \"0644\" and \"00.7\" are invalid.\n// - It is not affected by i18n / l10n settings such as environment variables.\n// - Conversely, it always accepts either ',' or '.' as a decimal separator.\n// In particular, \"3,141,592\" is always invalid but \"3,141\" is always valid\n// (and approximately π). The caller is responsible for e.g. previously\n// rejecting or filtering s if it contains a comma, if that is unacceptable\n// to the caller. For example, JSON numbers always use a dot '.' and never a\n// comma ',', regardless of the LOCALE environment variable.\n// - It does allow arbitrary underscores. For example, \"_3.141_592\" would\n// successfully parse, again approximately π.\n// - It does allow \"inf\", \"+Infinity\" and \"-NAN\", case insensitive, but it\n// does not permit \"nan\" to be followed by an integer mantissa.\n// - It does not allow hexadecimal float" +
- "ing point numbers.\nwuffs_base__result_f64 //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s);\n\n// wuffs_base__ieee_754_bit_representation__etc converts between a double\n// precision numerical value and its IEEE 754 64-bit representation (1 sign\n// bit, 11 exponent bits, 52 explicit significand bits).\n//\n// For example, it converts between:\n// - +1.0 and 0x3FF0_0000_0000_0000.\n// - +5.5 and 0x4016_0000_0000_0000.\n// - -inf and 0xFFF0_0000_0000_0000.\n//\n// See https://en.wikipedia.org/wiki/Double-precision_floating-point_format\n\nstatic inline uint64_t //\nwuffs_base__ieee_754_bit_representation__from_f64(double f) {\n uint64_t u = 0;\n if (sizeof(uint64_t) == sizeof(double)) {\n memcpy(&u, &f, sizeof(uint64_t));\n }\n return u;\n}\n\nstatic inline double //\nwuffs_base__ieee_754_bit_representation__to_f64(uint64_t u) {\n double f = 0;\n if (sizeof(uint64_t) == sizeof(double)) {\n memcpy(&f, &u, sizeof(uint64_t));\n }\n return f;\n}\n\n " +
+ "ing point numbers.\nwuffs_base__result_f64 //\nwuffs_base__parse_number_f64(wuffs_base__slice_u8 s);\n\n// wuffs_base__ieee_754_bit_representation__etc converts between a double\n// precision numerical value and its IEEE 754 64-bit representation (1 sign\n// bit, 11 exponent bits, 52 explicit significand bits).\n//\n// For example, it converts between:\n// - +1.0 and 0x3FF0_0000_0000_0000.\n// - +5.5 and 0x4016_0000_0000_0000.\n// - -inf and 0xFFF0_0000_0000_0000.\n//\n// See https://en.wikipedia.org/wiki/Double-precision_floating-point_format\n\nstatic inline uint64_t //\nwuffs_base__ieee_754_bit_representation__from_f64(double f) {\n uint64_t u = 0;\n if (sizeof(uint64_t) == sizeof(double)) {\n memcpy(&u, &f, sizeof(uint64_t));\n }\n return u;\n}\n\nstatic inline double //\nwuffs_base__ieee_754_bit_representation__to_f64(uint64_t u) {\n double f = 0;\n if (sizeof(uint64_t) == sizeof(double)) {\n memcpy(&f, &u, sizeof(uint64_t));\n }\n return f;\n}\n\n" +
+ "" +
+ "// ---------------- Hexadecimal\n\n// wuffs_base__hexadecimal__decode2 converts \"6A6b\" to \"jk\", where e.g. 'j' is\n// U+006A. There are 2 source bytes for every destination byte.\n//\n// It returns the number of dst bytes written: the minimum of dst.len and\n// (src.len / 2). Excess source bytes are ignored.\n//\n// It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),\n// repeated. It may write nonsense bytes if not, although it will not read or\n// write out of bounds.\nsize_t //\nwuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 src);\n\n// wuffs_base__hexadecimal__decode4 converts \"\\\\x6A\\\\x6b\" to \"jk\", where e.g.\n// 'j' is U+006A. There are 4 source bytes for every destination byte.\n//\n// It returns the number of dst bytes written: the minimum of dst.len and\n// (src.len / 4). Excess source bytes are ignored.\n//\n// It assumes that the src bytes are two ignored bytes and then two hexadecimal\n// digits (0-9, A-F, a-f), repeated. It may wri" +
+ "te nonsense bytes if not,\n// although it will not read or write out of bounds.\nsize_t //\nwuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,\n wuffs_base__slice_u8 src);\n\n" +
"" +
"// ---------------- Unicode and UTF-8\n\n#define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000\n#define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF\n\n#define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD\n\n#define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800\n#define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF\n\n#define WUFFS_BASE__ASCII__MIN_INCL 0x00\n#define WUFFS_BASE__ASCII__MAX_INCL 0x7F\n\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4\n\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT_" +
"_MIN_INCL 0x00010000\n#define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF\n\n" +
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index e59aa6d..0d1b1aa 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -3591,7 +3591,35 @@
return f;
}
- // ---------------- Unicode and UTF-8
+// ---------------- Hexadecimal
+
+// wuffs_base__hexadecimal__decode2 converts "6A6b" to "jk", where e.g. 'j' is
+// U+006A. There are 2 source bytes for every destination byte.
+//
+// It returns the number of dst bytes written: the minimum of dst.len and
+// (src.len / 2). Excess source bytes are ignored.
+//
+// It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
+// repeated. It may write nonsense bytes if not, although it will not read or
+// write out of bounds.
+size_t //
+wuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src);
+
+// wuffs_base__hexadecimal__decode4 converts "\\x6A\\x6b" to "jk", where e.g.
+// 'j' is U+006A. There are 4 source bytes for every destination byte.
+//
+// It returns the number of dst bytes written: the minimum of dst.len and
+// (src.len / 4). Excess source bytes are ignored.
+//
+// It assumes that the src bytes are two ignored bytes and then two hexadecimal
+// digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
+// although it will not read or write out of bounds.
+size_t //
+wuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src);
+
+// ---------------- Unicode and UTF-8
#define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
#define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
@@ -9642,6 +9670,46 @@
} while (0);
}
+// ---------------- Hexadecimal
+
+size_t //
+wuffs_base__hexadecimal__decode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src) {
+ size_t src_len2 = src.len / 2;
+ size_t len = dst.len < src_len2 ? dst.len : src_len2;
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ *d = (wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
+ (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F);
+ d += 1;
+ s += 2;
+ }
+
+ return len;
+}
+
+size_t //
+wuffs_base__hexadecimal__decode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src) {
+ size_t src_len4 = src.len / 4;
+ size_t len = dst.len < src_len4 ? dst.len : src_len4;
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ *d = (wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
+ (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F);
+ d += 1;
+ s += 4;
+ }
+
+ return len;
+}
+
// ---------------- Unicode and UTF-8
size_t //
diff --git a/test/c/std/json.c b/test/c/std/json.c
index 9de587d..07d943c 100644
--- a/test/c/std/json.c
+++ b/test/c/std/json.c
@@ -349,6 +349,55 @@
}
const char* //
+test_strconv_hexadecimal() {
+ CHECK_FOCUS(__func__);
+
+ {
+ const char* str = "6A6b7"; // The "7" should be ignored.
+ wuffs_base__slice_u8 dst = global_have_slice;
+ wuffs_base__slice_u8 src =
+ wuffs_base__make_slice_u8((void*)str, strlen(str));
+ size_t have = wuffs_base__hexadecimal__decode2(dst, src);
+ if (have != 2) {
+ RETURN_FAIL("decode2: have %zu, want 2", have);
+ }
+ if (global_have_array[0] != 0x6A) {
+ RETURN_FAIL("decode2: dst[0]: have 0x%02X, want 0x6A",
+ (int)(global_have_array[0]));
+ }
+ if (global_have_array[1] != 0x6B) {
+ RETURN_FAIL("decode2: dst[1]: have 0x%02X, want 0x6B",
+ (int)(global_have_array[1]));
+ }
+ }
+
+ {
+ const char* str = "\\xa9\\x00\\xFe";
+ wuffs_base__slice_u8 dst = global_have_slice;
+ wuffs_base__slice_u8 src =
+ wuffs_base__make_slice_u8((void*)str, strlen(str));
+ size_t have = wuffs_base__hexadecimal__decode4(dst, src);
+ if (have != 3) {
+ RETURN_FAIL("decode4: have %zu, want 3", have);
+ }
+ if (global_have_array[0] != 0xA9) {
+ RETURN_FAIL("decode4: dst[0]: have 0x%02X, want 0xA9",
+ (int)(global_have_array[0]));
+ }
+ if (global_have_array[1] != 0x00) {
+ RETURN_FAIL("decode4: dst[1]: have 0x%02X, want 0x00",
+ (int)(global_have_array[1]));
+ }
+ if (global_have_array[2] != 0xFE) {
+ RETURN_FAIL("decode4: dst[2]: have 0x%02X, want 0xFE",
+ (int)(global_have_array[2]));
+ }
+ }
+
+ return NULL;
+}
+
+const char* //
test_strconv_parse_number_f64() {
CHECK_FOCUS(__func__);
@@ -1830,6 +1879,7 @@
// These strconv tests are really testing the Wuffs base library. They
// aren't specific to the std/json code, but putting them here is as good
// as any other place.
+ test_strconv_hexadecimal,
test_strconv_hpd_rounded_integer,
test_strconv_hpd_shift,
test_strconv_parse_number_f64,