package bin
Install
Dune Dependency
Authors
Maintainers
Sources
sha256=05701fb60e9f9b419cc2d3989cf58c60eba1b5e7a5d08fba7f9d92f29ea3a46e
sha512=2199910457d8dedeefe3ffa3e4ef7a4f0845bb66459bcf3951d6197ec5f32a0c49c29874341d7fc4ee026c82a95a0c8aaaea084840b10530f6c00a6120960174
doc/bin/Bin/index.html
Module Bin
Source
Bin
is a small library for encoding and decoding information from a buffer (like a bytes
or a bigstring
). Unlike a parser combinator, Bin
cannot decode a stream.
Bin
can be used to project values coming from a pre-allocated buffer such as a "framebuffer" (video, ethernet, etc.) or to inject values into it. Bin
can be seen as a library for describing (fairly basic) "C-like" types of values that can be injected/projected into/from a particular memory area:
#define PROPTAG_GET_COMMAND_LINE 0x00050001
#define VALUE_LENGTH_RESPONSE (1 << 31)
struct __attribute__((packed)) cmdline {
uint32_t id;
uint32_t value_len;
uint32_t param_len;
uint8 str[2048];
};
struct __attribute__((packed)) property_tag {
uint32_t id;
uint32_t value_len;
uint32_t param_len;
};
extern char _tags;
char *get_cmdline() {
struct cmdline p;
p.id = PROPTAG_GET_COMMAND_LINE;
p.value_len = len - sizeof(struct property_tag);
p.param_len = 2048 & ~VALUE_LENGTH_RESPONSE;
memcpy(&_tags, &p, sizeof(struct cmdline)); // inject
...
}
Bin
therefore allows you to describe a representation of a serialized value in bytes and to associate with it a function that allows you to obtain an OCaml value such as a record or a variant.
open Bin
type cmdline = {
id: int32
; value_len: int32
; param_len: int32
; cmdline: string
}
let cmdline =
record (fun id value_len param_len -> { id; value_len; param_len })
|+ field neint32 (Fun.const 0x00050001l)
|+ field neint32 (fun t -> t.value_len)
|+ field neint32 (fun t -> t.param_len)
|+ field cstring (fun t -> t.cmdline)
|> sealr
let encode_into tags ?(off = 0) value =
let off = ref off in
Bin.encode_bstr cmdline value tags off (* inject *)
Of course, it's not as fast as what we can do in C, but Bin
has the advantage of offering a small DSL that allows us to describe these types and go directly to OCaml values, which is generally more pleasant to manipulate with OCaml than to make C stubs.
Primitives.
seq ~len v
is a representation of fixed-length arrays of values of type v
.
This combinator allows defining a representative of one type in terms of another by supplying coercions between them.
The type for fields holding values of type 'b
and belonging to a record of type 'a
.
field n t g
is the representation of the field called n
of type t
with getter g
. For instance:
type t = { foo: string }
let foo = field cstring (fun t -> t.foo)
r |+ f
is the open record r
augmented with the field f
.
sealr r
seals the open record r
.
Variants.
type t = Foo | Bar of string
let t =
variant (fun foo bar -> function Foo -> foo | Bar s -> bar s)
|~ case0 Foo
|~ case1 cstring (fun x -> Bar x)
|> sealv
The type for representing variant cases of type 'a
with patterns of type 'b
.
The type for representing patterns for a variant of type 'a
.
case0 v
is a representation of a variant constructor v
with no arguments. For instance:
type t = Foo
let foo = case0 Foo
case1 n t c
is a representation of a variant constructor c
with an argument of type t
. For instances:
type t = Foo of string
let foo = case1 cstring (fun s -> Foo s)
v |~ c
is the open variant v
augmented with the case c
.
sealv v
seals the open variant v
.
Decoder.
decode_bstr repr
is the binary decoder for values of type repr
.
Encoder.
size_of_value encoding value
attempts to calculate the number of bytes needed to encode the given value
according to the given encoding.
size_of_encoding ?off encoding bstr
attempts to calculate the number of bytes required to decode a value according to the given encoding
and according to what can be decoded in the given byte sequence bstr
(at the given offset off
, defaults to 0
).