(* * Copyright (c) 2011-2015 Anil Madhavapeddy * Copyright (c) 2013-2015 Thomas Gazagnaire * 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 ]