From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id JAA15223; Wed, 28 Apr 2004 09:43:02 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id JAA15448 for ; Wed, 28 Apr 2004 09:43:01 +0200 (MET DST) Received: from postfix3-1.free.fr (postfix3-1.free.fr [213.228.0.44]) by nez-perce.inria.fr (8.12.10/8.12.10) with ESMTP id i3S7h0jq030449 for ; Wed, 28 Apr 2004 09:43:00 +0200 Received: from warp (lns-th2-5f-81-56-197-80.adsl.proxad.net [81.56.197.80]) by postfix3-1.free.fr (Postfix) with SMTP id 25D34C442F; Wed, 28 Apr 2004 09:42:59 +0200 (CEST) Message-ID: <009401c42cf4$4ef2e4c0$ef01a8c0@warp> From: "Nicolas Cannasse" To: "Gerd Stolpmann" Cc: "Yamagata Yoriyuki" , References: <00cb01c42afd$7fc1b430$19b0e152@warp> <20040426.221606.71081508.yoriyuki@mbg.ocn.ne.jp> <015701c42b9a$00065730$ef01a8c0@warp> <20040427.002643.78700697.yoriyuki@mbg.ocn.ne.jp> <016401c42bc4$b6438840$19b0e152@warp> <1083013017.8842.327.camel@ice.gerd-stolpmann.de> <007a01c42c8b$00941ec0$19b0e152@warp> <1083104549.23577.91.camel@ice.gerd-stolpmann.de> Subject: Re: [Caml-list] Re: Common IO structure Date: Wed, 28 Apr 2004 09:42:07 +0200 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 6.00.2800.1409 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409 X-Miltered: at nez-perce by Joe's j-chkmail ("http://j-chkmail.ensmp.fr")! X-Loop: caml-list@inria.fr X-Spam: no; 0.00; cannasse:01 warplayer:01 caml-list:01 implicitly:01 generalised:01 layered:01 buffer:01 char:01 cannasse:01 unicode:01 unicode:01 bool:01 nicolas:01 nicolas:01 byte:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk [...] > I guess you mean this one from a previous mail: > > class ['a,'b] input = object > method read : 'a > method nread : int -> 'b > method close_in : unit > end > > class ['a,'b,'c] output = object > method write : 'a > method nwrite : 'b > method close_out : 'c > end > > I doubt this is very practical. Consider you want to write Unicode > characters into a file (I think a common example). The file as such is a > byte stream, but you want an additional Unicode interface that converts > implicitly to, say UTF-8. With your idea of generalised channel, the > only way to do this is to build layers, something like > > let file_as_byte_channel = new file_out_channel "name" in > let file_as_uni_channel = new convert_utf8_to_byte file_as_byte_channel > > Call file_as_byte_channel # write to output a byte, and call > file_as_uni_channel # write to output a Unicode character. You don't > have a single object that can do both, however. Even worse: If you want > to use both interfaces alternately, you have to be careful to flush > buffers at the right time (in the case there are buffers). I don't know so much about UTF-8, but does it accept normal bytes ? For example, ANSI chars are converted to identity by UTF-8, aren't they ? So to write text only you only need to keep the second instance. Of course if you're dealing with a channel that can write both binary data (without any conversion) and text data (with UTF-8) the best is to write an adaptator that will enable you to do the both, and flush the buffers for you. But we're already out of the common example you're describing. Layered IO are powerful. This is how it works in Java : you create for example a ZipOutputStream with an existing OutputStream. Of course it's possible that the ZipOutputStream have its own internal buffer, so you have to be very careful to flush it before writing something directly to the underlying OutputStream. Pseudo code : use my ouputstream create a new zip outputstream wrapped on my outputstream write contents to it flush continue using my outputstream That's same for UTF-8/binary streams. More interesting, for example in Java you have a CRC32OutputStream, you can put in at any layer you want, and at any time extract the CRC32 calculated from all the data that went through it. > I think it is better to have two methods, one for the polymorphic case, > and one for strings. The latter plays a special role, simply because all > I/O finally is string I/O. I don't agree with this. Most of IO are (char,string) IO that's true but some are not, I already show example that were (bool,(int * int)) output. Of course, you can always define the following : class type ['a,'b] abstract_input = object method read : 'a method read_buf : 'b .... end class type ['a] input = ['a,string] abstract_input So having one more polymorphic parameter is not so troublesome, and can actually help. Regards, Nicolas Cannasse ------------------- 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