Have std/cbor parse simple values
diff --git a/example/jsonptr/jsonptr.cc b/example/jsonptr/jsonptr.cc
index fdd346a..1c70de3 100644
--- a/example/jsonptr/jsonptr.cc
+++ b/example/jsonptr/jsonptr.cc
@@ -1044,6 +1044,25 @@
}
const char* //
+write_cbor_simple_value(uint64_t tag, uint8_t* ptr, size_t len) {
+ if (g_flags.output_format == file_format::cbor) {
+ return write_dst(ptr, len);
+ }
+
+ if (!g_flags.output_cbor_metadata_as_json_comments) {
+ return nullptr;
+ }
+ uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
+ size_t n = wuffs_base__render_number_u64(
+ wuffs_base__make_slice_u8(&buf[0],
+ WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL),
+ tag, WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS);
+ TRY(write_dst("/*cbor:simple", 13));
+ TRY(write_dst(&buf[0], n));
+ return write_dst("*/null", 6);
+}
+
+const char* //
write_cbor_tag(uint64_t tag, uint8_t* ptr, size_t len) {
if (g_flags.output_format == file_format::cbor) {
return write_dst(ptr, len);
@@ -1610,6 +1629,10 @@
TRY(write_cbor_minus_1_minus_x(
g_src.data.ptr + g_curr_token_end_src_index - len, len));
goto after_value;
+ } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
+ TRY(write_cbor_simple_value(
+ vbd, g_src.data.ptr + g_curr_token_end_src_index - len, len));
+ goto after_value;
}
}
diff --git a/release/c/wuffs-unsupported-snapshot.c b/release/c/wuffs-unsupported-snapshot.c
index 560309b..c68b1f6 100644
--- a/release/c/wuffs-unsupported-snapshot.c
+++ b/release/c/wuffs-unsupported-snapshot.c
@@ -5554,6 +5554,8 @@
#define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 8388608
+#define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 4194304
+
// ---------------- Struct Declarations
typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
@@ -16264,6 +16266,11 @@
// ---------------- Private Consts
+static const uint32_t
+WUFFS_CBOR__LITERALS[4]WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 8388612, 8388616, 8388610, 8388609,
+};
+
static const uint8_t
WUFFS_CBOR__TOKEN_LENGTHS[32]WUFFS_BASE__POTENTIALLY_UNUSED = {
1, 1, 1, 1, 1, 1, 1, 1,
@@ -16816,7 +16823,27 @@
}
goto label__outer__continue;
} else if (v_c_major == 7) {
- if (v_c_minor == 31) {
+ if (v_c_minor < 20) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)((4194304 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor < 24) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor == 24) {
+ if (v_string_length < 24) {
+ goto label__goto_fail__break;
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)((4194304 | ((uint32_t)((v_string_length & 255)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(2)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor == 31) {
if (v_depth <= 0) {
goto label__goto_fail__break;
}
diff --git a/std/cbor/decode_cbor.wuffs b/std/cbor/decode_cbor.wuffs
index 51c95cd..1eafc81 100644
--- a/std/cbor/decode_cbor.wuffs
+++ b/std/cbor/decode_cbor.wuffs
@@ -43,6 +43,21 @@
// value (+1 + x) might also overflow a uint64_t.
pub const TOKEN_VALUE_MINOR__MINUS_1_MINUS_X : base.u32 = 0x080_0000
+// TOKEN_VALUE_MINOR__SIMPLE_VALUE means that the low 8 bits of the token's
+// value_minor is a CBOR simple value either in the range 0 ..= 19 or in the
+// range 24 ..= 255.
+//
+// Simple values in the range 20 ..= 23 (which correspond to: false, true, null
+// and undefined) are represented by WUFFS_BASE__TOKEN__VBC__LITERAL tokens.
+pub const TOKEN_VALUE_MINOR__SIMPLE_VALUE : base.u32 = 0x040_0000
+
+pri const LITERALS : array[4] base.u32[..= 0x1FF_FFFF] = [
+ (base.TOKEN__VBC__LITERAL << 21) | base.TOKEN__VBD__LITERAL__FALSE,
+ (base.TOKEN__VBC__LITERAL << 21) | base.TOKEN__VBD__LITERAL__TRUE,
+ (base.TOKEN__VBC__LITERAL << 21) | base.TOKEN__VBD__LITERAL__NULL,
+ (base.TOKEN__VBC__LITERAL << 21) | base.TOKEN__VBD__LITERAL__UNDEFINED,
+]
+
pri const TOKEN_LENGTHS : array[32] base.u8[..= 9] = [
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
@@ -561,7 +576,36 @@
} else if c_major == 7 {
// -------- BEGIN Major type 7: miscellaneous.
- if c_minor == 0x1F {
+ if c_minor < 0x14 {
+ args.dst.write_simple_token_fast!(
+ value_major: TOKEN_VALUE_MAJOR,
+ value_minor: TOKEN_VALUE_MINOR__SIMPLE_VALUE |
+ ((string_length & 0xFF) as base.u32),
+ continued: 0,
+ length: 1)
+ break.goto_parsed_a_leaf_value
+
+ } else if c_minor < 0x18 {
+ args.dst.write_simple_token_fast!(
+ value_major: 0,
+ value_minor: LITERALS[c_minor & 3],
+ continued: 0,
+ length: 1)
+ break.goto_parsed_a_leaf_value
+
+ } else if c_minor == 0x18 {
+ if string_length < 0x18 {
+ break.goto_fail
+ }
+ args.dst.write_simple_token_fast!(
+ value_major: TOKEN_VALUE_MAJOR,
+ value_minor: TOKEN_VALUE_MINOR__SIMPLE_VALUE |
+ ((string_length & 0xFF) as base.u32),
+ continued: 0,
+ length: 2)
+ break.goto_parsed_a_leaf_value
+
+ } else if c_minor == 0x1F {
// Indefinite-length strings were dealt with separately, above.
// Here, we expect to be in an indefinite-length container.
if depth <= 0 {