diff --git a/CHANGES b/CHANGES index 4a91495e..6c09a151 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1.6.0 (trunk): +* Add `blitv` to copy over a list of buffers (from Thomas Leonard). + 1.5.0 (2014-11-24): * Make `camlp4` an optional build-time dependency (#35). * Remove `ounit` as a dependency in the `opam` file. diff --git a/lib/cstruct.ml b/lib/cstruct.ml index d57b48f1..005c32b5 100644 --- a/lib/cstruct.ml +++ b/lib/cstruct.ml @@ -231,6 +231,23 @@ let copyv ts = ) 0 ts in dst +let blitv src dst = + let rec aux dst n = function + | [] -> n, [] + | hd::tl -> + let avail = len dst in + let first = len hd in + if first <= avail then ( + blit hd 0 dst 0 first; + aux (shift dst first) (n + first) tl + ) else ( + blit hd 0 dst 0 avail; + let rest_hd = shift hd first in + (n + avail, rest_hd :: tl) + ) in + aux dst 0 src + + let to_string t = let sz = len t in let s = String.create sz in diff --git a/lib/cstruct.mli b/lib/cstruct.mli index 81623dd4..9af73ead 100644 --- a/lib/cstruct.mli +++ b/lib/cstruct.mli @@ -378,6 +378,13 @@ val copyv: t list -> string (** [copyv cstrs] is the string representation of the concatenation of all cstructs in [cstrs]. *) +val blitv: t list -> t -> int * t list +(** [blitv src dst] will copy the list of [src] buffers into [dst] and + return a tuple of the total number of bytes written and a list of + any uncopied buffers. [blitv] will never raise an exception, since + it returns any uncopied bytes if the [dst] buffer is not big enough + to fit the full list of [src] buffers. *) + (** {2 Iterations} *) type 'a iter = unit -> 'a option