-
-
Notifications
You must be signed in to change notification settings - Fork 26
/
helpers.ml
85 lines (68 loc) · 2.27 KB
/
helpers.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
(* This file is part of Luv, released under the MIT license. See LICENSE.md for
details, or visit https://github.com/aantron/luv/blob/master/LICENSE.md. *)
module type WITH_DATA_FIELD =
sig
type 'kind base
type 'kind t = ('kind base) Ctypes.structure
val set_data : ([ `Base ] t) Ctypes.ptr -> unit Ctypes.ptr -> unit
val get_data : ([ `Base ] t) Ctypes.ptr -> unit Ctypes.ptr
val default_reference_count : int
end
module Retained (Object : WITH_DATA_FIELD) =
struct
type 'kind t = ('kind Object.t) Ctypes.ptr
let coerce : _ t -> [ `Base ] t =
Obj.magic
let allocate ?(reference_count = Object.default_reference_count) kind =
let references = Array.make reference_count ignore in
let c_object = Ctypes.addr (Ctypes.make kind) in
references.(C.Types.Handle.self_reference_index) <- Obj.magic c_object;
let gc_root = Ctypes.Root.create references in
Object.set_data (coerce c_object) gc_root;
c_object
let release c_object =
Ctypes.Root.release (Object.get_data (coerce c_object))
let set_reference
?(index = C.Types.Handle.generic_callback_index) c_object value =
let references : _ array =
Ctypes.Root.get (Object.get_data (coerce c_object)) in
references.(index) <- Obj.magic value
end
module Buf =
struct
let bigstrings_to_iovecs bigstrings count =
let iovecs = Ctypes.CArray.make C.Types.Buf.t count in
bigstrings |> List.iteri begin fun index bigstring ->
let iovec = Ctypes.CArray.get iovecs index in
let base = Ctypes.(bigarray_start array1) bigstring in
let length = Bigarray.Array1.dim bigstring in
Ctypes.setf iovec C.Types.Buf.base base;
Ctypes.setf iovec C.Types.Buf.len (Unsigned.UInt.of_int length)
end;
iovecs
end
module Bit_field =
struct
let list_to_c to_c flags =
List.map to_c flags
|> List.fold_left (lor) 0
let c_to_list to_c all field =
let rec loop acc = function
| [] ->
acc
| flag::rest ->
if (field land to_c flag) <> 0 then
loop (flag::acc) rest
else
loop acc rest
in
loop [] all
let test to_c mask field =
let mask = list_to_c to_c mask in
(mask land field) = mask
let accumulate flag condition acc =
if condition then
acc lor flag
else
acc
end