diff options
| author | Laytan Laats <laytanlaats@hotmail.com> | 2024-08-09 21:56:54 +0200 |
|---|---|---|
| committer | Laytan Laats <laytanlaats@hotmail.com> | 2024-08-09 21:56:54 +0200 |
| commit | 912f99abc8942dd4d1111ccd8f892e8c8e52b29b (patch) | |
| tree | c885b4853f1e003a06c50ce05ca55d5737e47c2a /core/encoding | |
| parent | c5ed7083d2fa4c47adb61dd529475194515cc74f (diff) | |
encoding/cbor: various fixes
- "null" is the proper way to represent the nil value in the diagnostic
format
- hex encoding in diagnostic format was wrong
- struct keys weren't sorted the right deterministic way
Diffstat (limited to 'core/encoding')
| -rw-r--r-- | core/encoding/cbor/cbor.odin | 5 | ||||
| -rw-r--r-- | core/encoding/cbor/marshal.odin | 18 | ||||
| -rw-r--r-- | core/encoding/hex/hex.odin | 7 |
3 files changed, 20 insertions, 10 deletions
diff --git a/core/encoding/cbor/cbor.odin b/core/encoding/cbor/cbor.odin index 7897b2a37..692be0020 100644 --- a/core/encoding/cbor/cbor.odin +++ b/core/encoding/cbor/cbor.odin @@ -3,6 +3,7 @@ package encoding_cbor import "base:intrinsics" import "core:encoding/json" +import "core:encoding/hex" import "core:io" import "core:mem" import "core:strconv" @@ -399,11 +400,11 @@ to_diagnostic_format_writer :: proc(w: io.Writer, val: Value, padding := 0) -> i io.write_string(w, str) or_return case bool: io.write_string(w, "true" if v else "false") or_return - case Nil: io.write_string(w, "nil") or_return + case Nil: io.write_string(w, "null") or_return case Undefined: io.write_string(w, "undefined") or_return case ^Bytes: io.write_string(w, "h'") or_return - for b in v { io.write_int(w, int(b), 16) or_return } + hex.encode_into_writer(w, v^) or_return io.write_string(w, "'") or_return case ^Text: io.write_string(w, `"`) or_return diff --git a/core/encoding/cbor/marshal.odin b/core/encoding/cbor/marshal.odin index 6657807f5..aca71deb2 100644 --- a/core/encoding/cbor/marshal.odin +++ b/core/encoding/cbor/marshal.odin @@ -481,9 +481,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er } } - marshal_entry :: #force_inline proc(e: Encoder, info: runtime.Type_Info_Struct, v: any, name: string, i: int) -> Marshal_Error { - err_conv(_encode_text(e, name)) or_return - + marshal_entry :: #force_inline proc(e: Encoder, info: runtime.Type_Info_Struct, v: any, i: int) -> Marshal_Error { id := info.types[i].id data := rawptr(uintptr(v.data) + info.offsets[i]) field_any := any{data, id} @@ -517,7 +515,7 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er if .Deterministic_Map_Sorting in e.flags { Name :: struct { - name: string, + name: []byte, field: int, } entries := make([dynamic]Name, 0, n, e.temp_allocator) or_return @@ -529,16 +527,19 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er continue } - append(&entries, Name{fname, i}) or_return + key_builder := strings.builder_make(e.temp_allocator) or_return + err_conv(_encode_text(Encoder{e.flags, strings.to_stream(&key_builder), e.temp_allocator}, fname)) or_return + append(&entries, Name{key_builder.buf[:], i}) or_return } // Sort lexicographic on the bytes of the key. slice.sort_by_cmp(entries[:], proc(a, b: Name) -> slice.Ordering { - return slice.Ordering(bytes.compare(transmute([]byte)a.name, transmute([]byte)b.name)) + return slice.Ordering(bytes.compare(a.name, b.name)) }) for entry in entries { - marshal_entry(e, info, v, entry.name, entry.field) or_return + io.write_full(e.writer, entry.name) or_return + marshal_entry(e, info, v, entry.field) or_return } } else { for _, i in info.names[:info.field_count] { @@ -547,7 +548,8 @@ _marshal_into_encoder :: proc(e: Encoder, v: any, ti: ^runtime.Type_Info) -> (er continue } - marshal_entry(e, info, v, fname, i) or_return + err_conv(_encode_text(e, fname)) or_return + marshal_entry(e, info, v, i) or_return } } return diff --git a/core/encoding/hex/hex.odin b/core/encoding/hex/hex.odin index c2cd89c5b..c1753003e 100644 --- a/core/encoding/hex/hex.odin +++ b/core/encoding/hex/hex.odin @@ -1,5 +1,6 @@ package encoding_hex +import "core:io" import "core:strings" encode :: proc(src: []byte, allocator := context.allocator, loc := #caller_location) -> []byte #no_bounds_check { @@ -14,6 +15,12 @@ encode :: proc(src: []byte, allocator := context.allocator, loc := #caller_locat return dst } +encode_into_writer :: proc(dst: io.Writer, src: []byte) -> io.Error { + for v in src { + io.write(dst, {HEXTABLE[v>>4], HEXTABLE[v&0x0f]}) or_return + } + return nil +} decode :: proc(src: []byte, allocator := context.allocator, loc := #caller_location) -> (dst: []byte, ok: bool) #no_bounds_check { if len(src) % 2 == 1 { |