package cstruct
Install
dune-project
Dependency
Authors
Maintainers
Sources
sha256=55d1f42cb85f7872fee499c5ed382aea17b06d55d1709e071d1ba85c7a09fef3
sha512=c3aa9a5a9125a1d022506a76fd7cdf32b21edcdc9df1202d8a9f382d02a28a33fea9a958f79e9302907ade1fce3f166b620c320aed6486e3efcc9a7464379cab
doc/cstruct/Cstruct/index.html
Module CstructSource
Manipulate external memory buffers as C-like structures.
Cstruct is a library and ppx rewriter to make it easier to access C-like structures directly from OCaml. It supports both reading and writing to these memory buffers, and they are accessed via the Bigarray module.
The library interface below is intended to be used in conjunction with the ppx rewriter that is also supplied with this library (in the cstruct-ppx ocamlfind package).
An example description for the pcap packet format is:
[%%cstruct
type pcap_header = {
magic_number: uint32_t; (* magic number *)
version_major: uint16_t; (* major version number *)
version_minor: uint16_t; (* minor version number *)
thiszone: uint32_t; (* GMT to local correction *)
sigfigs: uint32_t; (* accuracy of timestamps *)
snaplen: uint32_t; (* max length of captured packets, in octets *)
network: uint32_t; (* data link type *)
} [@@little_endian]
]
[%%cstruct
type pcap_packet = {
ts_sec: uint32_t; (* timestamp seconds *)
ts_usec: uint32_t; (* timestamp microseconds *)
incl_len: uint32_t; (* number of octets of packet saved in file *)
orig_len: uint32_t; (* actual length of packet *)
} [@@little_endian]
]
[%%cstruct
type ethernet = {
dst: uint8_t; [@len 6];
src: uint8_t; [@len 6];
ethertype: uint16_t;
} [@@big_endian]
]
[%%cstruct
type ipv4 = {
hlen_version: uint8_t;
tos: uint8_t;
len: uint16_t;
id: uint16_t;
off: uint16_t;
ttl: uint8_t;
proto: uint8_t;
csum: uint16_t;
src: uint8_t; [@len 4];
dst: uint8_t; [@len 4]
} [@@big_endian]
]These will expand to get and set functions for every field, with types appropriate to the particular definition. For instance:
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 hexdump_pcap_packet_to_buffer : Buffer.t -> Cstruct.t -> unitThe buffers generate a different set of functions. For the ethernet definitions, we have:
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 -> stringYou can also declare C-like enums:
[%%cenum
type foo32 =
| ONE32
| TWO32 [@id 0xfffffffel]
| THREE32
[@@uint32_t]
]
[%%cenum
type bar16 =
| ONE [@id 1]
| TWO
| FOUR [@id 4
| FIVE
[@@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 optionBase types
type buffer =
(char, Bigarray_compat.int8_unsigned_elt, Bigarray_compat.c_layout)
Bigarray_compat.Array1.tType of a buffer. A cstruct is composed of an underlying buffer and position/length within this buffer.
A single byte type
8-bit unsigned integer. The representation is currently an unboxed OCaml integer.
16-bit unsigned integer. The representation is currently an unboxed OCaml integer.
32-bit unsigned integer. The representation is currently a boxed OCaml int32.
64-bit unsigned integer. The representation is currently a boxed OCaml int64.
Creation and conversion
of_bigarray ~off ~len b is the cstruct contained in b starting at off, of length len.
create len is a fresh cstruct of size len with an offset of 0, filled with zero bytes.
create_unsafe len is a cstruct of size len with an offset of 0.
Note that the returned cstruct will contain arbitrary data, likely including the contents of previously-deallocated cstructs.
Beware!
Forgetting to replace this data could cause your application to leak sensitive information.
of_string ~allocator ~off ~len str is the cstruct representation of str slice located at off offset and of len length, with the underlying buffer allocated by alloc. If allocator is not provided, create is used.
of_bytes ~allocator byt is the cstruct representation of byt slice located at off offset and of len length, with the underlying buffer allocated by alloc. If allocator is not provided, create is used.
of_hex str is the cstruct cs. Every pair of hex-encoded characters in str are converted to one byte in cs. Whitespaces (space, newline, tab, carriage return) in str are skipped. The resulting cstruct is exactly half the size of the non-skipped characters of str.
Comparison
equal t1 t2 is true iff t1 and t2 correspond to the same sequence of bytes.
Getters and Setters
check_bounds cstr len is true if len is a non-negative integer and cstr.buffer's size is greater or equal than len false otherwise.
check_alignment cstr alignment is true if the first byte stored within cstr is at a memory address where address mod alignment = 0, false otherwise. Typical uses are to check a buffer is aligned to a page or disk sector boundary.
get_char t off returns the character contained in the cstruct at offset off.
get_uint8 t off returns the byte contained in the cstruct at offset off.
set_char t off c sets the byte contained in the cstruct at offset off to character c.
set_uint8 t off c sets the byte contained in the cstruct at offset off to byte c.
copy cstr off len is the string representation of the segment of t starting at off of size len.
blit src srcoff dst dstoff len copies len characters from cstruct src, starting at index srcoff, to cstruct dst, starting at index dstoff. It works correctly even if src and dst are the same string, and the source and destination intervals overlap.
blit_from_string src srcoff dst dstoff len copies len characters from string src, starting at index srcoff, to cstruct dst, starting at index dstoff.
blit_from_bytes src srcoff dst dstoff len copies len characters from bytes src, starting at index srcoff, to cstruct dst, starting at index dstoff.
blit_to_bytes src srcoff dst dstoff len copies len characters from cstruct src, starting at index srcoff, to the dst buffer, starting at index dstoff.
blit_to_string is a deprecated alias of blit_to_bytes.
Returns the length of the current cstruct view. Note that this length is potentially smaller than the actual size of the underlying buffer, as the sub or set_len functions can construct a smaller view.
set_len t len sets the length of the cstruct t to a new absolute value, and returns a fresh cstruct with these settings.
add_len t l will add l bytes to the length of the buffer, and return a fresh cstruct with these settings.
split ~start cstr len is a tuple containing the cstruct extracted from cstr at offset start (default: 0) of length len as first element, and the rest of cstr as second element.
to_string t will allocate a fresh OCaml string and copy the contents of the cstruct into it, and return that string copy.
to_bytes t will allocate a fresh OCaml bytes and copy the contents of the cstruct into it, and return that byte copy.
Debugging
When the going gets tough, the tough hexdump their cstructs and peer at it until the bug disappears. This will directly prettyprint the contents of the cstruct to the standard output.
hexdump_to_buffer buf c will append the pretty-printed hexdump of the cstruct c to the buffer buf.
hexdump_pp f c pretty-prints a hexdump of c to f.
debug t will print out the internal details of a cstruct such as its base offset and the length, and raise an assertion failure if invariants have been violated. Not intended for casual use.
Get/set big-endian integers of various sizes. The second argument of those functions is the position relative to the current offset of the cstruct.
Get/set little-endian integers of various sizes. The second argument of those functions is the position relative to the current offset of the cstruct.
List of buffers
copyv cstrs is the string representation of the concatenation of all cstructs in cstrs.
fillv ~src ~dst copies from src to dst until src is exhausted or dst is full. Returns the number of bytes copied and the remaining data from src, if any. This is useful if you want buffer data into fixed-sized chunks.
Iterations
Type of an iterator.
iter lenf of_cstr cstr is an iterator over cstr that returns elements of size lenf cstr and type of_cstr cstr.
fold f iter acc is (f iterN accN ... (f iter acc)...).
concat ts is the concatenation of all the ts. It is not guaranteed that * the result is a newly created t in the zero- and one-element cases.