Skip to content

Instantly share code, notes, and snippets.

@gdsfh
Created September 19, 2013 18:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gdsfh/e695c4920efafecbdb57 to your computer and use it in GitHub Desktop.
Save gdsfh/e695c4920efafecbdb57 to your computer and use it in GitHub Desktop.
(*
из описания
open Cstruct_codegen;
value example = cstruct "mystruct"
[ uint8 "ui8"
; int64 "si64"
]
;
value () = codegen [example]
;
*)
module Mystruct
:
sig
(* Abstract data type to represent values of C-like structure 'mystruct' *)
type t
(* size of structure [t] in bytes *)
val sizeof : int
(* Creates a value of type [t] on bigarray of size [sizeof].
one can modify bigarray, and these modifications will
affect fields of created value (they will be visible with
get_<field> or [dump]).
Raises [Failure] on size mismatch. *)
val of_bigarray : (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t -> t
(* getters and setters: *)
val get_ui8 : t -> int
val set_ui8 : t -> int -> unit
val get_si64 : t -> int64
val set_si64 : t -> int64 -> unit
(* makes a value of type [t] and initializes it with
field values passed as labelled arguments. *)
val make : ui8:int -> si64:int64 -> t
(* dumps a value of type [t] to string, result looks like
'{ a=1 ; b=3456 }' *)
val dump : t -> string
end
=
struct
type t = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
let get_ui8 t = ExtUnix.Specific.BA.LittleEndian.unsafe_get_uint8 t 0
let set_ui8 t v = ExtUnix.Specific.BA.LittleEndian.unsafe_set_uint8 t 0 v
let get_si64 t = ExtUnix.Specific.BA.LittleEndian.unsafe_get_int64 t 1
let set_si64 t v = ExtUnix.Specific.BA.LittleEndian.unsafe_set_int64 t 1 v
let sizeof = 9
let of_bigarray t =
if Bigarray.Array1.dim t <> sizeof
then failwith "Mystruct.of_bigarray: size doesn't match"
else t
let make ~ui8 ~si64 =
let t = Bigarray.Array1.create Bigarray.char Bigarray.c_layout sizeof in
(
set_ui8 t ui8;
set_si64 t si64;
t
)
let dump t =
let b = Buffer.create 50 in
(
Buffer.add_string b "{ ui8=";
Buffer.add_string b (string_of_int (get_ui8 t));
Buffer.add_string b " ; si64=";
Buffer.add_string b (Int64.to_string (get_si64 t));
Buffer.add_string b " }";
Buffer.contents b
)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment