-/* $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
-/* $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
/* $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
\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
}\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
--- /dev/null
+/* 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
mtx_destroy( &stream->lock );
/* Close handle */
- _PDCLIB_close( stream->handle );
+ stream->ops->close(stream->handle);
/* Remove stream from list */
if ( previous != NULL )
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;
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.
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;
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()),
#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
*/
#include <_PDCLIB_int.h>
+#include <_PDCLIB_io.h>
#include <stdbool.h>
#include <stddef.h>
_PDCLIB_BEGIN_EXTERN_C
/* 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.
/* 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
\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
+++ /dev/null
-/* $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
--- /dev/null
+/* _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
#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;
break;
default: /* Invalid mode */
errno = EINVAL;
- return NULL;
+ return false;
}
HANDLE fd = CreateFileA(filename, desiredAccess,
fprintf(stderr, "Error: %s\n", msgBuf);
#endif
_PDCLIB_w32errno();
- return NULL;
+ return false;
}
if(mode & _PDCLIB_FAPPEND) {
if(!ok) {
_PDCLIB_w32errno();
CloseHandle(fd);
- return NULL;
+ return false;
}
}
- return fd;
+ pFd->pointer = fd;
+ *pOps = &_PDCLIB_fileops;
+ return true;
}
#endif
+++ /dev/null
-/* $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
-
#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.
*/
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;
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]) {
/* 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);
}
/* 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.
*/