caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Benjamin Geer <ben@socialtools.net>
To: "Vladimir N. Silyaev" <vsilyaev@mindspring.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Re: Common IO structure
Date: Tue, 04 May 2004 22:31:14 +0100	[thread overview]
Message-ID: <40980BA2.1010102@socialtools.net> (raw)
In-Reply-To: <20040503061212.GA64216@server.vns.oc.ca.us>

[-- Attachment #1: Type: text/plain, Size: 957 bytes --]

Vladimir N. Silyaev 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?

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.

Ben

[-- Attachment #2: buf.ml --]
[-- Type: text/plain, Size: 3216 bytes --]

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

module AsyncBuffer : Async =
struct
  type t = {
    buf : string;
    mutable pos : int;
    mutable limit: int;
  }
  
  let create () =
    let capacity = 1024 in
      {
        buf = String.create capacity;
        pos = 0;   
        limit = capacity;
      }
  
  let limit b =
    b.limit

  let position b =
    b.pos

  let remaining b =
    b.limit - b.pos

  let contents b =
    String.sub b.buf b.pos (remaining b)

  let get b =
    let c = b.buf.[b.pos] in
      if b.pos < b.limit then
        (b.pos <- b.pos + 1; c)
      else
        raise Buffer_underflow

  let put b c =
    if b.pos < b.limit then
      (b.buf.[b.pos] <- c;
       b.pos <- b.pos + 1)
    else
      raise Buffer_overflow

  let read b dst offset len =
    let real_len =
      if len > remaining b then
        remaining b
      else
        len in
      String.blit b.buf b.pos dst offset real_len;
      b.pos <- b.pos + real_len;
      real_len

  let write b src offset len =
    if len <= remaining b then
      let result =
        String.blit src offset b.buf b.pos len in
        b.pos <- b.pos + len;
        result
    else
      raise Buffer_overflow

  let from_fd b fd =
    try
      let len = Unix.read fd b.buf b.pos (remaining b) in
        b.pos <- b.pos + len;
        if len = 0 then
          raise End_of_file
    with Unix.Unix_error (err, _, _) as e ->
      match err with
          Unix.EAGAIN | Unix.EWOULDBLOCK -> ()
        | _ -> raise e
          
  let to_fd b fd =
    try
      let len = Unix.write fd b.buf b.pos (remaining b) in
        b.pos <- b.pos + len
    with Unix.Unix_error (err, _, _) as e ->
      match err with
          Unix.EAGAIN | Unix.EWOULDBLOCK -> ()
        | _ -> raise e
      
  let clear b =
    b.pos <- 0;
    b.limit <- String.length b.buf
  
  let flip b =
    b.limit <- b.pos;
    b.pos <- 0

  let compact b =
    String.blit b.buf b.pos b.buf 0 (remaining b)
  
  let rewind b =
    b.pos <- 0
end

let copy_fd in_fd out_fd =
  let b = AsyncBuffer.create () in
    try
      while (true) do
        AsyncBuffer.from_fd b in_fd;
        AsyncBuffer.flip b;
        AsyncBuffer.to_fd b out_fd;
        AsyncBuffer.compact b
      done
    with End_of_file -> ()

let copy_file input_filename output_filename =
  let in_fd = Unix.openfile input_filename
                [ Unix.O_RDONLY; Unix.O_NONBLOCK ] 0o644 in
  let out_fd = Unix.openfile output_filename
                 [ Unix.O_WRONLY; Unix.O_CREAT; Unix.O_TRUNC; Unix.O_NONBLOCK ] 0o644 in
  let output_data = String.create 10 in
    copy_fd in_fd out_fd;
    Unix.close in_fd;
    Unix.close out_fd

let _ =
  copy_file "input.txt" "output.txt"

  reply	other threads:[~2004-05-04 21:31 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2004-05-03  6:12 Vladimir N. Silyaev
2004-05-04 21:31 ` Benjamin Geer [this message]
2004-05-04 22:59   ` Yamagata Yoriyuki
2004-05-05  8:11     ` skaller
2004-05-05 15:48       ` Marcin 'Qrczak' Kowalczyk
2004-05-05 19:28         ` skaller
2004-05-05 17:33     ` Vladimir N. Silyaev
2004-05-05 17:31   ` Vladimir N. Silyaev
2004-05-07 22:11     ` Benjamin Geer
2004-05-08  7:29       ` Vladimir N. Silyaev
2004-05-09 17:35         ` Benjamin Geer
  -- strict thread matches above, loose matches on Subject: below --
2004-04-24  9:28 [Caml-list] [ANN] The Missing Library Nicolas Cannasse
2004-04-25  8:56 ` Common IO structure (was Re: [Caml-list] [ANN] The Missing Library) Yamagata Yoriyuki
2004-04-25 11:54   ` Gerd Stolpmann
2004-04-26 14:53     ` [Caml-list] Re: Common IO structure Yamagata Yoriyuki
2004-04-26 21:02       ` Gerd Stolpmann
2004-04-25 19:42   ` Common IO structure (was Re: [Caml-list] [ANN] The Missing Library) Nicolas Cannasse
2004-04-26 13:16     ` [Caml-list] Re: Common IO structure Yamagata Yoriyuki
2004-04-26 13:53       ` Jacques GARRIGUE
2004-04-26 14:26         ` Nicolas Cannasse
2004-04-28  6:52           ` Jacques GARRIGUE
2004-04-26 14:23       ` Nicolas Cannasse
2004-04-26 14:55         ` skaller
2004-04-26 15:26         ` Yamagata Yoriyuki
2004-04-26 19:28           ` Nicolas Cannasse
2004-04-26 20:56             ` Gerd Stolpmann
2004-04-26 21:14               ` John Goerzen
2004-04-26 22:32                 ` Gerd Stolpmann
2004-04-26 21:52               ` Benjamin Geer
2004-04-27 16:00               ` Yamagata Yoriyuki
2004-04-27 21:51                 ` Gerd Stolpmann
2004-04-27 19:08               ` Nicolas Cannasse
2004-04-27 22:22                 ` Gerd Stolpmann
2004-04-28  7:42                   ` Nicolas Cannasse
2004-04-29 10:13                 ` Yamagata Yoriyuki
2004-04-27 15:43             ` Yamagata Yoriyuki
2004-04-27 16:17               ` Nicolas Cannasse
2004-04-27 16:58                 ` Yamagata Yoriyuki
2004-04-27 23:35                   ` Benjamin Geer
2004-04-28  3:44                     ` John Goerzen
2004-04-28 13:01                       ` Richard Jones
2004-04-28 21:30                       ` Benjamin Geer
2004-04-28 21:44                         ` John Goerzen
2004-04-28 22:41                           ` Richard Jones
2004-04-29 11:51                             ` Benjamin Geer
2004-04-29 12:03                               ` Richard Jones
2004-04-29 15:16                                 ` Benjamin Geer
2004-04-29 10:27                           ` Yamagata Yoriyuki
2004-04-29 13:03                             ` John Goerzen
2004-04-29 13:40                               ` Yamagata Yoriyuki
2004-04-29 14:02                                 ` John Goerzen
2004-04-29 15:31                                   ` Yamagata Yoriyuki
2004-04-29 17:31                                     ` james woodyatt
2004-04-29 23:53                                       ` Benjamin Geer
2004-04-30  4:10                                         ` james woodyatt
2004-04-29 11:23                           ` Benjamin Geer
2004-04-29 12:23                             ` Richard Jones
2004-04-29 15:10                               ` Benjamin Geer
2004-04-29 15:35                                 ` John Goerzen
2004-04-29 15:46                                   ` Benjamin Geer
2004-04-29 15:58                                     ` Richard Jones
2004-04-29 20:41                                     ` John Goerzen
2004-04-29 22:35                                       ` Benjamin Geer
2004-05-01 14:37                               ` Brian Hurt
2004-04-29 13:23                             ` John Goerzen
2004-04-29 14:12                               ` John Goerzen
2004-04-29 15:37                               ` Benjamin Geer
2004-04-28  7:05                     ` Nicolas Cannasse
2004-04-28  0:20                   ` skaller
2004-04-28  3:39                   ` John Goerzen
2004-04-28 13:04                   ` Richard Jones

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=40980BA2.1010102@socialtools.net \
    --to=ben@socialtools.net \
    --cc=caml-list@inria.fr \
    --cc=vsilyaev@mindspring.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).