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"
next prev parent 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