## winix-base-file-io-driver-for-os--premicrothread.api
#
# Here we define the base interface between the platform-independent
# and the platform-dependent layers of our file I/O stack.
#
# The platform-dependent layer implements this interface,
# the platform-independent layer is built atop this interface.
#
# An extended version of this api is defined in
#
#
src/lib/std/src/io/winix-extended-file-io-driver-for-os--premicrothread.api#
# The api for the next layer up is defined by
#
#
src/lib/std/src/io/winix-file-for-os--premicrothread.api#
# This api is designed for monothreaded code,
# so threadkit defines a replacement api:
#
#
src/lib/std/src/io/winix-base-file-io-driver-for-os.api#
# For additional overview and background see bottom-of-file comments.
# Compiled by:
#
src/lib/std/src/standard-core.sublib# Included by:
#
src/lib/std/src/io/winix-extended-file-io-driver-for-os--premicrothread.apistipulate
package wt = winix_types; # winix_types is from
src/lib/std/src/posix/winix-types.pkgherein
# This api is implemented by:
#
#
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg #
api Winix_Base_File_Io_Driver_For_Os__Premicrothread {
#
Element;
#
Vector;
Vector_Slice;
#
Rw_Vector;
Rw_Vector_Slice;
eqtype File_Position;
compare: (File_Position, File_Position) -> Order;
Filereader
=
FILEREADER
{
filename: String, # The filename given to the host OS to open, else "<stdin>" or whatever.
best_io_quantum: Int, # Preferred number of bytes to read/write, for best performance.
# For plain files this is hardwired to 4096 -- see buffer_size_b
# in
src/lib/std/src/posix/winix-text-file-io-driver-for-posix--premicrothread.pkg # and
src/lib/std/src/posix/winix-data-file-io-driver-for-posix--premicrothread.pkg # For vectors it gets set to the size of the vector -- see open_vector() in
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg # For mailslot I/O we use 1024 -- see
src/lib/std/src/io/winix-mailslot-io-g.pkg read_vector: Int -> Vector, # Read up to 'Int' elements from the stream and return them packed in a fresh read-only vector.
# Read methods. Any given FILEREADER is allowed to
# omit some (which? all??) methods, in which case
# that field will be NULL. (This is of course fucking insane -- so much for "well typed programs don't go wrong"! -- 2012-12-23 CrT)
#
#
blockx: Null_Or( Void -> Void ), # If this fn is supplied, blocking_operation() in
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg # will call it before doing a blocking operation. The current codebase appears to use this only to
# raise an exception if blocking I/O is attempted on a closed stream.
# The 'x' in the name is only for greppability; added 2012-03-07.
can_readx: Null_Or( Void -> Bool ), # If this fn is supplied and returns TRUE, reading will not block.
# This is used (only?) in nonblocking_operation() in
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg # The 'x' in the name is only for greppability; added 2012-03-07.
avail: Void -> Null_Or( Int ), # Return number of stream elements which can be read without blocking (if known) else NULL.
# For a plain file this is just (file_length - file_position).
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( wt::io::Iod )
};
#
# Filereader instances may be created via make_filereader in
src/lib/std/src/psx/posix-io.pkg #
# In general one instance will be created for
# each file opened, by a call to a
#
#
src/lib/std/src/posix/winix-text-file-io-driver-for-posix--premicrothread.pkg #
# fn like
#
# open_for_read
#
# made by user code -- filewriters are our chief
# low-level representation for an open file.
Filewriter
=
FILEWRITER
{
filename: String, # The filename given to the host OS to open, else "<stdout>" or "<stderr>" or whatever.
best_io_quantum: Int, # Preferred number of bytes to read/write, for best performance.
# For plain files this is hardwired to 4096 -- see buffer_size_b
# in
src/lib/std/src/posix/winix-text-file-io-driver-for-posix--premicrothread.pkg # and
src/lib/std/src/posix/winix-data-file-io-driver-for-posix--premicrothread.pkg # For vectors it gets set to the size of the vector -- see open_vector() in
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg # For mailslot I/O we use 1024 -- see
src/lib/std/src/io/winix-mailslot-io-g.pkg # Write methods. Any given FILEWRITER is allowed to
# omit some (which? all??) methods, in which case
# that field will be NULL:
#
write_vector: Null_Or( Vector_Slice -> Int ), # Write elements from given read-only slice, return number written.
#
write_rw_vector: Null_Or( Rw_Vector_Slice -> Int ), # Write elements from given read-write slice, return number written.
can_output: Null_Or( Void -> Bool ),
blockx: Null_Or( Void -> Void ), # If this fn is supplied, blocking_operation() in
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg # will call it before doing a blocking operation. The current codebase appears to use this only to
# raise an exception if blocking I/O is attempted on a closed stream.
# The 'x' in the name is only for greppability; added 2012-03-07.
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( wt::io::Iod )
};
#
# Filewriter instances may be created via make_filewriter in
src/lib/std/src/psx/posix-io.pkg #
# In general one instance will be created for
# each file opened, by a call to a
#
#
src/lib/std/src/posix/winix-text-file-io-driver-for-posix--premicrothread.pkg #
# fn like
#
# open_for_write
# open_for_append
#
# Filewriter instances are also created in (e.g.):
#
#
src/lib/compiler/back/low/library/string-out-stream.pkg #
src/lib/std/src/psx/posix-io.pkg open_vector: Vector -> Filereader;
null_reader: Void -> Filereader;
null_writer: Void -> Filewriter;
augment_reader: Filereader -> Filereader;
augment_writer: Filewriter -> Filewriter;
};
end;
########################################################################################
# Background and overview
#
# The purpose of this file is to define a standard api
# to file read/write services, so as to decouple clients
# of those services from implementations of them.
#
# In particular, by adopting a record-of-functions style
# api, we allow runtime substitution of different I/O
# implementations, just by passing in a different
# FILEREADER or FILEWRITER implementation.
#
# The API defined here was designed with single-threaded
# operation in mind, so the threadkit defines a separate version:
#
#
src/lib/std/src/io/winix-base-file-io-driver-for-os.api#
# The api we define here gets implemented in the generic
#
#
src/lib/std/src/io/winix-base-file-io-driver-for-posix-g--premicrothread.pkg#
# which then gets specialized to "text" I/O vs "binary" I/O
# (a distinction largely irrelevant on Linux/Unix, but needed
# to humor end-of-line handling on Windows and MacOS) on a
# platform-specific basis, which on linux is:
#
#
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#
# From the client's point of view, the main difference between
# the two is that the 'text' version treats files as streams of
# Char values, but the 'binary' version treats files as streams of
# eight-bit unsigned int values.
## COPYRIGHT (c) 1995 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.