mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-29 16:51:49 -07:00
Merge branch 'odin-lang:master' into master
This commit is contained in:
@@ -108,13 +108,13 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
if opt.write_uint_as_hex && (opt.spec == .JSON5 || opt.spec == .MJSON) {
|
||||
switch i in a {
|
||||
case u8, u16, u32, u64, u128:
|
||||
s = strconv.append_bits_128(buf[:], u, 16, info.signed, 8*ti.size, "0123456789abcdef", { .Prefix })
|
||||
s = strconv.write_bits_128(buf[:], u, 16, info.signed, 8*ti.size, "0123456789abcdef", { .Prefix })
|
||||
|
||||
case:
|
||||
s = strconv.append_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
|
||||
s = strconv.write_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
|
||||
}
|
||||
} else {
|
||||
s = strconv.append_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
|
||||
s = strconv.write_bits_128(buf[:], u, 10, info.signed, 8*ti.size, "0123456789", nil)
|
||||
}
|
||||
|
||||
io.write_string(w, s) or_return
|
||||
@@ -292,7 +292,7 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
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)
|
||||
name = strconv.write_bits_128(buf[:], u, 10, info.signed, 8*kti.size, "0123456789", nil)
|
||||
|
||||
opt_write_key(w, opt, name) or_return
|
||||
case: return .Unsupported_Type
|
||||
@@ -359,10 +359,10 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
||||
#partial switch info in ti.variant {
|
||||
case runtime.Type_Info_String:
|
||||
switch x in v {
|
||||
case string:
|
||||
return x == ""
|
||||
case cstring:
|
||||
return x == nil || x == ""
|
||||
case string: return x == ""
|
||||
case cstring: return x == nil || x == ""
|
||||
case string16: return x == ""
|
||||
case cstring16: return x == nil || x == ""
|
||||
}
|
||||
case runtime.Type_Info_Any:
|
||||
return v.(any) == nil
|
||||
|
||||
@@ -101,7 +101,7 @@ get_token :: proc(t: ^Tokenizer) -> (token: Token, err: Error) {
|
||||
}
|
||||
}
|
||||
|
||||
scan_espace :: proc(t: ^Tokenizer) -> bool {
|
||||
scan_escape :: proc(t: ^Tokenizer) -> bool {
|
||||
switch t.r {
|
||||
case '"', '\'', '\\', '/', 'b', 'n', 'r', 't', 'f':
|
||||
next_rune(t)
|
||||
@@ -310,7 +310,7 @@ get_token :: proc(t: ^Tokenizer) -> (token: Token, err: Error) {
|
||||
break
|
||||
}
|
||||
if r == '\\' {
|
||||
scan_espace(t)
|
||||
scan_escape(t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -117,9 +117,25 @@ assign_int :: proc(val: any, i: $T) -> bool {
|
||||
case uint: dst = uint (i)
|
||||
case uintptr: dst = uintptr(i)
|
||||
case:
|
||||
is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool {
|
||||
if ti == nil {
|
||||
return false
|
||||
}
|
||||
t := runtime.type_info_base(ti)
|
||||
#partial switch info in t.variant {
|
||||
case runtime.Type_Info_Integer:
|
||||
switch info.endianness {
|
||||
case .Platform: return false
|
||||
case .Little: return ODIN_ENDIAN != .Little
|
||||
case .Big: return ODIN_ENDIAN != .Big
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
ti := type_info_of(v.id)
|
||||
if _, ok := ti.variant.(runtime.Type_Info_Bit_Set); ok {
|
||||
do_byte_swap := !reflect.bit_set_is_big_endian(v)
|
||||
if info, ok := ti.variant.(runtime.Type_Info_Bit_Set); ok {
|
||||
do_byte_swap := is_bit_set_different_endian_to_platform(info.underlying)
|
||||
switch ti.size * 8 {
|
||||
case 0: // no-op.
|
||||
case 8:
|
||||
@@ -390,6 +406,9 @@ unmarshal_expect_token :: proc(p: ^Parser, kind: Token_Kind, loc := #caller_loca
|
||||
return prev
|
||||
}
|
||||
|
||||
// Struct tags can include not only the name of the JSON key, but also a tag such as `omitempty`.
|
||||
// Example: `json:"key_name,omitempty"`
|
||||
// This returns the first field as `json_name`, and the rest are returned as `extra`.
|
||||
@(private)
|
||||
json_name_from_tag_value :: proc(value: string) -> (json_name, extra: string) {
|
||||
json_name = value
|
||||
@@ -425,12 +444,6 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
||||
defer delete(key, p.allocator)
|
||||
|
||||
unmarshal_expect_token(p, .Colon)
|
||||
|
||||
field_test :: #force_inline proc "contextless" (field_used: [^]byte, offset: uintptr) -> bool {
|
||||
prev_set := field_used[offset/8] & byte(offset&7) != 0
|
||||
field_used[offset/8] |= byte(offset&7)
|
||||
return prev_set
|
||||
}
|
||||
|
||||
field_used_bytes := (reflect.size_of_typeid(ti.id)+7)/8
|
||||
field_used := intrinsics.alloca(field_used_bytes + 1, 1) // + 1 to not overflow on size_of 0 types.
|
||||
@@ -449,7 +462,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
||||
|
||||
if use_field_idx < 0 {
|
||||
for field, field_idx in fields {
|
||||
if key == field.name {
|
||||
tag_value := reflect.struct_tag_get(field.tag, "json")
|
||||
json_name, _ := json_name_from_tag_value(tag_value)
|
||||
if json_name == "" && key == field.name {
|
||||
use_field_idx = field_idx
|
||||
break
|
||||
}
|
||||
@@ -470,7 +485,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
||||
}
|
||||
}
|
||||
|
||||
if field.name == key || (field.tag != "" && reflect.struct_tag_get(field.tag, "json") == key) {
|
||||
tag_value := reflect.struct_tag_get(field.tag, "json")
|
||||
json_name, _ := json_name_from_tag_value(tag_value)
|
||||
if (json_name == "" && field.name == key) || json_name == key {
|
||||
offset = field.offset
|
||||
type = field.type
|
||||
found = true
|
||||
@@ -492,6 +509,11 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
||||
}
|
||||
|
||||
if field_found {
|
||||
field_test :: #force_inline proc "contextless" (field_used: [^]byte, offset: uintptr) -> bool {
|
||||
prev_set := field_used[offset/8] & byte(offset&7) != 0
|
||||
field_used[offset/8] |= byte(offset&7)
|
||||
return prev_set
|
||||
}
|
||||
if field_test(field_used, offset) {
|
||||
return .Multiple_Use_Field
|
||||
}
|
||||
@@ -548,7 +570,9 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
||||
key_ptr: rawptr
|
||||
|
||||
#partial switch tk in t.key.variant {
|
||||
case runtime.Type_Info_String:
|
||||
case runtime.Type_Info_String:
|
||||
assert(tk.encoding == .UTF_8)
|
||||
|
||||
key_ptr = rawptr(&key)
|
||||
key_cstr: cstring
|
||||
if reflect.is_cstring(t.key) {
|
||||
|
||||
Reference in New Issue
Block a user