369 |
closed : bool ref, |
closed : bool ref, |
370 |
bufferMode : IO.buffer_mode ref, |
bufferMode : IO.buffer_mode ref, |
371 |
writer : writer, |
writer : writer, |
372 |
writeArr : {buf : A.array, i : int, sz : int option} -> unit, |
writeArr : AS.slice -> unit, |
373 |
writeVec : {buf : V.vector, i : int, sz : int option} -> unit, |
writeVec : VS.slice -> unit, |
374 |
cleanTag : CleanIO.tag |
cleanTag : CleanIO.tag |
375 |
} |
} |
376 |
|
|
385 |
case !pos |
case !pos |
386 |
of 0 => () |
of 0 => () |
387 |
| n => (( |
| n => (( |
388 |
writeArr {buf=buf, i=0, sz=SOME n}; pos := 0) |
writeArr (AS.slice (buf, 0, SOME n)); pos := 0) |
389 |
handle ex => outputExn (strm, mlOp, ex)) |
handle ex => outputExn (strm, mlOp, ex)) |
390 |
(* end case *)) |
(* end case *)) |
391 |
|
|
393 |
val _ = isClosedOut (strm, "output") |
val _ = isClosedOut (strm, "output") |
394 |
val {buf, pos, bufferMode, ...} = os |
val {buf, pos, bufferMode, ...} = os |
395 |
fun flush () = flushBuffer (strm, "output") |
fun flush () = flushBuffer (strm, "output") |
396 |
fun flushAll () = (#writeArr os {buf=buf, i=0, sz=NONE} |
fun flushAll () = (#writeArr os (AS.full buf) |
397 |
handle ex => outputExn (strm, "output", ex)) |
handle ex => outputExn (strm, "output", ex)) |
398 |
fun writeDirect () = ( |
fun writeDirect () = ( |
399 |
case !pos |
case !pos |
400 |
of 0 => () |
of 0 => () |
401 |
| n => (#writeArr os {buf=buf, i=0, sz=SOME n}; pos := 0) |
| n => (#writeArr os (AS.slice (buf, 0, SOME n)); |
402 |
|
pos := 0) |
403 |
(* end case *); |
(* end case *); |
404 |
#writeVec os {buf=v, i=0, sz=NONE}) |
#writeVec os (VS.full v)) |
405 |
handle ex => outputExn (strm, "output", ex) |
handle ex => outputExn (strm, "output", ex) |
406 |
fun insert copyVec = let |
fun insert copyVec = let |
407 |
val bufLen = A.length buf |
val bufLen = A.length buf |
443 |
case !bufferMode |
case !bufferMode |
444 |
of IO.NO_BUF => ( |
of IO.NO_BUF => ( |
445 |
arrUpdate (buf, 0, elem); |
arrUpdate (buf, 0, elem); |
446 |
writeArr {buf=buf, i=0, sz=SOME 1} |
writeArr (AS.slice (buf, 0, SOME 1)) |
447 |
handle ex => outputExn (strm, "output1", ex)) |
handle ex => outputExn (strm, "output1", ex)) |
448 |
| _ => let val i = !pos val i' = i+1 |
| _ => let val i = !pos val i' = i+1 |
449 |
in |
in |
468 |
|
|
469 |
fun mkOutstream (wr as PIO.WR{chunkSize, writeArr, writeVec, ...}, mode) = |
fun mkOutstream (wr as PIO.WR{chunkSize, writeArr, writeVec, ...}, mode) = |
470 |
let |
let |
471 |
fun iterate f (buf, i, sz) = let |
fun iterate (f, size, subslice) = let |
472 |
fun lp (_, 0) = () |
fun lp sl = |
473 |
| lp (i, n) = let val n' = f{buf=buf, i=i, sz=SOME n} |
if size sl = 0 then () |
474 |
in lp (i+n', n-n') end |
else let val n = f sl |
475 |
in |
in |
476 |
lp (i, sz) |
lp (subslice (sl, n, NONE)) |
477 |
end |
end |
|
val writeArr' = (case writeArr |
|
|
of NONE => (fn _ => raise IO.BlockingNotSupported) |
|
|
| (SOME f) => let |
|
|
fun write {buf, i, sz} = let |
|
|
val len = (case sz |
|
|
of NONE => A.length buf - i |
|
|
| (SOME n) => n |
|
|
(* end case *)) |
|
478 |
in |
in |
479 |
iterate f (buf, i, len) |
lp |
|
end |
|
|
in |
|
|
write |
|
480 |
end |
end |
481 |
|
val writeArr' = (case writeArr |
482 |
|
of NONE => (fn _ => raise IO.BlockingNotSupported) |
483 |
|
| (SOME f) => iterate (f, AS.length, AS.subslice) |
484 |
(* end case *)) |
(* end case *)) |
485 |
val writeVec' = (case writeVec |
val writeVec' = (case writeVec |
486 |
of NONE => (fn _ => raise IO.BlockingNotSupported) |
of NONE => (fn _ => raise IO.BlockingNotSupported) |
487 |
| (SOME f) => let |
| (SOME f) => iterate (f, VS.length, VS.subslice) |
|
fun write {buf, i, sz} = let |
|
|
val len = (case sz |
|
|
of NONE => V.length buf - i |
|
|
| (SOME n) => n |
|
|
(* end case *)) |
|
|
in |
|
|
iterate f (buf, i, len) |
|
|
end |
|
|
in |
|
|
write |
|
|
end |
|
488 |
(* end case *)) |
(* end case *)) |
489 |
(* install a dummy cleaner *) |
(* install a dummy cleaner *) |
490 |
val tag = CleanIO.addCleaner { |
val tag = CleanIO.addCleaner { |