PreviousUpNext

15.4.1109  src/lib/std/src/io/winix-base-file-io-driver-for-posix-g–premicrothread.pkg

## 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.sublib

stipulate
    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.pkg
herein

    # 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.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext