mte/unikernel/duniverse/mirage-channel/src/mirage_channel.mli
2025-11-11 02:07:51 +01:00

117 lines
4.5 KiB
OCaml

(*
* Copyright (c) 2011-2015 Anil Madhavapeddy <anil@recoil.org>
* Copyright (c) 2013-2015 Thomas Gazagnaire <thomas@gazagnaire.org>
* Copyright (c) 2013 Citrix Systems Inc
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)
(** MirageOS signature for channel devices.
Channels are buffered byte-streams which are attached to an
unbuffered flow (e.g. a TCPv4 connection).
{e Release v5.0.0 } *)
module type S = sig
type error
(** The type for errors. *)
val pp_error: error Fmt.t
(** [pp_error] is the pretty-printer for errors. *)
type write_error = private [> Mirage_flow.write_error]
(** The type for write errors. *)
val pp_write_error: write_error Fmt.t
(** [pp_write_error] is the pretty-printer for write errors. *)
type flow
(** The type for unbuffered network flow. *)
type t
(** The type for the state associated with channels, such as the
inflight buffers. *)
val create: flow -> t
(** [create flow] allocates send and receive buffers and
associates them with the given unbuffered [flow]. *)
val to_flow: t -> flow
(** [to_flow t] returns the flow that backs this channel. *)
val read_char: t -> (char Mirage_flow.or_eof, error) result Lwt.t
(** Reads a single character from the channel, blocking if there is
no immediately available input data. *)
val read_some: ?len:int -> t -> (Cstruct.t Mirage_flow.or_eof, error) result Lwt.t
(** [read_some ?len t] reads up to [len] characters from the
input channel and at most a full [buffer]. If [len] is not
specified, it reads all available data and returns that
buffer. *)
val read_exactly: len:int -> t -> (Cstruct.t list Mirage_flow.or_eof, error) result Lwt.t
(** [read_exactly len t] reads [len] bytes from the channel [t] or fails
with [Eof]. *)
val read_line: ?len:int -> t -> (Cstruct.t list Mirage_flow.or_eof, error) result Lwt.t
(** [read_line t] reads a line of input, which is terminated
either by a CRLF sequence, or the end of the channel (which
counts as a line).
If [?len] is provided then the maximum length of the line returned will be
[len] bytes. If the line is longer than [len] then an error will be
returned. With [len = 0], [read_line] always returns an error.
If the input data is untrusted then care should be taken to ensure [len]
is set to an application-specific small value to bound the amount of
memory allocated by [read_line].
@return Returns a list of views that terminates at EOF. *)
val write_char: t -> char -> unit
(** [write_char t ch] writes a single character to the output
channel. *)
val write_string: t -> string -> int -> int -> unit
(** [write_string t buf off len] writes [len] bytes from a string
[buf], starting from from offset [off]. *)
val write_buffer: t -> Cstruct.t -> unit
(** [write_buffer t buf] copies the buffer to the channel's
output buffer. The buffer should not be modified after being
written, and it will be recycled into the buffer allocation pool
at some future point. *)
val write_line: t -> string -> unit
(** [write_line t buf] writes the string [buf] to the output
channel and append a newline character afterwards. *)
val flush: t -> (unit, write_error) result Lwt.t
(** [flush t] flushes the output buffer and block if necessary
until it is all written out to the flow. *)
val close: t -> (unit, write_error) result Lwt.t
(** [close t] calls {!flush} and then close the underlying
flow. *)
val shutdown : t -> [ `read | `write | `read_write ] -> (unit, write_error) result Lwt.t
(** [shutdown t mode] calls {!flush} and then shutdown on the underlying
flow. *)
end
(** Functor to create a CHANNEL from a flow implementation *)
module Make(F: Mirage_flow.S)
: S with type flow = F.flow
and type error = private [> `Read_zero | `Flow of F.error | `Line_too_long ]