module Io:General structured I/O module.sig
..end
This module defines the base types and combinators that you can use to build literates for your data type.
A literate for a type 'a
is someone who can both read and write values of type 'a
over arbitrary
fragment channels (which are defined in the module Fragments
.)
Once you have defined a literate, you can use it to do I/O over any kind of fragment channel. Basic fragment channels (pretty-printed, human-readable ASCII ; binary and XML) are defined in the modules Human_io, Binary_io and XML_io. You can also mix channel kinds and for instance read from binary fragment channels and write to ASCII fragment channels.
To do IO with a type
type foo = (int * (float list) * (string option list)) option array
you must :
io_pair
, io_list
, etc.:
let io_foo =
io_array (io_option
io_int
(io_list io_float)
(io_list (io_option io_string)))
;;
typeio_in =
Fragments.io_in
typeio_out =
Fragments.io_out
exception Unknown_constructor
type'a
r =io_in -> 'a
type'a
w ='a -> io_out -> unit
type'a
literate ='a r * 'a w
type'a
sum_io_spec =(string -> 'a r) * ('a -> string * (io_out -> unit))
io_sum
to build a literate for the given type.
It is a pair (reader,writer)
where reader
is first given the name of the constructor
and has to return a reader that will read the arguments of the constructor and apply
the constructor to return a value of type 'a
. writer
pattern-matches the sum
type and returns a pair (name, writer')
where name
is a string encoding the name
of the constructor, and writer'
is a writer for the arguments (which therefore have
to be curryfied.
For instance, the specifier for the 'a option
type is defined as:
(function
| "none" -> fun i -> None
| "some" -> fun i -> Some(read xio i)
| _ -> raise Unknown_tag),
(function
| None -> "none", write io_unit ()
| Some x -> "some", write xio x)
type'a
record_io_spec =(string * ('a -> io_in -> 'a) * ('a -> io_out -> unit)) list
io_record
to build a literate for
that record type. This is a list of triplets
[(field1,reader1,writer1); (field2,reader2,writer2); ...]
where fieldi
is an identifiers for the field,
readeri
takes the current value of the record,
and updates it by reading a value for the field fieldi
,
and writeri
takes a record and an output channel and writes its
field fieldi
.
type('a, 'b)
iterator ='b -> ('a -> unit) -> unit
type('a, 'b)
builder =unit -> ('a -> unit) * (unit -> 'b)
(add,get)
where add
is a function that adds
one element to the bag and get
returns the contents of the bag.type('a, 'b)
collection_io_spec ='a literate * ('a, 'b) iterator * ('a, 'b) builder
'thing
is made of a literate for the
type 'thing
, an iterator and a builder.val assoc3 : 'a -> ('a * 'b * 'c) list -> 'b * 'c
val read : 'a literate -> io_in -> 'a
read lit ch
reads a value from the channel ch
using the literate lit
. For instance,
read io_int ch
returns an integer.val write : 'a literate -> 'a -> io_out -> unit
write lit v ch
writes the value v
to the channel ch
using the literate lit
. For example,
write io_int 33 ch
writes the integer 33
to the channel ch
.val write_and_flush : 'a literate -> 'a -> io_out -> unit
val finish : io_in -> unit
finish ch
finishes reading the input channel. Actually, it reads the Stop_data tag.val flush : io_out -> unit
flush ch
flushed the output channel. Actually, it emits the Stop_data tag and flushes the I/O buffers.val io_int : int literate
val io_int64 : int64 literate
val io_string : string literate
val io_char : char literate
val io_bool : bool literate
val io_float : float literate
val io_unit : unit literate
val io_convert : ('a -> 'b) -> ('b -> 'a) -> 'a literate -> 'b literate
f : 'a -> 'b
its inverse g : 'b -> 'a
and a literate io
for 'a
creates a literate for 'b
.val io_pair : 'a literate -> 'b literate -> ('a * 'b) literate
io_pair lit1 lit2
takes literates lit1
and lit2
for types
'a
and 'b
and returns a literate for the type 'a * 'b
.val io_triple : 'a literate ->
'b literate -> 'c literate -> ('a * 'b * 'c) literate
val io_quadruple : 'a literate ->
'b literate ->
'c literate -> 'd literate -> ('a * 'b * 'c * 'd) literate
val io_list : 'a literate -> 'a list literate
io_list io_int
is a literate able to read and write
lists of integers.val io_array : 'a literate -> 'a array literate
val io_hashtbl : 'a literate -> 'b literate -> ('a, 'b) Hashtbl.t literate
val io_record : 'a record_io_spec -> 'a -> 'a literate
record_io_spec
describing your record.val io_collection : ('a, 'b) collection_io_spec -> 'b literate
val io_sum : 'a sum_io_spec -> 'a literate
record_io_spec
describing your sum type.val io_option : 'a literate -> 'a option literate
'a option
sum type.val io_not_implemented : 'a literate
val convert : reader:io_in -> writer:io_out -> unit -> unit
reader
to writer
. This can be used to convert data between different
formats (e.g., pretty-printed to XML, or XML to binary, etc.) Note that it is not necessary to have a literate
for the data to be converted.val dump : reader:io_in -> unit -> unit
stdout
.