The first type parameter controls whether the iobuf can be written to. The second type parameter controls whether the window and limits can be changed.
Perms module for information on how the first type parameter is used.
seek access, a function's type uses
_ rather than
as the type argument to
_ allows the function to be directly applied to
either permission. Using a specific permission would require code to use coercion
create ~len creates a new iobuf, backed by a bigstring of length
with the limits and window set to the entire bigstring.
of_string s returns a new iobuf whose contents are
set_bounds_and_buffer ~src ~dst copies bounds metadata (i.e., limits and window) and
shallowly copies the buffer (data pointer) from
dst. It does not access
data, but does allow access through
dst. This makes
dst an alias of
set_bounds_and_buffer creates an alias, we disallow immutable
[> write]. Otherwise, one of
dst could be
read and the other
immutable :> read, which would allow to write the
alias's data through the
set_bounds_and_buffer is typically used to allocate a frame iobuf only once. This
frame can be updated repeatedly and handed to users, without further allocation. Only
the most allocation-sensitive applications need this.
set_bounds_and_buffer_sub ?pos ?len ~src ~dst () is a more efficient version of:
set_bounds_and_buffer ~src:(Iobuf.sub_shared ?pos ?len src) ~dst.
set_bounds_and_buffer ~src ~dst is not the same as
~src () because the limits are narrowed in the latter case.
One may wonder why you'd want to call
no_seek, given that a cast is already
t : (_, seek) t :> (_, no_seek) t. It turns out that if you want to
f : (_, _) t -> unit of your own, which can be conveniently applied to
seek iobufs without the user having to cast
seek up, you need this
read_only is more of an historical convenience now that
read_write is a
polymorphic variant, as one can now explicitly specify the general type for an
argument with something like
t : (_ perms, _) t :> (read, _) t.
capacity t returns the size of
t's limits subrange. The capacity of an iobuf can
be reduced via
length t returns the size of
is_empty t is
length t = 0.
One can call
Lo_bound.window t to get a snapshot of the lower bound of the
window, and then later restore that snapshot with
Lo_bound.restore. This is
useful for speculatively parsing, and then rewinding when there isn't enough data to
Using a snapshot with a different iobuf, even a sub iobuf of the snapshotted one, has unspecified results. An exception may be raised, or a silent error may occur. However, the safety guarantees of the iobuf will not be violated, i.e., the attempt will not enlarge the limits of the subject iobuf.
flip_lo t sets the window to range from the lower limit to the lower bound of the
old window. This is typically called after a series of
Fills, to reposition the
window in preparation to
Consume the newly written data.
The bounded version narrows the effective limit. This can preserve some data near the
limit, such as an hypothetical packet header, in the case of
unfilled suffix of a buffer, in
compact t copies data from the window to the lower limit of the iobuf and sets the
window to range from the end of the copied data to the upper limit. This is typically
called after a series of
Consumes to save unread data and prepare for the next
flip_hi t sets the window to range from the the upper bound of the current window to
the upper limit. This operation is dual to
flip_lo and is typically called when the
data in the current (narrowed) window has been processed and the window needs to be
positioned over the remaining data in the buffer. For example:
(* ... determine initial_data_len ... *)
Iobuf.resize buf ~len:initial_data_len;
(* ... and process initial data ... *)
Now the window of
buf ranges over the remainder of the data.
"consume" and "fill" functions access data at the lower bound of the window and advance lower bound of the window. "peek" and "poke" functions access data but do not advance the window.
Consume.string t ~len reads
len characters (all, by default) from
t into a new
string and advances the lower bound of the window accordingly.
Fill.bin_prot X.bin_write_t t x writes
t in bin-prot form, advancing past
the bytes written.
Poke functions access a value at
pos from the lower bound of the window
and do not advance.
Poke.bin_prot X.bin_write_t t x writes
x to the beginning of
t in binary form
Unsafe has submodules that are like their corresponding module, except with no range
fill_bin_prot writes a bin-prot value to the lower bound of the window, prefixed by
its length, and advances by the amount written.
fill_bin_prot returns an error if
the window is too small to write the value.
consume_bin_prot t reader reads a bin-prot value from the lower bound of the window,
which should have been written using
fill_bin_prot, and advances the window by the
consume_bin_prot returns an error if there is not a complete message
in the window and in that case the window is left unchanged.
Don't use these without a good reason, as they are incompatible with similar functions
Writer. They use a 4-byte length rather than an 8-byte length.
Blit copies between iobufs and advances neither
Blit_consume copies between iobufs and advances
src but does not advance
Blit_fill copies between iobufs and advances
dst but does not advance
Blit_consume_and_fill copies between iobufs and advances both
recvmmsg's context comprises data needed by the system call.
recvmmsg_assume_fd_is_nonblocking fd context returns the number of
read into (or
fd must not block.
THREAD_IO_CUTOFF is ignored.
EINVAL is returned if an
Iobuf passed to
Recvmmsg_context.create has its
or limits changed.
Expert module is for building efficient out-of-module