(* $Id: netchannels.mli 1009 2006-10-01 20:26:01Z gerd $
* ----------------------------------------------------------------------
*
*)
(** Object-oriented I/O: Basic types and classes
*
* {b Contents}
*
* - {!Netchannels.types}
* - {!Netchannels.input}
* - {!Netchannels.output}
* - {!Netchannels.delegation}
* - {!Netchannels.lifting}
* - {!Netchannels.descriptors}
* - {!Netchannels.transactional}
* - {!Netchannels.filters}
* {ul {- {!Netchannels.filters_notes}}}
*
* The tutorial has been moved to {!Netchannels_tut}.
*)
(** {1:types Types} *)
(* ***************************** Types ******************************** *)
(** There are three levels of class types for channels:
* - [rec_in_channel] and [rec_out_channel]: Primitive, but standardized level
* - [raw_in_channel] and [raw_out_channel]: Unix level
* - [in_obj_channel] and [out_obj_channel]: Application level
*
* The "rec" level has been recently introduced to improve interoperability
* with other libraries (e.g. camomile). The idea is to standardize the
* real core methods of I/O, so they have the same meaning in all libraries.
* Read
* "{{:http://www.ocaml-programming.de/rec/IO-Classes.html}Basic I/O class types}"
* for more.
*
* The "raw" level represents the level of Unix file descriptors.
*
* The application level is what should be used in programs. In addition
* to the "raw" level one can find a number of convenience methods,
* e.g. [input_line] to read a line from the channel. The downside is that
* these methods usually work only for blocking I/O.
*
* One can lower the level by coercion, e.g. to turn an [in_obj_channel]
* into a [rec_in_channel], apply the function
*
* [(fun ch -> (ch : in_obj_channel :> rec_in_channel))]
*
* To higher the level, apply [lift_in] or [lift_out], defined below.
*)
(** {b Interface changes:} Since ocamlnet-0.98, the semantics of
* the methods [input] and [output] has slightly changed. When the end
* of the channel is reached, [input] raises now [End_of_file]. In previous
* releases of ocamlnet, the value 0 was returned. When the channel cannot
* process data, but is in non-blocking mode, both methods now return the
* value 0. In previous releases of ocamlnet, the behaviour was not
* defined.
*)
exception Closed_channel
(** Raised when channel operations are called when the channel is closed *)
exception Buffer_underrun
(** Raised by input methods if the internal buffer of the channel is too
* empty to read even one byte of data.
* This exception is only used by certain implementations of channel
* classes.
*)
exception Command_failure of Unix.process_status
(** Raised by [close_in] or [close_out] if the channel is connected with
* another process, and the execution of that process fails.
*)
(** Recommended input class type for library interoperability. *)
class type rec_in_channel = object
(** Description
*
* This class type is defined in
* "{{:http://www.ocaml-programming.de/rec/IO-Classes.html}Basic I/O class types}"
* as collaborative effort of several library creators.
*)
method input : string -> int -> int -> int
(** Reads octets from the channel and puts them into the string. The
* first [int] argument is the position of the substring, and the second
* [int] argument is the length of the substring where the data are
* stored. The method returns the number of octets actually read and
* stored.
*
* When the end of the channel is reached and there is no further octet
* to read, the exception [End_of_file] will be raised. {b This has
* been changed in ocamlnet-0.97! In previous releases the number 0
* was returned at the end of the channel.}
*
* When the channel is non-blocking, and there are currently no bytes
* to read, the number 0 will be returned. {b This has
* been changed in ocamlnet-0.97! In previous releases this behaviour
* was undefined.}
*
* When the channel is closed, the exception [Closed_channel] will be
* raised if an ocamlnet implementation is used. For implementations
* of other libraries there is no standard for this case.
*)
method close_in : unit -> unit
(** Closes the channel for input.
*
* When the channel is already closed, the exception [Closed_channel] will
* be raised if an ocamlnet implementation is used. For implementations
* of other libraries there is no standard for this case.
*)
end
(** Basic Unix-level class type for input channels as used by ocamlnet. In addition
* to the recommended standard, ocamlnet always support a position counter
*)
class type raw_in_channel = object
inherit rec_in_channel
method pos_in : int
(** Returns the current channel position. This position can be expected
* to be consistent with the returned number of bytes of [input], i.e.
* when [input] returns [n], the position is advanced by [n].
*
* As seek operations are outside the scope of [Netchannels],
* implementations may or may not take seek operations into account.
*)
end
(** Recommended output class type for library interoperability. *)
class type rec_out_channel = object
(** Description
*
* This class type is defined in
* "{{:http://www.ocaml-programming.de/rec/IO-Classes.html}Basic I/O class types}"
* as collaborative effort of several library creators.
*)
method output : string -> int -> int -> int
(** Takes octets from the string and writes them into the channel. The
* first [int] argument is the position of the substring, and the second
* [int] argument is the length of the substring where the data can
* be found. The method returns the number of octets actually written.
*
* The implementation may choose to collect written octets in a buffer
* before they actually delivered to the underlying resource.
*
* When the channel is non-blocking, and there are currently no bytes
* to write, the number 0 will be returned. {b This has
* been changed in ocamlnet-0.97! In previous releases this behaviour
* was undefined.}
*
* When the channel is closed, the exception [Closed_channel] will be
* raised if an ocamlnet implementation is used. For implementations
* of other libraries there is no standard for this case.
*)
method flush : unit -> unit
(** If there is a write buffer, it will be flushed. Otherwise, nothing
* happens
*)
method close_out : unit -> unit
(** Flushes the buffer, if any, and closes the channel for output.
*
* When the channel is already closed, the exception [Closed_channel] will
* be raised if an ocamlnet implementation is used. For implementations
* of other libraries there is no standard for this case.
*)
end
(** Basic Unix-level class type for output channels as used by ocamlnet. In addition
* to the recommended standard, ocamlnet always support a position counter
*)
class type raw_out_channel = object
inherit rec_out_channel
method pos_out : int
(** Returns the current channel position. This position can be expected
* to be consistent with the returned number of bytes of [output], i.e.
* when [output] returns [n], the position is advanced by [n].
*
* As seek operations are outside the scope of [Netchannels],
* implementations may or may not take seek operations into account.
*)
end
(** A channel supporting both input and output. The input and output
* aspects are strictly separated
*)
class type raw_io_channel = object
inherit raw_in_channel
inherit raw_out_channel
end
(** Further methods usually supported by ocamlnet channel implementations.
* These methods are only reasonable when the channel is of blocking type,
* i.e. waits for input when not enough data are available to perform an
* operation. Implementations may choose to fail when they detect the
* channel is non-blocking.
*)
class type compl_in_channel = object
method really_input : string -> int -> int -> unit
(** Reads exactly as many octets from the channel as the second [int]
* argument specifies. The octets are placed at the position denoted
* by the first [int] argument into the string.
*
* When the end of the channel is reached before the passed number of
* octets are read, the exception [End_of_file] is raised.
*)
method input_char : unit -> char
(** Reads exactly one character from the channel, or raises [End_of_file]
*)
method input_line : unit -> string
(** Reads the next line from the channel. When the channel is already
* at the end before [input_line] is called, the exception [End_of_file]
* is raised.
*)
method input_byte : unit -> int
(** Reads exactly one octet from the channel and returns its code,
* or raises [End_of_file]
*)
end
(** The application-level input channel supports raw and complemented methods *)
class type in_obj_channel = object
inherit raw_in_channel
inherit compl_in_channel
end
(** Further methods usually supported by ocamlnet channel implementations.
* These methods are only reasonable when the channel is of blocking type,
* i.e. waits for output readiness when the underlying resource currently
* cannot process enough dat