Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
1c22bf4
Add experimental Travis setup
avsm Sep 21, 2013
2c821c7
correct add-apt-repository
avsm Sep 21, 2013
39c4651
simplify scripts, add badge
avsm Sep 21, 2013
3fdfdbf
Make build verbose
avsm Sep 21, 2013
7e95ba8
add test script
avsm Sep 21, 2013
098730f
Merge branch 'travis'
avsm Sep 21, 2013
8373609
Sync CHANGES
avsm Sep 21, 2013
7f7b39c
travis: install native compilers
avsm Sep 21, 2013
0d15227
sync oasis autogen
avsm Sep 21, 2013
9801af3
install time package in Travis
avsm Sep 21, 2013
0179421
improve the Travis test matrix with the latest PPAs
avsm Oct 12, 2013
2a4221a
Check and raise error in case of negative offsets for blits
avsm Oct 12, 2013
4f3eb49
travis: install time
avsm Oct 12, 2013
082e4f0
a candidate fix for mirage/ocaml-cstruct#3
avsm Oct 12, 2013
716af9d
better fix for mirage/ocaml-cstruct#4 so that parsing outputs the rig…
avsm Oct 12, 2013
184b7ea
test: fix enum test compilation
avsm Oct 12, 2013
344d173
tests: restore pcap printing
avsm Oct 12, 2013
25b9a66
tests: make basic test compile again with new api
avsm Oct 12, 2013
e76009e
sync CHANGES
avsm Oct 12, 2013
d8cf981
Correctly preserve the sequence after a constant constructor is set d…
avsm Oct 12, 2013
99bca2b
Do not repeat the `sizeof_<field>` binding for every get/set field (s…
avsm Oct 12, 2013
4ab5d84
Do not repeat the `sizeof_<field>` signature for every get/set field.
avsm Oct 12, 2013
5a9686c
update README with more information about the generated functions
avsm Oct 12, 2013
fdde118
Merge pull request #18 from avsm/maybe_fix_cstruct_32bit_overflow
avsm Oct 12, 2013
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .travis-ci.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
OPAM_DEPENDS="ocplib-endian lwt async"

case "$OCAML_VERSION,$OPAM_VERSION" in
3.12.1,1.0.0) ppa=avsm/ocaml312+opam10 ;;
3.12.1,1.1.0) ppa=avsm/ocaml312+opam11 ;;
4.00.1,1.0.0) ppa=avsm/ocaml40+opam10 ;;
4.00.1,1.1.0) ppa=avsm/ocaml40+opam11 ;;
4.01.0,1.0.0) ppa=avsm/ocaml41+opam10 ;;
4.01.0,1.1.0) ppa=avsm/ocaml41+opam11 ;;
*) echo Unknown $OCAML_VERSION,$OPAM_VERSION; exit 1 ;;
esac

echo "yes" | sudo add-apt-repository ppa:$ppa
sudo apt-get update -qq
sudo apt-get install -qq ocaml ocaml-native-compilers camlp4-extra opam time

export OPAMYES=1
export OPAMVERBOSE=1
echo OCaml version
ocaml -version
echo OPAM versions
opam --version
opam --git-version

opam init
opam install ${OPAM_DEPENDS}

eval `opam config env`
make
./test.sh
9 changes: 9 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
language: c
script: bash -ex .travis-ci.sh
env:
- OCAML_VERSION=4.01.0 OPAM_VERSION=1.0.0
- OCAML_VERSION=4.01.0 OPAM_VERSION=1.1.0
- OCAML_VERSION=4.00.1 OPAM_VERSION=1.0.0
- OCAML_VERSION=4.00.1 OPAM_VERSION=1.1.0
- OCAML_VERSION=3.12.1 OPAM_VERSION=1.0.0
- OCAML_VERSION=3.12.1 OPAM_VERSION=1.1.0
7 changes: 7 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
0.7.2 (trunk):
* Improved ocamldoc for BE/LE modules.
* Add Travis-CI test scripts and fix `test.sh` script compilation.
* Check and raise error in case of negative offsets for blits (#4).
* Correctly preserve the sequence after a constant constructor is set during a `cenum` definition.
* Do not repeat the `sizeof_<field>` binding for every get/set field (should be no externally observable change).

0.7.1 (06-Mar-2013):
* Add `Async_cstruct.Pipe` to map pipes of `Cstruct` buffers to strings or `Bigsubstring`.

Expand Down
87 changes: 82 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,91 @@ cstruct ipv4 {
} as big_endian
```

This auto-generates generates functions of the form below in the `ml` file:

```
let sizeof_pcap_packet = 16
let get_pcap_packet_ts_sec v = Cstruct.LE.get_uint32 v 0
let set_pcap_packet_ts_sec v x = Cstruct.LE.set_uint32 v 0 x
let get_pcap_packet_ts_usec v = Cstruct.LE.get_uint32 v 4
let set_pcap_packet_ts_usec v x = Cstruct.LE.set_uint32 v 4 x
let get_pcap_packet_incl_len v = Cstruct.LE.get_uint32 v 8
let set_pcap_packet_incl_len v x = Cstruct.LE.set_uint32 v 8 x
let get_pcap_packet_orig_len v = Cstruct.LE.get_uint32 v 12
let set_pcap_packet_orig_len v x = Cstruct.LE.set_uint32 v 12 x

let sizeof_ethernet = 14
let get_ethernet_dst src = Cstruct.sub src 0 6
let copy_ethernet_dst src = Cstruct.copy src 0 6
let set_ethernet_dst src srcoff dst =
Cstruct.blit_from_string src srcoff dst 0 6
let blit_ethernet_dst src srcoff dst = Cstruct.blit src srcoff dst 0 6
let get_ethernet_src src = Cstruct.sub src 6 6
let copy_ethernet_src src = Cstruct.copy src 6 6
let set_ethernet_src src srcoff dst =
Cstruct.blit_from_string src srcoff dst 6 6
let blit_ethernet_src src srcoff dst = Cstruct.blit src srcoff dst 6 6
let get_ethernet_ethertype v = Cstruct.BE.get_uint16 v 12
let set_ethernet_ethertype v x = Cstruct.BE.set_uint16 v 12 x
```

The `mli` file will have signatures of this form:

```
val sizeof_pcap_packet : int
val get_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32
val set_pcap_packet_ts_sec : Cstruct.t -> Cstruct.uint32 -> unit
val get_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32
val set_pcap_packet_ts_usec : Cstruct.t -> Cstruct.uint32 -> unit
val get_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32
val set_pcap_packet_incl_len : Cstruct.t -> Cstruct.uint32 -> unit
val get_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32
val set_pcap_packet_orig_len : Cstruct.t -> Cstruct.uint32 -> unit

val sizeof_ethernet : int
val get_ethernet_dst : Cstruct.t -> Cstruct.t
val copy_ethernet_dst : Cstruct.t -> string
val set_ethernet_dst : string -> int -> Cstruct.t -> unit
val blit_ethernet_dst : Cstruct.t -> int -> Cstruct.t -> unit
val get_ethernet_src : Cstruct.t -> Cstruct.t
val copy_ethernet_src : Cstruct.t -> string
val set_ethernet_src : string -> int -> Cstruct.t -> unit
val blit_ethernet_src : Cstruct.t -> int -> Cstruct.t -> unit
val get_ethernet_ethertype : Cstruct.t -> Cstruct.uint16
val set_ethernet_ethertype : Cstruct.t -> Cstruct.uint16 -> unit
```
You can also declare C-like enums:

```
cenum foo64 {
ONE64;
TWO64;
THREE64
} as uint64_t
cenum foo32 {
ONE32;
TWO32 = 0xfffffffel;
THREE32
} as uint32_t

cenum bar16 {
ONE = 1;
TWO;
FOUR = 4;
FIVE
} as uint16_t
```

This generates signatures of the form:

```
type foo32 = | ONE32 | TWO32 | THREE32
val int_to_foo32 : int32 -> foo32 option
val foo32_to_int : foo32 -> int32
val foo32_to_string : foo32 -> string
val string_to_foo32 : string -> foo32 option
type bar16 = | ONE | TWO | FOUR | FIVE
val int_to_bar16 : int -> bar16 option
val bar16_to_int : bar16 -> int
val bar16_to_string : bar16 -> string
val string_to_bar16 : string -> bar16 option
```

Please see the `lib_test/` directory for more in-depth examples.

[![Build Status](https://travis-ci.org/avsm/ocaml-cstruct.png)](https://travis-ci.org/avsm/ocaml-cstruct)
2 changes: 1 addition & 1 deletion _oasis
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
OASISFormat: 0.3
Name: cstruct
Version: 0.7.1
Version: 0.7.2
Synopsis: Manipulate external buffers as C-like structs
Authors: Anil Madhavapeddy, Richard Mortier, Thomas Gazagnaire, Pierre Chambart
License: ISC
Expand Down
12 changes: 6 additions & 6 deletions lib/META
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# OASIS_START
# DO NOT EDIT (digest: c671864304beccb6078416a289ce5ee8)
version = "0.7.1"
# DO NOT EDIT (digest: 930869fcefc42a7e26a3e025657bc63c)
version = "0.7.2"
description = "Manipulate external buffers as C-like structs"
requires = "bigarray ocplib-endian ocplib-endian.bigstring"
archive(byte) = "cstruct.cma"
Expand All @@ -9,7 +9,7 @@ archive(native) = "cstruct.cmxa"
archive(native, plugin) = "cstruct.cmxs"
exists_if = "cstruct.cma"
package "unix" (
version = "0.7.1"
version = "0.7.2"
description = "Manipulate external buffers as C-like structs"
requires = "cstruct unix"
archive(byte) = "unix_cstruct.cma"
Expand All @@ -20,7 +20,7 @@ package "unix" (
)

package "syntax" (
version = "0.7.1"
version = "0.7.2"
description = "Syntax extension for Cstruct"
requires = "camlp4"
archive(syntax, preprocessor) = "cstruct-syntax.cma"
Expand All @@ -29,7 +29,7 @@ package "syntax" (
)

package "lwt" (
version = "0.7.1"
version = "0.7.2"
description = "Manipulate external buffers as C-like structs"
requires = "cstruct lwt.unix"
archive(byte) = "lwt_cstruct.cma"
Expand All @@ -40,7 +40,7 @@ package "lwt" (
)

package "async" (
version = "0.7.1"
version = "0.7.2"
description = "Manipulate external buffers as C-like structs"
requires = "cstruct async threads"
archive(byte) = "async_cstruct.cma"
Expand Down
8 changes: 4 additions & 4 deletions lib/cstruct.ml
Original file line number Diff line number Diff line change
Expand Up @@ -132,23 +132,23 @@ external unsafe_blit_string_to_bigstring : string -> int -> buffer -> int -> int
external unsafe_blit_bigstring_to_string : buffer -> int -> string -> int -> int -> unit = "caml_blit_bigstring_to_string" "noalloc"

let copy src srcoff len =
if src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if len < 0 || srcoff < 0 || src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
let s = String.create len in
unsafe_blit_bigstring_to_string src.buffer (src.off+srcoff) s 0 len;
s

let blit src srcoff dst dstoff len =
if src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if len < 0 || srcoff < 0 || src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if dst.len - dstoff < len then raise (Invalid_argument (invalid_bounds dstoff len));
unsafe_blit_bigstring_to_bigstring src.buffer (src.off+srcoff) dst.buffer (dst.off+dstoff) len

let blit_from_string src srcoff dst dstoff len =
if String.length src - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if len < 0 || srcoff < 0 || dstoff < 0 || String.length src - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if dst.len - dstoff < len then raise (Invalid_argument (invalid_bounds dstoff len));
unsafe_blit_string_to_bigstring src srcoff dst.buffer (dst.off+dstoff) len

let blit_to_string src srcoff dst dstoff len =
if src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if len < 0 || srcoff < 0 || dstoff < 0 || src.len - srcoff < len then raise (Invalid_argument (invalid_bounds srcoff len));
if String.length dst - dstoff < len then raise (Invalid_argument (invalid_bounds dstoff len));
unsafe_blit_bigstring_to_string src.buffer (src.off+srcoff) dst dstoff len

Expand Down
26 changes: 11 additions & 15 deletions lib_test/basic.ml
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,27 @@ cstruct bar {

let _ =
(* Test basic set/get functions *)
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
for i = 0 to 255 do
set_bar_a be i;
assert(get_bar_a be = i)
done;
let le = Bigarray.(Array1.create char c_layout sizeof_bar) in
let le = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_bar)) in
for i = 0 to 255 do
set_foo_a le i;
assert(get_foo_a le = i)
done;
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
for i = 0 to 65535 do
set_bar_b be i;
assert(get_bar_b be = i)
done;
let le = Bigarray.(Array1.create char c_layout sizeof_bar) in
let le = Cstruct.of_bigarray(Bigarray.(Array1.create char c_layout sizeof_bar)) in
for i = 0 to 65535 do
set_foo_b le i;
assert(get_foo_b le = i)
done;
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
let rec fn = function
|i when i < 0l -> ()
|i ->
Expand All @@ -59,7 +59,7 @@ let _ =
fn (Int32.sub i 0x10l)
in fn 0xffffffff_l;
(* Get/set buffers and blits *)
let le = Bigarray.(Array1.create char c_layout sizeof_bar) in
let le = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_bar)) in
let rec fn = function
|i when i < 0l -> ()
|i ->
Expand All @@ -75,19 +75,15 @@ let _ =
assert(copy_bar_d le = s1);
Printf.printf "%s %s\n" (copy_foo_d be) (copy_bar_d le);
(* Create sub-view and shift it back *)
let be = Bigarray.(Array1.create char c_layout sizeof_foo) in
let be = Cstruct.of_bigarray (Bigarray.(Array1.create char c_layout sizeof_foo)) in
set_foo_a be 7;
set_foo_b be 44;
set_foo_c be 0xbeef_l;
set_foo_d "abcdefgh" 0 be;
(* shifting the base array should fail *)
assert(not (Cstruct.shift_left be 1));
(* get a subview *)
let be2 = Cstruct.shift be 3 in
assert(Cstruct.BE.get_uint32 be2 0 = 0xbeef_l);
(* shift it back *)
assert(Cstruct.shift_left be2 3);
assert(Cstruct.BE.get_uint32 be2 3 = 0xbeef_l);
assert(not (Cstruct.shift_left be2 1));
assert(get_foo_b be2 = 44);
assert(get_foo_a be2 = 7)
assert(Cstruct.BE.get_uint32 be 3 = 0xbeef_l);
assert(get_foo_b be = 44);
assert(get_foo_a be = 7)

21 changes: 15 additions & 6 deletions lib_test/enum.ml
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,17 @@ cenum foo64 {

cenum foo32 {
ONE32;
TWO32 = 3;
TWO32 = 0xfffffffel;
THREE32
} as uint32_t

cenum bar16 {
ONE = 1;
TWO;
FOUR = 4;
FIVE
} as uint16_t

cenum foo16 {
ONE16;
TWO16;
Expand All @@ -47,9 +54,11 @@ let _ =
ignore(foo32_to_int ONE32);
ignore(foo16_to_int ONE16);
ignore(foo8_to_int ONE8);
assert(foo32_to_int TWO32 = 3l);
assert(foo32_to_int THREE32 = 1l);
assert(int_to_foo32 3l = Some (TWO32));
assert(int_to_foo32 1l = Some (THREE32));
assert(bar16_to_int FOUR = 4);
assert(bar16_to_int FIVE = 5);
assert(foo32_to_int TWO32 = 0xfffffffel);
assert(foo32_to_int THREE32 = 0xffffffffl);
assert(int_to_foo32 0xfffffffel = Some (TWO32));
assert(int_to_foo32 0xffffffffl = Some (THREE32));
assert(string_to_foo16 "ONE16" = Some ONE16);
print_endline (foo8_to_string ONE8)
assert(foo8_to_string ONE8 = "ONE8")
7 changes: 7 additions & 0 deletions lib_test/enum.mli
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,13 @@ cenum foo32 {
THREE32
} as uint32_t

cenum bar16 {
ONE = 1;
TWO;
FOUR = 4;
FIVE
} as uint16_t

cenum foo16 {
ONE16;
TWO16;
Expand Down
Loading