nx_cbor_test.nx source
↩ module page · 145 lines · 4873 B
1// nx_cbor_test.nx -- RFC 8949 encoder shape verification.
2//
3// Tests against the spec's reference byte patterns so we know
4// downstream CBOR consumers (Python's cbor2, JS cbor-x, Rust's
5// ciborium, etc.) will round-trip the substrate's output.
6
7import "nx_syscalls.nx"
8import "nx_tier.nx"
9import "nx_cbor.nx"
10
11func main() -> nx_int {
12 let buf: *u8 = (sys_mmap(256)) as *u8
13
14 // ===== Major 0 (unsigned int) ================================
15 // 0 -> 0x00
16 var p: nx_int = nx_cbor_emit_u64(buf, 0, 0)
17 if p != 1 { return 1 }
18 if buf[0] != 0x00 { return 2 }
19
20 // 23 (max inline) -> 0x17
21 p = nx_cbor_emit_u64(buf, 0, 23)
22 if p != 1 { return 3 }
23 if buf[0] != 0x17 { return 4 }
24
25 // 24 (first 1-byte follow) -> 0x18 0x18
26 p = nx_cbor_emit_u64(buf, 0, 24)
27 if p != 2 { return 5 }
28 if buf[0] != 0x18 { return 6 }
29 if buf[1] != 0x18 { return 7 }
30
31 // 255 -> 0x18 0xFF
32 p = nx_cbor_emit_u64(buf, 0, 255)
33 if buf[0] != 0x18 { return 8 }
34 if buf[1] != 0xFF { return 9 }
35
36 // 256 (first 2-byte follow) -> 0x19 0x01 0x00
37 p = nx_cbor_emit_u64(buf, 0, 256)
38 if p != 3 { return 10 }
39 if buf[0] != 0x19 { return 11 }
40 if buf[1] != 0x01 { return 12 }
41 if buf[2] != 0x00 { return 13 }
42
43 // 65535 -> 0x19 0xFF 0xFF
44 p = nx_cbor_emit_u64(buf, 0, 65535)
45 if buf[0] != 0x19 { return 14 }
46 if buf[1] != 0xFF { return 15 }
47 if buf[2] != 0xFF { return 16 }
48
49 // 65536 (first 4-byte follow) -> 0x1A 0x00 0x01 0x00 0x00
50 p = nx_cbor_emit_u64(buf, 0, 65536)
51 if p != 5 { return 17 }
52 if buf[0] != 0x1A { return 18 }
53 if buf[1] != 0x00 { return 19 }
54 if buf[2] != 0x01 { return 20 }
55 if buf[3] != 0x00 { return 21 }
56 if buf[4] != 0x00 { return 22 }
57
58 // ===== Major 1 (negative int) ================================
59 // -1 -> 0x20 (payload = 0, since -1 - (-1) = 0)
60 p = nx_cbor_emit_i64(buf, 0, 0 - 1)
61 if p != 1 { return 30 }
62 if buf[0] != 0x20 { return 31 }
63
64 // -24 -> 0x37 (payload = 23, inline)
65 p = nx_cbor_emit_i64(buf, 0, 0 - 24)
66 if p != 1 { return 32 }
67 if buf[0] != 0x37 { return 33 }
68
69 // -25 -> 0x38 0x18 (payload = 24, 1-byte follow)
70 p = nx_cbor_emit_i64(buf, 0, 0 - 25)
71 if p != 2 { return 34 }
72 if buf[0] != 0x38 { return 35 }
73 if buf[1] != 0x18 { return 36 }
74
75 // -100 -> 0x38 0x63 (payload = 99)
76 p = nx_cbor_emit_i64(buf, 0, 0 - 100)
77 if buf[0] != 0x38 { return 37 }
78 if buf[1] != 0x63 { return 38 }
79
80 // ===== Major 4 (array) =======================================
81 // empty array [] -> 0x80
82 p = nx_cbor_emit_array_header(buf, 0, 0)
83 if p != 1 { return 40 }
84 if buf[0] != 0x80 { return 41 }
85
86 // [1, 2, 3] -> 0x83 0x01 0x02 0x03
87 p = nx_cbor_emit_array_header(buf, 0, 3)
88 p = nx_cbor_emit_u64(buf, p, 1)
89 p = nx_cbor_emit_u64(buf, p, 2)
90 p = nx_cbor_emit_u64(buf, p, 3)
91 if p != 4 { return 42 }
92 if buf[0] != 0x83 { return 43 }
93 if buf[1] != 0x01 { return 44 }
94 if buf[2] != 0x02 { return 45 }
95 if buf[3] != 0x03 { return 46 }
96
97 // ===== Major 5 (map) =========================================
98 // {} -> 0xA0
99 p = nx_cbor_emit_map_header(buf, 0, 0)
100 if p != 1 { return 50 }
101 if buf[0] != 0xA0 { return 51 }
102
103 // {1: 2} -> 0xA1 0x01 0x02
104 p = nx_cbor_emit_map_header(buf, 0, 1)
105 p = nx_cbor_emit_u64(buf, p, 1)
106 p = nx_cbor_emit_u64(buf, p, 2)
107 if p != 3 { return 52 }
108 if buf[0] != 0xA1 { return 53 }
109 if buf[1] != 0x01 { return 54 }
110 if buf[2] != 0x02 { return 55 }
111
112 // ===== Span emit shape =======================================
113 //
114 // Span with trace=100, span=1, parent=-1, kind=0, start=0, end=100,
115 // 2 attrs: (0xAA, 100), (0xBB, 200).
116 //
117 // Expected: map header (7 pairs) + 7 (key,value) pairs. The
118 // attrs value is an array(2) of array(2)-pairs.
119 let attrs: *i64 = (sys_mmap(32)) as *i64
120 attrs[0] = 0xAA; attrs[1] = 100
121 attrs[2] = 0xBB; attrs[3] = 200
122
123 p = nx_cbor_emit_span(buf, 0, 100, 1, 0 - 1, 0, 0, 100, attrs, 2)
124 // First byte: 0xA7 (map of 7 pairs).
125 if buf[0] != 0xA7 { return 60 }
126 // Sanity: total bytes should be > 14 (7 header + 7 keys + various
127 // values + attr array). Just check it landed something.
128 if p < 14 { return 61 }
129
130 // Round-trip header read: extract major type + length from first
131 // byte to confirm structure.
132 let first: nx_int = buf[0]
133 let maj: nx_int = first / 32 // first >> 5
134 let len: nx_int = first - maj * 32 // first & 0x1F
135 if maj != NX_CBOR_MAJ_MAP { return 62 }
136 if len != NX_CBOR_SPAN_N_PAIRS { return 63 }
137
138 // ===== Inline-boundary verification: pow2 helper =============
139 if _nx_cbor_pow2(0) != 1 { return 70 }
140 if _nx_cbor_pow2(1) != 2 { return 71 }
141 if _nx_cbor_pow2(8) != 256 { return 72 }
142 if _nx_cbor_pow2(16) != 65536 { return 73 }
143
144 return 0
145}