From 6a415e963a0610c107fabc0aa2e845614865dffc Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Wed, 6 Jul 2022 22:27:12 -0400 Subject: [PATCH] fix(cbor): use int64 as main int type --- src/cbor/containers_cbor.ml | 65 +++++++++++++++++----------------- src/cbor/containers_cbor.mli | 2 +- src/cbor/tests/t_appendix_a.ml | 4 +-- tests/core/t_cbor.ml | 6 ++-- 4 files changed, 38 insertions(+), 39 deletions(-) diff --git a/src/cbor/containers_cbor.ml b/src/cbor/containers_cbor.ml index e82b03da..fd34015e 100644 --- a/src/cbor/containers_cbor.ml +++ b/src/cbor/containers_cbor.ml @@ -5,7 +5,7 @@ type t = | `Undefined | `Simple of int | `Bool of bool - | `Int of int + | `Int of int64 | `Float of float | `Bytes of string | `Text of string @@ -19,7 +19,7 @@ let rec pp_diagnostic out (self : t) = | `Undefined -> Fmt.string out "undefined" | `Simple i -> Fmt.fprintf out "simple(%d)" i | `Bool b -> Fmt.bool out b - | `Int i -> Fmt.int out i + | `Int i -> Fmt.int64 out i | `Float f -> Fmt.float out f | `Bytes b -> Fmt.fprintf out "h'%s'" (CCString.to_hex b) | `Text s -> Fmt.fprintf out "%S" s @@ -49,6 +49,13 @@ let to_string_diagnostic (self : t) : string = 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 b = Bytes.unsafe_of_string s in let i = ref 0 in @@ -87,14 +94,6 @@ let decode_exn (s : string) : t = j 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 *) let read_int ~allow_indefinite low = match low with @@ -153,10 +152,10 @@ let decode_exn (s : string) : t = let high = (c land 0b111_00000) lsr 5 in let low = c land 0b000_11111 in match high with - | 0 -> `Int (read_int ~allow_indefinite:false low |> i64_to_int) + | 0 -> `Int (read_int ~allow_indefinite:false low) | 1 -> - let i = read_int ~allow_indefinite:false low |> i64_to_int in - `Int (-1 - i) + let i = read_int ~allow_indefinite:false low in + `Int Int64.(sub minus_one i) | 2 -> let s = read_bytes ~ty:`Bytes low in `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 (* add unsigned integer, including first tag byte *) - let add_uint (high : int) (x : int) = - assert (x >= 0); - if x < 24 then - add_byte high x - else if x <= 0xff then ( + let add_uint (high : int) (x : int64) = + assert (x >= 0L); + if x < 24L then + add_byte high (i64_to_int x) + else if x <= 0xffL then ( add_byte high 24; - Buffer.add_char buf (Char.unsafe_chr x) - ) else if x <= 0xff_ff then ( + Buffer.add_char buf (Char.unsafe_chr (i64_to_int x)) + ) else if x <= 0xff_ffL then ( add_byte high 25; - Buffer.add_uint16_be buf x - ) else if x <= 0xff_ff_ff_ff then ( + Buffer.add_uint16_be buf (i64_to_int x) + ) else if x <= 0xff_ff_ff_ffL then ( add_byte high 26; - Buffer.add_int32_be buf (Int32.of_int x) + Buffer.add_int32_be buf (Int64.to_int32 x) ) else ( add_byte high 27; - Buffer.add_int64_be buf (Int64.of_int x) + Buffer.add_int64_be buf x ) in @@ -293,33 +292,33 @@ let encode ?(buf = Buffer.create 32) (self : t) : string = (* float 64 *) add_i64 (Int64.bits_of_float f) | `Array l -> - add_uint 4 (List.length l); + add_uint 4 (Int64.of_int (List.length l)); List.iter encode_val l | `Map l -> - add_uint 5 (List.length l); + add_uint 5 (Int64.of_int (List.length l)); List.iter (fun (k, v) -> encode_val k; encode_val v) l | `Text s -> - add_uint 3 (String.length s); + add_uint 3 (Int64.of_int (String.length s)); Buffer.add_string buf s | `Bytes s -> - add_uint 2 (String.length s); + add_uint 2 (Int64.of_int (String.length s)); Buffer.add_string buf s | `Tag (t, v) -> - add_uint 6 t; + add_uint 6 (Int64.of_int t); encode_val v | `Int i -> - if i >= 0 then + if i >= Int64.zero then 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. *) 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 - add_uint 1 (-i - 1) + add_uint 1 Int64.(sub (neg i) one) in encode_val self; Buffer.contents buf diff --git a/src/cbor/containers_cbor.mli b/src/cbor/containers_cbor.mli index 5efc1480..dca02fe6 100644 --- a/src/cbor/containers_cbor.mli +++ b/src/cbor/containers_cbor.mli @@ -16,7 +16,7 @@ type t = | `Undefined | `Simple of int | `Bool of bool - | `Int of int + | `Int of int64 | `Float of float | `Bytes of string | `Text of string diff --git a/src/cbor/tests/t_appendix_a.ml b/src/cbor/tests/t_appendix_a.ml index da49d1bf..aef954f5 100644 --- a/src/cbor/tests/t_appendix_a.ml +++ b/src/cbor/tests/t_appendix_a.ml @@ -122,11 +122,11 @@ let run_test (c : count) (t : Test.t) : unit = try compare_cj (List.assoc (`Text k) l) v with Not_found -> false) l2 - | `Int i, `Int j -> i = j + | `Int i, `Int j -> i = Int64.of_int j | `Text s1, `String s2 -> s1 = s2 | `Array l1, `List 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" -> (* skip bigint test*) true diff --git a/tests/core/t_cbor.ml b/tests/core/t_cbor.ml index fd46bbe3..c33bd494 100644 --- a/tests/core/t_cbor.ml +++ b/tests/core/t_cbor.ml @@ -13,7 +13,7 @@ let gen_c : Cbor.t Q.Gen.t = 1, return `Null; 1, return `Undefined; ( 3, - let+ x = int in + let+ x = int >|= Int64.of_int in `Int x ); ( 1, 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 `Simple i | `Int i -> - let+ i = Q.Shrink.int i in - `Int i + let+ i = Q.Shrink.int (Int64.to_int i) in + `Int (Int64.of_int i) | `Tag (t, i) -> let+ i = shrink i in `Tag (t, i)