fix(cbor): use int64 as main int type

This commit is contained in:
Simon Cruanes 2022-07-06 22:27:12 -04:00
parent 484aa3a1e7
commit 6a415e963a
No known key found for this signature in database
GPG key ID: EBFFF6F283F3A2B4
4 changed files with 38 additions and 39 deletions

View file

@ -5,7 +5,7 @@ type t =
| `Undefined | `Undefined
| `Simple of int | `Simple of int
| `Bool of bool | `Bool of bool
| `Int of int | `Int of int64
| `Float of float | `Float of float
| `Bytes of string | `Bytes of string
| `Text of string | `Text of string
@ -19,7 +19,7 @@ let rec pp_diagnostic out (self : t) =
| `Undefined -> Fmt.string out "undefined" | `Undefined -> Fmt.string out "undefined"
| `Simple i -> Fmt.fprintf out "simple(%d)" i | `Simple i -> Fmt.fprintf out "simple(%d)" i
| `Bool b -> Fmt.bool out b | `Bool b -> Fmt.bool out b
| `Int i -> Fmt.int out i | `Int i -> Fmt.int64 out i
| `Float f -> Fmt.float out f | `Float f -> Fmt.float out f
| `Bytes b -> Fmt.fprintf out "h'%s'" (CCString.to_hex b) | `Bytes b -> Fmt.fprintf out "h'%s'" (CCString.to_hex b)
| `Text s -> Fmt.fprintf out "%S" s | `Text s -> Fmt.fprintf out "%S" s
@ -49,6 +49,13 @@ let to_string_diagnostic (self : t) : string =
exception Indefinite exception Indefinite
let[@inline] i64_to_int i =
let j = Int64.to_int i in
if Int64.(of_int j = i) then
j
else
failwith "int64 does not fit in int"
let decode_exn (s : string) : t = let decode_exn (s : string) : t =
let b = Bytes.unsafe_of_string s in let b = Bytes.unsafe_of_string s in
let i = ref 0 in let i = ref 0 in
@ -87,14 +94,6 @@ let decode_exn (s : string) : t =
j j
in in
let[@inline] i64_to_int i =
let j = Int64.to_int i in
if Int64.(of_int j = i) then
j
else
failwith "int64 does not fit in int"
in
(* read integer value from least significant bits *) (* read integer value from least significant bits *)
let read_int ~allow_indefinite low = let read_int ~allow_indefinite low =
match low with match low with
@ -153,10 +152,10 @@ let decode_exn (s : string) : t =
let high = (c land 0b111_00000) lsr 5 in let high = (c land 0b111_00000) lsr 5 in
let low = c land 0b000_11111 in let low = c land 0b000_11111 in
match high with match high with
| 0 -> `Int (read_int ~allow_indefinite:false low |> i64_to_int) | 0 -> `Int (read_int ~allow_indefinite:false low)
| 1 -> | 1 ->
let i = read_int ~allow_indefinite:false low |> i64_to_int in let i = read_int ~allow_indefinite:false low in
`Int (-1 - i) `Int Int64.(sub minus_one i)
| 2 -> | 2 ->
let s = read_bytes ~ty:`Bytes low in let s = read_bytes ~ty:`Bytes low in
`Bytes s `Bytes s
@ -255,22 +254,22 @@ let encode ?(buf = Buffer.create 32) (self : t) : string =
let add_i64 (i : int64) = Buffer.add_int64_be buf i in let add_i64 (i : int64) = Buffer.add_int64_be buf i in
(* add unsigned integer, including first tag byte *) (* add unsigned integer, including first tag byte *)
let add_uint (high : int) (x : int) = let add_uint (high : int) (x : int64) =
assert (x >= 0); assert (x >= 0L);
if x < 24 then if x < 24L then
add_byte high x add_byte high (i64_to_int x)
else if x <= 0xff then ( else if x <= 0xffL then (
add_byte high 24; add_byte high 24;
Buffer.add_char buf (Char.unsafe_chr x) Buffer.add_char buf (Char.unsafe_chr (i64_to_int x))
) else if x <= 0xff_ff then ( ) else if x <= 0xff_ffL then (
add_byte high 25; add_byte high 25;
Buffer.add_uint16_be buf x Buffer.add_uint16_be buf (i64_to_int x)
) else if x <= 0xff_ff_ff_ff then ( ) else if x <= 0xff_ff_ff_ffL then (
add_byte high 26; add_byte high 26;
Buffer.add_int32_be buf (Int32.of_int x) Buffer.add_int32_be buf (Int64.to_int32 x)
) else ( ) else (
add_byte high 27; add_byte high 27;
Buffer.add_int64_be buf (Int64.of_int x) Buffer.add_int64_be buf x
) )
in in
@ -293,33 +292,33 @@ let encode ?(buf = Buffer.create 32) (self : t) : string =
(* float 64 *) (* float 64 *)
add_i64 (Int64.bits_of_float f) add_i64 (Int64.bits_of_float f)
| `Array l -> | `Array l ->
add_uint 4 (List.length l); add_uint 4 (Int64.of_int (List.length l));
List.iter encode_val l List.iter encode_val l
| `Map l -> | `Map l ->
add_uint 5 (List.length l); add_uint 5 (Int64.of_int (List.length l));
List.iter List.iter
(fun (k, v) -> (fun (k, v) ->
encode_val k; encode_val k;
encode_val v) encode_val v)
l l
| `Text s -> | `Text s ->
add_uint 3 (String.length s); add_uint 3 (Int64.of_int (String.length s));
Buffer.add_string buf s Buffer.add_string buf s
| `Bytes s -> | `Bytes s ->
add_uint 2 (String.length s); add_uint 2 (Int64.of_int (String.length s));
Buffer.add_string buf s Buffer.add_string buf s
| `Tag (t, v) -> | `Tag (t, v) ->
add_uint 6 t; add_uint 6 (Int64.of_int t);
encode_val v encode_val v
| `Int i -> | `Int i ->
if i >= 0 then if i >= Int64.zero then
add_uint 0 i add_uint 0 i
else if min_int + 2 > i then ( else if Int64.(add min_int 2L) > i then (
(* large negative int, be careful. encode [(-i)-1] via int64. *) (* large negative int, be careful. encode [(-i)-1] via int64. *)
add_byte 1 27; add_byte 1 27;
Buffer.add_int64_be buf Int64.(neg (add 1L (of_int i))) Buffer.add_int64_be buf Int64.(neg (add 1L i))
) else ) else
add_uint 1 (-i - 1) add_uint 1 Int64.(sub (neg i) one)
in in
encode_val self; encode_val self;
Buffer.contents buf Buffer.contents buf

View file

@ -16,7 +16,7 @@ type t =
| `Undefined | `Undefined
| `Simple of int | `Simple of int
| `Bool of bool | `Bool of bool
| `Int of int | `Int of int64
| `Float of float | `Float of float
| `Bytes of string | `Bytes of string
| `Text of string | `Text of string

View file

@ -122,11 +122,11 @@ let run_test (c : count) (t : Test.t) : unit =
try compare_cj (List.assoc (`Text k) l) v try compare_cj (List.assoc (`Text k) l) v
with Not_found -> false) with Not_found -> false)
l2 l2
| `Int i, `Int j -> i = j | `Int i, `Int j -> i = Int64.of_int j
| `Text s1, `String s2 -> s1 = s2 | `Text s1, `String s2 -> s1 = s2
| `Array l1, `List l2 -> | `Array l1, `List l2 ->
List.length l1 = List.length l2 && List.for_all2 compare_cj l1 l2 List.length l1 = List.length l2 && List.for_all2 compare_cj l1 l2
| `Int i, `Intlit s -> string_of_int i = s | `Int i, `Intlit s -> Int64.to_string i = s
| _, `Intlit "-18446744073709551617" -> | _, `Intlit "-18446744073709551617" ->
(* skip bigint test*) (* skip bigint test*)
true true

View file

@ -13,7 +13,7 @@ let gen_c : Cbor.t Q.Gen.t =
1, return `Null; 1, return `Null;
1, return `Undefined; 1, return `Undefined;
( 3, ( 3,
let+ x = int in let+ x = int >|= Int64.of_int in
`Int x ); `Int x );
( 1, ( 1,
let+ b = bool in let+ b = bool in
@ -71,8 +71,8 @@ let rec shrink (c : Cbor.t) : Cbor.t Q.Iter.t =
let+ i = Q.Shrink.int i in let+ i = Q.Shrink.int i in
`Simple i `Simple i
| `Int i -> | `Int i ->
let+ i = Q.Shrink.int i in let+ i = Q.Shrink.int (Int64.to_int i) in
`Int i `Int (Int64.of_int i)
| `Tag (t, i) -> | `Tag (t, i) ->
let+ i = shrink i in let+ i = shrink i in
`Tag (t, i) `Tag (t, i)