Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

improve buffer get/set interfaces

now has:
- get_struct_field to get a zero-copy view
- copy_struct_field to get a string copy
- set_struct_field to copy a string into a buf
- blit_struct_field to copy a source bigarray into the field
  • Loading branch information...
commit 0d7edfda5f090f659bb68fc71040c9d2d86e56c3 1 parent 8dae999
@avsm authored
View
21 lib/cstruct.ml
@@ -32,13 +32,26 @@ let get_uint8 s off =
let set_uint8 s off v =
set s off (Char.chr v)
-let get_buffer s off len =
- sub s off len
+let sub_buffer src srcoff len =
+ sub src srcoff len
-let set_buffer s off len src =
- let dst = sub s off len in
+let copy_buffer src srcoff len =
+ let s = String.create len in
+ for i = 0 to len - 1 do
+ s.[i] <- get src (srcoff+i)
+ done;
+ s
+
+let blit_buffer src srcoff dst dstoff len =
+ let src = sub src srcoff len in
+ let dst = sub dst dstoff len in
blit src dst
+let set_buffer src srcoff dst dstoff len =
+ for i = srcoff to srcoff + len - 1 do
+ set dst (dstoff+i) src.[i]
+ done
+
module BE = struct
let get_uint16 s off =
View
8 lib/cstruct.mli
@@ -23,8 +23,12 @@ type uint64 = int64
val get_uint8 : buf -> int -> uint8
val set_uint8 : buf -> int -> uint8 -> unit
-val get_buffer : buf -> int -> int -> buf
-val set_buffer : buf -> int -> int -> buf -> unit
+
+val sub_buffer : buf -> int -> int -> buf
+val copy_buffer : buf -> int -> int -> string
+
+val blit_buffer : buf -> int -> buf -> int -> int -> unit
+val set_buffer : string -> int -> buf -> int -> int -> unit
module BE : sig
val get_uint16 : buf -> int -> uint16
View
13 lib_test/basic.ml
@@ -18,13 +18,14 @@ cstruct foo {
uint8_t a;
uint16_t b;
uint32_t c;
- uint8_t d[4]
+ uint8_t d[8]
} as big_endian
cstruct bar {
uint8_t a;
uint16_t b;
- uint32_t c
+ uint32_t c;
+ uint8_t d[8]
} as big_endian
@@ -65,4 +66,10 @@ let _ =
assert(get_foo_c le = i);
fn (Int32.sub i 0x10l)
in fn 0xffffffff_l;
- ()
+ let s1 = "deadbeef" in
+ set_foo_d s1 0 be;
+ assert(copy_foo_d be = s1);
+ let sb1 = get_foo_d be in
+ blit_bar_d sb1 0 le;
+ assert(copy_bar_d le = s1);
+ Printf.printf "%s %s\n" (copy_foo_d be) (copy_bar_d le)
View
36 syntax/pa_cstruct.ml
@@ -112,34 +112,48 @@ let mode_mod _loc =
let getter_name s f = sprintf "get_%s_%s" s.name f.field
let setter_name s f = sprintf "set_%s_%s" s.name f.field
+let op_name op s f = sprintf "%s_%s_%s" op s.name f.field
let output_get _loc s f =
let m = mode_mod _loc s.endian in
- let num x = <:expr< $int:string_of_int x$ >> in
- <:str_item<
- let $lid:getter_name s f$ v =
+ let num x = <:expr< $int:string_of_int x$ >> in
+ match f.ty with
+ |Buffer len ->
+ <:str_item<
+ let $lid:op_name "get" s f$ src = Cstruct.sub_buffer src $num f.off$ $num len$ ;;
+ let $lid:op_name "copy" s f$ src = Cstruct.copy_buffer src $num f.off$ $num len$
+ >>
+ |ty ->
+ <:str_item<
+ let $lid:getter_name s f$ v =
$match f.ty with
|UInt8 -> <:expr< Cstruct.get_uint8 v $num f.off$ >>
|UInt16 -> <:expr< $m$.get_uint16 v $num f.off$ >>
|UInt32 -> <:expr< $m$.get_uint32 v $num f.off$ >>
|UInt64 -> <:expr< $m$.get_uint64 v $num f.off$ >>
- |Buffer len -> <:expr< Cstruct.get_buffer v $num f.off$ $num len$ >>
+ |Buffer len -> assert false
$
- >>
+ >>
let output_set _loc s f =
let m = mode_mod _loc s.endian in
let num x = <:expr< $int:string_of_int x$ >> in
- <:str_item<
- let $lid:setter_name s f$ v x =
- $match f.ty with
+ match f.ty with
+ |Buffer len ->
+ <:str_item<
+ let $lid:setter_name s f$ src srcoff dst = Cstruct.set_buffer src srcoff dst $num f.off$ $num len$ ;;
+ let $lid:op_name "blit" s f$ src srcoff dst = Cstruct.blit_buffer src srcoff dst $num f.off$ $num len$
+ >>
+ |ty ->
+ <:str_item<
+ let $lid:setter_name s f$ v x = $match f.ty with
|UInt8 -> <:expr< Cstruct.set_uint8 v $num f.off$ x >>
|UInt16 -> <:expr< $m$.set_uint16 v $num f.off$ x >>
|UInt32 -> <:expr< $m$.set_uint32 v $num f.off$ x >>
|UInt64 -> <:expr< $m$.set_uint64 v $num f.off$ x >>
- |Buffer len -> <:expr< Cstruct.set_buffer v $num f.off$ $num len$ x >>
- $
- >>
+ |Buffer len -> assert false
+ $
+ >>
let output_sizeof _loc s =
<:str_item<
Please sign in to comment.
Something went wrong with that request. Please try again.