coding.odin 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. package encoding_cbor
  2. import "base:intrinsics"
  3. import "base:runtime"
  4. import "core:bytes"
  5. import "core:encoding/endian"
  6. import "core:io"
  7. import "core:slice"
  8. import "core:strings"
  9. Encoder_Flag :: enum {
  10. // CBOR defines a tag header that also acts as a file/binary header,
  11. // this way decoders can check the first header of the binary and see if it is CBOR.
  12. Self_Described_CBOR,
  13. // Integers are stored in the smallest integer type it fits.
  14. // This involves checking each int against the max of all its smaller types.
  15. Deterministic_Int_Size,
  16. // Floats are stored in the smallest size float type without losing precision.
  17. // This involves casting each float down to its smaller types and checking if it changed.
  18. Deterministic_Float_Size,
  19. // Sort maps by their keys in bytewise lexicographic order of their deterministic encoding.
  20. // NOTE: In order to do this, all keys of a map have to be pre-computed, sorted, and
  21. // then written, this involves temporary allocations for the keys and a copy of the map itself.
  22. Deterministic_Map_Sorting,
  23. }
  24. Encoder_Flags :: bit_set[Encoder_Flag]
  25. // Flags for fully deterministic output (if you are not using streaming/indeterminate length).
  26. ENCODE_FULLY_DETERMINISTIC :: Encoder_Flags{.Deterministic_Int_Size, .Deterministic_Float_Size, .Deterministic_Map_Sorting}
  27. // Flags for the smallest encoding output.
  28. ENCODE_SMALL :: Encoder_Flags{.Deterministic_Int_Size, .Deterministic_Float_Size}
  29. Encoder :: struct {
  30. flags: Encoder_Flags,
  31. writer: io.Writer,
  32. temp_allocator: runtime.Allocator,
  33. }
  34. Decoder_Flag :: enum {
  35. // Rejects (with an error `.Disallowed_Streaming`) when a streaming CBOR header is encountered.
  36. Disallow_Streaming,
  37. // Pre-allocates buffers and containers with the size that was set in the CBOR header.
  38. // This should only be enabled when you control both ends of the encoding, if you don't,
  39. // attackers can craft input that causes massive (`max(u64)`) byte allocations for a few bytes of
  40. // CBOR.
  41. Trusted_Input,
  42. // Makes the decoder shrink of excess capacity from allocated buffers/containers before returning.
  43. Shrink_Excess,
  44. }
  45. Decoder_Flags :: bit_set[Decoder_Flag]
  46. Decoder :: struct {
  47. // The max amount of bytes allowed to pre-allocate when `.Trusted_Input` is not set on the
  48. // flags.
  49. max_pre_alloc: int,
  50. flags: Decoder_Flags,
  51. reader: io.Reader,
  52. }
  53. /*
  54. Decodes both deterministic and non-deterministic CBOR into a `Value` variant.
  55. `Text` and `Bytes` can safely be cast to cstrings because of an added 0 byte.
  56. Allocations are done using the given allocator,
  57. *no* allocations are done on the `context.temp_allocator`.
  58. A value can be (fully and recursively) deallocated using the `destroy` proc in this package.
  59. Disable streaming/indeterminate lengths with the `.Disallow_Streaming` flag.
  60. Shrink excess bytes in buffers and containers with the `.Shrink_Excess` flag.
  61. Mark the input as trusted input with the `.Trusted_Input` flag, this turns off the safety feature
  62. of not pre-allocating more than `max_pre_alloc` bytes before reading into the bytes. You should only
  63. do this when you own both sides of the encoding and are sure there can't be malicious bytes used as
  64. an input.
  65. */
  66. decode_from :: proc {
  67. decode_from_string,
  68. decode_from_reader,
  69. decode_from_decoder,
  70. }
  71. decode :: decode_from
  72. // Decodes the given string as CBOR.
  73. // See docs on the proc group `decode` for more information.
  74. decode_from_string :: proc(s: string, flags: Decoder_Flags = {}, allocator := context.allocator) -> (v: Value, err: Decode_Error) {
  75. r: strings.Reader
  76. strings.reader_init(&r, s)
  77. return decode_from_reader(strings.reader_to_stream(&r), flags, allocator)
  78. }
  79. // Reads a CBOR value from the given reader.
  80. // See docs on the proc group `decode` for more information.
  81. decode_from_reader :: proc(r: io.Reader, flags: Decoder_Flags = {}, allocator := context.allocator) -> (v: Value, err: Decode_Error) {
  82. return decode_from_decoder(
  83. Decoder{ DEFAULT_MAX_PRE_ALLOC, flags, r },
  84. allocator=allocator,
  85. )
  86. }
  87. // Reads a CBOR value from the given decoder.
  88. // See docs on the proc group `decode` for more information.
  89. decode_from_decoder :: proc(d: Decoder, allocator := context.allocator) -> (v: Value, err: Decode_Error) {
  90. context.allocator = allocator
  91. d := d
  92. if d.max_pre_alloc <= 0 {
  93. d.max_pre_alloc = DEFAULT_MAX_PRE_ALLOC
  94. }
  95. v, err = _decode_from_decoder(d)
  96. // Normal EOF does not exist here, we try to read the exact amount that is said to be provided.
  97. if err == .EOF { err = .Unexpected_EOF }
  98. return
  99. }
  100. _decode_from_decoder :: proc(d: Decoder, hdr: Header = Header(0)) -> (v: Value, err: Decode_Error) {
  101. hdr := hdr
  102. r := d.reader
  103. if hdr == Header(0) { hdr = _decode_header(r) or_return }
  104. switch hdr {
  105. case .U8: return _decode_u8 (r)
  106. case .U16: return _decode_u16(r)
  107. case .U32: return _decode_u32(r)
  108. case .U64: return _decode_u64(r)
  109. case .Neg_U8: return Negative_U8 (_decode_u8 (r) or_return), nil
  110. case .Neg_U16: return Negative_U16(_decode_u16(r) or_return), nil
  111. case .Neg_U32: return Negative_U32(_decode_u32(r) or_return), nil
  112. case .Neg_U64: return Negative_U64(_decode_u64(r) or_return), nil
  113. case .Simple: return _decode_simple(r)
  114. case .F16: return _decode_f16(r)
  115. case .F32: return _decode_f32(r)
  116. case .F64: return _decode_f64(r)
  117. case .True: return true, nil
  118. case .False: return false, nil
  119. case .Nil: return Nil{}, nil
  120. case .Undefined: return Undefined{}, nil
  121. case .Break: return nil, .Break
  122. }
  123. maj, add := _header_split(hdr)
  124. switch maj {
  125. case .Unsigned: return _decode_tiny_u8(add)
  126. case .Negative: return Negative_U8(_decode_tiny_u8(add) or_return), nil
  127. case .Bytes: return _decode_bytes_ptr(d, add)
  128. case .Text: return _decode_text_ptr(d, add)
  129. case .Array: return _decode_array_ptr(d, add)
  130. case .Map: return _decode_map_ptr(d, add)
  131. case .Tag: return _decode_tag_ptr(d, add)
  132. case .Other: return _decode_tiny_simple(add)
  133. case: return nil, .Bad_Major
  134. }
  135. }
  136. /*
  137. Encodes the CBOR value into a binary CBOR.
  138. Flags can be used to control the output (mainly determinism, which coincidently affects size).
  139. The default flags `ENCODE_SMALL` (`.Deterministic_Int_Size`, `.Deterministic_Float_Size`) will try
  140. to put ints and floats into their smallest possible byte size without losing equality.
  141. Adding the `.Self_Described_CBOR` flag will wrap the value in a tag that lets generic decoders know
  142. the contents are CBOR from just reading the first byte.
  143. Adding the `.Deterministic_Map_Sorting` flag will sort the encoded maps by the byte content of the
  144. encoded key. This flag has a cost on performance and memory efficiency because all keys in a map
  145. have to be precomputed, sorted and only then written to the output.
  146. Empty flags will do nothing extra to the value.
  147. The allocations for the `.Deterministic_Map_Sorting` flag are done using the given temp_allocator.
  148. but are followed by the necessary `delete` and `free` calls if the allocator supports them.
  149. This is helpful when the CBOR size is so big that you don't want to collect all the temporary
  150. allocations until the end.
  151. */
  152. encode_into :: proc {
  153. encode_into_bytes,
  154. encode_into_builder,
  155. encode_into_writer,
  156. encode_into_encoder,
  157. }
  158. encode :: encode_into
  159. // Encodes the CBOR value into binary CBOR allocated on the given allocator.
  160. // See the docs on the proc group `encode_into` for more info.
  161. encode_into_bytes :: proc(v: Value, flags := ENCODE_SMALL, allocator := context.allocator, temp_allocator := context.temp_allocator) -> (data: []byte, err: Encode_Error) {
  162. b := strings.builder_make(allocator) or_return
  163. encode_into_builder(&b, v, flags, temp_allocator) or_return
  164. return b.buf[:], nil
  165. }
  166. // Encodes the CBOR value into binary CBOR written to the given builder.
  167. // See the docs on the proc group `encode_into` for more info.
  168. encode_into_builder :: proc(b: ^strings.Builder, v: Value, flags := ENCODE_SMALL, temp_allocator := context.temp_allocator) -> Encode_Error {
  169. return encode_into_writer(strings.to_stream(b), v, flags, temp_allocator)
  170. }
  171. // Encodes the CBOR value into binary CBOR written to the given writer.
  172. // See the docs on the proc group `encode_into` for more info.
  173. encode_into_writer :: proc(w: io.Writer, v: Value, flags := ENCODE_SMALL, temp_allocator := context.temp_allocator) -> Encode_Error {
  174. return encode_into_encoder(Encoder{flags, w, temp_allocator}, v)
  175. }
  176. // Encodes the CBOR value into binary CBOR written to the given encoder.
  177. // See the docs on the proc group `encode_into` for more info.
  178. encode_into_encoder :: proc(e: Encoder, v: Value) -> Encode_Error {
  179. e := e
  180. if e.temp_allocator.procedure == nil {
  181. e.temp_allocator = context.temp_allocator
  182. }
  183. if .Self_Described_CBOR in e.flags {
  184. _encode_u64(e, TAG_SELF_DESCRIBED_CBOR, .Tag) or_return
  185. e.flags &~= { .Self_Described_CBOR }
  186. }
  187. switch v_spec in v {
  188. case u8: return _encode_u8(e.writer, v_spec, .Unsigned)
  189. case u16: return _encode_u16(e, v_spec, .Unsigned)
  190. case u32: return _encode_u32(e, v_spec, .Unsigned)
  191. case u64: return _encode_u64(e, v_spec, .Unsigned)
  192. case Negative_U8: return _encode_u8(e.writer, u8(v_spec), .Negative)
  193. case Negative_U16: return _encode_u16(e, u16(v_spec), .Negative)
  194. case Negative_U32: return _encode_u32(e, u32(v_spec), .Negative)
  195. case Negative_U64: return _encode_u64(e, u64(v_spec), .Negative)
  196. case ^Bytes: return _encode_bytes(e, v_spec^)
  197. case ^Text: return _encode_text(e, v_spec^)
  198. case ^Array: return _encode_array(e, v_spec^)
  199. case ^Map: return _encode_map(e, v_spec^)
  200. case ^Tag: return _encode_tag(e, v_spec^)
  201. case Simple: return _encode_simple(e.writer, v_spec)
  202. case f16: return _encode_f16(e.writer, v_spec)
  203. case f32: return _encode_f32(e, v_spec)
  204. case f64: return _encode_f64(e, v_spec)
  205. case bool: return _encode_bool(e.writer, v_spec)
  206. case Nil: return _encode_nil(e.writer)
  207. case Undefined: return _encode_undefined(e.writer)
  208. case: return nil
  209. }
  210. }
  211. _decode_header :: proc(r: io.Reader) -> (hdr: Header, err: io.Error) {
  212. hdr = Header(_decode_u8(r) or_return)
  213. return
  214. }
  215. _header_split :: proc(hdr: Header) -> (Major, Add) {
  216. return Major(u8(hdr) >> 5), Add(u8(hdr) & 0x1f)
  217. }
  218. _decode_u8 :: proc(r: io.Reader) -> (v: u8, err: io.Error) {
  219. byte: [1]byte = ---
  220. io.read_full(r, byte[:]) or_return
  221. return byte[0], nil
  222. }
  223. _encode_uint :: proc {
  224. _encode_u8,
  225. _encode_u16,
  226. _encode_u32,
  227. _encode_u64,
  228. }
  229. _encode_u8 :: proc(w: io.Writer, v: u8, major: Major = .Unsigned) -> (err: io.Error) {
  230. header := u8(major) << 5
  231. if v < u8(Add.One_Byte) {
  232. header |= v
  233. _, err = io.write_full(w, {header})
  234. return
  235. }
  236. header |= u8(Add.One_Byte)
  237. _, err = io.write_full(w, {header, v})
  238. return
  239. }
  240. _decode_tiny_u8 :: proc(additional: Add) -> (u8, Decode_Data_Error) {
  241. if additional < .One_Byte {
  242. return u8(additional), nil
  243. }
  244. return 0, .Bad_Argument
  245. }
  246. _decode_u16 :: proc(r: io.Reader) -> (v: u16, err: io.Error) {
  247. bytes: [2]byte = ---
  248. io.read_full(r, bytes[:]) or_return
  249. return endian.unchecked_get_u16be(bytes[:]), nil
  250. }
  251. _encode_u16 :: proc(e: Encoder, v: u16, major: Major = .Unsigned) -> Encode_Error {
  252. if .Deterministic_Int_Size in e.flags {
  253. return _encode_deterministic_uint(e.writer, v, major)
  254. }
  255. return _encode_u16_exact(e.writer, v, major)
  256. }
  257. _encode_u16_exact :: proc(w: io.Writer, v: u16, major: Major = .Unsigned) -> (err: io.Error) {
  258. bytes: [3]byte = ---
  259. bytes[0] = (u8(major) << 5) | u8(Add.Two_Bytes)
  260. endian.unchecked_put_u16be(bytes[1:], v)
  261. _, err = io.write_full(w, bytes[:])
  262. return
  263. }
  264. _decode_u32 :: proc(r: io.Reader) -> (v: u32, err: io.Error) {
  265. bytes: [4]byte = ---
  266. io.read_full(r, bytes[:]) or_return
  267. return endian.unchecked_get_u32be(bytes[:]), nil
  268. }
  269. _encode_u32 :: proc(e: Encoder, v: u32, major: Major = .Unsigned) -> Encode_Error {
  270. if .Deterministic_Int_Size in e.flags {
  271. return _encode_deterministic_uint(e.writer, v, major)
  272. }
  273. return _encode_u32_exact(e.writer, v, major)
  274. }
  275. _encode_u32_exact :: proc(w: io.Writer, v: u32, major: Major = .Unsigned) -> (err: io.Error) {
  276. bytes: [5]byte = ---
  277. bytes[0] = (u8(major) << 5) | u8(Add.Four_Bytes)
  278. endian.unchecked_put_u32be(bytes[1:], v)
  279. _, err = io.write_full(w, bytes[:])
  280. return
  281. }
  282. _decode_u64 :: proc(r: io.Reader) -> (v: u64, err: io.Error) {
  283. bytes: [8]byte = ---
  284. io.read_full(r, bytes[:]) or_return
  285. return endian.unchecked_get_u64be(bytes[:]), nil
  286. }
  287. _encode_u64 :: proc(e: Encoder, v: u64, major: Major = .Unsigned) -> Encode_Error {
  288. if .Deterministic_Int_Size in e.flags {
  289. return _encode_deterministic_uint(e.writer, v, major)
  290. }
  291. return _encode_u64_exact(e.writer, v, major)
  292. }
  293. _encode_u64_exact :: proc(w: io.Writer, v: u64, major: Major = .Unsigned) -> (err: io.Error) {
  294. bytes: [9]byte = ---
  295. bytes[0] = (u8(major) << 5) | u8(Add.Eight_Bytes)
  296. endian.unchecked_put_u64be(bytes[1:], v)
  297. _, err = io.write_full(w, bytes[:])
  298. return
  299. }
  300. _decode_bytes_ptr :: proc(d: Decoder, add: Add, type: Major = .Bytes) -> (v: ^Bytes, err: Decode_Error) {
  301. v = new(Bytes) or_return
  302. defer if err != nil { free(v) }
  303. v^ = _decode_bytes(d, add, type) or_return
  304. return
  305. }
  306. _decode_bytes :: proc(d: Decoder, add: Add, type: Major = .Bytes, allocator := context.allocator) -> (v: Bytes, err: Decode_Error) {
  307. context.allocator = allocator
  308. add := add
  309. n, scap := _decode_len_str(d, add) or_return
  310. buf := strings.builder_make(0, scap) or_return
  311. defer if err != nil { strings.builder_destroy(&buf) }
  312. buf_stream := strings.to_stream(&buf)
  313. if n == -1 {
  314. indefinite_loop: for {
  315. header := _decode_header(d.reader) or_return
  316. maj: Major
  317. maj, add = _header_split(header)
  318. #partial switch maj {
  319. case type:
  320. iter_n, iter_cap := _decode_len_str(d, add) or_return
  321. if iter_n == -1 {
  322. return nil, .Nested_Indefinite_Length
  323. }
  324. reserve(&buf.buf, len(buf.buf) + iter_cap) or_return
  325. io.copy_n(buf_stream, d.reader, i64(iter_n)) or_return
  326. case .Other:
  327. if add != .Break { return nil, .Bad_Argument }
  328. break indefinite_loop
  329. case:
  330. return nil, .Bad_Major
  331. }
  332. }
  333. } else {
  334. io.copy_n(buf_stream, d.reader, i64(n)) or_return
  335. }
  336. v = buf.buf[:]
  337. // Write zero byte so this can be converted to cstring.
  338. strings.write_byte(&buf, 0)
  339. if .Shrink_Excess in d.flags { shrink(&buf.buf) }
  340. return
  341. }
  342. _encode_bytes :: proc(e: Encoder, val: Bytes, major: Major = .Bytes) -> (err: Encode_Error) {
  343. assert(len(val) >= 0)
  344. _encode_u64(e, u64(len(val)), major) or_return
  345. _, err = io.write_full(e.writer, val[:])
  346. return
  347. }
  348. _decode_text_ptr :: proc(d: Decoder, add: Add) -> (v: ^Text, err: Decode_Error) {
  349. v = new(Text) or_return
  350. defer if err != nil { free(v) }
  351. v^ = _decode_text(d, add) or_return
  352. return
  353. }
  354. _decode_text :: proc(d: Decoder, add: Add, allocator := context.allocator) -> (v: Text, err: Decode_Error) {
  355. return (Text)(_decode_bytes(d, add, .Text, allocator) or_return), nil
  356. }
  357. _encode_text :: proc(e: Encoder, val: Text) -> Encode_Error {
  358. return _encode_bytes(e, transmute([]byte)val, .Text)
  359. }
  360. _decode_array_ptr :: proc(d: Decoder, add: Add) -> (v: ^Array, err: Decode_Error) {
  361. v = new(Array) or_return
  362. defer if err != nil { free(v) }
  363. v^ = _decode_array(d, add) or_return
  364. return
  365. }
  366. _decode_array :: proc(d: Decoder, add: Add) -> (v: Array, err: Decode_Error) {
  367. n, scap := _decode_len_container(d, add) or_return
  368. array := make([dynamic]Value, 0, scap) or_return
  369. defer if err != nil {
  370. for entry in array { destroy(entry) }
  371. delete(array)
  372. }
  373. for i := 0; n == -1 || i < n; i += 1 {
  374. val, verr := _decode_from_decoder(d)
  375. if n == -1 && verr == .Break {
  376. break
  377. } else if verr != nil {
  378. err = verr
  379. return
  380. }
  381. append(&array, val) or_return
  382. }
  383. if .Shrink_Excess in d.flags { shrink(&array) }
  384. v = array[:]
  385. return
  386. }
  387. _encode_array :: proc(e: Encoder, arr: Array) -> Encode_Error {
  388. assert(len(arr) >= 0)
  389. _encode_u64(e, u64(len(arr)), .Array)
  390. for val in arr {
  391. encode(e, val) or_return
  392. }
  393. return nil
  394. }
  395. _decode_map_ptr :: proc(d: Decoder, add: Add) -> (v: ^Map, err: Decode_Error) {
  396. v = new(Map) or_return
  397. defer if err != nil { free(v) }
  398. v^ = _decode_map(d, add) or_return
  399. return
  400. }
  401. _decode_map :: proc(d: Decoder, add: Add) -> (v: Map, err: Decode_Error) {
  402. n, scap := _decode_len_container(d, add) or_return
  403. items := make([dynamic]Map_Entry, 0, scap) or_return
  404. defer if err != nil {
  405. for entry in items {
  406. destroy(entry.key)
  407. destroy(entry.value)
  408. }
  409. delete(items)
  410. }
  411. for i := 0; n == -1 || i < n; i += 1 {
  412. key, kerr := _decode_from_decoder(d)
  413. if n == -1 && kerr == .Break {
  414. break
  415. } else if kerr != nil {
  416. return nil, kerr
  417. }
  418. value := _decode_from_decoder(d) or_return
  419. append(&items, Map_Entry{
  420. key = key,
  421. value = value,
  422. }) or_return
  423. }
  424. if .Shrink_Excess in d.flags { shrink(&items) }
  425. v = items[:]
  426. return
  427. }
  428. _encode_map :: proc(e: Encoder, m: Map) -> (err: Encode_Error) {
  429. assert(len(m) >= 0)
  430. _encode_u64(e, u64(len(m)), .Map) or_return
  431. if .Deterministic_Map_Sorting not_in e.flags {
  432. for entry in m {
  433. encode(e, entry.key) or_return
  434. encode(e, entry.value) or_return
  435. }
  436. return
  437. }
  438. // Deterministic_Map_Sorting needs us to sort the entries by the byte contents of the
  439. // encoded key.
  440. //
  441. // This means we have to store and sort them before writing incurring extra (temporary) allocations.
  442. Map_Entry_With_Key :: struct {
  443. encoded_key: []byte,
  444. entry: Map_Entry,
  445. }
  446. entries := make([]Map_Entry_With_Key, len(m), e.temp_allocator) or_return
  447. defer delete(entries, e.temp_allocator)
  448. for &entry, i in entries {
  449. entry.entry = m[i]
  450. buf := strings.builder_make(e.temp_allocator) or_return
  451. ke := e
  452. ke.writer = strings.to_stream(&buf)
  453. encode(ke, entry.entry.key) or_return
  454. entry.encoded_key = buf.buf[:]
  455. }
  456. // Sort lexicographic on the bytes of the key.
  457. slice.sort_by_cmp(entries, proc(a, b: Map_Entry_With_Key) -> slice.Ordering {
  458. return slice.Ordering(bytes.compare(a.encoded_key, b.encoded_key))
  459. })
  460. for entry in entries {
  461. io.write_full(e.writer, entry.encoded_key) or_return
  462. delete(entry.encoded_key, e.temp_allocator)
  463. encode(e, entry.entry.value) or_return
  464. }
  465. return nil
  466. }
  467. _decode_tag_ptr :: proc(d: Decoder, add: Add) -> (v: Value, err: Decode_Error) {
  468. tag := _decode_tag(d, add) or_return
  469. if t, ok := tag.?; ok {
  470. defer if err != nil { destroy(t.value) }
  471. tp := new(Tag) or_return
  472. tp^ = t
  473. return tp, nil
  474. }
  475. // no error, no tag, this was the self described CBOR tag, skip it.
  476. return _decode_from_decoder(d)
  477. }
  478. _decode_tag :: proc(d: Decoder, add: Add) -> (v: Maybe(Tag), err: Decode_Error) {
  479. num := _decode_uint_as_u64(d.reader, add) or_return
  480. // CBOR can be wrapped in a tag that decoders can use to see/check if the binary data is CBOR.
  481. // We can ignore it here.
  482. if num == TAG_SELF_DESCRIBED_CBOR {
  483. return
  484. }
  485. t := Tag{
  486. number = num,
  487. value = _decode_from_decoder(d) or_return,
  488. }
  489. if nested, ok := t.value.(^Tag); ok {
  490. destroy(nested)
  491. return nil, .Nested_Tag
  492. }
  493. return t, nil
  494. }
  495. _decode_uint_as_u64 :: proc(r: io.Reader, add: Add) -> (nr: u64, err: Decode_Error) {
  496. #partial switch add {
  497. case .One_Byte: return u64(_decode_u8(r) or_return), nil
  498. case .Two_Bytes: return u64(_decode_u16(r) or_return), nil
  499. case .Four_Bytes: return u64(_decode_u32(r) or_return), nil
  500. case .Eight_Bytes: return u64(_decode_u64(r) or_return), nil
  501. case: return u64(_decode_tiny_u8(add) or_return), nil
  502. }
  503. }
  504. _encode_tag :: proc(e: Encoder, val: Tag) -> Encode_Error {
  505. _encode_u64(e, val.number, .Tag) or_return
  506. return encode(e, val.value)
  507. }
  508. _decode_simple :: proc(r: io.Reader) -> (v: Simple, err: io.Error) {
  509. buf: [1]byte = ---
  510. io.read_full(r, buf[:]) or_return
  511. return Simple(buf[0]), nil
  512. }
  513. _encode_simple :: proc(w: io.Writer, v: Simple) -> (err: Encode_Error) {
  514. header := u8(Major.Other) << 5
  515. if v < Simple(Add.False) {
  516. header |= u8(v)
  517. _, err = io.write_full(w, {header})
  518. return
  519. } else if v <= Simple(Add.Break) {
  520. return .Invalid_Simple
  521. }
  522. header |= u8(Add.One_Byte)
  523. _, err = io.write_full(w, {header, u8(v)})
  524. return
  525. }
  526. _decode_tiny_simple :: proc(add: Add) -> (Simple, Decode_Data_Error) {
  527. if add < Add.False {
  528. return Simple(add), nil
  529. }
  530. return 0, .Bad_Argument
  531. }
  532. _decode_f16 :: proc(r: io.Reader) -> (v: f16, err: io.Error) {
  533. bytes: [2]byte = ---
  534. io.read_full(r, bytes[:]) or_return
  535. n := endian.unchecked_get_u16be(bytes[:])
  536. return transmute(f16)n, nil
  537. }
  538. _encode_f16 :: proc(w: io.Writer, v: f16) -> (err: io.Error) {
  539. bytes: [3]byte = ---
  540. bytes[0] = u8(Header.F16)
  541. endian.unchecked_put_u16be(bytes[1:], transmute(u16)v)
  542. _, err = io.write_full(w, bytes[:])
  543. return
  544. }
  545. _decode_f32 :: proc(r: io.Reader) -> (v: f32, err: io.Error) {
  546. bytes: [4]byte = ---
  547. io.read_full(r, bytes[:]) or_return
  548. n := endian.unchecked_get_u32be(bytes[:])
  549. return transmute(f32)n, nil
  550. }
  551. _encode_f32 :: proc(e: Encoder, v: f32) -> io.Error {
  552. if .Deterministic_Float_Size in e.flags {
  553. return _encode_deterministic_float(e.writer, v)
  554. }
  555. return _encode_f32_exact(e.writer, v)
  556. }
  557. _encode_f32_exact :: proc(w: io.Writer, v: f32) -> (err: io.Error) {
  558. bytes: [5]byte = ---
  559. bytes[0] = u8(Header.F32)
  560. endian.unchecked_put_u32be(bytes[1:], transmute(u32)v)
  561. _, err = io.write_full(w, bytes[:])
  562. return
  563. }
  564. _decode_f64 :: proc(r: io.Reader) -> (v: f64, err: io.Error) {
  565. bytes: [8]byte = ---
  566. io.read_full(r, bytes[:]) or_return
  567. n := endian.unchecked_get_u64be(bytes[:])
  568. return transmute(f64)n, nil
  569. }
  570. _encode_f64 :: proc(e: Encoder, v: f64) -> io.Error {
  571. if .Deterministic_Float_Size in e.flags {
  572. return _encode_deterministic_float(e.writer, v)
  573. }
  574. return _encode_f64_exact(e.writer, v)
  575. }
  576. _encode_f64_exact :: proc(w: io.Writer, v: f64) -> (err: io.Error) {
  577. bytes: [9]byte = ---
  578. bytes[0] = u8(Header.F64)
  579. endian.unchecked_put_u64be(bytes[1:], transmute(u64)v)
  580. _, err = io.write_full(w, bytes[:])
  581. return
  582. }
  583. _encode_bool :: proc(w: io.Writer, v: bool) -> (err: io.Error) {
  584. switch v {
  585. case true: _, err = io.write_full(w, {u8(Header.True )}); return
  586. case false: _, err = io.write_full(w, {u8(Header.False)}); return
  587. case: unreachable()
  588. }
  589. }
  590. _encode_undefined :: proc(w: io.Writer) -> io.Error {
  591. _, err := io.write_full(w, {u8(Header.Undefined)})
  592. return err
  593. }
  594. _encode_nil :: proc(w: io.Writer) -> io.Error {
  595. _, err := io.write_full(w, {u8(Header.Nil)})
  596. return err
  597. }
  598. // Streaming
  599. encode_stream_begin :: proc(w: io.Writer, major: Major) -> (err: io.Error) {
  600. assert(major >= Major(.Bytes) && major <= Major(.Map), "illegal stream type")
  601. header := (u8(major) << 5) | u8(Add.Length_Unknown)
  602. _, err = io.write_full(w, {header})
  603. return
  604. }
  605. encode_stream_end :: proc(w: io.Writer) -> io.Error {
  606. header := (u8(Major.Other) << 5) | u8(Add.Break)
  607. _, err := io.write_full(w, {header})
  608. return err
  609. }
  610. encode_stream_bytes :: _encode_bytes
  611. encode_stream_text :: _encode_text
  612. encode_stream_array_item :: encode
  613. encode_stream_map_entry :: proc(e: Encoder, key: Value, val: Value) -> Encode_Error {
  614. encode(e, key) or_return
  615. return encode(e, val)
  616. }
  617. // For `Bytes` and `Text` strings: Decodes the number of items the header says follows.
  618. // If the number is not specified -1 is returned and streaming should be initiated.
  619. // A suitable starting capacity is also returned for a buffer that is allocated up the stack.
  620. _decode_len_str :: proc(d: Decoder, add: Add) -> (n: int, scap: int, err: Decode_Error) {
  621. if add == .Length_Unknown {
  622. if .Disallow_Streaming in d.flags {
  623. return -1, -1, .Disallowed_Streaming
  624. }
  625. return -1, INITIAL_STREAMED_BYTES_CAPACITY, nil
  626. }
  627. _n := _decode_uint_as_u64(d.reader, add) or_return
  628. if _n > u64(max(int)) { return -1, -1, .Length_Too_Big }
  629. n = int(_n)
  630. scap = n + 1 // Space for zero byte.
  631. if .Trusted_Input not_in d.flags {
  632. scap = min(d.max_pre_alloc, scap)
  633. }
  634. return
  635. }
  636. // For `Array` and `Map` types: Decodes the number of items the header says follows.
  637. // If the number is not specified -1 is returned and streaming should be initiated.
  638. // A suitable starting capacity is also returned for a buffer that is allocated up the stack.
  639. _decode_len_container :: proc(d: Decoder, add: Add) -> (n: int, scap: int, err: Decode_Error) {
  640. if add == .Length_Unknown {
  641. if .Disallow_Streaming in d.flags {
  642. return -1, -1, .Disallowed_Streaming
  643. }
  644. return -1, INITIAL_STREAMED_CONTAINER_CAPACITY, nil
  645. }
  646. _n := _decode_uint_as_u64(d.reader, add) or_return
  647. if _n > u64(max(int)) { return -1, -1, .Length_Too_Big }
  648. n = int(_n)
  649. scap = n
  650. if .Trusted_Input not_in d.flags {
  651. // NOTE: if this is a map it will be twice this.
  652. scap = min(d.max_pre_alloc / size_of(Value), scap)
  653. }
  654. return
  655. }
  656. // Deterministic encoding is (among other things) encoding all values into their smallest
  657. // possible representation.
  658. // See section 4 of RFC 8949.
  659. _encode_deterministic_uint :: proc {
  660. _encode_u8,
  661. _encode_deterministic_u16,
  662. _encode_deterministic_u32,
  663. _encode_deterministic_u64,
  664. _encode_deterministic_u128,
  665. }
  666. _encode_deterministic_u16 :: proc(w: io.Writer, v: u16, major: Major = .Unsigned) -> Encode_Error {
  667. switch {
  668. case v <= u16(max(u8)): return _encode_u8(w, u8(v), major)
  669. case: return _encode_u16_exact(w, v, major)
  670. }
  671. }
  672. _encode_deterministic_u32 :: proc(w: io.Writer, v: u32, major: Major = .Unsigned) -> Encode_Error {
  673. switch {
  674. case v <= u32(max(u8)): return _encode_u8(w, u8(v), major)
  675. case v <= u32(max(u16)): return _encode_u16_exact(w, u16(v), major)
  676. case: return _encode_u32_exact(w, u32(v), major)
  677. }
  678. }
  679. _encode_deterministic_u64 :: proc(w: io.Writer, v: u64, major: Major = .Unsigned) -> Encode_Error {
  680. switch {
  681. case v <= u64(max(u8)): return _encode_u8(w, u8(v), major)
  682. case v <= u64(max(u16)): return _encode_u16_exact(w, u16(v), major)
  683. case v <= u64(max(u32)): return _encode_u32_exact(w, u32(v), major)
  684. case: return _encode_u64_exact(w, u64(v), major)
  685. }
  686. }
  687. _encode_deterministic_u128 :: proc(w: io.Writer, v: u128, major: Major = .Unsigned) -> Encode_Error {
  688. switch {
  689. case v <= u128(max(u8)): return _encode_u8(w, u8(v), major)
  690. case v <= u128(max(u16)): return _encode_u16_exact(w, u16(v), major)
  691. case v <= u128(max(u32)): return _encode_u32_exact(w, u32(v), major)
  692. case v <= u128(max(u64)): return _encode_u64_exact(w, u64(v), major)
  693. case: return .Int_Too_Big
  694. }
  695. }
  696. _encode_deterministic_negative :: #force_inline proc(w: io.Writer, v: $T) -> Encode_Error
  697. where T == Negative_U8 || T == Negative_U16 || T == Negative_U32 || T == Negative_U64 {
  698. return _encode_deterministic_uint(w, v, .Negative)
  699. }
  700. // A Deterministic float is a float in the smallest type that stays the same after down casting.
  701. _encode_deterministic_float :: proc {
  702. _encode_f16,
  703. _encode_deterministic_f32,
  704. _encode_deterministic_f64,
  705. }
  706. _encode_deterministic_f32 :: proc(w: io.Writer, v: f32) -> io.Error {
  707. if (f32(f16(v)) == v) {
  708. return _encode_f16(w, f16(v))
  709. }
  710. return _encode_f32_exact(w, v)
  711. }
  712. _encode_deterministic_f64 :: proc(w: io.Writer, v: f64) -> io.Error {
  713. if (f64(f16(v)) == v) {
  714. return _encode_f16(w, f16(v))
  715. }
  716. if (f64(f32(v)) == v) {
  717. return _encode_f32_exact(w, f32(v))
  718. }
  719. return _encode_f64_exact(w, v)
  720. }