118 lines
4.5 KiB
OCaml
118 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 ]
|