-#ifndef _PDCLIB_IO_H\r
-#define _PDCLIB_IO_H\r
+#ifndef __PDCLIB_IO_H\r
+#define __PDCLIB_IO_H __PDCLIB_IO_H\r
#include "_PDCLIB_int.h"\r
#include "_PDCLIB_threadconfig.h"\r
\r
-/* PDCLib internal I/O logic <_PDCLIB_int.h>\r
+/* PDCLib internal I/O logic <_PDCLIB_io.h>\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
/* stream handle should not be free()d on close (stdin, stdout, stderr) */\r
#define _PDCLIB_STATIC 32768u\r
\r
-typedef union _PDCLIB_fd\r
+union _PDCLIB_fd\r
{\r
#if defined(_PDCLIB_OSFD_T)\r
_PDCLIB_OSFD_T osfd;\r
void * pointer;\r
_PDCLIB_uintptr_t uval;\r
_PDCLIB_intptr_t sval; \r
-} _PDCLIB_fd_t;\r
+};\r
+\r
+/******************************************************************************/\r
+/* Internal functions */\r
+/******************************************************************************/\r
+\r
+/* The worker for all printf() type of functions. The pointer spec should point\r
+ to the introducing '%' of a conversion specifier. The status structure is to\r
+ be that of the current printf() function, of which the members n, s, stream\r
+ and arg will be preserved; i will be updated; and all others will be trashed\r
+ by the function.\r
+ Returns a pointer to the first character not parsed as conversion specifier.\r
+*/\r
+const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status );\r
+\r
+/* The worker for all scanf() type of functions. The pointer spec should point\r
+ to the introducing '%' of a conversion specifier. The status structure is to\r
+ be that of the current scanf() function, of which the member stream will be\r
+ preserved; n, i, and s will be updated; and all others will be trashed by\r
+ the function.\r
+ Returns a pointer to the first character not parsed as conversion specifier,\r
+ or NULL in case of error.\r
+ FIXME: Should distinguish between matching and input error\r
+*/\r
+const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status );\r
+\r
+/* Parsing any fopen() style filemode string into a number of flags. */\r
+unsigned int _PDCLIB_filemode( const char * mode );\r
+\r
+/* Sanity checking and preparing of read buffer, should be called first thing \r
+ by any stdio read-data function.\r
+ Returns 0 on success, EOF on error.\r
+ On error, EOF / error flags and errno are set appropriately.\r
+*/\r
+int _PDCLIB_prepread( _PDCLIB_file_t * stream );\r
+\r
+/* Sanity checking, should be called first thing by any stdio write-data\r
+ function.\r
+ Returns 0 on success, EOF on error.\r
+ On error, error flags and errno are set appropriately.\r
+*/\r
+int _PDCLIB_prepwrite( _PDCLIB_file_t * stream );\r
+\r
+/* Closing all streams on program exit */\r
+void _PDCLIB_closeall( void );\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
+int _PDCLIB_flushbuffer( _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
+int _PDCLIB_fillbuffer( _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 _PDCLIB_seek( _PDCLIB_file_t * stream, \r
_PDCLIB_int_fast64_t offset, int whence );\r
\r
/* File backend I/O operations\r
* PDCLib will call through to these methods as needed to implement the stdio\r
* functions.\r
*/\r
-typedef struct _PDCLIB_fileops\r
+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
_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_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
+struct _PDCLIB_file\r
{\r
const _PDCLIB_fileops_t * ops;\r
_PDCLIB_fd_t handle; /* OS file handle */\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
+ _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */\r
char * filename; /* Name the current stream has been opened with */\r
- struct _PDCLIB_file_t * next; /* Pointer to next struct (internal) */\r
+ _PDCLIB_file_t * next; /* Pointer to next struct (internal) */\r
};\r
\r
+static inline _PDCLIB_size_t _PDCLIB_getchars( char * out, _PDCLIB_size_t n,\r
+ int stopchar,\r
+ _PDCLIB_file_t * stream )\r
+{\r
+ _PDCLIB_size_t i = 0;\r
+ int c;\r
+ while ( stream->ungetidx > 0 && i != n )\r
+ {\r
+ c = (unsigned char) \r
+ ( out[ i++ ] = stream->ungetbuf[ --(stream->ungetidx) ] );\r
+ if( c == stopchar )\r
+ return i;\r
+ }\r
+\r
+ while ( i != n )\r
+ {\r
+ while ( stream->bufidx != stream->bufend && i != n) \r
+ {\r
+ c = (unsigned char) \r
+ ( out[ i++ ] = stream->buffer[ stream->bufidx++ ] );\r
+ if( c == stopchar )\r
+ return i;\r
+ }\r
+\r
+ if ( stream->bufidx == stream->bufend )\r
+ {\r
+ if( _PDCLIB_fillbuffer( stream ) == -1 )\r
+ {\r
+ return i;\r
+ }\r
+ }\r
+ }\r
+\r
+ return i;\r
+}\r
\r
#endif\r