## winix-base-file-io-driver-for-posix-g--premicrothread.pkg
#
# Code common to text and binary file-io drivers on posix.
#
# This is the bottom layer on our file stack;
#
# See also:
#
#
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g.pkg# Compiled by:
#
src/lib/std/src/standard-core.sublibstipulate
package iox = io_exceptions; # io_exceptions is from
src/lib/std/src/io/io-exceptions.pkg package wxt = winix_types; # winix_types is from
src/lib/std/src/posix/winix-types.pkg # winix_types is from
src/lib/std/src/win32/winix-types.pkgherein
# This generic is invoked (only) in:
#
#
src/lib/std/src/io/winix-base-text-file-io-driver-for-posix--premicrothread.pkg #
src/lib/std/src/io/winix-base-data-file-io-driver-for-posix--premicrothread.pkg #
generic package winix_base_file_io_driver_for_posix_g__premicrothread (
# =====================================================
#
# These will be vectors/slices of
# characters for text file I/O, but of
# 8-bit unts for binary file I/O:
#
package vector: Typelocked_Vector; # Typelocked_Vector is from
src/lib/std/src/typelocked-vector.api package vector_slice: Typelocked_Vector_Slice; # Typelocked_Vector_Slice is from
src/lib/std/src/typelocked-vector-slice.api package rw_vector: Typelocked_Rw_Vector; # Typelocked_Rw_Vector is from
src/lib/std/src/typelocked-rw-vector.api package rw_vector_slice: Typelocked_Rw_Vector_Slice; # Typelocked_Rw_Vector_Slice is from
src/lib/std/src/typelocked-rw-vector-slice.api #
sharing vector::Element == vector_slice::Element
== rw_vector::Element
== rw_vector_slice::Element;
#
sharing vector::Vector == vector_slice::Vector
== rw_vector::Vector
== rw_vector_slice::Vector;
#
sharing vector_slice::Slice == rw_vector_slice::Vector_Slice;
sharing rw_vector::Rw_Vector == rw_vector_slice::Rw_Vector;
eqtype File_Position;
some_element: vector::Element;
compare: (File_Position, File_Position) -> Order;
)
: Winix_Base_File_Io_Driver_For_Os__Premicrothread # Winix_Base_File_Io_Driver_For_Os__Premicrothread is from
src/lib/std/src/io/winix-base-file-io-driver-for-os--premicrothread.api where Element == vector::Element
where Vector == vector::Vector
where Vector_Slice == vector_slice::Slice
where Rw_Vector == rw_vector::Rw_Vector
where Rw_Vector_Slice == rw_vector_slice::Slice
where File_Position == File_Position
=
package {
#
package wv = rw_vector; # rw_vector is from
src/lib/std/src/rw-vector.pkg package wvs = rw_vector_slice; # rw_vector_slice is from
src/lib/std/src/rw-vector-slice.pkg package rv = vector; # vector is from
src/lib/std/src/vector.pkg package rvs = vector_slice; # vector_slice is from
src/lib/std/src/vector-slice.pkg Element = wv::Element;
Vector = rv::Vector;
Vector_Slice = rvs::Slice;
Rw_Vector = wv::Rw_Vector;
Rw_Vector_Slice = wvs::Slice;
File_Position = File_Position;
compare = compare;
Filereader # For background see comments in
src/lib/std/src/io/winix-base-file-io-driver-for-os--premicrothread.api =
FILEREADER
{
filename: String, # Filename or else something like "<stdin>".
best_io_quantum: Int,
read_vector: Int -> Vector,
blockx: Null_Or( Void -> Void ),
can_readx: Null_Or( Void -> Bool ),
avail: Void -> Null_Or( Int ), # Number of items certainly available to read without blocking.
get_file_position: Null_Or( Void -> File_Position ),
set_file_position: Null_Or( File_Position -> Void ),
end_file_position: Null_Or( Void -> File_Position ),
verify_file_position: Null_Or( Void -> File_Position ),
close: Void -> Void,
io_descriptor: Null_Or( wxt::io::Iod )
};
Filewriter # For background see comments in
src/lib/std/src/io/winix-base-file-io-driver-for-os--premicrothread.api =
FILEWRITER
{
filename: String, # Filename or else something like "<stdout>".
best_io_quantum: Int,
write_vector: Null_Or( Vector_Slice -> Int ),
write_rw_vector: Null_Or( Rw_Vector_Slice -> Int ),
blockx: Null_Or( Void -> Void ),
can_output: Null_Or( Void -> Bool ),
get_file_position: Null_Or( Void -> File_Position ),
set_file_position: Null_Or( File_Position -> Void ),
end_file_position: Null_Or( Void -> File_Position ),
verify_file_position: Null_Or( Void -> File_Position ),
close: Void -> Void,
io_descriptor: Null_Or( wxt::io::Iod )
};
fun blocking_operation (f, blockx) x
=
{ blockx ();
#
null_or::the (f x);
};
fun nonblocking_operation (read, can_readx) x
=
if (can_readx()) THE (read x);
else NULL;
fi;
fun augment_reader (FILEREADER rd)
=
{
fun readrw_to_readro readrw n
=
{ a = wv::make_rw_vector (n, some_element);
#
n = readrw (wvs::make_full_slice a);
#
wvs::to_vector (wvs::make_slice (a, 0, THE n));
};
fun readrw_to_readro_nonblocking readrw_nonblocking n
=
{ a = wv::make_rw_vector (n, some_element);
#
case (readrw_nonblocking (wvs::make_full_slice a))
#
THE n' => THE (wvs::to_vector (wvs::make_slice (a, 0, THE n')));
NULL => NULL;
esac;
};
fun readro_to_readrw readro asl
=
{ (wvs::burst_slice asl) -> (a, start, nelems);
#
v = readro nelems;
len = rv::length v;
wv::copy_vector { from => v, into => a, at => start };
len;
};
fun readro_to_readrw_nonblocking readro_nonblocking asl
=
{ (wvs::burst_slice asl) -> (a, start, nelems);
#
case (readro_nonblocking nelems)
#
THE v => { len = rv::length v;
#
wv::copy_vector { from => v, into => a, at => start };
THE len;
};
NULL => NULL;
esac;
};
read_vector'
=
case rd
#
{ read_vector => f, ... } => f;
esac;
FILEREADER
{
read_vector => read_vector',
# The remainder are inherited unchanged:
filename => rd.filename,
best_io_quantum => rd.best_io_quantum,
blockx => rd.blockx,
can_readx => rd.can_readx,
avail => rd.avail,
get_file_position => rd.get_file_position,
set_file_position => rd.set_file_position,
end_file_position => rd.end_file_position,
verify_file_position => rd.verify_file_position,
close => rd.close,
io_descriptor => rd.io_descriptor
};
};
fun augment_writer (FILEWRITER wr)
=
{ fun writev_to_writea writev asl
=
writev (rvs::make_full_slice (wvs::to_vector asl));
fun writea_to_writev writea vsl
=
case (rvs::length vsl)
#
0 => 0;
n => { a = wv::make_rw_vector (n, rvs::get (vsl, 0));
#
wvs::copy_vector
{
from => rvs::make_subslice (vsl, 1, NULL),
into => a,
at => 1
};
writea (wvs::make_full_slice a);
};
esac;
write_vector'
=
case wr
#
{ write_vector=>THE f, ... } => THE f;
{ write_rw_vector=>THE f, ... } => THE (writea_to_writev f);
_ => NULL;
esac;
write_rw_vector'
=
case wr
#
{ write_rw_vector => THE f, ... } => THE f;
{ write_vector => THE f, ... } => THE (writev_to_writea f);
_ => NULL;
esac;
FILEWRITER
{
write_vector => write_vector',
write_rw_vector => write_rw_vector',
# The remainder are inherited unchanged:
filename => wr.filename,
best_io_quantum => wr.best_io_quantum,
blockx => wr.blockx,
can_output => wr.can_output,
get_file_position => wr.get_file_position,
set_file_position => wr.set_file_position,
end_file_position => wr.end_file_position,
verify_file_position=> wr.verify_file_position,
close => wr.close,
io_descriptor => wr.io_descriptor
};
};
fun open_vector v
=
{ position = REF 0;
closed = REF FALSE;
fun raise_exception_if_closed ()
=
if *closed raise exception iox::CLOSED_IO_STREAM; fi;
len = rv::length v;
fun avail ()
=
len - *position;
fun read_ro n
=
{
p = *position;
m = tagged_int_guts::min (n, len - p);
raise_exception_if_closed ();
position := p + m;
rvs::to_vector (rvs::make_slice (v, p, THE m));
};
fun checked k ()
=
{ raise_exception_if_closed ();
k;
};
# Random access not supported because position type is abstract:
#
FILEREADER
{
filename => "<vector>",
best_io_quantum => len,
read_vector => read_ro,
blockx => THE raise_exception_if_closed,
can_readx => THE (checked TRUE),
avail => THE o avail,
get_file_position => NULL,
set_file_position => NULL,
end_file_position => NULL,
verify_file_position => NULL,
close => \\ () = closed := TRUE,
io_descriptor => NULL
};
};
fun null_reader ()
=
{ closed = REF FALSE;
#
fun raise_exception_if_closed ()
=
if *closed raise exception iox::CLOSED_IO_STREAM; fi;
fun checked k _
=
{ raise_exception_if_closed ();
k;
};
FILEREADER
{
filename => "<null>",
best_io_quantum => 1,
read_vector => checked (rv::from_list []),
blockx => THE raise_exception_if_closed,
can_readx => THE (checked TRUE),
avail => \\ () = THE 0,
get_file_position => NULL,
set_file_position => NULL,
end_file_position => NULL,
verify_file_position => NULL,
close => \\ () = closed := TRUE,
io_descriptor => NULL
};
};
fun null_writer ()
=
{ closed = REF FALSE;
#
fun raise_exception_if_closed ()
=
if *closed raise exception iox::CLOSED_IO_STREAM; fi;
fun checked k ()
=
k;
fun write_vector vsl = { raise_exception_if_closed (); rvs::length vsl; };
fun write_rw_vector asl = { raise_exception_if_closed (); wvs::length asl; };
FILEWRITER
{
filename => "<null>",
best_io_quantum => 1,
write_vector => THE write_vector,
write_rw_vector => THE write_rw_vector,
blockx => THE raise_exception_if_closed,
can_output => THE (checked TRUE),
get_file_position => NULL,
set_file_position => NULL,
end_file_position => NULL,
verify_file_position => NULL,
close => \\ () = closed := TRUE,
io_descriptor => NULL
};
};
}; # generic package winix_base_file_io_driver_for_posix_g__premicrothread
end;
## COPYRIGHT (c) 1995 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.