upstream: https://github.com/janestreet/memtrace
1(** Binary buffer operations for reading and writing trace data. *)
2
3module Shared_writer_fd : sig
4 type t
5 (** A Unix file descriptor, shared between multiple writers. *)
6
7 exception Closed
8
9 val make : Unix.file_descr -> t
10 (** [make fd] wraps a file descriptor for shared writing. *)
11
12 val write_fully : t -> bytes -> pos:int -> len:int -> unit
13 (** Writes the specified range of a buffer to the file descriptor, raising
14 Closed if [close] has been called. *)
15
16 val close : t -> unit
17 (** [close t] closes the shared file descriptor. *)
18end
19
20module Write : sig
21 type t = private { buf : Bytes.t; mutable pos : int; pos_end : int }
22 (** A [t] is a subsequence of a Bytes.t, to be written sequentially.
23
24 None of the operations below allocate or resize the underlying byte buffer
25 \- the underlying Bytes.t is managed by the caller, and may be shared
26 between mutiple [t]s. *)
27
28 val of_bytes : Bytes.t -> t
29 (** [of_bytes buf] creates a write buffer spanning the entire byte buffer. *)
30
31 val of_bytes_sub : Bytes.t -> pos:int -> pos_end:int -> t
32 (** [of_bytes_sub buf ~pos ~pos_end] creates a write buffer for a sub-range.
33 *)
34
35 val remaining : t -> int
36 (** [remaining t] returns the number of bytes available for writing. *)
37
38 val write_fd : Shared_writer_fd.t -> t -> unit
39 (** [write_fd fd b] writes the bytes written to b to the fd.
40
41 No bufs are invalidated. *)
42
43 (** Writing to a buf. All types are written little-endian. All functions raise
44 Overflow if there is insufficient space remaining. *)
45
46 exception Overflow of int
47
48 val put_8 : t -> int -> unit
49 (** Write an 8-bit integer. *)
50
51 val put_16 : t -> int -> unit
52 (** Write a 16-bit integer. *)
53
54 val put_32 : t -> int32 -> unit
55 (** Write a 32-bit integer. *)
56
57 val put_64 : t -> int64 -> unit
58 (** Write a 64-bit integer. *)
59
60 val put_float : t -> float -> unit
61 (** Write a float. *)
62
63 val put_string : t -> string -> unit
64 (** Write a length-prefixed string. *)
65
66 val put_vint : t -> int -> unit
67 (** Write a variable-length integer. *)
68
69 (** The skip_t functions reserve space to be filled by a later update_t. (for
70 e.g. length fields that are only known when writing is finished). *)
71
72 type position_8 = private int
73 (** Saved position for an 8-bit field. *)
74
75 val skip_8 : t -> position_8
76 (** Reserve space for an 8-bit integer. *)
77
78 val update_8 : t -> position_8 -> int -> unit
79 (** Fill in a previously reserved 8-bit integer. *)
80
81 type position_16 = private int
82 (** Saved position for a 16-bit field. *)
83
84 val skip_16 : t -> position_16
85 (** Reserve space for a 16-bit integer. *)
86
87 val update_16 : t -> position_16 -> int -> unit
88 (** Fill in a previously reserved 16-bit integer. *)
89
90 type position_32 = private int
91 (** Saved position for a 32-bit field. *)
92
93 val skip_32 : t -> position_32
94 (** Reserve space for a 32-bit integer. *)
95
96 val update_32 : t -> position_32 -> int32 -> unit
97 (** Fill in a previously reserved 32-bit integer. *)
98
99 type position_64 = private int
100 (** Saved position for a 64-bit field. *)
101
102 val skip_64 : t -> position_64
103 (** Reserve space for a 64-bit integer. *)
104
105 val update_64 : t -> position_64 -> int64 -> unit
106 (** Fill in a previously reserved 64-bit integer. *)
107
108 type position_float = private int
109 (** Saved position for a float field. *)
110
111 val skip_float : t -> position_float
112 (** Reserve space for a float. *)
113
114 val update_float : t -> position_float -> float -> unit
115 (** Fill in a previously reserved float. *)
116end
117
118module Read : sig
119 type t = private { buf : Bytes.t; mutable pos : int; pos_end : int }
120 (** A [t] is a subsequence of a Bytes.t, to be read sequentially.
121
122 None of the operations below allocate or resize the underlying byte buffer
123 \- the underlying Bytes.t is managed by the caller, and may be shared
124 between mutiple [t]s. *)
125
126 val of_bytes : Bytes.t -> t
127 (** [of_bytes buf] creates a read buffer spanning the entire byte buffer. *)
128
129 val of_bytes_sub : Bytes.t -> pos:int -> pos_end:int -> t
130 (** [of_bytes_sub buf ~pos ~pos_end] creates a read buffer for a sub-range. *)
131
132 val remaining : t -> int
133 (** [remaining t] returns the number of bytes available for reading. *)
134
135 val split : t -> int -> t * t
136 (** [split b len] splits b into (a, b), where a contains at most len bytes and
137 b contains the rest, if any.
138
139 The two returned parts share the same underlying Bytes.t. *)
140
141 val read_fd : Unix.file_descr -> Bytes.t -> t
142 (** [read_fd fd byt] returns a buf containing bytes read from fd, whose
143 underlying buffer is byt.
144
145 All [t]s sharing this underlying buffer are invalidated. *)
146
147 val refill_fd : Unix.file_descr -> t -> t
148 (** [refill_fd fd b] returns a buf containing the contents of b followed by
149 bytes read from fd, whose underlying buffer is that of b.
150
151 All bufs sharing this underlying buffer (including b) are invalidated. *)
152
153 val empty : t
154 (** The empty read buffer. *)
155
156 (** Reading from a buf. All types are read little-endian. All functions raise
157 Underflow if there are insufficient bytes remaining. *)
158
159 exception Underflow of int
160
161 val get_8 : t -> int
162 (** Read an 8-bit integer. *)
163
164 val get_16 : t -> int
165 (** Read a 16-bit integer. *)
166
167 val get_32 : t -> int32
168 (** Read a 32-bit integer. *)
169
170 val get_64 : t -> int64
171 (** Read a 64-bit integer. *)
172
173 val get_float : t -> float
174 (** Read a float. *)
175
176 val get_string : t -> string
177 (** Read a length-prefixed string. *)
178
179 val get_vint : t -> int
180 (** Read a variable-length integer. May overflow on 32-bit machines. *)
181end