mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
encoding/cbor: deterministically store bit sets as big endian
This commit is contained in:
@@ -675,21 +675,3 @@ _i128_to_uint :: proc(v: i128) -> (u: u64, m: Major, err: Encode_Data_Error) {
|
|||||||
u, err = _u128_to_u64(u128(v))
|
u, err = _u128_to_u64(u128(v))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@(private)
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
@@ -541,7 +541,8 @@ marshal_into_encoder :: proc(e: Encoder, v: any) -> (err: Marshal_Error) {
|
|||||||
return marshal_into(e, any{v.data, info.base.id})
|
return marshal_into(e, any{v.data, info.base.id})
|
||||||
|
|
||||||
case runtime.Type_Info_Bit_Set:
|
case runtime.Type_Info_Bit_Set:
|
||||||
do_byte_swap := is_bit_set_different_endian_to_platform(info.underlying)
|
// Store bit_set as big endian just like the protocol.
|
||||||
|
do_byte_swap := !reflect.bit_set_is_big_endian(v)
|
||||||
switch ti.size * 8 {
|
switch ti.size * 8 {
|
||||||
case 0:
|
case 0:
|
||||||
return _encode_u8(e.writer, 0)
|
return _encode_u8(e.writer, 0)
|
||||||
|
|||||||
@@ -856,12 +856,11 @@ _assign_int :: proc(val: any, i: $T) -> bool {
|
|||||||
case uintptr: dst = uintptr(i)
|
case uintptr: dst = uintptr(i)
|
||||||
case:
|
case:
|
||||||
ti := type_info_of(v.id)
|
ti := type_info_of(v.id)
|
||||||
do_byte_swap := is_bit_set_different_endian_to_platform(ti)
|
if _, ok := ti.variant.(runtime.Type_Info_Bit_Set); ok {
|
||||||
#partial switch info in ti.variant {
|
do_byte_swap := !reflect.bit_set_is_big_endian(v)
|
||||||
case runtime.Type_Info_Bit_Set:
|
|
||||||
switch ti.size * 8 {
|
switch ti.size * 8 {
|
||||||
case 0:
|
case 0: // no-op.
|
||||||
case 8:
|
case 8:
|
||||||
x := (^u8)(v.data)
|
x := (^u8)(v.data)
|
||||||
x^ = u8(i)
|
x^ = u8(i)
|
||||||
case 16:
|
case 16:
|
||||||
@@ -876,9 +875,9 @@ _assign_int :: proc(val: any, i: $T) -> bool {
|
|||||||
case:
|
case:
|
||||||
panic("unknown bit_size size")
|
panic("unknown bit_size size")
|
||||||
}
|
}
|
||||||
case:
|
return true
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -934,6 +934,27 @@ set_union_value :: proc(dst: any, value: any) -> bool {
|
|||||||
panic("expected a union to reflect.set_union_variant_typeid")
|
panic("expected a union to reflect.set_union_variant_typeid")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@(require_results)
|
||||||
|
bit_set_is_big_endian :: proc(value: any, loc := #caller_location) -> bool {
|
||||||
|
if value == nil { return ODIN_ENDIAN == .Big }
|
||||||
|
|
||||||
|
ti := runtime.type_info_base(type_info_of(value.id))
|
||||||
|
if info, ok := ti.variant.(runtime.Type_Info_Bit_Set); ok {
|
||||||
|
if info.underlying == nil { return ODIN_ENDIAN == .Big }
|
||||||
|
|
||||||
|
underlying_ti := runtime.type_info_base(info.underlying)
|
||||||
|
if underlying_info, uok := underlying_ti.variant.(runtime.Type_Info_Integer); uok {
|
||||||
|
switch underlying_info.endianness {
|
||||||
|
case .Platform: return ODIN_ENDIAN == .Big
|
||||||
|
case .Little: return false
|
||||||
|
case .Big: return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ODIN_ENDIAN == .Big
|
||||||
|
}
|
||||||
|
panic("expected a bit_set to reflect.bit_set_is_big_endian", loc)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@(require_results)
|
@(require_results)
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ test_marshalling :: proc(t: ^testing.T) {
|
|||||||
],
|
],
|
||||||
"cstr": "Hellnope",
|
"cstr": "Hellnope",
|
||||||
"ennie": 0,
|
"ennie": 0,
|
||||||
"ennieb": 2,
|
"ennieb": 512,
|
||||||
"iamint": -256,
|
"iamint": -256,
|
||||||
"important": "!",
|
"important": "!",
|
||||||
"my_bytes": h'',
|
"my_bytes": h'',
|
||||||
|
|||||||
Reference in New Issue
Block a user