coding.odin 28 KB

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