PreviousUpNext

15.4.1223  src/lib/std/src/win32/winix-data-file-io-driver-for-win32.pkg

## winix-data-file-io-driver-for-win32.pkg
#
# Here we implement the win32 version of platform-specific
# data ("binary") file I/O support.  
#
# This file gets used in:
#
#     src/lib/std/src/win32/winix-data-file-for-win32.pkg
#
# Compare to:
#
#     src/lib/std/src/win32/winix-text-file-io-driver-for-win32.pkg
#     src/lib/std/src/posix/winix-data-file-io-driver-for-posix.pkg
#     src/lib/src/lib/thread-kit/src/win32/threadkit-winix-data-file-io-driver-for-win32.pkg

local
    package file_position = file_position_guts
    package os = winix_guts
in
package winix_data_file_io_driver_for_win32
:       Winix_Base_File_Io_Driver_For_Os                                # Winix_Base_File_Io_Driver_For_Os      is from   src/lib/std/src/io/winix-base-file-io-driver-for-os.api
{
        package drv = winix_base_data_file_io_driver_for_posix

        package W32FS = Win32::file_system
        package W32IO = Win32::IO
        package W32G = Win32::general

        package v = vector_of_one_byte_unts

        type File_Descriptor = W32G::hndl

        pfi = file_position::from_int
        pti = file_position::toInt
        pfw = file_position::from_int o W32G::unt::toInt
        ptw = W32G::unt::from_int o file_position::toInt
            
        say = W32G::logMsg

        fun announce s x y = (
# *         say "winix_data_file_io_driver_for_win32: "; say (s: String); say "\n";  *
            x y)

        bufferSzB = 4096

        seek = pfw o W32IO::setFilePointer'

        fun posFns iod = 
            if (winix::io::kind iod == winix::io::Kind::file) then 
                let my pos:  Ref( file_position::Int ) = REF (pfi 0)
                    fun getPos () : file_position::Int = *pos
                    fun setPos p = 
                        pos := announce "setPos: seek" 
                                 seek (W32FS::IODToHndl iod,
                                       ptw p,
                                       W32IO::FILE_BEGIN)
                    fun endPos () : file_position::Int = 
                        (case W32FS::getLowFileSize (W32FS::IODToHndl iod) of
                             THE w => pfw w
                           | _ => raise exception winix::RUNTIME_EXCEPTION("endPos: no file size", NULL))
                    fun verifyPos () = 
                        (pos := announce "verifyPos: seek"
                                  seek (W32FS::IODToHndl iod,
                                        0wx0,
                                        W32IO::FILE_CURRENT);
                         *pos)
                in
                    ignore (verifyPos());
                    { pos=pos,
                      getPos=THE getPos,
                      setPos=THE setPos,
                      endPos=THE endPos,
                      verifyPos=THE verifyPos
                    }
                end
            else { pos=REF (pfi 0),
                   getPos=NULL, setPos=NULL, endPos=NULL, verifyPos=NULL
                 }

        fun addCheck f (THE g) = THE (f g)
          | addCheck _ NULL = NULL

        fun mkReader { initablekMode=FALSE, ... } = 
            raise exception io::NONBLOCKING_IO_NOT_SUPPORTED
          | mkReader { fd, name, initablekMode } = 
            let closed = REF FALSE
                fun ensureOpen f x = 
                    if *closed then raise exception io::CLOSED_IO_STREAM else f x
                blocking = REF initablekMode
                iod = W32FS::hndlToIOD fd
                my { pos, getPos, setPos, endPos, verifyPos } = posFns iod
                fun incPos k = pos := position.+(*pos, pfi k)
                fun readVec n = 
                    let v = announce "read" 
                                  W32IO::readVec (W32FS::IODToHndl iod, n)
                    in  incPos (v::length v); v
                    end
                fun readArr arg = 
                    let k = announce "readBuf" 
                                  W32IO::readArr (W32FS::IODToHndl iod, arg)
                    in  incPos k; k
                    end
                fun close () = 
                    if *closed then ()
                    else (closed:=TRUE; announce "close" 
                                          W32IO::close (W32FS::IODToHndl iod))
                fun avail () = 
                    if *closed then THE 0
                    else (case W32FS::getLowFileSize (W32FS::IODToHndl iod) of
                              THE w => THE (position.-(pfw w,*pos))
                            | NULL => NULL
                         )
            in
                drv::FILEREADER {
                    name = name,
                    chunkSize = bufferSzB,
                    readVec = THE (ensureOpen readVec),
                    readArr = THE (ensureOpen readArr),
                    readVecNB = NULL,
                    readArrNB = NULL,
                    block = NULL,
                    max_readable_without_blocking = NULL,
                    avail = avail,
                    getPos = getPos,
                    setPos = addCheck ensureOpen setPos,
                    endPos = addCheck ensureOpen endPos,
                    verifyPos = addCheck ensureOpen verifyPos,
                    close = close,
                    ioDesc = THE iod
                }
            end

        shareAll = W32G::unt::bitwise_or (W32IO::FILE_SHARE_READ,
                                     W32IO::FILE_SHARE_WRITE)

        fun checkHndl name h = 
            if W32G::isValidHandle h then h
            else 
                raise exception winix::RUNTIME_EXCEPTION ("win32-binary-base-io: checkHndl: "$name$": failed", NULL)

        fun openRd name = 
            mkReader {
                fd = checkHndl "openRd" 
                               (announce ("openRd: createFile:"$name)
                                         W32IO::createFile {
                                             name=name,
                                             access=W32IO::GENERIC_READ,
                                             share=shareAll,
                                             mode=W32IO::OPEN_EXISTING,
                                             attributes=0wx0
                                         } ),
                name = name,
                initablekMode = TRUE
            }

        fun mkWriter { initablekMode=FALSE, ... } =
            raise exception io::NONBLOCKING_IO_NOT_SUPPORTED
          | mkWriter { fd, name, initablekMode, appendMode, chunkSize } = 
            let closed = REF FALSE
                blocking = REF initablekMode
                fun ensureOpen f x = 
                    if *closed then raise exception io::CLOSED_IO_STREAM else f x
                iod = W32FS::hndlToIOD fd
                my { pos, getPos, setPos, endPos, verifyPos } = posFns iod
                fun incPos k = pos := position.+(*pos, pfi k)
                fun writeVec v = 
                    let k = announce "writeVec" 
                                  W32IO::writeVec (W32FS::IODToHndl iod, v)
                    in  incPos k; k
                    end
                fun writeArr v = 
                    let k = announce "writeArr" 
                                  W32IO::writeArr (W32FS::IODToHndl iod, v)
                    in  incPos k; k
                    end
                fun close () = 
                    if *closed then ()
                    else (closed:=TRUE; 
                          announce "close" 
                            W32IO::close (W32FS::IODToHndl iod))
          in
            drv::FILEWRITER {
                name = name,
                chunkSize = chunkSize,
                writeVec = THE (ensureOpen writeVec),
                writeArr = THE (ensureOpen writeArr),
                writeVecNB = NULL,
                writeArrNB = NULL,
                block = NULL,
                canOutput = NULL,
                getPos = getPos,
                setPos = addCheck ensureOpen setPos,
                endPos = addCheck ensureOpen endPos,
                verifyPos = addCheck ensureOpen verifyPos,
                close = close,
                ioDesc = THE iod
              }
          end

        fun openWr name = 
            mkWriter {
                fd = checkHndl "openWr" 
                               (announce ("openWr: createFile:"$name)
                                         W32IO::createFile {
                                             name=name,
                                             access=W32IO::GENERIC_WRITE,
                                             share=shareAll,
                                             mode=W32IO::CREATE_ALWAYS,
                                             attributes=W32FS::FILE_ATTRIBUTE_NORMAL
                                         } ),
                name = name,
                initablekMode = TRUE,
                appendMode = FALSE,
                chunkSize = bufferSzB
            }

        fun openApp name = 
            let h = checkHndl "openApp" 
                                  (announce ("openApp: createFile:"$name)
                                            W32IO::createFile {
                                                name=name,
                                                access=W32IO::GENERIC_WRITE,
                                                share=shareAll,
                                                mode=W32IO::OPEN_EXISTING,
                                                attributes=W32FS::FILE_ATTRIBUTE_NORMAL
                                            } )
                announce "setFilePointer'"
                                 W32IO::setFilePointer' (h, 0wx0, W32IO::FILE_END)
            in
                mkWriter {
                    fd = h,
                    name = name,
                    initablekMode = TRUE,
                    appendMode = TRUE,
                    chunkSize = bufferSzB
                }
            end

    };
end



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext