Skip to content

Commit

Permalink
Merge pull request #418 from adatario/fix_uint48
Browse files Browse the repository at this point in the history
Buf_write: Fix BE.uint48 and LE.uint48.
  • Loading branch information
talex5 committed Jan 31, 2023
2 parents 931b8ef + 931be24 commit 789c6d2
Show file tree
Hide file tree
Showing 4 changed files with 95 additions and 5 deletions.
2 changes: 2 additions & 0 deletions lib_eio/buf_read.ml
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ let any_char t =
consume t 1;
c

let uint8 t = Char.code (any_char t)

let peek_char t =
match ensure t 1 with
| () -> Some (get t 0)
Expand Down
3 changes: 3 additions & 0 deletions lib_eio/buf_read.mli
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ val string : string -> unit parser
@raise Failure if [s] is not a prefix of the stream. *)

val uint8 : int parser
(** [uint8] parses the next byte as an unsigned 8-bit integer. *)

(** Big endian parsers *)
module BE : sig
val uint16 : int parser
Expand Down
10 changes: 5 additions & 5 deletions lib_eio/buf_write.ml
Original file line number Diff line number Diff line change
Expand Up @@ -281,10 +281,10 @@ module BE = struct
let uint48 t i =
writable_exn t;
ensure_space t 6;
Bigstringaf.unsafe_set_int32_be t.buffer t.write_pos
Int64.(to_int32 (shift_right_logical i 4));
Bigstringaf.unsafe_set_int16_be t.buffer (t.write_pos + 2)
Int64.(to_int i);
Bigstringaf.unsafe_set_int16_be t.buffer t.write_pos
Int64.(to_int (shift_right_logical i 32));
Bigstringaf.unsafe_set_int32_be t.buffer (t.write_pos + 2)
Int64.(to_int32 i);
advance_pos t 6

let uint64 t i =
Expand Down Expand Up @@ -325,7 +325,7 @@ module LE = struct
Bigstringaf.unsafe_set_int16_le t.buffer t.write_pos
Int64.(to_int i);
Bigstringaf.unsafe_set_int32_le t.buffer (t.write_pos + 2)
Int64.(to_int32 (shift_right_logical i 2));
Int64.(to_int32 (shift_right_logical i 16));
advance_pos t 6

let uint64 t i =
Expand Down
85 changes: 85 additions & 0 deletions tests/buf_write.md
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,88 @@ If we don't pass a switch then we can still cancel flushes manually:
+Aborted
- : unit = ()
```

## Round-trips with Buf_read

```ocaml
module Read = Eio.Buf_read
let test (x : 'a) (f : Write.t -> 'a -> unit) (g : Read.t -> 'a) =
let encoded =
let t = Write.create 10 in
f t x;
Write.serialize_to_string t
in
let decoded = Read.parse_string_exn g encoded in
if x <> decoded then Fmt.failwith "Failed to round-trip: %S" encoded;
encoded
let to_hex data =
let b = Buffer.create (String.length data * 2) in
data |> String.iter (fun c ->
Buffer.add_string b (Printf.sprintf "%02x" (Char.code c))
);
Buffer.contents b
```

```ocaml
# test "test" (Write.string ?off:None ?len:None) Read.take_all;;
- : string = "test"
# test '\253' Write.char Read.any_char |> String.escaped;;
- : string = "\\253"
# test 0xa5 Write.uint8 Read.uint8 |> to_hex;;
- : string = "a5"
```

Big-endian:

```ocaml
# test 0xa123 Write.BE.uint16 Read.BE.uint16 |> to_hex;;
- : string = "a123"
# test 0xa1234567l Write.BE.uint32 Read.BE.uint32 |> to_hex;;
- : string = "a1234567"
# test 0xa1234567890aL Write.BE.uint48 Read.BE.uint48 |> to_hex;;
- : string = "a1234567890a"
# test 0xa1234567890abcdeL Write.BE.uint64 Read.BE.uint64 |> to_hex;;
- : string = "a1234567890abcde"
# test 32.25 Write.BE.float Read.BE.float |> to_hex;;
- : string = "42010000"
# test 32.25 Write.BE.double Read.BE.double |> to_hex;;
- : string = "4040200000000000"
```

Little-endian (using `to_hex'` to reverse the output):

```ocaml
let to_hex' d =
let l = String.length d in
String.init l (fun i -> d.[l - i - 1])
|> to_hex
```

```ocaml
# test 0xa123 Write.LE.uint16 Read.LE.uint16 |> to_hex';;
- : string = "a123"
# test 0xa1234567l Write.LE.uint32 Read.LE.uint32 |> to_hex';;
- : string = "a1234567"
# test 0xa1234567890aL Write.LE.uint48 Read.LE.uint48 |> to_hex';;
- : string = "a1234567890a"
# test 0xa1234567890abcdeL Write.LE.uint64 Read.LE.uint64 |> to_hex';;
- : string = "a1234567890abcde"
# test 32.25 Write.LE.float Read.LE.float |> to_hex';;
- : string = "42010000"
# test 32.25 Write.LE.double Read.LE.double |> to_hex';;
- : string = "4040200000000000"
```

0 comments on commit 789c6d2

Please sign in to comment.