]> pd.if.org Git - pdclib/commitdiff
PDCLIB-8: First phase of intergation of new I/O backend system (with minimal
authorOwen Shepherd <owen.shepherd@e43.eu>
Wed, 5 Dec 2012 02:20:16 +0000 (02:20 +0000)
committerOwen Shepherd <owen.shepherd@e43.eu>
Wed, 5 Dec 2012 02:20:16 +0000 (02:20 +0000)
disruption of existing code)
* _PDCLIB_fdopen: renamed _PDCLIB_fvopen to more clearly deliniate from POSIX
  fdopen function and state purpose
* _PDCLIB_fd_t is now a library provided union type
   Contains members of type void*, uintptr_t, intptr_t. If another type is
   required, define _PDCLIB_OSFD_T to that type in _PDCLIB_config.h
* _PDCLIB_fileops_t added. This structure contains the file operations
* _PDCLIB_fillbuffer, _PDCLIB_flushbuffer, _PDCLIB_seek become internal APIs
    (_PDCLIB_seek's days are numbered!)
* _PDCLIB_close is removed
* tmpfile() and fopen() should now call through to _PDCLIB_fvopen and provide
  a pointer to an appropriate _PDCLIB_fileops_t structure

Win32 port updated. Other ports are TODO

19 files changed:
functions/stdio/_PDCLIB_fillbuffer.c [moved from platform/win32/functions/_PDCLIB/_PDCLIB_fillbuffer.c with 62% similarity]
functions/stdio/_PDCLIB_flushbuffer.c [moved from platform/win32/functions/_PDCLIB/_PDCLIB_flushbuffer.c with 70% similarity]
functions/stdio/_PDCLIB_fvopen.c [moved from functions/stdio/_PDCLIB_fdopen.c with 90% similarity]
functions/stdio/_PDCLIB_seek.c [new file with mode: 0644]
functions/stdio/fclose.c
functions/stdio/fopen.c
functions/stdio/freopen.c
includes/stdio.h
internals/_PDCLIB_aux.h
internals/_PDCLIB_glue.h
internals/_PDCLIB_io.h
platform/win32/crt0.c
platform/win32/functions/_PDCLIB/_PDCLIB_close.c [deleted file]
platform/win32/functions/_PDCLIB/_PDCLIB_fileops.c [new file with mode: 0644]
platform/win32/functions/_PDCLIB/_PDCLIB_open.c
platform/win32/functions/_PDCLIB/_PDCLIB_seek.c [deleted file]
platform/win32/functions/_PDCLIB/_PDCLIB_stdinit.c
platform/win32/functions/stdio/tmpfile.c
platform/win32/internals/_PDCLIB_config.h

similarity index 62%
rename from platform/win32/functions/_PDCLIB/_PDCLIB_fillbuffer.c
rename to functions/stdio/_PDCLIB_fillbuffer.c
index c6a2b6b520f436a6f5a1433d1f5483e3eec1ebeb..dfdfe262510d858043e23bfb3a30505271bbb2f0 100644 (file)
@@ -1,54 +1,45 @@
-/* $Id$ */
-
-/* _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )
-
-   This file is part of the Public Domain C Library (PDCLib).
-   Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-/* This is a stub version of _PDCLIB_fillbuffer
-*/
-
-#include <stdio.h>
-
-#ifndef REGTEST
-#include <_PDCLIB_glue.h>
-#include <errno.h>
-#include <windows.h>
-
-void _PDCLIB_w32errno(void);
-int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )
-{
-    DWORD nBytesRead;
-    BOOL ok = ReadFile( stream->handle, stream->buffer, stream->bufsize,
-                        &nBytesRead, NULL );
-
-    if( ok ) {
-        if( nBytesRead == 0 ) {
-            stream->status |= _PDCLIB_EOFFLAG;
-            return EOF;
-        }
-        stream->pos.offset += nBytesRead;
-        stream->bufend = nBytesRead;
-        stream->bufidx = 0;
-        return 0;
-    } else {
-        _PDCLIB_w32errno();
-        stream->status |= _PDCLIB_ERRORFLAG;
-        return EOF;
-    }
-}
-
-#endif
-
-#ifdef TEST
-#include <_PDCLIB_test.h>
-
-int main( void )
-{
-    /* Testing covered by ftell.c */
-    return TEST_RESULTS;
-}
-
-#endif
-
+/* _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )\r
+\r
+   This file is part of the Public Domain C Library (PDCLib).\r
+   Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#include <stdio.h>\r
+\r
+#ifndef REGTEST\r
+#include <_PDCLIB_glue.h>\r
+\r
+int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream )\r
+{\r
+    size_t bytesRead;\r
+    bool ok = stream->ops->read( stream->handle, stream->buffer, stream->bufsize,\r
+                        &bytesRead);\r
+\r
+    if( ok ) {\r
+        if( bytesRead == 0 ) {\r
+            stream->status |= _PDCLIB_EOFFLAG;\r
+            return EOF;\r
+        }\r
+        stream->pos.offset += bytesRead;\r
+        stream->bufend = bytesRead;\r
+        stream->bufidx = 0;\r
+        return 0;\r
+    } else {\r
+        stream->status |= _PDCLIB_ERRORFLAG;\r
+        return EOF;\r
+    }\r
+}\r
+\r
+#endif\r
+\r
+#ifdef TEST\r
+#include <_PDCLIB_test.h>\r
+\r
+int main( void )\r
+{\r
+    /* Testing covered by ftell.c */\r
+    return TEST_RESULTS;\r
+}\r
+\r
+#endif\r
+\r
similarity index 70%
rename from platform/win32/functions/_PDCLIB/_PDCLIB_flushbuffer.c
rename to functions/stdio/_PDCLIB_flushbuffer.c
index c0ade01ec18251948f3ef60323f91745b2490f8c..ffbbb4f088c88ef84767a056e3570fd7c78055a4 100644 (file)
@@ -1,66 +1,56 @@
-/* $Id$ */
-
-/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )
-
-   This file is part of the Public Domain C Library (PDCLib).
-   Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-/* This is a stub implementation of _PDCLIB_flushbuffer
-*/
-
-#include <stdio.h>
-#include <string.h>
-
-#ifndef REGTEST
-#include <_PDCLIB_glue.h>
-#include <errno.h>
-#include <windows.h>
-
-void _PDCLIB_w32errno( void );
-
-int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )
-{
-    if ( ! ( stream->status & _PDCLIB_FBIN ) )
-    {
-        /* TODO: Text stream conversion here */
-    }
-
-    DWORD written = 0;
-
-
-    while(written != stream->bufidx) {
-        DWORD justWrote;
-        DWORD toWrite = stream->bufidx - written;
-        BOOL res = WriteFile( stream->handle, stream->buffer + written, 
-                              toWrite, &justWrote, NULL);
-        written += justWrote;
-        stream->pos.offset += justWrote;
-
-        if(!res) {
-            stream->status |=_PDCLIB_ERRORFLAG;
-            stream->bufidx -= written;
-            memmove( stream->buffer, stream->buffer + written, stream->bufidx );
-            _PDCLIB_w32errno();
-            return EOF;
-        }
-    }
-
-    stream->bufidx = 0;
-    return 0;
-}
-
-#endif
-
-
-#ifdef TEST
-#include <_PDCLIB_test.h>
-
-int main( void )
-{
-    /* Testing covered by ftell.c */
-    return TEST_RESULTS;
-}
-
-#endif
-
+/* _PDCLIB_flushbuffer( struct _PDCLIB_file_t * )\r
+\r
+   This file is part of the Public Domain C Library (PDCLib).\r
+   Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <string.h>\r
+\r
+#ifndef REGTEST\r
+#include <_PDCLIB_glue.h>\r
+\r
+int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream )\r
+{\r
+    if ( ! ( stream->status & _PDCLIB_FBIN ) )\r
+    {\r
+        /* TODO: Text stream conversion here */\r
+    }\r
+\r
+    size_t written = 0;\r
+\r
+\r
+    while(written != stream->bufidx) {\r
+        size_t justWrote;\r
+        size_t toWrite = stream->bufidx - written;\r
+        bool res = stream->ops->write( stream->handle, stream->buffer + written, \r
+                              toWrite, &justWrote);\r
+        written += justWrote;\r
+        stream->pos.offset += justWrote;\r
+\r
+        if(!res) {\r
+            stream->status |=_PDCLIB_ERRORFLAG;\r
+            stream->bufidx -= written;\r
+            memmove( stream->buffer, stream->buffer + written, stream->bufidx );\r
+            return EOF;\r
+        }\r
+    }\r
+\r
+    stream->bufidx = 0;\r
+    return 0;\r
+}\r
+\r
+#endif\r
+\r
+\r
+#ifdef TEST\r
+#include <_PDCLIB_test.h>\r
+\r
+int main( void )\r
+{\r
+    /* Testing covered by ftell.c */\r
+    return TEST_RESULTS;\r
+}\r
+\r
+#endif\r
+\r
similarity index 90%
rename from functions/stdio/_PDCLIB_fdopen.c
rename to functions/stdio/_PDCLIB_fvopen.c
index c628ebcd1e5da4ebf48131e2b9771c47c4d0cce1..466009b04d070f069a28d1aa8899f57ff39f0cce 100644 (file)
@@ -1,6 +1,6 @@
 /* $Id$ */\r
 \r
-/* _PDCLIB_fdopen( _PDCLIB_fd_t fd, const char * )\r
+/* _PDCLIB_fvopen( _PDCLIB_fd_t fd, _PDCLIB_fileops_t *  )\r
 \r
    This file is part of the Public Domain C Library (PDCLib).\r
    Permission is granted to use, modify, and / or redistribute at will.\r
@@ -16,7 +16,8 @@
 \r
 extern struct _PDCLIB_file_t * _PDCLIB_filelist;\r
 \r
-struct _PDCLIB_file_t * _PDCLIB_fdopen( _PDCLIB_fd_t fd, \r
+struct _PDCLIB_file_t * _PDCLIB_fvopen( _PDCLIB_fd_t               fd, \r
+                                        const _PDCLIB_fileops_t *  ops,\r
                                         int mode,\r
                                         const char * _PDCLIB_restrict filename )\r
 {\r
@@ -47,6 +48,7 @@ struct _PDCLIB_file_t * _PDCLIB_fdopen( _PDCLIB_fd_t fd,
     }\r
 \r
     rc->status = mode;\r
+    rc->ops    = ops;\r
     rc->handle = fd;\r
     /* Setting pointers into the memory block allocated above */\r
     rc->ungetbuf = (unsigned char *)rc + sizeof( struct _PDCLIB_file_t );\r
diff --git a/functions/stdio/_PDCLIB_seek.c b/functions/stdio/_PDCLIB_seek.c
new file mode 100644 (file)
index 0000000..5a3f982
--- /dev/null
@@ -0,0 +1,39 @@
+/* int64_t _PDCLIB_seek( FILE *, int64_t, int )\r
+\r
+   This file is part of the Public Domain C Library (PDCLib).\r
+   Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#include <stdio.h>\r
+#include <stdint.h>\r
+#include <errno.h>\r
+#ifndef REGTEST\r
+\r
+int_fast64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t offset, \r
+                           int whence )\r
+{\r
+    int_fast64_t newPos;\r
+    if(!stream->ops->seek(stream->handle, offset, whence, &newPos)) {\r
+        return EOF;\r
+    }\r
+\r
+    stream->ungetidx = 0;\r
+    stream->bufidx = 0;\r
+    stream->bufend = 0;\r
+    stream->pos.offset = newPos;\r
+    return newPos;\r
+}\r
+\r
+#endif\r
+\r
+#ifdef TEST\r
+#include <_PDCLIB_test.h>\r
+\r
+int main( void )\r
+{\r
+    /* Testing covered by ftell.c */\r
+    return TEST_RESULTS;\r
+}\r
+\r
+#endif\r
+\r
index c4f5d8a1b1bdc02cb928a023960fd00968e7210c..3d9e25724f45bdf58de3ee14ba16d183af0bb0fa 100644 (file)
@@ -39,7 +39,7 @@ int fclose( struct _PDCLIB_file_t * stream )
             mtx_destroy( &stream->lock );
 
             /* Close handle */
-            _PDCLIB_close( stream->handle );
+            stream->ops->close(stream->handle);
 
             /* Remove stream from list */
             if ( previous != NULL )
index ff8e8e8a08862ea7679d54d3457d41531c3a7599..e806b00a2ef76c31879a2aa0a19b55b368962aa6 100644 (file)
@@ -24,15 +24,16 @@ FILE * fopen( const char * _PDCLIB_restrict filename,
     if( imode == 0 || filename == NULL )
         return NULL;
 
-    _PDCLIB_fd_t fd = _PDCLIB_open( filename, imode );
-    if(fd == _PDCLIB_NOHANDLE) {
+    _PDCLIB_fd_t              fd;
+    const _PDCLIB_fileops_t * ops;
+    if(!_PDCLIB_open( &fd, &ops, filename, imode )) {
         return NULL;
     }
 
-    FILE * f = _PDCLIB_fdopen( fd, imode, filename );
+    FILE * f = _PDCLIB_fvopen( fd, ops, imode, filename );
     if(!f) {
         int saveErrno = errno;
-        _PDCLIB_close( fd );
+        ops->close(fd);
         errno = saveErrno;
     }
     return f;
index 7868c95207052b3ac47f97abe79559640872aa5d..9c49756d5e73dcdea7a4f89e53b5547deff06081 100644 (file)
@@ -33,7 +33,8 @@ struct _PDCLIB_file_t * freopen(
         funlockfile( stream );
         return NULL;
     }
-    _PDCLIB_close( stream->handle );
+    stream->ops->close(stream->handle);
+    
     /* TODO: It is not nice to do this on a stream we just closed.
        It does not matter with the current implementation of clearerr(),
        but it might start to matter if someone replaced that implementation.
@@ -76,7 +77,8 @@ struct _PDCLIB_file_t * freopen(
     stream->bufend = 0;
     stream->ungetidx = 0;
     /* TODO: Setting mbstate */
-    if ( ( stream->handle = _PDCLIB_open( filename, stream->status ) ) == _PDCLIB_NOHANDLE )
+    if ( ! _PDCLIB_open( &stream->handle, &stream->ops, filename, 
+                         stream->status ) )
     {
         funlockfile( stream );
         return NULL;
index 79a54bde2fedec9ac42e1cf8ed21baf0d9cdaa2a..9d423c1ec031e818c557cf2b55cc41529d0d1b04 100644 (file)
@@ -171,12 +171,14 @@ int fflush( FILE * stream ) _PDCLIB_nothrow;
 
    Returns a pointer to the stream handle if successfull, NULL otherwise.
 */
-FILE * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode ) _PDCLIB_nothrow;
+FILE * fopen( const char * _PDCLIB_restrict filename, 
+              const char * _PDCLIB_restrict mode ) _PDCLIB_nothrow;
 
 /* Creates a stream connected to the file descriptor \p fd with mode \p mode.
    Mode must match the mode with which the file descriptor was opened.
 */
-FILE * _PDCLIB_fdopen( _PDCLIB_fd_t fd, int mode, const char* filename ) _PDCLIB_nothrow;
+FILE * _PDCLIB_fvopen( _PDCLIB_fd_t fd, const _PDCLIB_fileops_t * ops, 
+                       int mode, const char * filename ) _PDCLIB_nothrow;
 
 /* Close any file currently associated with the given stream. Open the file
    identified by the given filename with the given mode (equivalent to fopen()),
index bfb0842806f48aae3c71ec6cef33303d22943a9a..0844962b5f3aec80e58bbae0cca1acfdd6b47832 100644 (file)
 #ifdef __cplusplus
        #define _PDCLIB_BEGIN_EXTERN_C extern "C" {
        #define _PDCLIB_END_EXTERN_C }
+  typedef bool _PDCLIB_bool;
 #else
-   #define _PDCLIB_BEGIN_EXTERN_C
-   #define _PDCLIB_END_EXTERN_C
+  #define _PDCLIB_BEGIN_EXTERN_C
+  #define _PDCLIB_END_EXTERN_C
+  typedef _Bool _PDCLIB_bool;
 #endif
 
 /*#if _PDCLIB_C_VERSION != 1999
index d49cc114338273c0c4c9ce6681ea9334660029c6..7f3c4fa7469c5553ffb9872e551d4cb5968da763 100644 (file)
@@ -9,6 +9,7 @@
 */
 
 #include <_PDCLIB_int.h>
+#include <_PDCLIB_io.h>
 #include <stdbool.h>
 #include <stddef.h>
 _PDCLIB_BEGIN_EXTERN_C
@@ -49,33 +50,14 @@ void * _PDCLIB_reallocpages( void* p, size_t on, size_t nn, bool mayMove);
 
 /* stdio.h */
 
-/* A system call that opens a file identified by name in a given mode. Return 
-   a file descriptor uniquely identifying that file.
-   (The mode is the return value of the _PDCLIB_filemode() function.)
-*/
-_PDCLIB_fd_t _PDCLIB_open( char const * const filename, unsigned int mode );
-
-/* A system call that writes a stream's buffer.
-   Returns 0 on success, EOF on write error.
-   Sets stream error flags and errno appropriately on error.
-*/
-int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream );
-
-/* A system call that fills a stream's buffer.
-   Returns 0 on success, EOF on read error / EOF.
-   Sets stream EOF / error flags and errno appropriately on error.
-*/
-int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream );
-
-/* A system call that repositions within a file. Returns new offset on success,
-   -1 / errno on error.
-*/
-_PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t offset, int whence );
-
-/* A system call that closes a file identified by given file descriptor. Return
-   zero on success, non-zero otherwise.
-*/
-int _PDCLIB_close( _PDCLIB_fd_t fd );
+/* Open the file with the given name and mode. Return the file descriptor in 
+ * *fd and a pointer to the operations structure in **ops on success.
+ *
+ * Return true on success and false on failure.
+ */
+bool _PDCLIB_open( 
+   _PDCLIB_fd_t* fd, const _PDCLIB_fileops_t** ops,
+   char const * filename, unsigned int mode );
 
 /* A system call that removes a file identified by name. Return zero on success,
    non-zero otherwise.
index 0dfdad258fc6356a107597cfc830080cd1ccf82a..829bb4586ed66781c2b2aca73f88f934651678a5 100644 (file)
 /* stream handle should not be free()d on close (stdin, stdout, stderr) */\r
 #define _PDCLIB_STATIC     32768u\r
 \r
+typedef union _PDCLIB_fd\r
+{\r
+#if defined(_PDCLIB_OSFD_T)\r
+    _PDCLIB_OSFD_T      osfd;\r
+#endif\r
+    void *              pointer;\r
+    _PDCLIB_uintptr_t   uval;\r
+    _PDCLIB_intptr_t    sval;     \r
+} _PDCLIB_fd_t;\r
+\r
+/* Internal functions */\r
+/* Writes a stream's buffer.\r
+   Returns 0 on success, EOF on write error.\r
+   Sets stream error flags and errno appropriately on error.\r
+*/\r
+int _PDCLIB_flushbuffer( struct _PDCLIB_file_t * stream );\r
+\r
+/* Fills a stream's buffer.\r
+   Returns 0 on success, EOF on read error / EOF.\r
+   Sets stream EOF / error flags and errno appropriately on error.\r
+*/\r
+int _PDCLIB_fillbuffer( struct _PDCLIB_file_t * stream );\r
+\r
+/* Repositions within a file. Returns new offset on success,\r
+   -1 / errno on error.\r
+*/\r
+_PDCLIB_int_fast64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, \r
+                                  _PDCLIB_int_fast64_t offset, int whence );\r
+\r
+/* File backend I/O operations\r
+ *\r
+ * PDCLib will call through to these methods as needed to implement the stdio\r
+ * functions.\r
+ */\r
+typedef struct _PDCLIB_fileops\r
+{\r
+    /*! Read length bytes from the file into buf; returning the number of bytes\r
+     *  actually read in *numBytesRead.\r
+     *\r
+     *  Returns true if bytes were read successfully; on end of file, returns\r
+     *  true with *numBytesRead == 0.\r
+     *\r
+     *  On error, returns false and sets errno appropriately. *numBytesRead is\r
+     *  ignored in this situation.\r
+     */\r
+    _PDCLIB_bool (*read)( _PDCLIB_fd_t self, \r
+                          void * buf, \r
+                          _PDCLIB_size_t length, \r
+                          _PDCLIB_size_t * numBytesRead );\r
+\r
+    /*! Write length bytes to the file from buf; returning the number of bytes\r
+     *  actually written in *numBytesWritten\r
+     *\r
+     *  Returns true if bytes were written successfully. On error, returns false\r
+     *  and setss errno appropriately (as with read, *numBytesWritten is \r
+     *  ignored)\r
+     */\r
+    _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf, \r
+                   _PDCLIB_size_t length, _PDCLIB_size_t * numBytesWritten );\r
+\r
+    /* Seek to the file offset specified by offset, from location whence, which\r
+     * may be one of the standard constants SEEK_SET/SEEK_CUR/SEEK_END\r
+     */\r
+    _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset, \r
+                          int whence, _PDCLIB_int_fast64_t *newPos );\r
+\r
+    void (*close)( _PDCLIB_fd_t self );\r
+\r
+    /*! Behaves as read does, except for wide characters. Both length and \r
+     *  *numCharsRead represent counts of characters, not bytes.\r
+     *\r
+     *  This function is optional; if missing, PDCLib will buffer the character\r
+     *  data as bytes and perform translation directly into the user's buffers.\r
+     *  It is useful if your backend can directly take wide characters (for \r
+     *  example, the Windows console)\r
+     */\r
+    _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf, \r
+                     _PDCLIB_size_t length, _PDCLIB_size_t * numCharsRead );\r
+\r
+    /* Behaves as write does, except for wide characters. As with wread, both\r
+     * length and *numCharsWritten are character counts.\r
+     *\r
+     * This function is also optional; if missing, PDCLib will buffer the \r
+     * character data as bytes and do translation directly from the user's \r
+     * buffers. You only need to implement this if your backend can directly \r
+     * take wide characters (for example, the Windows console)\r
+     */\r
+    _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf, \r
+                     _PDCLIB_size_t length, _PDCLIB_size_t * numCharsWritten );\r
+} _PDCLIB_fileops_t;\r
+\r
 /* Position / status structure for getpos() / fsetpos(). */\r
 struct _PDCLIB_fpos_t\r
 {\r
-    _PDCLIB_uint64_t offset; /* File position offset */\r
-    int              status; /* Multibyte parsing state (unused, reserved) */\r
+    _PDCLIB_int_fast64_t offset; /* File position offset */\r
+    int                  status; /* Multibyte parsing state (unused, reserved) */\r
 };\r
 \r
 /* FILE structure */\r
 struct _PDCLIB_file_t\r
 {\r
-    _PDCLIB_fd_t            handle;   /* OS file handle */\r
-    _PDCLIB_MTX_T           lock;     /* file lock */\r
-    char *                  buffer;   /* Pointer to buffer memory */\r
-    _PDCLIB_size_t          bufsize;  /* Size of buffer */\r
-    _PDCLIB_size_t          bufidx;   /* Index of current position in buffer */\r
-    _PDCLIB_size_t          bufend;   /* Index of last pre-read character in buffer */\r
-    struct _PDCLIB_fpos_t   pos;      /* Offset and multibyte parsing state */\r
-    _PDCLIB_size_t          ungetidx; /* Number of ungetc()'ed characters */\r
-    unsigned char *         ungetbuf; /* ungetc() buffer */\r
-    unsigned int            status;   /* Status flags; see above */\r
+    const _PDCLIB_fileops_t * ops;\r
+    _PDCLIB_fd_t              handle;   /* OS file handle */\r
+    _PDCLIB_MTX_T             lock;     /* file lock */\r
+    char *                    buffer;   /* Pointer to buffer memory */\r
+    _PDCLIB_size_t            bufsize;  /* Size of buffer */\r
+    _PDCLIB_size_t            bufidx;   /* Index of current position in buffer */\r
+    _PDCLIB_size_t            bufend;   /* Index of last pre-read character in buffer */\r
+    struct _PDCLIB_fpos_t     pos;      /* Offset and multibyte parsing state */\r
+    _PDCLIB_size_t            ungetidx; /* Number of ungetc()'ed characters */\r
+    unsigned char *           ungetbuf; /* ungetc() buffer */\r
+    unsigned int              status;   /* Status flags; see above */\r
     /* multibyte parsing status to be added later */\r
-    char *                  filename; /* Name the current stream has been opened with */\r
-    struct _PDCLIB_file_t * next;     /* Pointer to next struct (internal) */\r
+    char *                    filename; /* Name the current stream has been opened with */\r
+    struct _PDCLIB_file_t *   next;     /* Pointer to next struct (internal) */\r
 };\r
 \r
 \r
index 7da2a8151e2ad3b279e0c9005d45b8b56b22c919..d32a6ac703976a8e2793a6c04d5be482b9aba575 100644 (file)
@@ -104,9 +104,9 @@ void __cdecl mainCRTStartup( void );
 \r
 void __cdecl mainCRTStartup( void ) \r
 {\r
-    stdin->handle  = GetStdHandle(STD_INPUT_HANDLE);\r
-    stdout->handle = GetStdHandle(STD_OUTPUT_HANDLE);\r
-    stderr->handle = GetStdHandle(STD_ERROR_HANDLE);\r
+    stdin->handle.pointer  = GetStdHandle(STD_INPUT_HANDLE);\r
+    stdout->handle.pointer = GetStdHandle(STD_OUTPUT_HANDLE);\r
+    stderr->handle.pointer = GetStdHandle(STD_ERROR_HANDLE);\r
 \r
     oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter );\r
 \r
diff --git a/platform/win32/functions/_PDCLIB/_PDCLIB_close.c b/platform/win32/functions/_PDCLIB/_PDCLIB_close.c
deleted file mode 100644 (file)
index 7fc10a3..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-/* $Id$ */
-
-/* _PDCLIB_close( _PDCLIB_fd_t fd )
-
-   This file is part of the Public Domain C Library (PDCLib).
-   Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-/* This is a stub example implementation of _PDCLIB_close()
-*/
-
-#include <stdio.h>
-
-#ifndef REGTEST
-#include <_PDCLIB_glue.h>
-#include <errno.h>
-#include <windows.h>
-
-void _PDCLIB_w32errno(void);
-int _PDCLIB_close( HANDLE fd )
-{
-    if(CloseHandle((HANDLE) fd))
-        return 0;
-    _PDCLIB_w32errno();
-    return 1;
-}
-
-#endif
-
-#ifdef TEST
-#include <_PDCLIB_test.h>
-
-int main( void )
-{
-    /* No testdriver; tested in driver for _PDCLIB_open(). */
-    return TEST_RESULTS;
-}
-
-#endif
diff --git a/platform/win32/functions/_PDCLIB/_PDCLIB_fileops.c b/platform/win32/functions/_PDCLIB/_PDCLIB_fileops.c
new file mode 100644 (file)
index 0000000..1d48e11
--- /dev/null
@@ -0,0 +1,87 @@
+/* _PDCLIB_fileops\r
+\r
+   This file is part of the Public Domain C Library (PDCLib).\r
+   Permission is granted to use, modify, and / or redistribute at will.\r
+*/\r
+\r
+#ifndef REGTEST\r
+#include <stdio.h>\r
+#include <stdint.h>\r
+#include <_PDCLIB_glue.h>\r
+#include <errno.h>\r
+#include <windows.h>\r
+\r
+#if _PDCLIB_C_MIN(2011)\r
+_Static_assert(SEEK_SET == FILE_BEGIN, "SEEK_SET is incorrect");\r
+_Static_assert(SEEK_CUR == FILE_CURRENT, "SEEK_CUR is incorrect");\r
+_Static_assert(SEEK_END == FILE_END, "SEEK_END is incorrect");\r
+#endif\r
+\r
+void _PDCLIB_w32errno(void);\r
+\r
+static bool readf( _PDCLIB_fd_t self, void * buf, size_t length, \r
+                   size_t * numBytesRead )\r
+{\r
+    DWORD dwLen = length > INT32_MAX ? INT32_MAX : length;\r
+    DWORD dwBytesRead;\r
+    if(ReadFile(self.pointer, buf, dwLen, &dwBytesRead, NULL)) {\r
+        *numBytesRead = dwBytesRead;\r
+        return true;\r
+    } else {\r
+        _PDCLIB_w32errno();\r
+        return false;\r
+    }\r
+}\r
+\r
+static bool writef( _PDCLIB_fd_t self, const void * buf, size_t length, \r
+                   size_t * numBytesWritten )\r
+{\r
+    DWORD dwLen = length > INT32_MAX ? INT32_MAX : length;\r
+    DWORD dwBytesWritten;\r
+\r
+    if(WriteFile(self.pointer, buf, dwLen, &dwBytesWritten, NULL)) {\r
+        *numBytesWritten = dwBytesWritten;\r
+        return true;\r
+    } else {\r
+        _PDCLIB_w32errno();\r
+        return false;\r
+    }\r
+}\r
+static bool seekf( _PDCLIB_fd_t self, int_fast64_t offset, int whence,\r
+    int_fast64_t* newPos )\r
+{\r
+    LARGE_INTEGER liOffset;\r
+    liOffset.QuadPart = offset;\r
+    if(!SetFilePointerEx( self.pointer, liOffset, &liOffset, whence )) {\r
+        _PDCLIB_w32errno();\r
+        return false;\r
+    }\r
+\r
+    *newPos = liOffset.QuadPart;\r
+    return true;\r
+}\r
+\r
+static void closef( _PDCLIB_fd_t self )\r
+{\r
+    CloseHandle( self.pointer );\r
+}\r
+\r
+const _PDCLIB_fileops_t _PDCLIB_fileops = {\r
+    .read  = readf,\r
+    .write = writef,\r
+    .seek  = seekf,\r
+    .close = closef,\r
+};\r
+\r
+#endif\r
+\r
+#ifdef TEST\r
+#include <_PDCLIB_test.h>\r
+\r
+int main( void )\r
+{\r
+    // Tested by stdio test cases\r
+    return TEST_RESULTS;\r
+}\r
+\r
+#endif\r
index a6ac387c8842dc1f476c376ac37d7f213554ade4..af1ee52843ea64a5211aff17aa7865efeb5f9a7e 100644 (file)
 #include <_PDCLIB_glue.h>
 #include <windows.h>
 
+extern const _PDCLIB_fileops_t _PDCLIB_fileops;
+
 void _PDCLIB_w32errno(void);
-HANDLE _PDCLIB_open( char const * const filename, unsigned int mode )
+bool _PDCLIB_open( _PDCLIB_fd_t * pFd, const _PDCLIB_fileops_t ** pOps,
+                   char const * const filename, unsigned int mode )
 {
     DWORD desiredAccess;
     DWORD creationDisposition;
@@ -51,7 +54,7 @@ HANDLE _PDCLIB_open( char const * const filename, unsigned int mode )
         break;
     default: /* Invalid mode */
         errno = EINVAL;
-        return NULL;
+        return false;
     }
 
     HANDLE fd = CreateFileA(filename, desiredAccess, 
@@ -75,7 +78,7 @@ HANDLE _PDCLIB_open( char const * const filename, unsigned int mode )
         fprintf(stderr, "Error: %s\n", msgBuf);
 #endif
         _PDCLIB_w32errno();
-        return NULL;
+        return false;
     }
 
     if(mode & _PDCLIB_FAPPEND) {
@@ -85,11 +88,13 @@ HANDLE _PDCLIB_open( char const * const filename, unsigned int mode )
         if(!ok) {
             _PDCLIB_w32errno();
             CloseHandle(fd);
-            return NULL;
+            return false;
         }
     }
 
-    return fd;
+    pFd->pointer = fd;
+    *pOps = &_PDCLIB_fileops;
+    return true;
 }
 
 #endif
diff --git a/platform/win32/functions/_PDCLIB/_PDCLIB_seek.c b/platform/win32/functions/_PDCLIB/_PDCLIB_seek.c
deleted file mode 100644 (file)
index 6bf53e9..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/* $Id$ */
-
-/* int64_t _PDCLIB_seek( FILE *, int64_t, int )
-
-   This file is part of the Public Domain C Library (PDCLib).
-   Permission is granted to use, modify, and / or redistribute at will.
-*/
-
-#include <stdio.h>
-#include <errno.h>
-#ifndef REGTEST
-#include <_PDCLIB_glue.h>
-#include <windows.h>
-
-#if _PDCLIB_C_MIN(2011)
-_Static_assert(SEEK_SET == FILE_BEGIN, "SEEK_SET is incorrect");
-_Static_assert(SEEK_CUR == FILE_CURRENT, "SEEK_CUR is incorrect");
-_Static_assert(SEEK_END == FILE_END, "SEEK_END is incorrect");
-#endif
-
-extern void _PDCLIB_w32errno( void );
-_PDCLIB_int64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, _PDCLIB_int64_t offset, int whence )
-{
-    LARGE_INTEGER liOffset;
-    liOffset.QuadPart = offset;
-    BOOL rv = SetFilePointerEx( stream->handle, liOffset, &liOffset, whence );
-    if(!rv) {
-        _PDCLIB_w32errno();
-        return EOF;
-    }
-
-    stream->ungetidx = 0;
-    stream->bufidx = 0;
-    stream->bufend = 0;
-    stream->pos.offset = liOffset.QuadPart;
-    return liOffset.QuadPart;
-}
-
-#endif
-
-#ifdef TEST
-#include <_PDCLIB_test.h>
-
-int main( void )
-{
-    /* Testing covered by ftell.c */
-    return TEST_RESULTS;
-}
-
-#endif
-
index 8eb40f70ceda97560af5f2d33a7eb1f21a5da3c9..6ff9608985781d1db571c0aa86b6b5a61e5383ee 100644 (file)
@@ -17,6 +17,8 @@
 
 #ifndef REGTEST
 
+extern const _PDCLIB_fileops_t _PDCLIB_fileops;
+
 /* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file
    descriptors 0, 1, and 2 respectively.
 */
@@ -29,9 +31,9 @@ static unsigned char _PDCLIB_sin_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
 static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
 static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
 
-static struct _PDCLIB_file_t _PDCLIB_serr = { NULL, { 0 }, _PDCLIB_serr_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_serr_ungetbuf, _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, NULL };
-static struct _PDCLIB_file_t _PDCLIB_sout = { NULL, { 0 }, _PDCLIB_sout_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sout_ungetbuf, _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, &_PDCLIB_serr };
-static struct _PDCLIB_file_t _PDCLIB_sin  = { NULL, { 0 }, _PDCLIB_sin_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sin_ungetbuf, _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC, NULL, &_PDCLIB_sout };
+static struct _PDCLIB_file_t _PDCLIB_serr = { &_PDCLIB_fileops, NULL, { 0 }, _PDCLIB_serr_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_serr_ungetbuf, _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, NULL };
+static struct _PDCLIB_file_t _PDCLIB_sout = { &_PDCLIB_fileops, NULL, { 0 }, _PDCLIB_sout_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sout_ungetbuf, _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, &_PDCLIB_serr };
+static struct _PDCLIB_file_t _PDCLIB_sin  = { &_PDCLIB_fileops, NULL, { 0 }, _PDCLIB_sin_buffer,  BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sin_ungetbuf,  _IOLBF | _PDCLIB_FREAD  | _PDCLIB_STATIC, NULL, &_PDCLIB_sout };
 
 struct _PDCLIB_file_t * stdin  = &_PDCLIB_sin;
 struct _PDCLIB_file_t * stdout = &_PDCLIB_sout;
index f3292349f08a9cbb3eb29832c73c1bc892faabf9..1b3b4bab9b6886b7b5db8493825b34ca610d1618 100644 (file)
@@ -16,7 +16,9 @@
 
 static char tmpname_prefix[4] = {0, 0, 0, 0};
 
+extern const _PDCLIB_fileops_t _PDCLIB_fileops;
 extern void _PDCLIB_w32errno( void );
+
 struct _PDCLIB_file_t * tmpfile( void )
 {
     if(!tmpname_prefix[0]) {
@@ -67,7 +69,7 @@ struct _PDCLIB_file_t * tmpfile( void )
     /* Set the file to delete on close */
     DeleteFile(name);
 
-    FILE* fs = _PDCLIB_fdopen(fd, _PDCLIB_FWRITE | _PDCLIB_FRW, name);
+    FILE* fs = _PDCLIB_fvopen(((_PDCLIB_fd_t){fd}), &_PDCLIB_fileops, _PDCLIB_FWRITE | _PDCLIB_FRW, name);
     if(!fs) {
         CloseHandle(fd);
     }
index abefef934233fddbb9eb890417ab3ddfbeb8a8ec..57a2d29f6a59b13d11d3c35c0153374038408005 100644 (file)
@@ -341,9 +341,6 @@ struct _PDCLIB_imaxdiv_t
 
 /* I/O ---------------------------------------------------------------------- */
 
-/* The type of the file descriptor returned by _PDCLIB_open(). */
-typedef void * _PDCLIB_fd_t;
-
 /* The value (of type _PDCLIB_fd_t) returned by _PDCLIB_open() if the operation
    failed.
 */