Version française
Home     About     Download     Resources     Contact us    
Browse thread
[Caml-list] Re: Common IO structure
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Vladimir N. Silyaev <vsilyaev@m...>
Subject: Re: [Caml-list] Re: Common IO structure
On Tue, May 04, 2004 at 10:31:14PM +0100, Benjamin Geer wrote:
> >If you felt interested, please look into the attached file io.ml.
> 
> This looks like a good start to me; what do others think?
> 
> I have two questions about it:
> 
> First, I think that rather than having to hard-code the use of the UTF8 
> module in an application in order to handle UTF-8 characters, it would 
> be more useful to be able to specify encodings using string arguments; 
> the choice of encoding is often determined by reading a configuration 
> file.  Would there be a way to support this?
Sure. I probably should specify more clearly, it was envisioned
that IO module would only specify signatures for IO.Stream.[Read/Write],
IO.Block.[Read/Write] and IO.Filter.[Read/Write]. Rest of the file was
just an quick and dirty implementation of mapping IO to Pervasives modules,
Unix socket and sample filter for UTF8 bytestream<->unicode converter.

And assume that we have in addition to UTF8 filter, filter
UTF16 bytestream <->unicode, Latin1 bytestream<->unicode, there is could
be a helper function, which takes filename, encoding name and returns
IO.Stream.Read specialized with Unicode type. This could be done
relatively easy, by providing functoral interface to the camomile, and
reusing existing code.

> 
> Second, I'm wondering if this design can be adapted to accommodate 
> non-blocking I/O.  The 'get' function has to return a character, but on 
> a non-blocking socket, there might not be any character to return.  I've 
> attached a sketch of an approach that might be more suitable for 
> non-blocking I/O; I'd like to add it to your design, but I'm having 
> trouble figuring out how.  I would be very interested in your thoughts 
> on this.
Sure non blocking I/O could be supported, but one should be aware,
that get and/or put could throw exception.

> exception Buffer_underflow
> exception Buffer_overflow
> 
> module type Async =
> sig
>   type t
>   val create : unit -> t
>   val get : t -> char
>   val put : t -> char -> unit
>   val read : t -> string -> int -> int -> int
>   val write : t -> string -> int -> int -> unit
>   val from_fd : t -> Unix.file_descr -> unit
>   val to_fd : t -> Unix.file_descr -> unit
>   val clear : t -> unit
>   val flip : t -> unit
>   val compact : t -> unit
>   val rewind : t -> unit
>   val limit : t -> int
>   val position : t -> int
>   val remaining : t -> int
>   val contents : t -> string
> end

This signature looks like a good starting point. However I would rather
separate this code to three different pieces:
 - input, asynchronous source of bytes
 - output, synchronous source of symbols (char)
 - algorithm(filter), converts input to output,
   and throws exception where apropriate

Input is a signature, for example like this:
module Block = struct
  module type Read =
  sig
    type t
    val nb_read:  t -> string -> int -> int -> int
  end

Output is IO.Stream.Read + IO.Block.Read

And algorithm is a functor, which actually manages all buffering
and offset arithmetic.

Such code structuring would allow algorithm reuse with different
type of input.

Please note,  that write and read inherently separated in signatures,
it allows simpler interface, supports read/write only streams
and better feet common model, where read and writes are separated.
However, module couldn't implement both read and write signatures, if
it's required.

Regards,
Vladimir


-------------------
To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr
Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/
Beginner's list: http://groups.yahoo.com/group/ocaml_beginners