diff options
Diffstat (limited to 'Build/source/libs/pplib/pplib-src/src/util/utiliof.h')
-rw-r--r-- | Build/source/libs/pplib/pplib-src/src/util/utiliof.h | 673 |
1 files changed, 673 insertions, 0 deletions
diff --git a/Build/source/libs/pplib/pplib-src/src/util/utiliof.h b/Build/source/libs/pplib/pplib-src/src/util/utiliof.h new file mode 100644 index 00000000000..bad43a77374 --- /dev/null +++ b/Build/source/libs/pplib/pplib-src/src/util/utiliof.h @@ -0,0 +1,673 @@ + +#ifndef UTIL_IOF_H +#define UTIL_IOF_H + +#include <stdio.h> // for FILE * +#include <errno.h> // for errno +#include <string.h> // for strerror() +#include <stdint.h> // for uintN_t + +#include "utildecl.h" +#include "utilnumber.h" + +/* handler call modes */ + +typedef enum { + IOFREAD = 0, /* read to buffer */ + IOFLOAD = 1, /* read all to buffer */ + IOFWRITE = 2, /* write buffer to the output */ + IOFFLUSH = 3, /* flush buffer to the output */ + IOFCLOSE = 4 /* (flush and) close */ +} iof_mode; + +/* return statuses */ + +typedef enum { + IOFEOF = -1, /* end of input */ + IOFEMPTY = -2, /* end of input buffer*/ + IOFFULL = -3, /* end of output buffer */ + IOFERR = -4 /* error */ +} iof_status; + +const char * iof_status_kind (iof_status status); + +/* iof_file */ + +typedef struct iof_file { + union { + FILE *iofh; // access via iof_file_get_fh / iof_file_set_fh (below) + union { + struct { uint8_t *buf, *pos, *end; }; + struct { const uint8_t *rbuf, *rpos, *rend; }; // to trick compiler warnings about cast discarding const + }; + }; + size_t *offset; + char *name; + size_t size; + int refcount; + int flags; +} iof_file; + +/* iof handler function */ + +typedef struct iof iof; +typedef size_t (*iof_handler) (iof *I, iof_mode mode); + +/* iof structure; keep 8N bytes */ + +#define IOF_MEMBERS \ + union { \ + struct { uint8_t *buf, *pos, *end; }; \ + struct { uint16_t *hbuf, *hpos, *hend; }; \ + struct { uint32_t *ibuf, *ipos, *iend; }; \ + struct { const uint8_t *rbuf, *rpos, *rend; }; \ + }; \ + size_t space; \ + iof_handler more; \ + union { void *link; iof *next; FILE *file; iof_file *iofile; }; \ + int flags; \ + int refcount + +/* + buf -- the beginning of buffer + pos -- the current position + end -- the end of buffer + space -- private space size, not always eq. (end - buf) + more -- handler function + next/file/iofile/link -- reader source or writer target + source -- source filter + flags -- private filter info + refcount -- refcount +*/ + +struct iof { + IOF_MEMBERS; +}; + +typedef void (*iof_dump_function) (const void *value, iof *O); + +/* flags */ + +#define IOF_ALLOC (1<<0) // iof is allocated +#define IOF_HEAP (1<<1) // iof taken from iof heap +#define IOF_BUFFER_ALLOC (1<<2) // buffer allocated +#define IOF_BUFFER_HEAP (1<<3) // buffer taken from iof heap + +#define IOF_SHORT (1<<4) // buffer uses 16bit integers +#define IOF_LONG (1<<5) // buffer uses 32bit integers + +#define IOF_TAIL (1<<6) // preserve reader tail +#define IOF_READER (1<<7) // is reader +#define IOF_WRITER (1<<8) // is writer + +#define IOF_DATA (1<<9) // binds some memory +#define IOF_FILE_HANDLE (1<<10) // links FILE * +#define IOF_FILE (1<<11) // links iof_file * +#define IOF_NEXT (1<<12) // links next iof * +#define IOF_CLOSE_FILE (1<<13) // close FILE * on free +#define IOF_REOPEN_FILE (1<<14) // close/reopen mode for iof_file +#define IOF_RECLOSE_FILE (1<<15) // ditto + +#define IOF_STOPPED (1<<16) // stopped + +// #define IOF_CUSTOM (1<<17) // first custom flag + +#define IOF_BUFSIZ (sizeof(iof) + BUFSIZ*sizeof(uint8_t)) + +/* +reading buffer -- all of buf, pos, end pointers are initialized to the beginning of the private buffer, + next call to a handler function moves the end pointer to bufer+space +writer -- buf and pos pointers initialized to the beginning of the buffer, end initialized to bufer+space + +Every call to handler returns size_t number of bytes +available (to write/read) or 0 if there is no more space. + +We usually align the data buffer just after the iof structure. +This is convenient, especially when a memory for the structure +and its buffer is to be allocated. In the case of growing output +buffers we used to check if the memory of the buffer is allocated +by the handler function using test (O->buf != (O+1)). We don't use +it any longer not to rely on little secrets. Now there is an explicit +IOF_BUFFER_ALLOC flag for that. IOF_ALLOC tells if the structure +itself is taken from malloc (not used so far). Assuming the buffer size +is way larger the sizeof(iof) +*/ + +/* initializers */ + +#define IOF_READER_INIT(handler, file, buffer, size, flags) \ + { {{ (uint8_t *)(buffer), (uint8_t *)(buffer), (uint8_t *)(buffer) }}, size, handler, { file }, (flags)|IOF_READER, 0 } + +#define IOF_WRITER_INIT(handler, file, buffer, size, flags) \ + { {{ (uint8_t *)(buffer), (uint8_t *)(buffer), (uint8_t *)(buffer) + size }}, size, handler, { file }, (flags)|IOF_WRITER, 0 } + +#define IOF_STRING_INIT(buffer, size) \ + { {{ (uint8_t *)(buffer), (uint8_t *)(buffer), (uint8_t *)(buffer) + size }}, size, NULL, { NULL }, 0|IOF_READER|IOF_DATA, 0 } + +#define IOF_STRING() IOF_STRING_INIT(0, 0) + +/* refcount */ + +#define iof_incref(I) (++(I)->refcount) +#define iof_decref(I) ((void)(--(I)->refcount <= 0 && iof_close(I))) +#define iof_unref(I) (--(I)->refcount) + +/* binding buffer of a given size */ + +#define iof_setup_reader(I, buffer, size) \ + ((I)->buf = (I)->pos = (I)->end = (uint8_t *)(buffer), \ + (I)->space = size, (I)->flags = 0|IOF_READER, (I)->refcount = 0) + +#define iof_setup_writer(O, buffer, size) \ + ((O)->buf = (O)->pos = (uint8_t *)(buffer), \ + (O)->end = (uint8_t *)(buffer) + size, \ + (O)->space = size, (O)->flags = 0|IOF_WRITER, (O)->refcount = 0) + +/* basics */ + +#define iof_space(I) ((I)->end - (I)->buf) +#define iof_left(I) ((I)->end - (I)->pos) +#define iof_size(I) ((I)->pos - (I)->buf) + +#define iof_input(I) ((I)->more ? (I)->more((I), IOFREAD) : 0lu) +#define iof_load(I) ((I)->more ? (I)->more((I), IOFLOAD) : 0lu) + +#define iof_output(O) ((O)->more ? (O)->more((O), IOFWRITE) : 0lu) +//#define iof_flush(O) ((O)->pos > (O)->buf && (O)->more ? (O)->more(O, IOFFLUSH) : 0lu) +// flush should be unconditional, because encoders emits EOD markers only on flush +#define iof_flush(O) ((O)->more ? (O)->more(O, IOFFLUSH) : 0lu) +#define iof_close(O) ((O)->more ? (O)->more(O, IOFCLOSE) : 0lu) + +#define iof_stop(F) ((void)(F->pos = F->end = F->buf, F->flags |= IOF_STOPPED)) + +/* +Rewriting reader tail to the beginning of new data portion; readers reacting on IOFREAD +mode must be aware of some not yet read data, but treat it necessary only if IOF_TAIL flag is set. +Parsers using iof input may protect not yet read data when there may be a need to put bytes +back to the stream. This is trivial when I->pos > I->buf, as we can make a move by --I->pos. +But when there is a need to put back more then one byte, we can protect the data tail, so that +realoder will rewrite it to the beginning of new data chunk. + + iof_tail(I) - internal, used by iof handlers at IOFREAD mode + iof_protect_tail(I) - used by parsers to ensure some bytes chunk in one piece + +*/ + +size_t iof_save_tail (iof *I); +#define iof_tail(I) (((I)->flags & IOF_TAIL) && (I)->pos < (I)->end ? iof_save_tail(I) : 0) + +size_t iof_input_save_tail (iof *I, size_t back); +#define iof_protect_tail(I, back, length) ((iof_left(I) >= (length) - (back)) ? 1 : (iof_input_save_tail(I, back) >= length - back)) + +//uint8_t * iof_tail_data (iof *I, size_t *ptail); +//#define iof_tail_free(data) util_free(data) + +/* panic */ + +// #define iof_panic(mess) return 0 +#ifndef iof_panic + #define iof_panic(mess) (fputs(mess, stderr), abort()) +#endif +//#define iof_memory_error() iof_panic(strerror(errno)) +#define iof_fwrite_error() iof_panic(strerror(errno)) + +/* generic helpers */ + +UTILAPI uint8_t * iof_copy_file_data (const char *filename, size_t *psize); +UTILAPI uint8_t * iof_copy_file_handle_data (FILE *file, size_t *psize); + +/* In the future we may need releasing file handle and restoring it from iofile->name, so access file handle via macros */ + +#define iof_file_get_fh(iofile) ((iofile)->iofh) +#define iof_file_set_fh(iofile, fh) ((iofile)->iofh = fh) +#define iof_file_get_file(iofile) (((iofile)->flags & IOF_DATA) ? NULL : iof_file_get_fh(iofile)) +FILE * iof_get_file (iof *F); + +/* basic iof_file interface */ + +iof_file * iof_file_new (FILE *file); +iof_file * iof_file_init (iof_file *iofile, FILE *file); + +iof_file * iof_file_rdata (const void *data, size_t size); +iof_file * iof_file_wdata (void *data, size_t size); + +iof_file * iof_file_rdata_init (iof_file *iofile, const void *data, size_t size); +iof_file * iof_file_wdata_init (iof_file *iofile, void *data, size_t size); + +iof_file * iof_file_reader_from_file_handle (iof_file *iofile, const char *filename, FILE *file, int preload, int closefile); +iof_file * iof_file_reader_from_file (iof_file *iofile, const char *filename, int preload); +iof_file * iof_file_reader_from_data (iof_file *iofile, const void *data, size_t size, int preload, int freedata); +//iof_file * iof_file_writer_from_file (iof_file *iofile, const char *filename); + +void * iof_copy_data (const void *data, size_t size); +#define iof_data_free(data) util_free(data) +#define iof_file_wdata_copy(data, size) iof_file_wdata(iof_copy_data(data, size), size) +#define iof_file_rdata_copy(data, size) iof_file_rdata(iof_copy_data(data, size), size) + +void iof_file_free (iof_file *iofile); + +#define iof_file_get_name(iofile) ((iofile)->name) +void iof_file_set_name (iof_file *iofile, const char *name); + +#define iof_file_incref(iofile) (++(iofile)->refcount) +#define iof_file_decref(iofile) ((void)(--(iofile)->refcount <= 0 && (iof_file_free(iofile), 0))) + +int iof_file_seek (iof_file *iofile, long offset, int whence); +long iof_file_tell (iof_file *iofile); +size_t iof_file_size (iof_file *iofile); +int iof_file_eof (iof_file *iofile); + +size_t iof_file_read (void *ptr, size_t size, size_t items, iof_file *iofile); +size_t iof_file_write (const void *ptr, size_t size, size_t items, iof_file *iofile); +size_t iof_file_ensure (iof_file *iofile, size_t bytes); +int iof_file_flush (iof_file *iofile); + +int iof_file_getc (iof_file *iofile); +int iof_file_putc (iof_file *iofile, int c); + +int iof_file_reclose_input (iof_file *iofile); +int iof_file_reopen_input (iof_file *iofile); + +#define iof_file_reopen(iofile) (((iofile)->flags & IOF_REOPEN_FILE) ? iof_file_reopen_input(iofile) : 1) +#define iof_file_reclose(iofile) (void)(((iofile)->flags & IOF_RECLOSE_FILE) ? iof_file_reclose_input(iofile) : 0) + +void iof_file_close_input (iof_file *iofile); + +/* wrappers of basic operations for iof */ + +int iof_reader_seek (iof *I, long offset, int whence); +int iof_reader_reseek (iof *I, long offset, int whence); +int iof_writer_seek (iof *I, long offset, int whence); +int iof_writer_reseek (iof *I, long offset, int whence); + +int iof_seek (iof *I, long offset, int whence); +int iof_reseek (iof *I, long offset, int whence); + +long iof_reader_tell (iof *I); +long iof_writer_tell (iof *I); +long iof_tell (iof *I); +size_t iof_fsize (iof *I); + +#define iof_setup_iofile(I, f) (iof_file_incref(f), (I)->iofile = f, (I)->flags |= IOF_FILE) +#define iof_setup_file(I, fh) ((I)->file = fh, (I)->flags |= IOF_FILE_HANDLE) +#define iof_setup_next(I, N) ((I)->next = N, iof_incref(N), (I)->flags |= IOF_NEXT) + +/* file handler reader and writer */ + +UTILAPI iof * iof_setup_file_handle_reader (iof *I, void *buffer, size_t space, FILE *f); +UTILAPI iof * iof_setup_file_handle_writer (iof *O, void *buffer, size_t space, FILE *f); + +/* file reader and writer */ + +UTILAPI iof * iof_setup_file_reader (iof *I, void *buffer, size_t space, const char *filename); +UTILAPI iof * iof_setup_file_writer (iof *O, void *buffer, size_t space, const char *filename); + +/* mem writer */ + +UTILAPI iof * iof_setup_buffer (iof *O, void *buffer, size_t space); +UTILAPI iof * iof_setup_buffermin (iof *O, void *buffer, size_t space, size_t min); + +UTILAPI iof * iof_buffer_create (size_t space); +#define iof_buffer_new() iof_buffer_create(BUFSIZ) + +/* custom handler */ + +UTILAPI iof * iof_reader (iof *I, void *link, iof_handler reader, const void *s, size_t bytes); +UTILAPI iof * iof_writer (iof *O, void *link, iof_handler writer, void *s, size_t bytes); + +/* stdout wrapper */ + +extern UTILAPI iof iof_stdout; +extern UTILAPI iof iof_stderr; + +/* simple string reader */ + +UTILAPI iof * iof_string_reader (iof *I, const void *s, size_t bytes); + +#define iof_string(I, s, bytes) \ + (((I)->rbuf = (I)->rpos = (const uint8_t *)s), ((I)->rend = (I)->rbuf + (bytes)), ((I)->flags |= IOF_DATA), (I)) + +/* dummies */ + +UTILAPI iof * iof_dummy (void *buffer, size_t space); +UTILAPI iof * iof_null (void *buffer, size_t space); + +/* checking available space */ + +#define iof_loadable(I) ((I)->pos < (I)->end || iof_load(I)) +#define iof_readable(I) ((I)->pos < (I)->end || iof_input(I)) +#define iof_writable(O) ((O)->pos < (O)->end || iof_output(O)) + +#define iof_hloadable iof_loadable +#define iof_iloadable iof_loadable + +#define iof_hreadable iof_readable +#define iof_ireadable iof_readable + +#define iof_hwritable iof_writable +#define iof_iwritable iof_writable + +/* ensure space to write several bytes (several means less then I->space) */ + +#define iof_ensure(O, n) ((O)->pos+(n)-1 < (O)->end || iof_output(O)) // iof_ensure(O, 1) eq iof_writable(O) +#define iof_hensure(O, n) ((O)->hpos+(n)-1 < (O)->hend || iof_output(O)) +#define iof_iensure(O, n) ((O)->ipos+(n)-1 < (O)->iend || iof_output(O)) + +/* reading */ + +UTILAPI int iof_getc (iof *I); +UTILAPI int iof_hgetc (iof *I); +UTILAPI int iof_igetc (iof *I); + +// UTILAPI int iof_cmp (iof *I, const char *s); +// UTILAPI int iof_cmpn (iof *I, const char *s, size_t bytes); + +UTILAPI iof_status iof_pass (iof *I, iof *O); +#define iof_hpass iof_pass +#define iof_ipass iof_pass + +/* readers helpers */ + +UTILAPI size_t iof_read (iof *I, void *s, size_t bytes); +UTILAPI size_t iof_hread (iof *I, void *s, size_t bytes); +UTILAPI size_t iof_iread (iof *I, void *s, size_t bytes); + +UTILAPI size_t iof_skip (iof *I, size_t bytes); +UTILAPI size_t iof_hskip (iof *I, size_t bytes); +UTILAPI size_t iof_iskip (iof *I, size_t bytes); + +/* get */ + +#define iof_pos(I) (*(I)->pos++) +#define iof_hpos(I) (*(I)->hpos++) +#define iof_ipos(I) (*(I)->ipos++) + +#define iof_get(I) (iof_readable(I) ? (int)(*(I)->pos++) : IOFEOF) +#define iof_hget(I) (iof_hreadable(I) ? (int)(*(I)->hpos++) : IOFEOF) +#define iof_iget(I) (iof_ireadable(I) ? (int)(*(I)->ipos++) : IOFEOF) + +#define iof_char(I) (iof_readable(I) ? (int)(*(I)->pos) : IOFEOF) +#define iof_hcurr(I) (iof_hreadable(I) ? (int)(*(I)->hpos) : IOFEOF) +#define iof_icurr(I) (iof_ireadable(I) ? (int)(*(I)->ipos) : IOFEOF) + +#define iof_next(I) (++(I)->pos, iof_char(I)) +#define iof_hnext(I) (++(I)->hpos, iof_hcurr(I)) +#define iof_inext(I) (++(I)->ipos, iof_icurr(I)) + +/* unget */ + +/* +If possible, we just move the position backward. If it is not possible to +move backward, we call iof_backup(I, c) that sets all pointers to the end of +a private backup space, then moves buf AND pos pointers backward and set c at +pos (==buf). We can backup characters as long as there is a private space. If +several calls to iof_backup() are followed by iof_get(), pos pointer +increases in normal way and so the use of another iof_unget() works just fine +by moving the position. Once we swallow all backup characters (when +pos==end), backup handler restores the previous pointers. + +Obviously we assume that the character provided to iof_unget() is always the +character just obtained from iof_get(). We CAN'T just overwrite the character +at a given position as the space we read may not be writable. + +When backup is in use, we can only get bytes until automatically restored. +*/ + +/* backup */ + +/* +#define iof_uses_backup(I) ((I)->more == iof_unget_handler) + +#define iof_save(I, B) \ + ((B)->buf = (I)->buf, (B)->pos = (I)->pos, (B)->end = (I)->end, (B)->space = (I)->space, \ + (B)->link = I->link, (B)->more = (I)->more, (B)->flags = (I)->flags) +#define iof_restore(B, I) iof_save(I, B) + +#define iof_unget(I, c) \ + ((void)(c == (uint8_t)c ? ((I)->pos > (I)->buf ? --(I)->pos : iof_backup(I, c)) : 0) +int iof_backup (iof *I, int c); +*/ + +/* writing */ + +UTILAPI size_t iof_write_file_handle (iof *O, FILE *file); +UTILAPI size_t iof_write_file (iof *O, const char *filename); +UTILAPI size_t iof_write_iofile (iof *O, iof_file *iofile, int savepos); + +UTILAPI int iof_putc (iof *O, int u); +UTILAPI int iof_hputc (iof *O, int u); +UTILAPI int iof_iputc (iof *O, int u); + +UTILAPI size_t iof_write (iof *O, const void *data, size_t size); +UTILAPI size_t iof_hwrite (iof *O, const void *data, size_t size); +UTILAPI size_t iof_iwrite (iof *O, const void *data, size_t size); + +UTILAPI iof_status iof_puts (iof *O, const void *data); +UTILAPI size_t iof_put_string (iof *O, const void *data); +UTILAPI size_t iof_putfs (iof *O, const char *format, ...); +UTILAPI size_t iof_repc (iof *O, char c, size_t bytes); + +#define iof_putl(O, s) iof_write(O, "" s, sizeof(s)-1) +//#define iof_putl iof_puts + +#define iof_set(O, c) (*(O)->pos++ = (uint8_t)(c)) +#define iof_set2(O, c1, c2) (iof_set(O, c1), iof_set(O, c2)) +#define iof_set3(O, c1, c2, c3) (iof_set(O, c1), iof_set(O, c2), iof_set(O, c3)) +#define iof_set4(O, c1, c2, c3, c4) (iof_set(O, c1), iof_set(O, c2), iof_set(O, c3), iof_set(O, c4)) +#define iof_set5(O, c1, c2, c3, c4, c5) (iof_set(O, c1), iof_set(O, c2), iof_set(O, c3), iof_set(O, c4), iof_set(O, c5)) + +#define iof_hset(O, c) (*(O)->hpos++ = (uint16_t)(c)) +#define iof_iset(O, c) (*(O)->ipos++ = (uint32_t)(c)) + +#define iof_put(O, c) ((void)iof_ensure(O, 1), iof_set(O, c)) +#define iof_put2(O, c1, c2) ((void)iof_ensure(O, 2), iof_set2(O, c1, c2)) +#define iof_put3(O, c1, c2, c3) ((void)iof_ensure(O, 3), iof_set3(O, c1, c2, c3)) +#define iof_put4(O, c1, c2, c3, c4) ((void)iof_ensure(O, 4), iof_set4(O, c1, c2, c3, c4)) +#define iof_put5(O, c1, c2, c3, c4, c5) ((void)iof_ensure(O, 5), iof_set5(O, c1, c2, c3, c4, c5)) + +#define iof_hput(O, c) ((void)iof_hensure(O, 1), iof_hset(O, c)) +#define iof_iput(O, c) ((void)iof_iensure(O, 1), iof_iset(O, c)) + +#define iof_put_uc_hex(O, c) iof_put2(O, base16_uc_digit1(c), base16_uc_digit2(c)) +#define iof_put_lc_hex(O, c) iof_put2(O, base16_lc_digit1(c), base16_lc_digit2(c)) +#define iof_set_uc_hex(O, c) iof_set2(O, base16_uc_digit1(c), base16_uc_digit2(c)) +#define iof_set_lc_hex(O, c) iof_set2(O, base16_lc_digit1(c), base16_lc_digit2(c)) +#define iof_put_hex iof_put_uc_hex +#define iof_set_hex iof_set_uc_hex + +/* number from iof; return 1 on success, 0 otherwise */ + +#define iof_scan_sign(I, c, sign) _scan_sign(c, sign, iof_next(I)) +#define iof_scan_integer(I, c, number) _scan_integer(c, number, iof_next(I)) +#define iof_scan_radix(I, c, number, radix) _scan_radix(c, number, radix, iof_next(I)) +#define iof_read_integer(I, c, number) _read_integer(c, number, iof_next(I)) +#define iof_read_radix(I, c, number, radix) _read_radix(c, number, radix, iof_next(I)) + +#define iof_scan_decimal(I, c, number) _scan_decimal(c, number, iof_next(I)) +#define iof_scan_fraction(I, c, number, exponent10) _scan_fraction(c, number, exponent10, iof_next(I)) +#define iof_scan_exponent10(I, c, exponent10) _scan_exponent10(c, exponent10, iof_next(I)) + +UTILAPI int iof_get_int32 (iof *I, int32_t *number); +UTILAPI int iof_get_slong (iof *I, long *number); +UTILAPI int iof_get_int64 (iof *I, int64_t *number); + +UTILAPI int iof_get_uint32 (iof *I, uint32_t *number); +UTILAPI int iof_get_ulong (iof *I, unsigned long *number); +UTILAPI int iof_get_usize (iof *I, size_t *number); +UTILAPI int iof_get_uint64 (iof *I, uint64_t *number); + +UTILAPI int iof_get_int32_radix (iof *I, int32_t *number, int radix); +UTILAPI int iof_get_slong_radix (iof *I, long *number, int radix); +UTILAPI int iof_get_int64_radix (iof *I, int64_t *number, int radix); + +UTILAPI int iof_get_uint32_radix (iof *I, uint32_t *number, int radix); +UTILAPI int iof_get_ulong_radix (iof *I, unsigned long *number, int radix); +UTILAPI int iof_get_usize_radix (iof *I, size_t *number, int radix); +UTILAPI int iof_get_uint64_radix (iof *I, uint64_t *number, int radix); + +#if defined(INTLW_IS_INT64) +# define iof_get_intlw(I, number) iof_get_int64(I, number) +# define iof_get_uintlw(I, number) iof_get_uint64(I, number) +# define iof_get_intlw_radix(I, number, radix) iof_get_int64_radix(I, number, radix) +# define iof_get_uintlw_radix(I, number, radix) iof_get_uint64_radix(I, number, radix) +#elif defined(INTLW_IS_LONG) +# define iof_get_intlw(I, number) iof_get_slong(I, number) +# define iof_get_uintlw(I, number) iof_get_ulong(I, number) +# define iof_get_intlw_radix(I, number, radix) iof_get_slong_radix(I, number, radix) +# define iof_get_uintlw_radix(I, number, radix) iof_get_ulong_radix(I, number, radix) +#endif + +UTILAPI int iof_get_roman (iof *I, uint16_t *number); + +UTILAPI int iof_get_double (iof *I, double *number); +UTILAPI int iof_get_float (iof *I, float *number); + +UTILAPI int iof_conv_double (iof *I, double *number); +UTILAPI int iof_conv_float (iof *I, float *number); + +/* number to iof; return a number of written bytes */ + +UTILAPI size_t iof_put_int32 (iof *O, int32_t number); +UTILAPI size_t iof_put_slong (iof *O, long number); +UTILAPI size_t iof_put_int64 (iof *O, int64_t number); + +UTILAPI size_t iof_put_uint32 (iof *O, uint32_t number); +UTILAPI size_t iof_put_ulong (iof *O, unsigned long number); +UTILAPI size_t iof_put_usize (iof *O, size_t number); +UTILAPI size_t iof_put_uint64 (iof *O, uint64_t number); + +UTILAPI size_t iof_put_int32_radix (iof *O, int32_t number, int radix, int uc); +UTILAPI size_t iof_put_slong_radix (iof *O, long number, int radix, int uc); +UTILAPI size_t iof_put_int64_radix (iof *O, int64_t number, int radix, int uc); + +UTILAPI size_t iof_put_uint32_radix (iof *O, uint32_t number, int radix, int uc); +UTILAPI size_t iof_put_ulong_radix (iof *O, unsigned long number, int radix, int uc); +UTILAPI size_t iof_put_usize_radix (iof *O, size_t number, int radix, int uc); +UTILAPI size_t iof_put_uint64_radix (iof *O, uint64_t number, int radix, int uc); + +#if defined(INTLW_IS_INT64) +# define iof_put_intlw(O, number) iof_put_int64(O, number) +# define iof_put_uintlw(O, number) iof_put_uint64(O, number) +# define iof_put_intlw_radix(O, number, radix, uc) iof_put_int64_radix(O, number, radix, uc) +# define iof_put_uintlw_radix(O, number, radix, uc) iof_put_uint64_radix(O, number, radix, uc) +#elif defined(INTLW_IS_LONG) +# define iof_put_intlw(O, number) iof_put_slong(O, number) +# define iof_put_uintlw(O, number) iof_put_ulong(O, number) +# define iof_put_intlw_radix(O, number, radix, uc) iof_put_slong_radix(O, number, radix, uc) +# define iof_put_uintlw_radix(O, number, radix, uc) iof_put_ulong_radix(O, number, radix, uc) +#endif + +UTILAPI size_t iof_put_roman (iof *O, uint16_t number, int uc); + +UTILAPI size_t iof_put_double(iof *O, double number, int digits); +UTILAPI size_t iof_put_float(iof *O, float number, int digits); + +/* common helpers for binary parsers */ + +UTILAPI int iof_get_be_uint2 (iof *I, uint32_t *pnumber); +UTILAPI int iof_get_be_uint3 (iof *I, uint32_t *pnumber); +UTILAPI int iof_get_be_uint4 (iof *I, uint32_t *pnumber); + +UTILAPI int iof_get_le_uint2 (iof *I, uint32_t *pnumber); +UTILAPI int iof_get_le_uint3 (iof *I, uint32_t *pnumber); +UTILAPI int iof_get_le_uint4 (iof *I, uint32_t *pnumber); + +// iof_set() and iof_put() suite casts arguments to uint8_t, so we don't need &0xff mask + +#define iof_set_be_uint1(O, u) iof_set(O, u) +#define iof_set_be_uint2(O, u) iof_set2(O, (u)>>8, u) +#define iof_set_be_uint3(O, u) iof_set3(O, (u)>>16, (u)>>8, u) +#define iof_set_be_uint4(O, u) iof_set4(O, (u)>>24, (u)>>16, (u)>>8, u) + +#define iof_set_le_uint1(O, u) iof_set(O, u) +#define iof_set_le_uint2(O, u) iof_set2(O, u, (u)>>8) +#define iof_set_le_uint3(O, u) iof_set3(O, u, (u)>>8, (u)>>16) +#define iof_set_le_uint4(O, u) iof_set4(O, u, (u)>>8, (u)>>16, (u)>>24) + +#define iof_put_be_uint1(O, u) iof_put(O, u) +#define iof_put_be_uint2(O, u) iof_put2(O, (u)>>8, u) +#define iof_put_be_uint3(O, u) iof_put3(O, (u)>>16, (u)>>8, u) +#define iof_put_be_uint4(O, u) iof_put4(O, (u)>>24, (u)>>16, (u)>>8, u) + +#define iof_put_le_uint1(O, u) iof_put(O, u) +#define iof_put_le_uint2(O, u) iof_put2(O, u, (u)>>8) +#define iof_put_le_uint3(O, u) iof_put3(O, u, (u)>>8, (u)>>16) +#define iof_put_le_uint4(O, u) iof_put4(O, u, (u)>>8, (u)>>16, (u)>>24) + +/* buffer results */ + +#define iof_reader_result(I, size) ((size = (size_t)iof_left(I)), (I)->pos) +#define iof_writer_result(I, size) ((size = (size_t)iof_size(I)), (I)->buf) +#define iof_result(I, size) (((I)->flags & IOF_READER) ? iof_reader_result(I, size) : iof_writer_result(I, size)) + +uint8_t * iof_file_input_data (iof_file *iofile, size_t *psize, int *isnew); +//uint8_t * iof_file_reader_data (iof_file *iofile, size_t *size); +//uint8_t * iof_file_writer_data (iof_file *iofile, size_t *size); + +uint8_t * iof_reader_data (iof *I, size_t *psize); +uint8_t * iof_writer_data (iof *O, size_t *psize); +size_t iof_reader_to_file_handle (iof *I, FILE *file); +size_t iof_reader_to_file (iof *I, const char *filename); + +#define iof_loaded(I) ((I)->end = (I)->pos, (I)->pos = (I)->buf, iof_left(I)) + +#define iof_data_to_file_handle(data, size, file) fwrite(data, sizeof(uint8_t), size, file) +UTILAPI size_t iof_data_to_file (const void *data, size_t size, const char *filename); + +UTILAPI size_t iof_result_to_file_handle (iof *F, FILE *file); +UTILAPI size_t iof_result_to_file (iof *F, const char *filename); +UTILAPI void iof_debug (iof *I, const char *filename); + +/* common filters allocator */ + +void iof_filters_init (void); +void iof_filters_free (void); + +iof * iof_filter_reader_new (iof_handler handler, size_t statesize, void **pstate); +#define iof_filter_reader(handler, statesize, pstate) iof_filter_reader_new(handler, statesize, (void **)(pstate)) +iof * iof_filter_reader_with_buffer_new (iof_handler handler, size_t statesize, void **pstate, void *buffer, size_t buffersize); +#define iof_filter_reader_with_buffer(handler, statesize, pstate, buffer, buffersize) iof_filter_reader_with_buffer_new(handler, statesize, (void **)(pstate), buffer, buffersize) +iof * iof_filter_writer_new (iof_handler handler, size_t statesize, void **pstate); +#define iof_filter_writer(handler, statesize, pstate) iof_filter_writer_new(handler, statesize, (void **)(pstate)) +iof * iof_filter_writer_with_buffer_new (iof_handler handler, size_t statesize, void **pstate, void *buffer, size_t buffersize); +#define iof_filter_writer_with_buffer(handler, statesize, pstate, buffer, buffersize) iof_filter_writer_with_buffer_new(handler, statesize, (void **)(pstate), buffer, buffersize) + +#define iof_filter_state(statetype, F) (statetype)((void *)((F) + 1)) + +void iof_free (iof *F); +void iof_discard (iof *F); + +size_t iof_resize_buffer_to (iof *O, size_t space); +#define iof_resize_buffer(O) iof_resize_buffer_to(O, (O)->space << 1) + +size_t iof_decoder_retval (iof *I, const char *type, iof_status status); +size_t iof_encoder_retval (iof *O, const char *type, iof_status status); + +/* filters */ + +iof * iof_filter_file_handle_reader (FILE *file); +iof * iof_filter_file_handle_writer (FILE *file); + +iof * iof_filter_iofile_reader (iof_file *iofile, size_t offset); +iof * iof_filter_iofile_writer (iof_file *iofile, size_t offset); + +iof * iof_filter_file_reader (const char *filename); +iof * iof_filter_file_writer (const char *filename); + +iof * iof_filter_string_reader (const void *s, size_t length); +iof * iof_filter_string_writer (const void *s, size_t length); + +iof * iof_filter_buffer_writer (size_t size); + +iof * iof_filter_stream_reader (FILE *file, size_t offset, size_t length); +iof * iof_filter_stream_coreader (iof_file *iofile, size_t offset, size_t length); + +iof * iof_filter_stream_writer (FILE *file); +iof * iof_filter_stream_cowriter (iof_file *iofile, size_t offset); + +FILE * iof_filter_file_reader_source (iof *I, size_t *poffset, size_t *plength); +iof_file * iof_filter_file_coreader_source (iof *I, size_t *poffset, size_t *plength); +iof * iof_filter_reader_replacement (iof *P, iof_handler handler, size_t statesize, void **pstate); +#define iof_filter_reader_replace(P, handler, statesize, pstate) iof_filter_reader_replacement(P, handler, statesize, (void **)(pstate)) + +#endif
\ No newline at end of file |