Skip to content

Commit

Permalink
Merge pull request #305 from c-cube/cstruct-sub-copy
Browse files Browse the repository at this point in the history
add `Cstruct.sub_copy`
  • Loading branch information
dinosaure authored Nov 18, 2022
2 parents b14e6a3 + 7aaeb6e commit 63ca7cc
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 0 deletions.
5 changes: 5 additions & 0 deletions lib/cstruct.ml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,11 @@ let blit src srcoff dst dstoff len =
unsafe_blit_bigstring_to_bigstring src.buffer (src.off+srcoff) dst.buffer
(dst.off+dstoff) len

let sub_copy cstr off len : t =
let cstr2 = create_unsafe len in
blit cstr off cstr2 0 len;
cstr2

let blit_from_string src srcoff dst dstoff len =
if len < 0 || srcoff < 0 || dstoff < 0 || String.length src - srcoff < len then
err_blit_from_string_src src dst srcoff len
Expand Down
5 changes: 5 additions & 0 deletions lib/cstruct.mli
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,11 @@ val sub: t -> int -> int -> t
(** [sub cstr off len] is [{ t with off = t.off + off; len }]
@raise Invalid_argument if the offset exceeds cstruct length. *)

val sub_copy: t -> int -> int -> t
(** [sub_copy cstr off len] is a new copy of [sub cstr off len],
that does not share the underlying buffer of [cstr].
@raise Invalid_argument if the offset exceeds cstruct length. *)

val shift: t -> int -> t
(** [shift cstr len] is [{ cstr with off=t.off+len; len=t.len-len }]
@raise Invalid_argument if the offset exceeds cstruct length. *)
Expand Down
4 changes: 4 additions & 0 deletions lib/cstruct_cap.ml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ let sub t ~off ~len =
Cstruct.sub t off len
[@@inline]

let sub_copy t ~off ~len =
Cstruct.sub_copy t off len
[@@inline]

let unsafe_to_bigarray = Cstruct.to_bigarray

let concat vss =
Expand Down
8 changes: 8 additions & 0 deletions lib/cstruct_cap.mli
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,14 @@ val sub : 'a t -> off:int -> len:int -> 'a t
@raise Invalid_argument if the offset exceeds [t] length. *)

val sub_copy : 'a t -> off:int -> len:int -> rdwr t
(** [sub_copy t ~off ~len] is a new copy of [sub t ~off ~len],
that does not share the underlying buffer of [t].
The returned value has read-write capabilities because it doesn't
affect [t].
@raise Invalid_argument if the offset exceeds [t] length. *)

val shift : 'a t -> int -> 'a t
(** [shift t len] returns a proxy which shares the underlying buffer of [t]. The
returned value starts [len] bytes later than the given [t]. The returned
Expand Down
14 changes: 14 additions & 0 deletions lib_test/bounds.ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,19 @@ let test_sub () =
Alcotest.(check int) "sub 3" 20 z.Cstruct.off;
Alcotest.(check int) "sub 4" 60 z.Cstruct.len

let test_sub_copy () =
let x = Cstruct.create 100 in
let y = Cstruct.sub_copy x 10 80 in
Alcotest.(check int) "sub_copy 1" 0 y.Cstruct.off;
Alcotest.(check int) "sub_copy 2" 80 y.Cstruct.len;
let z = Cstruct.sub_copy y 10 60 in
Alcotest.(check int) "sub_copy 3" 0 z.Cstruct.off;
Alcotest.(check int) "sub_copy 4" 60 z.Cstruct.len;
Cstruct.set_uint8 x 50 42;
Alcotest.(check int) "x changed" 42 (Cstruct.get_uint8 x 50);
Alcotest.(check int) "y unchanged" 0 (Cstruct.get_uint8 y 50);
()

let test_negative_sub () =
let x = Cstruct.create 2 in
let y = Cstruct.sub x 1 1 in
Expand Down Expand Up @@ -453,6 +466,7 @@ let suite = [
"test negative shift", `Quick, test_negative_shift;
"test bad positive shift", `Quick, test_bad_positive_shift;
"test sub", `Quick, test_sub;
"test sub_copy", `Quick, test_sub_copy;
"test negative sub", `Quick, test_negative_sub;
"test sub len too big", `Quick, test_sub_len_too_big;
"test sub len too small", `Quick, test_sub_len_too_small;
Expand Down

0 comments on commit 63ca7cc

Please sign in to comment.