(** Binary buffer operations for reading and writing trace data. *) module Shared_writer_fd : sig type t (** A Unix file descriptor, shared between multiple writers. *) exception Closed val make : Unix.file_descr -> t (** [make fd] wraps a file descriptor for shared writing. *) val write_fully : t -> bytes -> pos:int -> len:int -> unit (** Writes the specified range of a buffer to the file descriptor, raising Closed if [close] has been called. *) val close : t -> unit (** [close t] closes the shared file descriptor. *) end module Write : sig type t = private { buf : Bytes.t; mutable pos : int; pos_end : int } (** A [t] is a subsequence of a Bytes.t, to be written sequentially. None of the operations below allocate or resize the underlying byte buffer \- the underlying Bytes.t is managed by the caller, and may be shared between mutiple [t]s. *) val of_bytes : Bytes.t -> t (** [of_bytes buf] creates a write buffer spanning the entire byte buffer. *) val of_bytes_sub : Bytes.t -> pos:int -> pos_end:int -> t (** [of_bytes_sub buf ~pos ~pos_end] creates a write buffer for a sub-range. *) val remaining : t -> int (** [remaining t] returns the number of bytes available for writing. *) val write_fd : Shared_writer_fd.t -> t -> unit (** [write_fd fd b] writes the bytes written to b to the fd. No bufs are invalidated. *) (** Writing to a buf. All types are written little-endian. All functions raise Overflow if there is insufficient space remaining. *) exception Overflow of int val put_8 : t -> int -> unit (** Write an 8-bit integer. *) val put_16 : t -> int -> unit (** Write a 16-bit integer. *) val put_32 : t -> int32 -> unit (** Write a 32-bit integer. *) val put_64 : t -> int64 -> unit (** Write a 64-bit integer. *) val put_float : t -> float -> unit (** Write a float. *) val put_string : t -> string -> unit (** Write a length-prefixed string. *) val put_vint : t -> int -> unit (** Write a variable-length integer. *) (** The skip_t functions reserve space to be filled by a later update_t. (for e.g. length fields that are only known when writing is finished). *) type position_8 = private int (** Saved position for an 8-bit field. *) val skip_8 : t -> position_8 (** Reserve space for an 8-bit integer. *) val update_8 : t -> position_8 -> int -> unit (** Fill in a previously reserved 8-bit integer. *) type position_16 = private int (** Saved position for a 16-bit field. *) val skip_16 : t -> position_16 (** Reserve space for a 16-bit integer. *) val update_16 : t -> position_16 -> int -> unit (** Fill in a previously reserved 16-bit integer. *) type position_32 = private int (** Saved position for a 32-bit field. *) val skip_32 : t -> position_32 (** Reserve space for a 32-bit integer. *) val update_32 : t -> position_32 -> int32 -> unit (** Fill in a previously reserved 32-bit integer. *) type position_64 = private int (** Saved position for a 64-bit field. *) val skip_64 : t -> position_64 (** Reserve space for a 64-bit integer. *) val update_64 : t -> position_64 -> int64 -> unit (** Fill in a previously reserved 64-bit integer. *) type position_float = private int (** Saved position for a float field. *) val skip_float : t -> position_float (** Reserve space for a float. *) val update_float : t -> position_float -> float -> unit (** Fill in a previously reserved float. *) end module Read : sig type t = private { buf : Bytes.t; mutable pos : int; pos_end : int } (** A [t] is a subsequence of a Bytes.t, to be read sequentially. None of the operations below allocate or resize the underlying byte buffer \- the underlying Bytes.t is managed by the caller, and may be shared between mutiple [t]s. *) val of_bytes : Bytes.t -> t (** [of_bytes buf] creates a read buffer spanning the entire byte buffer. *) val of_bytes_sub : Bytes.t -> pos:int -> pos_end:int -> t (** [of_bytes_sub buf ~pos ~pos_end] creates a read buffer for a sub-range. *) val remaining : t -> int (** [remaining t] returns the number of bytes available for reading. *) val split : t -> int -> t * t (** [split b len] splits b into (a, b), where a contains at most len bytes and b contains the rest, if any. The two returned parts share the same underlying Bytes.t. *) val read_fd : Unix.file_descr -> Bytes.t -> t (** [read_fd fd byt] returns a buf containing bytes read from fd, whose underlying buffer is byt. All [t]s sharing this underlying buffer are invalidated. *) val refill_fd : Unix.file_descr -> t -> t (** [refill_fd fd b] returns a buf containing the contents of b followed by bytes read from fd, whose underlying buffer is that of b. All bufs sharing this underlying buffer (including b) are invalidated. *) val empty : t (** The empty read buffer. *) (** Reading from a buf. All types are read little-endian. All functions raise Underflow if there are insufficient bytes remaining. *) exception Underflow of int val get_8 : t -> int (** Read an 8-bit integer. *) val get_16 : t -> int (** Read a 16-bit integer. *) val get_32 : t -> int32 (** Read a 32-bit integer. *) val get_64 : t -> int64 (** Read a 64-bit integer. *) val get_float : t -> float (** Read a float. *) val get_string : t -> string (** Read a length-prefixed string. *) val get_vint : t -> int (** Read a variable-length integer. May overflow on 32-bit machines. *) end