diff options
Diffstat (limited to 'core/encoding/json')
| -rw-r--r-- | core/encoding/json/marshal.odin | 78 | ||||
| -rw-r--r-- | core/encoding/json/unmarshal.odin | 30 |
2 files changed, 67 insertions, 41 deletions
diff --git a/core/encoding/json/marshal.odin b/core/encoding/json/marshal.odin index fa86d3468..009bf7ade 100644 --- a/core/encoding/json/marshal.odin +++ b/core/encoding/json/marshal.odin @@ -100,38 +100,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case runtime.Type_Info_Integer: buf: [40]byte - u: u128 - switch i in a { - case i8: u = u128(i) - case i16: u = u128(i) - case i32: u = u128(i) - case i64: u = u128(i) - case i128: u = u128(i) - case int: u = u128(i) - case u8: u = u128(i) - case u16: u = u128(i) - case u32: u = u128(i) - case u64: u = u128(i) - case u128: u = u128(i) - case uint: u = u128(i) - case uintptr: u = u128(i) - - case i16le: u = u128(i) - case i32le: u = u128(i) - case i64le: u = u128(i) - case u16le: u = u128(i) - case u32le: u = u128(i) - case u64le: u = u128(i) - case u128le: u = u128(i) - - case i16be: u = u128(i) - case i32be: u = u128(i) - case i64be: u = u128(i) - case u16be: u = u128(i) - case u32be: u = u128(i) - case u64be: u = u128(i) - case u128be: u = u128(i) - } + u := cast_any_int_to_u128(a) s: string @@ -310,7 +279,12 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err: case cstring: name = string(s) } opt_write_key(w, opt, name) or_return - + case runtime.Type_Info_Integer: + buf: [40]byte + u := cast_any_int_to_u128(ka) + name = strconv.append_bits_128(buf[:], u, 10, info.signed, 8*kti.size, "0123456789", nil) + + opt_write_key(w, opt, name) or_return case: return .Unsupported_Type } } @@ -662,3 +636,41 @@ opt_write_indentation :: proc(w: io.Writer, opt: ^Marshal_Options) -> (err: io.E return } + +@(private) +cast_any_int_to_u128 :: proc(any_int_value: any) -> u128 { + u: u128 = 0 + switch i in any_int_value { + case i8: u = u128(i) + case i16: u = u128(i) + case i32: u = u128(i) + case i64: u = u128(i) + case i128: u = u128(i) + case int: u = u128(i) + case u8: u = u128(i) + case u16: u = u128(i) + case u32: u = u128(i) + case u64: u = u128(i) + case u128: u = u128(i) + case uint: u = u128(i) + case uintptr: u = u128(i) + + case i16le: u = u128(i) + case i32le: u = u128(i) + case i64le: u = u128(i) + case u16le: u = u128(i) + case u32le: u = u128(i) + case u64le: u = u128(i) + case u128le: u = u128(i) + + case i16be: u = u128(i) + case i32be: u = u128(i) + case i64be: u = u128(i) + case u16be: u = u128(i) + case u32be: u = u128(i) + case u64be: u = u128(i) + case u128be: u = u128(i) + } + + return u +}
\ No newline at end of file diff --git a/core/encoding/json/unmarshal.odin b/core/encoding/json/unmarshal.odin index 344d2973e..1c1801bcd 100644 --- a/core/encoding/json/unmarshal.odin +++ b/core/encoding/json/unmarshal.odin @@ -475,7 +475,7 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm } case reflect.Type_Info_Map: - if !reflect.is_string(t.key) { + if !reflect.is_string(t.key) && !reflect.is_integer(t.key) { return UNSUPPORTED_TYPE } raw_map := (^mem.Raw_Map)(v.data) @@ -492,25 +492,39 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm key, _ := parse_object_key(p, p.allocator) unmarshal_expect_token(p, .Colon) - + mem.zero_slice(elem_backing) if uerr := unmarshal_value(p, map_backing_value); uerr != nil { delete(key, p.allocator) return uerr } - key_ptr := rawptr(&key) + key_ptr: rawptr - key_cstr: cstring - if reflect.is_cstring(t.key) { - key_cstr = cstring(raw_data(key)) - key_ptr = &key_cstr + #partial switch tk in t.key.variant { + case runtime.Type_Info_String: + key_ptr = rawptr(&key) + key_cstr: cstring + if reflect.is_cstring(t.key) { + key_cstr = cstring(raw_data(key)) + key_ptr = &key_cstr + } + case runtime.Type_Info_Integer: + i, ok := strconv.parse_i128(key) + if !ok { return UNSUPPORTED_TYPE } + key_ptr = rawptr(&i) + case: return UNSUPPORTED_TYPE } - + set_ptr := runtime.__dynamic_map_set_without_hash(raw_map, t.map_info, key_ptr, map_backing_value.data) if set_ptr == nil { delete(key, p.allocator) } + + // there's no need to keep string value on the heap, since it was copied into map + if reflect.is_integer(t.key) { + delete(key, p.allocator) + } if parse_comma(p) { break map_loop |