From: Bardur A. <oca...@sc...> - 2004-08-30 19:28:10
|
Hi all, It seems there is no function to read exactly n characters into a string (ie. IO.nread just without automatically shortening the string if EOF is hit while reading). Since at least one person needs it (me :)) I thought I would add this: let really_nread i n = if n < 0 then raise (Invalid_argument "IO.really_nread"); if n = 0 then "" else let s = String.create n in let l = ref n in let p = ref 0 in while !l > 0 do let r = i.in_input s !p !l in p := !p + r; l := !l - r; done; s which is exactly the same code as IO.nread, except it doesn't try to catch the No_more_input exception. Any objections to adding this? -- Bardur Arantsson <ba...@im...> <ba...@sc...> - You've got mail! Hope you don't have stocks. Robin Williams | Live on Broadway (2002) |
From: Nicolas C. <war...@fr...> - 2004-08-30 20:34:59
|
> Hi all, > > It seems there is no function to read exactly n characters > into a string (ie. IO.nread just without automatically > shortening the string if EOF is hit while reading). Since > at least one person needs it (me :)) I thought I would add > this: > > let really_nread i n = > if n < 0 then raise (Invalid_argument "IO.really_nread"); > if n = 0 then > "" > else > let s = String.create n in > let l = ref n in > let p = ref 0 in > while !l > 0 do > let r = i.in_input s !p !l in > p := !p + r; > l := !l - r; > done; > s > > which is exactly the same code as IO.nread, except it > doesn't try to catch the No_more_input exception. > > Any objections to adding this? This will cause an infinite loop on non-blocking IO (r = 0). You might want to raise Sys_blocked_io in this case. Nicolas Cannasse |
From: Bardur A. <oca...@sc...> - 2004-08-30 21:40:59
|
On Mon, Aug 30, 2004 at 10:35:51PM +0200, Nicolas Cannasse wrote: > > Hi all, > > > > It seems there is no function to read exactly n characters > > into a string (ie. IO.nread just without automatically > > shortening the string if EOF is hit while reading). Since > > at least one person needs it (me :)) I thought I would add > > this: > > > > let really_nread i n = > > if n < 0 then raise (Invalid_argument "IO.really_nread"); > > if n = 0 then > > "" > > else > > let s = String.create n in > > let l = ref n in > > let p = ref 0 in > > while !l > 0 do > > let r = i.in_input s !p !l in > > p := !p + r; > > l := !l - r; > > done; > > s > > > > which is exactly the same code as IO.nread, except it > > doesn't try to catch the No_more_input exception. > > > > Any objections to adding this? > > This will cause an infinite loop on non-blocking IO (r = 0). > You might want to raise Sys_blocked_io in this case. > Hmm... the channel adapter uses Pervasives.input to read. This in turn uses Pervasives.unsafe_input, which uses caml_ml_input(), which uses caml_do_read() which will actually raise Sys_blocked_io itself when the read() function returns the appropriate error code. So unless I'm missing something it should actually work correctly for non-blocking IO... -- Bardur Arantsson <ba...@im...> <ba...@sc...> Hard work often pays off after time. But laziness always pays off now. http://www.demotivators.com |
From: Nicolas C. <war...@fr...> - 2004-08-31 07:50:09
|
> > This will cause an infinite loop on non-blocking IO (r = 0). > > You might want to raise Sys_blocked_io in this case. > > > > Hmm... the ***channel adapter*** uses Pervasives.input to read. Yes, but not other adapters... Please have a look at specification here : http://www.ocaml-programming.de/rec/IO-Classes.html Nicolas |
From: Bardur A. <oca...@sc...> - 2004-08-31 10:29:07
Attachments:
io-really.patch
|
On Tue, Aug 31, 2004 at 09:49:01AM +0200, Nicolas Cannasse wrote: > > > This will cause an infinite loop on non-blocking IO (r = 0). > > > You might want to raise Sys_blocked_io in this case. > > > > > > > Hmm... the ***channel adapter*** uses Pervasives.input to read. > > Yes, but not other adapters... Please have a look at specification here : > http://www.ocaml-programming.de/rec/IO-Classes.html > > Nicolas > > Fair enough. :) But then IO.nread is subject to a similar problem: It will busy-wait on a non-blocking input until more input becomes available instead of returning the string read so far. I fixed that and added two more really_... functions which do exactly the same as their regular counterparts except that they raise an exception if unable to read/write the requested amount. I've attached the patch I intend to apply to add the functions really_nread really_input really_output and to fix IO.nread when used on non-blocking IO. Any objections? (Obviously, I'll add declarations and documentation to IO.mli if accepted.) -- Bardur Arantsson <ba...@im...> <ba...@sc...> On a posted sign: "Bill stickers will be prosecuted!" Written next to it: "Bill Stickers is innocent!" |
From: Nicolas C. <war...@fr...> - 2004-08-31 11:47:46
|
> Fair enough. :) > > But then IO.nread is subject to a similar problem: It will > busy-wait on a non-blocking input until more input becomes > available instead of returning the string read so far. > > I fixed that and added two more really_... functions which > do exactly the same as their regular counterparts except > that they raise an exception if unable to read/write the > requested amount. > > I've attached the patch I intend to apply to add the > functions > > really_nread > really_input > really_output > > and to fix IO.nread when used on non-blocking IO. > > Any objections? (Obviously, I'll add declarations and > documentation to IO.mli if accepted.) Looks ok for me. Nicolas |
From: Bardur A. <oca...@sc...> - 2004-08-31 20:04:10
|
On Tue, Aug 31, 2004 at 01:46:45PM +0200, Nicolas Cannasse wrote: > > Fair enough. :) > > > > But then IO.nread is subject to a similar problem: It will > > busy-wait on a non-blocking input until more input becomes > > available instead of returning the string read so far. > > > > I fixed that and added two more really_... functions which > > do exactly the same as their regular counterparts except > > that they raise an exception if unable to read/write the > > requested amount. > > > > I've attached the patch I intend to apply to add the > > functions > > > > really_nread > > really_input > > really_output > > > > and to fix IO.nread when used on non-blocking IO. > > > > Any objections? (Obviously, I'll add declarations and > > documentation to IO.mli if accepted.) > > Looks ok for me. > Committed. -- Bardur Arantsson <ba...@im...> <ba...@sc...> - Leela, you've got mail! - (sighs) - It's not spam! Computer and Leela | Futurama |
From: skaller <sk...@us...> - 2004-08-31 01:13:54
|
On Tue, 2004-08-31 at 05:26, Bardur Arantsson wrote: > It seems there is no function to read exactly n characters > into a string (ie. IO.nread just without automatically > shortening the string if EOF is hit while reading). Since > at least one person needs it (me :)) I thought I would add > this: > > let really_nread i n = > if n < 0 then raise (Invalid_argument "IO.really_nread"); > if n = 0 then Seeing the exception being raised here suggests to me Ocaml needs a better mechanism for errors. The exception being raised conforms to the "Same way as Ocaml std lib" policy. It exhibits these problems: (1) It doesn't say which argument (2) It doesn't say what the problem was (3) There's no reference to the file/line position of the raise >This will cause an infinite loop on non-blocking IO (r = 0). >You might want to raise Sys_blocked_io in this case. Weird. You raise Sys_blocked_io when in fact the problem is that it *isn't* blocked?? -- John Skaller, mailto:sk...@us... voice: 061-2-9660-0850, snail: PO BOX 401 Glebe NSW 2037 Australia Checkout the Felix programming language http://felix.sf.net |