X-Git-Url: https://pd.if.org/git/?p=pdclib;a=blobdiff_plain;f=internals%2F_PDCLIB_io.h;h=829bb4586ed66781c2b2aca73f88f934651678a5;hp=0dfdad258fc6356a107597cfc830080cd1ccf82a;hb=c5d49235e09fbd58416f10dec2799e61cf3431c8;hpb=4c7c56442f6b3e08c17594dd4e8095fca3aec9cf diff --git a/internals/_PDCLIB_io.h b/internals/_PDCLIB_io.h index 0dfdad2..829bb45 100644 --- a/internals/_PDCLIB_io.h +++ b/internals/_PDCLIB_io.h @@ -34,29 +34,121 @@ /* stream handle should not be free()d on close (stdin, stdout, stderr) */ #define _PDCLIB_STATIC 32768u +typedef union _PDCLIB_fd +{ +#if defined(_PDCLIB_OSFD_T) + _PDCLIB_OSFD_T osfd; +#endif + void * pointer; + _PDCLIB_uintptr_t uval; + _PDCLIB_intptr_t sval; +} _PDCLIB_fd_t; + +/* Internal functions */ +/* 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 ); + +/* 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 ); + +/* Repositions within a file. Returns new offset on success, + -1 / errno on error. +*/ +_PDCLIB_int_fast64_t _PDCLIB_seek( struct _PDCLIB_file_t * stream, + _PDCLIB_int_fast64_t offset, int whence ); + +/* File backend I/O operations + * + * PDCLib will call through to these methods as needed to implement the stdio + * functions. + */ +typedef struct _PDCLIB_fileops +{ + /*! Read length bytes from the file into buf; returning the number of bytes + * actually read in *numBytesRead. + * + * Returns true if bytes were read successfully; on end of file, returns + * true with *numBytesRead == 0. + * + * On error, returns false and sets errno appropriately. *numBytesRead is + * ignored in this situation. + */ + _PDCLIB_bool (*read)( _PDCLIB_fd_t self, + void * buf, + _PDCLIB_size_t length, + _PDCLIB_size_t * numBytesRead ); + + /*! Write length bytes to the file from buf; returning the number of bytes + * actually written in *numBytesWritten + * + * Returns true if bytes were written successfully. On error, returns false + * and setss errno appropriately (as with read, *numBytesWritten is + * ignored) + */ + _PDCLIB_bool (*write)( _PDCLIB_fd_t self, const void * buf, + _PDCLIB_size_t length, _PDCLIB_size_t * numBytesWritten ); + + /* Seek to the file offset specified by offset, from location whence, which + * may be one of the standard constants SEEK_SET/SEEK_CUR/SEEK_END + */ + _PDCLIB_bool (*seek)( _PDCLIB_fd_t self, _PDCLIB_int_fast64_t offset, + int whence, _PDCLIB_int_fast64_t *newPos ); + + void (*close)( _PDCLIB_fd_t self ); + + /*! Behaves as read does, except for wide characters. Both length and + * *numCharsRead represent counts of characters, not bytes. + * + * This function is optional; if missing, PDCLib will buffer the character + * data as bytes and perform translation directly into the user's buffers. + * It is useful if your backend can directly take wide characters (for + * example, the Windows console) + */ + _PDCLIB_bool (*wread)( _PDCLIB_fd_t self, _PDCLIB_wchar_t * buf, + _PDCLIB_size_t length, _PDCLIB_size_t * numCharsRead ); + + /* Behaves as write does, except for wide characters. As with wread, both + * length and *numCharsWritten are character counts. + * + * This function is also optional; if missing, PDCLib will buffer the + * character data as bytes and do translation directly from the user's + * buffers. You only need to implement this if your backend can directly + * take wide characters (for example, the Windows console) + */ + _PDCLIB_bool (*wwrite)( _PDCLIB_fd_t self, const _PDCLIB_wchar_t * buf, + _PDCLIB_size_t length, _PDCLIB_size_t * numCharsWritten ); +} _PDCLIB_fileops_t; + /* Position / status structure for getpos() / fsetpos(). */ struct _PDCLIB_fpos_t { - _PDCLIB_uint64_t offset; /* File position offset */ - int status; /* Multibyte parsing state (unused, reserved) */ + _PDCLIB_int_fast64_t offset; /* File position offset */ + int status; /* Multibyte parsing state (unused, reserved) */ }; /* FILE structure */ struct _PDCLIB_file_t { - _PDCLIB_fd_t handle; /* OS file handle */ - _PDCLIB_MTX_T lock; /* file lock */ - char * buffer; /* Pointer to buffer memory */ - _PDCLIB_size_t bufsize; /* Size of buffer */ - _PDCLIB_size_t bufidx; /* Index of current position in buffer */ - _PDCLIB_size_t bufend; /* Index of last pre-read character in buffer */ - struct _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */ - _PDCLIB_size_t ungetidx; /* Number of ungetc()'ed characters */ - unsigned char * ungetbuf; /* ungetc() buffer */ - unsigned int status; /* Status flags; see above */ + const _PDCLIB_fileops_t * ops; + _PDCLIB_fd_t handle; /* OS file handle */ + _PDCLIB_MTX_T lock; /* file lock */ + char * buffer; /* Pointer to buffer memory */ + _PDCLIB_size_t bufsize; /* Size of buffer */ + _PDCLIB_size_t bufidx; /* Index of current position in buffer */ + _PDCLIB_size_t bufend; /* Index of last pre-read character in buffer */ + struct _PDCLIB_fpos_t pos; /* Offset and multibyte parsing state */ + _PDCLIB_size_t ungetidx; /* Number of ungetc()'ed characters */ + unsigned char * ungetbuf; /* ungetc() buffer */ + unsigned int status; /* Status flags; see above */ /* multibyte parsing status to be added later */ - char * filename; /* Name the current stream has been opened with */ - struct _PDCLIB_file_t * next; /* Pointer to next struct (internal) */ + char * filename; /* Name the current stream has been opened with */ + struct _PDCLIB_file_t * next; /* Pointer to next struct (internal) */ };