From a263d0426e90acf7abb62de5c91d4def808c6094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= Date: Tue, 21 Feb 2023 10:13:00 +0100 Subject: [PATCH 1/2] Implement marshal/unmarshal --- lib/cstruct.ml | 19 +++++++++++++++++++ lib/cstruct.mli | 3 +++ lib/cstruct_stubs.c | 25 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/lib/cstruct.ml b/lib/cstruct.ml index 5c4b871..005664c 100644 --- a/lib/cstruct.ml +++ b/lib/cstruct.ml @@ -961,3 +961,22 @@ let mapi f ({ len; _ } as cs) = for i = 0 to len - 1 do set_char b i (f i (get_char cs i)) done ; b + +external unsafe_input_data_size : buffer -> int -> int -> int = "caml_unsafe_input_data_size" +external input_value_from_bigstring : buffer -> int -> int -> 'a = "caml_input_value_from_bigstring" +external output_value_to_bigstring : buffer -> int -> int -> 'a -> Marshal.extern_flags list -> int = "caml_output_value_to_bigstring" + +let unsafe_input_value t = + input_value_from_bigstring t.buffer t.off t.len + +let input_value t = + if t.len < Marshal.header_size then + invalid_arg "input_value"; + if t.len < unsafe_input_data_size t.buffer t.off t.len then + invalid_arg "input_value"; + (* check data size *) + unsafe_input_value t + +let output_value v flags t = + output_value_to_bigstring t.buffer t.off t.len v flags + + Marshal.header_size diff --git a/lib/cstruct.mli b/lib/cstruct.mli index fd5b081..13f75e5 100644 --- a/lib/cstruct.mli +++ b/lib/cstruct.mli @@ -836,3 +836,6 @@ val sum_lengths : caller:string -> t list -> int (** [sum_lengths ~caller acc l] is [acc] plus the sum of the lengths of the elements of [l]. Raises [Invalid_argument caller] if arithmetic overflows. *) + +val input_value : t -> 'a +val output_value : 'a -> Marshal.extern_flags list -> t -> int diff --git a/lib/cstruct_stubs.c b/lib/cstruct_stubs.c index 9f1b24e..1647f35 100644 --- a/lib/cstruct_stubs.c +++ b/lib/cstruct_stubs.c @@ -22,6 +22,7 @@ #include #include #include +#include #ifndef Bytes_val #define Bytes_val String_val @@ -79,3 +80,27 @@ caml_check_alignment_bigstring(value val_buf, value val_ofs, value val_alignment uintnat alignment = Unsigned_long_val(val_alignment); return Val_bool(address % alignment == 0); } + +/* this doesn't seem to be exposed?! */ +extern CAMLprim value caml_marshal_data_size(value v_str, value v_pos); + +CAMLprim value +caml_unsafe_input_data_size(value val_buf, value val_ofs, value val_len) +{ + return caml_marshal_data_size((value)((char *)Caml_ba_data_val(val_buf) + Long_val(val_ofs)), Val_int(0)); +} + +CAMLprim value +caml_input_value_from_bigstring(value val_buf, value val_ofs, value val_len) +{ + return caml_input_value_from_block((char *)Caml_ba_data_val(val_buf) + Long_val(val_ofs), + Long_val(val_len)); +} + +CAMLprim value +caml_output_value_to_bigstring(value val_buf, value val_ofs, value val_len, value v, value flags) +{ + return caml_output_value_to_block(v, flags, + (char *)Caml_ba_data_val(val_buf) + Long_val(val_ofs), + Long_val(val_len)); +} From b9197498b07ede9504e275a8995fba408f3a6bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Reynir=20Bj=C3=B6rnsson?= Date: Tue, 21 Feb 2023 10:49:11 +0100 Subject: [PATCH 2/2] Add input_value/output_value to cstruct_cap --- lib/cstruct_cap.ml | 3 +++ lib/cstruct_cap.mli | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/lib/cstruct_cap.ml b/lib/cstruct_cap.ml index 0d2c6f6..1e2e8e4 100644 --- a/lib/cstruct_cap.ml +++ b/lib/cstruct_cap.ml @@ -71,3 +71,6 @@ let concat vss = let len = List.fold_left go 0 vss in assert (len = Cstruct.length res) ; res + +let output_value = Cstruct.output_value +let input_value = Cstruct.input_value diff --git a/lib/cstruct_cap.mli b/lib/cstruct_cap.mli index cc73438..454dc95 100644 --- a/lib/cstruct_cap.mli +++ b/lib/cstruct_cap.mli @@ -670,3 +670,7 @@ val map : (char -> char) -> 'a rd t -> rdwr t val mapi : (int -> char -> char) -> 'a rd t -> rdwr t (** [map f cs] is [cs'] with [cs'.[i] = f i cs.[i]] for all indices [i] of [cs]. [f] is invoked in increasing index order. *) + + +val input_value : 'wr rd t -> 'a +val output_value : 'a -> Marshal.extern_flags list -> 'rd wr t -> int