summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luapplib/src/util/utiliof.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luapplib/src/util/utiliof.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/luapplib/src/util/utiliof.c2993
1 files changed, 0 insertions, 2993 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luapplib/src/util/utiliof.c b/Build/source/texk/web2c/luatexdir/luapplib/src/util/utiliof.c
deleted file mode 100644
index 41d6fba38f1..00000000000
--- a/Build/source/texk/web2c/luatexdir/luapplib/src/util/utiliof.c
+++ /dev/null
@@ -1,2993 +0,0 @@
-/* input/output stream */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-#include "utilmem.h"
-#include "utillog.h"
-#include "utiliof.h"
-
-/* commons */
-
-void * iof_copy_data (const void *data, size_t size)
-{
- return memcpy(util_malloc(size), data, size);
-}
-
-uint8_t * iof_copy_file_data (const char *filename, size_t *psize)
-{
- FILE *file;
- size_t size;
- uint8_t *data;
- if ((file = fopen(filename, "rb")) == NULL)
- return NULL;
- fseek(file, 0, SEEK_END);
- size = (size_t)ftell(file);
- data = (uint8_t *)util_malloc(size);
- fseek(file, 0, SEEK_SET);
- if ((*psize = fread(data, 1, size, file)) != size)
- {
- util_free(data);
- data = NULL;
- }
- fclose(file);
- return data;
-}
-
-uint8_t * iof_copy_file_handle_data (FILE *file, size_t *psize)
-{
- size_t size;
- uint8_t *data;
- //long offset = ftell(file); // keep offset intact?
- fseek(file, 0, SEEK_END);
- size = (size_t)ftell(file);
- data = (uint8_t *)util_malloc(size);
- fseek(file, 0, SEEK_SET);
- if ((*psize = fread(data, 1, size, file)) != size)
- {
- util_free(data);
- data = NULL;
- }
- //fseek(file, offset, SEEK_SET)
- return data;
-}
-
-FILE * iof_get_file (iof *F)
-{
- if (F->flags & IOF_FILE)
- return iof_file_get_file(F->iofile);
- if (F->flags & IOF_FILE_HANDLE)
- return F->file;
- return NULL;
-}
-
-const char * iof_status_kind (iof_status status)
-{
- switch (status)
- {
- case IOFEOF:
- return "IOFEOF";
- case IOFERR:
- return "IOFERR";
- case IOFEMPTY:
- return "IOFEMPTY";
- case IOFFULL:
- return "IOFFULL";
- default:
- break;
- }
- return "(unknown)";
-}
-
-/* shared pseudofile */
-
-#define IOF_FILE_DEFAULTS 0
-
-iof_file * iof_file_new (FILE *file)
-{
- iof_file *iofile = (iof_file *)util_malloc(sizeof(iof_file));
- iof_file_set_fh(iofile, file);
- iofile->offset = NULL;
- iofile->size = 0;
- iofile->name = NULL;
- iofile->refcount = 0;
- iofile->flags = IOF_FILE_DEFAULTS|IOF_ALLOC;
- return iofile;
-}
-
-iof_file * iof_file_init (iof_file *iofile, FILE *file)
-{
- iof_file_set_fh(iofile, file);
- iofile->offset = NULL;
- iofile->size = 0;
- iofile->name = NULL;
- iofile->refcount = 0;
- iofile->flags = IOF_FILE_DEFAULTS;
- return iofile;
-}
-
-iof_file * iof_file_rdata (const void *data, size_t size)
-{
- iof_file *iofile = (iof_file *)util_malloc(sizeof(iof_file));
- iofile->rbuf = iofile->rpos = (const uint8_t *)data;
- iofile->rend = iofile->rbuf + size;
- iofile->offset = NULL;
- iofile->size = 0;
- iofile->name = NULL;
- iofile->refcount = 0;
- iofile->flags = IOF_FILE_DEFAULTS|IOF_ALLOC|IOF_DATA;
- return iofile;
-}
-
-iof_file * iof_file_rdata_init (iof_file *iofile, const void *data, size_t size)
-{
- iofile->rbuf = iofile->rpos = (const uint8_t *)data;
- iofile->rend = iofile->rbuf + size;
- iofile->offset = NULL;
- iofile->size = 0; // lets keep it consequently set to zero (only for user disposition)
- iofile->name = NULL;
- iofile->refcount = 0;
- iofile->flags = IOF_FILE_DEFAULTS|IOF_DATA;
- return iofile;
-}
-
-iof_file * iof_file_wdata (void *data, size_t size)
-{
- return iof_file_rdata((const void *)data, size);
-}
-
-iof_file * iof_file_wdata_init (iof_file *iofile, void *data, size_t size)
-{
- return iof_file_rdata_init(iofile, (const void *)data, size);
-}
-
-/* typical uses so far */
-
-iof_file * iof_file_reader_from_file_handle (iof_file *iofile, const char *filename, FILE *file, int preload, int closefile)
-{
- uint8_t *data;
- size_t size;
-
- if (preload)
- {
- if ((data = iof_copy_file_handle_data(file, &size)) == NULL)
- {
- if (closefile) // callers expect close also on failure
- fclose(file);
- return NULL;
- }
- if (iofile == NULL)
- iofile = iof_file_rdata(data, size);
- else
- iof_file_rdata_init(iofile, data, size);
- iofile->flags |= IOF_BUFFER_ALLOC;
- if (closefile)
- fclose(file);
- }
- else
- {
- if (iofile == NULL)
- iofile = iof_file_new(file);
- else
- iof_file_init(iofile, file);
- if (closefile)
- iofile->flags |= IOF_CLOSE_FILE;
- }
- if (filename != NULL)
- iof_file_set_name(iofile, filename);
- return iofile;
-}
-
-iof_file * iof_file_reader_from_file (iof_file *iofile, const char *filename, int preload)
-{
- FILE *file;
- if ((file = fopen(filename, "rb")) == NULL)
- return NULL;
- return iof_file_reader_from_file_handle(iofile, filename, file, preload, 1); // takes care to fclose() on failure
-}
-
-iof_file * iof_file_reader_from_data (iof_file *iofile, const void *data, size_t size, int preload, int freedata)
-{
- void *newdata;
- if (data == NULL)
- return NULL;
- if (preload)
- {
- newdata = iof_copy_data(data, size);
- if (iofile == NULL)
- iofile = iof_file_rdata(newdata, size);
- else
- iof_file_rdata_init(iofile, newdata, size);
- iofile->flags |= IOF_BUFFER_ALLOC;
- //if (freedata) // hardly makes sense... we can't free const void *
- // util_free((void *)data);
- }
- else
- {
- if (iofile == NULL)
- iofile = iof_file_rdata(data, size);
- else
- iof_file_rdata_init(iofile, data, size);
- if (freedata)
- iofile->flags |= IOF_BUFFER_ALLOC;
- }
- return iofile;
-}
-
-/*
-iof_file * iof_file_writer_from_file (iof_file *iofile, const char *filename)
-{
- FILE *file;
- if ((file = fopen(filename, "wb")) == NULL)
- return NULL;
- if (iofile == NULL)
- iofile = iof_file_new(file);
- else
- iof_file_init(iofile, file);
- iofile->flags |= IOF_CLOSE_FILE;
- iof_file_set_name(iofile, filename);
- return iofile;
-}
-*/
-
-/*
-Because of limited number of FILE* handles available, we may need to close/reopen a file handle
-when accessing it. In applications so far (fonts, images) we typically need the entire source
-to parse the file on object creation and to rewrite or reload the data on dump. All iof_file API
-functions assume that iofile has FILE* opened. Reopening it on every access (ftell, fseek, read/write)
-makes no sense. So if the caller invalidates iofile by closing and NULLing its file handle,
-it is also responsible to reopen when necessary.
-*/
-
-int iof_file_reclose_input (iof_file *iofile)
-{
- FILE *file;
- if (iofile->flags & IOF_DATA)
- return 0;
- if ((file = iof_file_get_fh(iofile)) == NULL)
- return 0;
- fclose(file);
- iof_file_set_fh(iofile, NULL);
- iofile->flags &= ~IOF_RECLOSE_FILE;
- iofile->flags |= IOF_REOPEN_FILE;
- return 1;
-}
-
-int iof_file_reopen_input (iof_file *iofile)
-{ // returns true if iofile readable
- FILE *file;
- const char *filename;
- if (iofile->flags & IOF_DATA)
- return 1;
- if ((file = iof_file_get_fh(iofile)) != NULL)
- return 1; // if present, assumed readable
- if ((filename = iofile->name) == NULL || (file = fopen(filename, "rb")) == NULL)
- return 0;
- iof_file_set_fh(iofile, file);
- iofile->flags &= ~IOF_REOPEN_FILE;
- iofile->flags |= IOF_RECLOSE_FILE;
- return 1;
-}
-
-/* freeing iof_file */
-
-void iof_file_free (iof_file *iofile)
-{
- FILE *file;
- if (iofile->flags & IOF_DATA)
- {
- if (iofile->flags & IOF_BUFFER_ALLOC)
- {
- iofile->flags &= ~IOF_BUFFER_ALLOC;
- if (iofile->buf != NULL)
- {
- util_free(iofile->buf);
- iofile->buf = iofile->pos = iofile->end = NULL;
- }
- }
- }
- else if ((file = iof_file_get_fh(iofile)) != NULL)
- {
- if (iofile->flags & IOF_CLOSE_FILE)
- fclose(file);
- iof_file_set_fh(iofile, NULL);
- }
- iof_file_set_name(iofile, NULL);
- if (iofile->flags & IOF_ALLOC)
- util_free(iofile);
-}
-
-/*
-An attempt to close iofile input keeping things safe. In bindings we sometimes we need to force
-closing the file handle, otherwise it is closed when garbage collector graciously calls destroyer.
-Eg. we are done with an object representing pdf/image/font, but we can't move/replace it, as the
-host language keeps the garbage that keeps a file handle. When we call fclose(), we also have to
-set the handle to NULL. In many places we assume, that if the iofile wraps FILE *, than the handle
-is operable (no NULL checks). To close the handle keeping iofile alive safe, we can silently convert
-it dummy IOF_DATA buffer.
-*/
-
-void iof_file_close_input (iof_file *iofile)
-{
- FILE *file;
- if (iofile->flags & IOF_DATA)
- {
- if (iofile->flags & IOF_BUFFER_ALLOC)
- {
- iofile->flags &= ~IOF_BUFFER_ALLOC;
- if (iofile->buf != NULL)
- {
- util_free(iofile->buf);
- //iofile->buf = iofile->pos = iofile->end = NULL;
- }
- }
- }
- else if ((file = iof_file_get_fh(iofile)) != NULL)
- {
- iof_file_set_fh(iofile, NULL);
- fclose(file);
- }
- iof_file_set_name(iofile, NULL);
- /* now make it a dummy string iofile */
- iofile->buf = iofile->pos = iofile->end = NULL;
- iofile->flags |= IOF_DATA;
-}
-
-/* set filename for reopen */
-
-void iof_file_set_name (iof_file *iofile, const char *name)
-{
- if (iofile->name != NULL)
- util_free(iofile->name);
- if (name != NULL)
- iofile->name = iof_copy_data(name, strlen(name) + 1);
- else
- iofile->name = NULL;
-}
-
-/* seek */
-
-int iof_file_seek (iof_file *iofile, long offset, int whence)
-{
- if (iofile->flags & IOF_DATA)
- {
- switch (whence)
- {
- case SEEK_SET:
- if (offset >= 0 && iofile->buf + offset <= iofile->end)
- {
- iofile->pos = iofile->buf + offset;
- return 0;
- }
- return -1;
- case SEEK_CUR:
- if ((offset >= 0 && iofile->pos + offset <= iofile->end) || (offset < 0 && iofile->pos + offset >= iofile->buf))
- {
- iofile->pos += offset;
- return 0;
- }
- return -1;
- case SEEK_END:
- if (offset <= 0 && iofile->end + offset >= iofile->buf)
- {
- iofile->pos = iofile->end + offset;
- return 0;
- }
- return -1;
- }
- return -1;
- }
- return fseek(iof_file_get_fh(iofile), offset, whence);
-}
-
-/* */
-
-long iof_file_tell (iof_file *iofile)
-{
- return (iofile->flags & IOF_DATA) ? (long)(iofile->pos - iofile->buf) : ftell(iof_file_get_fh(iofile));
-}
-
-size_t iof_file_size (iof_file *iofile)
-{
- long pos, size;
- FILE *file;
- if (iofile->flags & IOF_DATA)
- return (size_t)iof_space(iofile);
- file = iof_file_get_fh(iofile);
- pos = ftell(file);
- fseek(file, 0, SEEK_END);
- size = ftell(file);
- fseek(file, pos, SEEK_SET);
- return size;
-}
-
-int iof_file_eof (iof_file *iofile)
-{
- if (iofile->flags & IOF_DATA)
- return iofile->pos == iofile->end ? -1 : 0;
- return feof(iof_file_get_fh(iofile));
-}
-
-int iof_file_flush (iof_file *iofile)
-{
- if (iofile->flags & IOF_DATA)
- return 0;
- return fflush(iof_file_get_fh(iofile));
-}
-
-size_t iof_file_read (void *ptr, size_t size, size_t items, iof_file *iofile)
-{
- if (iofile->flags & IOF_DATA)
- {
- size_t bytes = size * items;
- if (bytes > (size_t)iof_left(iofile))
- bytes = (size_t)iof_left(iofile);
- memcpy(ptr, iofile->pos, bytes);
- iofile->pos += bytes;
- return bytes / size; // number of elements read
- }
- return fread(ptr, size, items, iof_file_get_fh(iofile));
-}
-
-static size_t iof_file_data_resizeto (iof_file *iofile, size_t space)
-{
- uint8_t *newbuf;
- size_t size;
- size = iof_size(iofile);
- if (iofile->flags & IOF_BUFFER_ALLOC)
- {
- newbuf = (uint8_t *)util_realloc(iofile->buf, space);
- }
- else
- {
- newbuf = (uint8_t *)util_malloc(space);
- if (size > 0)
- memcpy(newbuf, iofile->buf, size);
- iofile->flags |= IOF_BUFFER_ALLOC;
- }
- iofile->buf = newbuf;
- iofile->pos = newbuf + size;
- iofile->end = newbuf + space;
- return space - size;
-}
-
-#define iof_file_data_resize(iofile) iof_file_data_resizeto(iofile, iof_space(iofile) << 1)
-
-size_t iof_file_write (const void *ptr, size_t size, size_t items, iof_file *iofile)
-{
- if (iofile->flags & IOF_DATA)
- {
- size_t space, sizesofar, bytes;
- bytes = size * items;
- if (bytes > (size_t)iof_left(iofile))
- {
- if ((space = iof_space(iofile)) == 0) // allow iofile->buf/end initially NULL
- space = BUFSIZ;
- for (sizesofar = iof_size(iofile), space <<= 1; sizesofar + bytes > space; space <<= 1)
- ;
- if (iof_file_data_resizeto(iofile, space) == 0)
- return 0;
- }
- memcpy(iofile->pos, ptr, bytes);
- iofile->pos += bytes;
- return bytes / size;
- }
- return fwrite(ptr, size, items, iof_file_get_fh(iofile));
-}
-
-size_t iof_file_ensure (iof_file *iofile, size_t bytes)
-{
- if (iofile->flags & IOF_DATA)
- {
- size_t space, sizesofar, left;
- left = (size_t)iof_left(iofile);
- if (bytes > left)
- {
- if ((space = iof_space(iofile)) == 0) // allow iofile->buf/end initially NULL
- space = BUFSIZ;
- for (sizesofar = iof_size(iofile), space <<= 1; sizesofar + bytes > space; space <<= 1);
- return iof_file_data_resizeto(iofile, space);
- }
- return left;
- }
- return 0;
-}
-
-int iof_file_getc (iof_file *iofile)
-{
- if (iofile->flags & IOF_DATA)
- return iofile->pos < iofile->end ? *iofile->pos++ : IOFEOF;
- return fgetc(iof_file_get_fh(iofile));
-}
-
-int iof_file_putc (iof_file *iofile, int c)
-{
- if (iofile->flags & IOF_DATA)
- {
- if (iofile->pos >= iofile->end)
- if (iof_file_data_resize(iofile) == 0)
- return IOFEOF;
- *iofile->pos++ = (uint8_t)c;
- return c;
- }
- return fputc(c, iof_file_get_fh(iofile));
-}
-
-static int iof_file_sync (iof_file *iofile, size_t *offset)
-{
- if (iofile->offset != offset)
- {
- if (iofile->offset != NULL)
- *iofile->offset = iof_file_tell(iofile);
- iofile->offset = offset;
- if (offset) // let offset be NULL
- return iof_file_seek(iofile, (long)*offset, SEEK_SET);
- }
- return 0;
-}
-
-//#define iof_file_unsync(iofile, poffset) (void)((iofile)->offset == poffset && (((iofile)->offset = NULL), 0))
-#define iof_file_unsync(iofile, poffset) ((void)poffset, (iofile)->offset = NULL)
-
-/* iof seek */
-
-#define iof_reader_reset(I) ((I)->pos = (I)->end = (I)->buf)
-#define iof_reader_reseek_file(I, offset, whence) (fseek((I)->file, offset, whence) == 0 ? (iof_reader_reset(I), 0) : -1)
-#define iof_reader_reseek_iofile(I, offset, whence) (iof_file_seek((I)->iofile, offset, whence) == 0 ? (iof_reader_reset(I), 0) : -1)
-
-#define iof_writer_reset(O) ((O)->pos = (O)->buf)
-#define iof_writer_reseek_file(O, offset, whence) (iof_flush(O), (fseek((O)->file, offset, whence) == 0 ? (iof_writer_reset(O), 0) : -1))
-#define iof_writer_reseek_iofile(O, offset, whence) (iof_flush(O), (iof_file_seek((O)->iofile, offset, whence) == 0 ? (iof_writer_reset(O), 0) : -1))
-
-static int iof_reader_seek_data (iof *I, long offset, int whence)
-{
- switch (whence)
- {
- case SEEK_SET:
- if (offset >= 0 && I->buf + offset <= I->end)
- {
- I->pos = I->buf + offset;
- return 0;
- }
- return -1;
- case SEEK_CUR:
- if ((offset >= 0 && I->pos + offset <= I->end) || (offset < 0 && I->pos + offset >= I->buf))
- {
- I->pos += offset;
- return 0;
- }
- return -1;
- case SEEK_END:
- if (offset <= 0 && I->end + offset >= I->buf)
- {
- I->pos = I->end + offset;
- return 0;
- }
- return -1;
- }
- return -1;
-}
-
-static int iof_reader_seek_iofile (iof *I, long offset, int whence)
-{
- long fileoffset;
- switch (whence)
- {
- case SEEK_SET:
- fileoffset = iof_file_tell(I->iofile);
- if (offset <= fileoffset && offset >= fileoffset - iof_space(I))
- {
- I->pos = I->end - (fileoffset - offset);
- return 0;
- }
- return iof_reader_reseek_iofile(I, offset, SEEK_SET);
- case SEEK_CUR:
- if ((offset >= 0 && I->pos + offset <= I->end) || (offset < 0 && I->pos + offset >= I->buf))
- {
- I->pos += offset;
- return 0;
- }
- return iof_reader_reseek_iofile(I, offset, SEEK_CUR);
- case SEEK_END:
- return iof_reader_reseek_iofile(I, offset, SEEK_END); // can we do better?
- }
- return -1;
-}
-
-static int iof_reader_seek_file (iof *I, long offset, int whence)
-{
- long fileoffset;
- switch (whence)
- {
- case SEEK_SET:
- fileoffset = ftell(I->file);
- if (offset <= fileoffset && offset >= fileoffset - iof_space(I))
- {
- I->pos = I->end - (fileoffset - offset);
- return 0;
- }
- return iof_reader_reseek_file(I, offset, SEEK_SET);
- case SEEK_CUR:
- if ((offset >= 0 && I->pos + offset <= I->end) || (offset < 0 && I->pos + offset >= I->buf))
- {
- I->pos += offset;
- return 0;
- }
- return iof_reader_reseek_file(I, offset, SEEK_CUR);
- case SEEK_END:
- return iof_reader_reseek_file(I, offset, SEEK_END); // can we do better?
- }
- return -1;
-}
-
-int iof_reader_seek (iof *I, long offset, int whence)
-{
- I->flags &= ~IOF_STOPPED;
- if (I->flags & IOF_FILE)
- return iof_reader_seek_iofile(I, offset, whence);
- if (I->flags & IOF_FILE_HANDLE)
- return iof_reader_seek_file(I, offset, whence);
- if (I->flags & IOF_DATA)
- return iof_reader_seek_data(I, offset, whence);
- return -1;
-}
-
-int iof_reader_reseek (iof *I, long offset, int whence)
-{
- I->flags &= ~IOF_STOPPED;
- if (I->flags & IOF_FILE)
- return iof_reader_reseek_iofile(I, offset, whence);
- if (I->flags & IOF_FILE_HANDLE)
- return iof_reader_reseek_file(I, offset, whence);
- if (I->flags & IOF_DATA)
- return iof_reader_seek_data(I, offset, whence);
- return -1;
-}
-
-static int iof_writer_seek_data (iof *O, long offset, int whence)
-{
- /*
- fseek() allows to seek after the end of file. Seeking does not increase the output file.
- No byte is written before fwirte(). It seems to fill the gap with zeros. Until we really need that,
- no seeking out of bounds for writers.
- */
- O->flags &= ~IOF_STOPPED;
- return iof_reader_seek_data(O, offset, whence);
-}
-
-static int iof_writer_seek_iofile (iof *O, long offset, int whence)
-{
- long fileoffset;
- switch (whence)
- {
- case SEEK_SET:
- fileoffset = iof_file_tell(O->iofile);
- if (offset >= fileoffset && offset <= fileoffset + iof_space(O))
- {
- O->pos = O->buf + (offset - fileoffset);
- return 0;
- }
- return iof_writer_reseek_iofile(O, offset, SEEK_SET);
- case SEEK_CUR:
- if ((offset >=0 && O->pos + offset <= O->end) || (offset < 0 && O->pos + offset >= O->buf))
- {
- O->pos += offset;
- return 0;
- }
- return iof_writer_reseek_iofile(O, offset, SEEK_CUR);
- case SEEK_END:
- return iof_writer_reseek_iofile(O, offset, SEEK_END);
- }
- return -1;
-}
-
-static int iof_writer_seek_file (iof *O, long offset, int whence)
-{
- long fileoffset;
- switch (whence)
- {
- case SEEK_SET:
- fileoffset = ftell(O->file);
- if (offset >= fileoffset && offset <= fileoffset + iof_space(O))
- {
- O->pos = O->buf + (offset - fileoffset);
- return 0;
- }
- return iof_writer_reseek_file(O, offset, SEEK_SET);
- case SEEK_CUR:
- if ((offset >=0 && O->pos + offset <= O->end) || (offset < 0 && O->pos + offset >= O->buf))
- {
- O->pos += offset;
- return 0;
- }
- return iof_writer_reseek_file(O, offset, SEEK_CUR);
- case SEEK_END:
- return iof_writer_reseek_file(O, offset, SEEK_END);
- }
- return -1;
-}
-
-int iof_writer_seek (iof *I, long offset, int whence)
-{
- I->flags &= ~IOF_STOPPED;
- if (I->flags & IOF_FILE)
- return iof_writer_seek_iofile(I, offset, whence);
- if (I->flags & IOF_FILE_HANDLE)
- return iof_writer_seek_file(I, offset, whence);
- if (I->flags & IOF_DATA)
- return iof_writer_seek_data(I, offset, whence);
- return -1;
-}
-
-int iof_writer_reseek (iof *I, long offset, int whence)
-{
- I->flags &= ~IOF_STOPPED;
- if (I->flags & IOF_FILE)
- return iof_writer_reseek_iofile(I, offset, whence);
- if (I->flags & IOF_FILE_HANDLE)
- return iof_writer_reseek_file(I, offset, whence);
- if (I->flags & IOF_DATA)
- return iof_writer_seek_data(I, offset, whence);
- return -1;
-}
-
-int iof_seek (iof *F, long offset, int whence)
-{
- return (F->flags & IOF_WRITER) ? iof_writer_seek(F, offset, whence) : iof_reader_seek(F, offset, whence);
-}
-
-int iof_reseek (iof *F, long offset, int whence)
-{
- return (F->flags & IOF_WRITER) ? iof_writer_reseek(F, offset, whence) : iof_reader_reseek(F, offset, whence);
-}
-
-/* tell */
-
-long iof_reader_tell (iof *I)
-{
- if (I->flags & IOF_FILE)
- return iof_file_tell(I->iofile) - (long)iof_left(I);
- if (I->flags & IOF_FILE_HANDLE)
- return ftell(I->file) - (long)iof_left(I);
- //if (I->flags & IOF_DATA)
- return (long)iof_size(I);
-}
-
-long iof_writer_tell (iof *O)
-{
- if (O->flags & IOF_FILE)
- return iof_file_tell(O->iofile) + (long)iof_size(O);
- if (O->flags & IOF_FILE_HANDLE)
- return ftell(O->file) + (long)iof_size(O);
- //if (I->flags & IOF_DATA)
- return (long)iof_size(O);
-}
-
-long iof_tell (iof *I)
-{
- return (I->flags & IOF_WRITER) ? iof_writer_tell(I) : iof_reader_tell(I);
-}
-
-size_t iof_fsize (iof *I)
-{
- size_t pos, size;
- if (I->flags & IOF_FILE)
- return iof_file_size(I->iofile);
- if (I->flags & IOF_FILE_HANDLE)
- {
- pos = (size_t)ftell(I->file);
- fseek(I->file, 0, SEEK_END);
- size = (size_t)ftell(I->file);
- fseek(I->file, (long)pos, SEEK_SET);
- return size;
- }
- //if (I->flags & IOF_DATA)
- return (size_t)iof_space(I);
-}
-
-/* save reader tail */
-
-size_t iof_save_tail (iof *I)
-{
- size_t size, left;
- size = iof_size(I);
- left = iof_left(I);
- if (size >= left)
- memcpy(I->buf, I->pos, left);
- else
- memmove(I->buf, I->pos, left);
- return left;
-}
-
-size_t iof_input_save_tail (iof *I, size_t back)
-{
- size_t size;
- I->flags |= IOF_TAIL;
- I->pos -= back;
- size = iof_input(I);
- I->pos += back;
- I->flags &= ~IOF_TAIL;
- return size; // + back - back
-}
-
-/* read from file */
-
-/* iof free*/
-
-static size_t file_read (iof *I);
-static size_t file_load (iof *I);
-
-static size_t file_reader (iof *I, iof_mode mode)
-{
- switch (mode)
- {
- case IOFREAD:
- return file_read(I);
- case IOFLOAD:
- return file_load(I);
- case IOFCLOSE:
- iof_free(I);
- return 0;
- default:
- return 0;
- }
-}
-
-iof * iof_setup_file_handle_reader (iof *I, void *buffer, size_t space, FILE *f)
-{
- iof_setup_reader(I, buffer, space);
- iof_setup_file(I, f);
- I->more = file_reader;
- return I;
-}
-
-iof * iof_setup_file_reader (iof *I, void *buffer, size_t space, const char *filename)
-{
- FILE *f;
- if ((f = fopen(filename, "rb")) == NULL)
- return NULL;
- iof_setup_reader(I, buffer, space);
- iof_setup_file(I, f);
- I->flags |= IOF_CLOSE_FILE;
- I->more = file_reader;
- return I;
-}
-
-/* write to file */
-
-static size_t file_write (iof *O, int flush);
-
-static size_t file_writer (iof *O, iof_mode mode)
-{
- switch (mode)
- {
- case IOFWRITE:
- return file_write(O, 0);
- case IOFFLUSH:
- return file_write(O, 1);
- case IOFCLOSE:
- file_write(O, 1);
- iof_free(O);
- return 0;
- default:
- return 0;
- }
-}
-
-iof * iof_setup_file_handle_writer (iof *O, void *buffer, size_t space, FILE *f)
-{
- iof_setup_writer(O, buffer, space);
- iof_setup_file(O, f);
- O->more = file_writer;
- return O;
-}
-
-iof * iof_setup_file_writer (iof *O, void *buffer, size_t space, const char *filename)
-{
- FILE *f;
- if ((f = fopen(filename, "wb")) == NULL)
- return NULL;
- iof_setup_writer(O, buffer, space);
- iof_setup_file(O, f);
- O->flags |= IOF_CLOSE_FILE;
- O->more = file_writer;
- return O;
-}
-
-/* a dedicated handler for stdout/stderr */
-
-static size_t stdout_writer (iof *O, iof_mode mode)
-{
- switch(mode)
- {
- case IOFWRITE:
- {
- fwrite(O->buf, sizeof(uint8_t), iof_size(O), stdout);
- O->pos = O->buf;
- return O->space;
- }
- case IOFCLOSE:
- case IOFFLUSH:
- {
- fwrite(O->buf, sizeof(uint8_t), iof_size(O), stdout);
- fflush(stdout);
- O->pos = O->buf;
- return 0;
- }
- default:
- break;
- }
- return 0;
-}
-
-static size_t stderr_writer (iof *O, iof_mode mode)
-{
- switch(mode)
- {
- case IOFWRITE:
- {
- fwrite(O->buf, sizeof(uint8_t), iof_size(O), stderr);
- O->pos = O->buf;
- return O->space;
- }
- case IOFCLOSE:
- case IOFFLUSH:
- {
- fwrite(O->buf, sizeof(uint8_t), iof_size(O), stderr);
- fflush(stderr);
- O->pos = O->buf;
- return 0;
- }
- default:
- break;
- }
- return 0;
-}
-
-static uint8_t iof_stdout_buffer[BUFSIZ];
-iof iof_stdout = IOF_WRITER_INIT(stdout_writer, NULL, iof_stdout_buffer, BUFSIZ, 0);
-
-static uint8_t iof_stderr_buffer[BUFSIZ];
-iof iof_stderr = IOF_WRITER_INIT(stderr_writer, NULL, iof_stderr_buffer, BUFSIZ, 0);
-
-/* read from somewhere */
-
-iof * iof_reader (iof *I, void *link, iof_handler reader, const void *m, size_t bytes)
-{
- I->space = 0;
- I->link = link;
- I->more = reader;
- I->flags = 0;
- I->refcount = 0;
- if (m != NULL)
- {
- I->rbuf = I->rpos = (const uint8_t *)m;
- I->rend = (const uint8_t *)m + bytes;
- return I;
- }
- return NULL;
-}
-
-iof * iof_string_reader (iof *I, const void *s, size_t bytes)
-{
- I->space = 0;
- I->link = NULL;
- I->more = NULL;
- I->flags = 0; // iof_string() sets IOF_DATA
- I->refcount = 0;
- if (s != NULL)
- return iof_string(I, s, bytes);
- return NULL;
-}
-
-/* write somewhere */
-
-iof * iof_writer (iof *O, void *link, iof_handler writer, void *m, size_t bytes)
-{
- O->space = 0;
- O->link = link;
- O->more = writer;
- O->flags = 0;
- O->refcount = 0;
- if (m != NULL && bytes > 0)
- {
- O->buf = O->pos = (uint8_t *)m;
- O->end = (uint8_t *)m + bytes;
- return O;
- }
- // return iof_null(O);
- return NULL;
-}
-
-/* write to growing bytes buffer */
-
-static size_t iof_mem_handler (iof *O, iof_mode mode)
-{
- switch(mode)
- {
- case IOFWRITE:
- return iof_resize_buffer(O);
- case IOFCLOSE:
- iof_free(O);
- return 0;
- default:
- return 0;
- }
-}
-
-iof * iof_setup_buffer (iof *O, void *buffer, size_t space)
-{
- iof_setup_writer(O, buffer, space);
- O->link = NULL;
- O->flags |= IOF_DATA;
- O->more = iof_mem_handler;
- return O;
-}
-
-iof * iof_setup_buffermin (iof *O, void *buffer, size_t space, size_t min)
-{
- iof_setup_buffer(O, buffer, space);
- if (space < min) // allocate min to avoid further rewriting
- {
- O->buf = O->pos = (uint8_t *)util_malloc(min);
- O->flags |= IOF_BUFFER_ALLOC;
- O->end = O->buf + min;
- }
- return O;
-}
-
-iof * iof_buffer_create (size_t space)
-{
- uint8_t *buffer;
- iof *O;
- O = (iof *)util_malloc(space);
- buffer = (uint8_t *)(O + 1);
- iof_setup_buffer(O, buffer, space);
- O->flags |= IOF_ALLOC;
- return O;
-}
-
-/* set/get */
-
-int iof_getc (iof *I)
-{
- if (iof_readable(I))
- return *I->pos++;
- return IOFEOF;
-}
-
-int iof_putc (iof *O, int u)
-{
- if (iof_writable(O))
- {
- iof_set(O, u);
- return (uint8_t)u;
- }
- return IOFFULL;
-}
-
-size_t iof_skip (iof *I, size_t bytes)
-{
- while (bytes)
- {
- if (iof_readable(I))
- ++I->pos;
- else
- break;
- --bytes;
- }
- return bytes;
-}
-
-/* from iof to iof */
-
-iof_status iof_pass (iof *I, iof *O)
-{
- size_t leftin, leftout;
- if ((leftin = iof_left(I)) == 0)
- leftin = iof_input(I);
- while (leftin)
- {
- if ((leftout = iof_left(O)) == 0)
- if ((leftout = iof_output(O)) == 0)
- return IOFFULL;
- while (leftin > leftout)
- {
- memcpy(O->pos, I->pos, leftout);
- I->pos += leftout;
- O->pos = O->end; /* eq. += leftout */
- leftin -= leftout;
- if ((leftout = iof_output(O)) == 0)
- return IOFFULL;
- }
- if (leftin)
- {
- memcpy(O->pos, I->pos, leftin);
- I->pos = I->end; /* eq. += leftin */
- O->pos += leftin;
- }
- leftin = iof_input(I);
- }
- return IOFEOF;
-}
-
-/* read n-bytes */
-
-size_t iof_read (iof *I, void *to, size_t size)
-{
- size_t leftin, done = 0;
- char *s = (char *)to;
-
- if ((leftin = iof_left(I)) == 0)
- if ((leftin = iof_input(I)) == 0)
- return done;
- while (size > leftin)
- {
- memcpy(s, I->pos, leftin * sizeof(uint8_t));
- size -= leftin;
- done += leftin;
- s += leftin;
- I->pos = I->end;
- if ((leftin = iof_input(I)) == 0)
- return done;
- }
- if (size)
- {
- memcpy(s, I->pos, size * sizeof(uint8_t));
- I->pos += size;
- done += size;
- }
- return done;
-}
-
-/* rewrite FILE content (use fseek if needed) */
-
-size_t iof_write_file_handle (iof *O, FILE *file)
-{
- size_t leftout, size, readout;
- if ((leftout = iof_left(O)) == 0)
- if ((leftout = iof_output(O)) == 0)
- return 0;
- size = 0;
- do {
- readout = fread(O->pos, 1, leftout, file);
- O->pos += readout;
- size += readout;
- } while(readout == leftout && (leftout = iof_output(O)) > 0);
- return size;
-}
-
-size_t iof_write_file (iof *O, const char *filename)
-{
- FILE *file;
- size_t size;
- if ((file = fopen(filename, "rb")) == NULL)
- return 0;
- size = iof_write_file_handle(O, file);
- fclose(file);
- return size;
-}
-
-size_t iof_write_iofile (iof *O, iof_file *iofile, int savepos)
-{
- long offset;
- size_t size;
- FILE *file;
- if (iofile->flags & IOF_DATA)
- return iof_write(O, iofile->pos, (size_t)(iofile->end - iofile->pos));
- file = iof_file_get_fh(iofile);
- if (savepos)
- {
- offset = ftell(file);
- size = iof_write_file_handle(O, file);
- fseek(file, offset, SEEK_SET);
- return size;
- }
- return iof_write_file_handle(O, file);
-}
-
-/* write n-bytes */
-
-size_t iof_write (iof *O, const void *data, size_t size)
-{
- size_t leftout, done = 0;
- const char *s = (const char *)data;
- if ((leftout = iof_left(O)) == 0)
- if ((leftout = iof_output(O)) == 0)
- return done;
- while (size > leftout)
- {
- memcpy(O->pos, s, leftout * sizeof(uint8_t));
- size -= leftout;
- done += leftout;
- s += leftout;
- O->pos = O->end;
- if ((leftout = iof_output(O)) == 0)
- return done;
- }
- if (size)
- {
- memcpy(O->pos, s, size * sizeof(uint8_t));
- O->pos += size;
- done += size;
- }
- return done;
-}
-
-/* write '\0'-terminated string */
-
-iof_status iof_puts (iof *O, const void *data)
-{
- const char *s = (const char *)data;
- while (*s)
- {
- if (iof_writable(O))
- iof_set(O, *s++);
- else
- return IOFFULL;
- }
- return IOFEOF; // ?
-}
-
-size_t iof_put_string (iof *O, const void *data)
-{
- const char *p, *s = (const char *)data;
- for (p = s; *p != '\0' && iof_writable(O); iof_set(O, *p++));
- return p - s;
-}
-
-/* write byte n-times */
-
-/*
-iof_status iof_repc (iof *O, char c, size_t bytes)
-{
- while (bytes)
- {
- if (iof_writable(O))
- iof_set(O, c);
- else
- return IOFFULL;
- --bytes;
- }
- return IOFEOF; // ?
-}
-*/
-
-size_t iof_repc (iof *O, char c, size_t bytes)
-{
- size_t leftout, todo = bytes;
- if ((leftout = iof_left(O)) == 0)
- if ((leftout = iof_output(O)) == 0)
- return 0;
- while (bytes > leftout)
- {
- memset(O->pos, c, leftout);
- bytes -= leftout;
- O->pos = O->end;
- if ((leftout = iof_output(O)) == 0)
- return todo - bytes;
- }
- if (bytes)
- {
- memset(O->pos, c, bytes);
- O->pos += bytes;
- }
- return todo;
-}
-
-/* putfs */
-
-#define IOF_FMT_SIZE 1024
-
-size_t iof_putfs (iof *O, const char *format, ...)
-{
- static char buffer[IOF_FMT_SIZE];
- va_list args;
- va_start(args, format);
- if (vsnprintf(buffer, IOF_FMT_SIZE, format, args) > 0)
- {
- va_end(args);
- return iof_put_string(O, buffer);
- }
- else
- {
- va_end(args);
- return iof_write(O, buffer, IOF_FMT_SIZE);
- }
-}
-
-/* integer from iof; return 1 on success, 0 otherwise */
-
-int iof_get_int32 (iof *I, int32_t *number)
-{
- int sign, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_get_slong (iof *I, long *number)
-{
- int sign, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_get_int64 (iof *I, int64_t *number)
-{
- int sign, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_get_uint32 (iof *I, uint32_t *number)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- return 1;
-}
-
-int iof_get_ulong (iof *I, unsigned long *number)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- return 1;
-}
-
-int iof_get_usize (iof *I, size_t *number)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- return 1;
-}
-
-int iof_get_uint64 (iof *I, uint64_t *number)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_integer(I, c, *number);
- return 1;
-}
-
-int iof_get_int32_radix (iof *I, int32_t *number, int radix)
-{
- int sign, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- if (sign) *number = -*number;
- return 1;
-
-}
-
-int iof_get_slong_radix (iof *I, long *number, int radix)
-{
- int sign, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_get_int64_radix (iof *I, int64_t *number, int radix)
-{
- int sign, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_get_uint32_radix (iof *I, uint32_t *number, int radix)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- return 1;
-}
-
-int iof_get_ulong_radix (iof *I, unsigned long *number, int radix)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- return 1;
-}
-
-int iof_get_usize_radix (iof *I, size_t *number, int radix)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- return 1;
-}
-
-int iof_get_uint64_radix (iof *I, uint64_t *number, int radix)
-{
- int c = iof_char(I);
- if (!base10_digit(c)) return 0;
- iof_read_radix(I, c, *number, radix);
- return 1;
-}
-
-/* get roman to uint16_t, cf. roman_to_uint16() from utilnumber.c*/
-
-/* todo: some trick in place of this macro horror? */
-
-#define roman1000(c) (c == 'M' || c == 'm')
-#define roman500(c) (c == 'D' || c == 'd')
-#define roman100(c) (c == 'C' || c == 'c')
-#define roman50(c) (c == 'L' || c == 'l')
-#define roman10(c) (c == 'X' || c == 'x')
-#define roman5(c) (c == 'V' || c == 'v')
-#define roman1(c) (c == 'I' || c == 'i')
-
-#define roman100s(I, c) \
- (roman100(c) ? (100 + ((c = iof_next(I), roman100(c)) ? (100 + ((c = iof_next(I), roman100(c)) ? (c = iof_next(I), 100) : 0)) : 0)) : 0)
-#define roman10s(I, c) \
- (roman10(c) ? (10 + ((c = iof_next(I), roman10(c)) ? (10 + ((c = iof_next(I), roman10(c)) ? (c = iof_next(I), 10) : 0)) : 0)) : 0)
-#define roman1s(I, c) \
- (roman1(c) ? (1 + ((c = iof_next(I), roman1(c)) ? (1 + ((c = iof_next(I), roman1(c)) ? (c = iof_next(I), 1) : 0)) : 0)) : 0)
-
-int iof_get_roman (iof *I, uint16_t *number)
-{
- int c;
- /* M */
- for (*number = 0, c = iof_char(I); roman1000(c); *number += 1000, c = iof_next(I));
- /* D C */
- if (roman500(c))
- {
- c = iof_next(I);
- *number += 500 + roman100s(I, c);
- }
- else if (roman100(c))
- {
- c = iof_next(I);
- if (roman1000(c))
- {
- c = iof_next(I);
- *number += 900;
- }
- else if (roman500(c))
- {
- c = iof_next(I);
- *number += 400;
- }
- else
- *number += 100 + roman100s(I, c);
- }
- /* L X */
- if (roman50(c))
- {
- c = iof_next(I);
- *number += 50 + roman10s(I, c);
- }
- else if (roman10(c))
- {
- c = iof_next(I);
- if (roman100(c))
- {
- c = iof_next(I);
- *number += 90;
- }
- else if (roman50(c))
- {
- c = iof_next(I);
- *number += 40;
- }
- else
- *number += 10 + roman10s(I, c);
- }
- /* V I */
- if (roman5(c))
- {
- c = iof_next(I);
- *number += 5 + roman1s(I, c);
- }
- else if (roman1(c))
- {
- c = iof_next(I);
- if (roman10(c))
- {
- c = iof_next(I);
- *number += 9;
- }
- else if (roman5(c))
- {
- c = iof_next(I);
- *number += 4;
- }
- else
- *number += 1 + roman1s(I, c);
- }
- return 1;
-}
-
-/* double from iof; return 1 on success */
-
-int iof_get_double (iof *I, double *number) // cf. string_to_double()
-{
- int sign, exponent10, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- iof_scan_decimal(I, c, *number);
- if (c == '.')
- {
- c = iof_next(I);
- iof_scan_fraction(I, c, *number, exponent10);
- }
- else
- exponent10 = 0;
- if (c == 'e' || c == 'E')
- {
- c = iof_next(I);
- iof_scan_exponent10(I, c, exponent10);
- }
- double_exp10(*number, exponent10);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_get_float (iof *I, float *number) // cf. string_to_float()
-{
- int sign, exponent10, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- iof_scan_decimal(I, c, *number);
- if (c == '.')
- {
- c = iof_next(I);
- iof_scan_fraction(I, c, *number, exponent10);
- }
- else
- exponent10 = 0;
- if (c == 'e' || c == 'E')
- {
- c = iof_next(I);
- iof_scan_exponent10(I, c, exponent10);
- }
- float_exp10(*number, exponent10);
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_conv_double (iof *I, double *number) // cf. convert_to_double()
-{
- int sign, exponent10, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- iof_scan_decimal(I, c, *number);
- if (c == '.' || c == ',')
- {
- c = iof_next(I);
- iof_scan_fraction(I, c, *number, exponent10);
- if (exponent10 < 0)
- double_negative_exp10(*number, exponent10);
- }
- if (sign) *number = -*number;
- return 1;
-}
-
-int iof_conv_float (iof *I, float *number) // cf. convert_to_float()
-{
- int sign, exponent10, c = iof_char(I);
- iof_scan_sign(I, c, sign);
- iof_scan_decimal(I, c, *number);
- if (c == '.' || c == ',')
- {
- c = iof_next(I);
- iof_scan_fraction(I, c, *number, exponent10);
- if (exponent10 < 0)
- float_negative_exp10(*number, exponent10);
- }
- if (sign) *number = -*number;
- return 1;
-}
-
-/* integer to iof; return a number of written bytes */
-
-size_t iof_put_int32 (iof *O, int32_t number)
-{
- const char *s;
- size_t size;
- s = int32_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_slong (iof *O, long number)
-{
- const char *s;
- size_t size;
- s = slong_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_int64 (iof *O, int64_t number)
-{
- const char *s;
- size_t size;
- s = int64_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_uint32 (iof *O, uint32_t number)
-{
- const char *s;
- size_t size;
- s = uint32_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_ulong (iof *O, unsigned long number)
-{
- const char *s;
- size_t size;
- s = ulong_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_usize (iof *O, size_t number)
-{
- const char *s;
- size_t size;
- s = usize_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_uint64 (iof *O, uint64_t number)
-{
- const char *s;
- size_t size;
- s = uint64_to_string(number, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_int32_radix (iof *O, int32_t number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = int32_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_slong_radix (iof *O, long number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = slong_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_int64_radix (iof *O, int64_t number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = int64_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_uint32_radix (iof *O, uint32_t number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = uint32_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_ulong_radix (iof *O, unsigned long number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = ulong_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_usize_radix (iof *O, size_t number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = usize_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_uint64_radix (iof *O, uint64_t number, int radix, int uc)
-{
- const char *s;
- size_t size;
- s = uint64_to_radix(number, radix, uc, &size);
- return iof_write(O, s, size);
-}
-
-/* roman numerals */
-
-size_t iof_put_roman (iof *O, uint16_t number, int uc)
-{
- const char *s;
- size_t size;
- s = uint16_to_roman(number, uc, &size);
- return iof_write(O, s, size);
-}
-
-/* double/float to iof; return the number of written bytes */
-
-size_t iof_put_double (iof *O, double number, int digits)
-{
- const char *s;
- size_t size;
- s = double_to_string(number, digits, &size);
- return iof_write(O, s, size);
-}
-
-size_t iof_put_float (iof *O, float number, int digits)
-{
- const char *s;
- size_t size;
- s = float_to_string(number, digits, &size);
- return iof_write(O, s, size);
-}
-
-/* iof to binary integer; pretty common */
-
-int iof_get_be_uint2 (iof *I, uint32_t *pnumber)
-{
- int c1, c2;
- if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0)
- return 0;
- *pnumber = (c1<<8)|c2;
- return 1;
-}
-
-int iof_get_be_uint3 (iof *I, uint32_t *pnumber)
-{
- int c1, c2, c3;
- if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0)
- return 0;
- *pnumber = (c1<<16)|(c2<<8)|c3;
- return 1;
-}
-
-int iof_get_be_uint4 (iof *I, uint32_t *pnumber)
-{
- int c1, c2, c3, c4;
- if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0 || (c4 = iof_get(I)) < 0)
- return 0;
- *pnumber = (c1<<24)|(c2<<16)|(c3<<8)|c4;
- return 1;
-}
-
-int iof_get_le_uint2 (iof *I, uint32_t *pnumber)
-{
- int c1, c2;
- if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0)
- return 0;
- *pnumber = (c2<<8)|c1;
- return 1;
-}
-
-int iof_get_le_uint3 (iof *I, uint32_t *pnumber)
-{
- int c1, c2, c3;
- if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0)
- return 0;
- *pnumber = (c3<<16)|(c2<<8)|c1;
- return 1;
-}
-
-int iof_get_le_uint4 (iof *I, uint32_t *pnumber)
-{
- int c1, c2, c3, c4;
- if ((c1 = iof_get(I)) < 0 || (c2 = iof_get(I)) < 0 || (c3 = iof_get(I)) < 0 || (c4 = iof_get(I)) < 0)
- return 0;
- *pnumber = (c4<<24)|(c3<<16)|(c2<<8)|c1;
- return 1;
-}
-
-/* iof input data */
-
-uint8_t * iof_file_input_data (iof_file *iofile, size_t *psize, int *isnew)
-{
- uint8_t *data;
- if (iofile->flags & IOF_DATA)
- {
- data = iofile->buf;
- *psize = iofile->end - iofile->buf;
- *isnew = 0;
- return data;
- }
- if (iof_file_reopen(iofile))
- {
- data = iof_copy_file_handle_data(iof_file_get_fh(iofile), psize);
- *isnew = 1;
- iof_file_reclose(iofile);
- return data;
- }
- return NULL;
-}
-
-/*
-uint8_t * iof_file_reader_data (iof_file *iofile, size_t *size)
-{
- uint8_t *data;
- if (!(iofile->flags & IOF_DATA) || iofile->pos == NULL || (*size = (size_t)iof_left(iofile)) == 0)
- return NULL;
- if (iofile->flags & IOF_BUFFER_ALLOC)
- {
- data = iofile->buf; // iofile->pos; // returned must be freeable, makes sense when ->buf == ->pos
- iofile->flags &= ~IOF_BUFFER_ALLOC;
- iofile->buf = iofile->pos = iofile->end = NULL;
- return data;
- }
- data = (uint8_t *)util_malloc(*size);
- memcpy(data, iofile->buf, *size);
- return data;
-}
-
-uint8_t * iof_file_writer_data (iof_file *iofile, size_t *size)
-{
- uint8_t *data;
- if (!(iofile->flags & IOF_DATA) || iofile->buf == NULL || (*size = (size_t)iof_size(iofile)) == 0)
- return NULL;
- if (iofile->flags & IOF_BUFFER_ALLOC)
- {
- iofile->flags &= ~IOF_BUFFER_ALLOC;
- data = iofile->buf;
- iofile->buf = iofile->pos = iofile->end = NULL;
- return data;
- }
- data = (uint8_t *)util_malloc(*size);
- memcpy(data, iofile->buf, *size);
- return data;
-}
-*/
-
-uint8_t * iof_reader_data (iof *I, size_t *psize)
-{
- uint8_t *data;
- *psize = (size_t)iof_left(I);
- if (I->flags & IOF_BUFFER_ALLOC)
- {
- data = I->buf; // actually I->pos, but we have to return something freeable
- I->flags &= ~IOF_BUFFER_ALLOC;
- I->buf = NULL;
- }
- else
- {
- data = util_malloc(*psize);
- memcpy(data, I->pos, *psize);
- }
- iof_close(I);
- return data;
-}
-
-
-uint8_t * iof_writer_data (iof *O, size_t *psize)
-{
- uint8_t *data;
- *psize = (size_t)iof_size(O);
- if (O->flags & IOF_BUFFER_ALLOC)
- {
- data = O->buf;
- O->flags &= ~IOF_BUFFER_ALLOC;
- O->buf = NULL;
- }
- else
- {
- data = util_malloc(*psize);
- memcpy(data, O->buf, *psize);
- }
- iof_close(O);
- return data;
-}
-
-size_t iof_reader_to_file_handle (iof *I, FILE *file)
-{
- size_t size;
- for (size = 0; iof_readable(I); I->pos = I->end)
- size += fwrite(I->buf, sizeof(uint8_t), iof_left(I), file);
- return size;
-}
-
-size_t iof_reader_to_file (iof *I, const char *filename)
-{
- FILE *file;
- size_t size;
- if ((file = fopen(filename, "wb")) == NULL)
- return 0;
- for (size = 0; iof_readable(I); I->pos = I->end)
- size += fwrite(I->buf, sizeof(uint8_t), iof_left(I), file);
- fclose(file);
- return size;
-}
-
-/* debug */
-
-size_t iof_data_to_file (const void *data, size_t size, const char *filename)
-{
- FILE *fh;
- if ((fh = fopen(filename, "wb")) == NULL)
- return 0;
- // size = fwrite(data, size, sizeof(uint8_t), fh); // WRONG, this always returns 1, as fwrite returns the number of elements successfully written out
- size = fwrite(data, sizeof(uint8_t), size, fh);
- fclose(fh);
- return size;
-}
-
-size_t iof_result_to_file_handle (iof *F, FILE *file)
-{
- const void *data;
- size_t size;
- data = iof_result(F, size);
- return iof_data_to_file_handle(data, size, file);
-}
-
-size_t iof_result_to_file (iof *F, const char *filename)
-{
- const void *data;
- size_t size;
- data = iof_result(F, size);
- return iof_data_to_file(data, size, filename);
-}
-
-void iof_debug (iof *I, const char *filename)
-{
- FILE *file = fopen(filename, "wb");
- if (file != NULL)
- {
- fprintf(file, ">>> buf %p <<<\n", I->buf);
- fwrite(I->buf, sizeof(uint8_t), iof_size(I), file);
- fprintf(file, "\n>>> pos %p (%ld) <<<\n", I->pos, (long)iof_size(I));
- fwrite(I->pos, sizeof(uint8_t), iof_left(I), file);
- fprintf(file, "\n>>> end %p (%ld) <<<\n", I->end, (long)iof_left(I));
- fwrite(I->end, sizeof(uint8_t), I->space - iof_space(I), file);
- fprintf(file, "\n>>> end of buffer %p (%ld) <<<\n", I->buf + I->space, (long)(I->buf + I->space - I->end));
- fclose(file);
- }
-}
-
-/* common filters api */
-
-/* sizes of filter states on x64
-size of iof_filter: 640 (no longer used; sizeof(iof) + sizeof larger state)
-size of file_state: 16
-size of stream_state: 16
-size of flate_state: 104
-size of lzw_state: 56
-size of predictor_state: 104
-size of basexx_state: 48
-size of basexx_state: 48
-size of basexx_state: 48
-size of eexec_state: 40
-size of runlength_state: 24
-size of rc4_state: 24
-size of aes_state: 72
-size of img_state: 576
-size of img: 496
-*/
-
-typedef struct iof_heap iof_heap;
-
-typedef struct {
- iof_heap *heap;
-} iof_heap_ghost;
-
-
-struct iof_heap {
- union { uint8_t *data; iof_heap_ghost *gdata; }; // union instead of casts (ARM)
- union { uint8_t *pos; iof_heap_ghost *gpos; };
- size_t size, space;
- iof_heap *next, *prev;
- int refcount;
- uint8_t dummy[4]; // pad to 8N bytes
-};
-
-/*
-We use hidden heap pointer for every allocated buffer, so heap->data should be kept properly aligned.
-Dummy 4-bytes pad doesn't really matter (the pad is there anyway), but iof_heap_take() must pad the
-requested size.
-*/
-
-static iof_heap * iof_buffers_heap = NULL;
-static iof_heap * iof_filters_heap = NULL;
-
-#define IOF_HEAP_FILTERS_COUNT 4
-#define IOF_BUFFER_SIZE 262144 // (1<<18)
-#define IOF_FILTER_SIZE 1024
-// sizeof(iof_filter) on x64 is now 640, img_state 576, img 496, others 16-104
-#define IOF_BUFFER_HEAP_SIZE (IOF_HEAP_FILTERS_COUNT * (IOF_BUFFER_SIZE + sizeof(iof_heap_ghost)))
-#define IOF_FILTER_HEAP_SIZE (IOF_HEAP_FILTERS_COUNT * (IOF_FILTER_SIZE + sizeof(iof_heap_ghost)))
-
-static iof_heap * iof_heap_new (size_t space)
-{
- iof_heap *iofheap;
- iofheap = (iof_heap *)util_malloc(sizeof(iof_heap) + space);
- iofheap->gdata = iofheap->gpos = (iof_heap_ghost *)(iofheap + 1);
- iofheap->size = iofheap->space = space;
- iofheap->next = NULL;
- iofheap->prev = NULL;
- iofheap->refcount = 0;
- return iofheap;
-}
-
-#define iof_heap_free(iofheap) util_free(iofheap)
-
-void iof_filters_init (void)
-{
- if (iof_buffers_heap == NULL)
- iof_buffers_heap = iof_heap_new(IOF_BUFFER_HEAP_SIZE);
- if (iof_filters_heap == NULL)
- iof_filters_heap = iof_heap_new(IOF_FILTER_HEAP_SIZE);
-}
-
-void iof_filters_free (void)
-{
- iof_heap *heap, *next;
- for (heap = iof_buffers_heap; heap != NULL; heap = next)
- {
- next = heap->next;
- if (heap->refcount != 0)
- loggerf("not closed iof filters left (%d)", heap->refcount);
- if (next != NULL)
- loggerf("iof filters heap left");
- iof_heap_free(heap);
- }
- iof_buffers_heap = NULL;
- for (heap = iof_filters_heap; heap != NULL; heap = next)
- {
- next = heap->next;
- if (heap->refcount != 0)
- loggerf("not closed iof buffers left (%d)", heap->refcount);
- if (next != NULL)
- loggerf("iof buffers heap left");
- iof_heap_free(heap);
- }
- iof_filters_heap = NULL;
-}
-
-#define iof_heap_get(hp, ghost, data, siz) \
- (ghost = (hp)->gpos, ghost->heap = (hp), data = (uint8_t *)(ghost + 1), (hp)->pos += siz, (hp)->size -= siz, ++(hp)->refcount)
-
-static void * iof_heap_take (iof_heap **pheap, size_t size)
-{
- uint8_t *data;
- iof_heap_ghost *ghost;
- iof_heap *heap, *newheap, *next;
-
- heap = *pheap;
- if (size & 7)
- size += 8 - (size & 7); // pad to 8N bytes so that (heap->pos + size) remains properly aligned
- size += sizeof(iof_heap_ghost);
- if (heap->size >= size)
- { /* take cheap mem from main heap */
- iof_heap_get(heap, ghost, data, size);
- return data;
- }
- if (size <= (heap->space >> 1))
- { /* make new cheap heap, make it front */
- *pheap = newheap = iof_heap_new(heap->space);
- newheap->next = heap;
- heap->prev = newheap;
- iof_heap_get(newheap, ghost, data, size);
- return data;
- }
- /* size much larger than expected? should not happen.
- make a single-item heap, keep the front heap intact. */
- newheap = iof_heap_new(size);
- if ((next = heap->next) != NULL)
- {
- newheap->next = next;
- next->prev = newheap;
- }
- heap->next = newheap;
- newheap->prev = heap;
- iof_heap_get(newheap, ghost, data, size);
- return data;
-}
-
-static void iof_heap_back (void *data)
-{
- iof_heap_ghost *ghost;
- iof_heap *heap, *next, *prev;
-
- ghost = ((iof_heap_ghost *)data) - 1;
- heap = ghost->heap;
- if (heap->refcount == 0)
- loggerf("invalid use of iof heap, refcount < 0");
- if (--heap->refcount <= 0)
- {
- if ((prev = heap->prev) != NULL)
- { /* free the heap */
- if ((next = heap->next) != NULL)
- prev->next = next, next->prev = prev;
- else
- prev->next = NULL;
- iof_heap_free(heap);
- }
- else
- { /* this is the front heap, just reset */
- heap->pos = heap->data;
- heap->size = heap->space;
- }
- }
-}
-
-/**/
-
-/*
-void * iof_filter_new (size_t size)
-{
- void *data;
- iof_filters_init();
- data = iof_heap_take(&iof_filters_heap, size);
- return memset(data, 0, size);
-}
-*/
-
-iof * iof_filter_reader_new (iof_handler handler, size_t statesize, void **pstate)
-{
- iof *F;
- void *filter;
- uint8_t *buffer;
- size_t buffersize;
-
- iof_filters_init();
- filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
- F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
- buffer = iof_heap_take(&iof_buffers_heap, IOF_BUFFER_SIZE);
- buffersize = IOF_BUFFER_SIZE;
- iof_setup_reader(F, buffer, buffersize);
- F->flags |= IOF_HEAP|IOF_BUFFER_HEAP;
- F->more = handler;
- *pstate = (F + 1);
- return F;
-}
-
-iof * iof_filter_reader_with_buffer_new (iof_handler handler, size_t statesize, void **pstate, void *buffer, size_t buffersize)
-{ // for filters that has own buffer (string, some image filters)
- iof *F;
- void *filter;
-
- iof_filters_init();
- filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
- F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
- iof_setup_reader(F, buffer, buffersize);
- F->flags |= IOF_HEAP;
- F->more = handler;
- *pstate = (F + 1);
- return F;
-}
-
-iof * iof_filter_writer_new (iof_handler handler, size_t statesize, void **pstate)
-{
- iof *F;
- void *filter;
- uint8_t *buffer;
- size_t buffersize;
-
- iof_filters_init();
- filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
- F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
- buffer = iof_heap_take(&iof_buffers_heap, IOF_BUFFER_SIZE);
- buffersize = IOF_BUFFER_SIZE;
- iof_setup_writer(F, buffer, buffersize);
- F->flags |= IOF_HEAP|IOF_BUFFER_HEAP;
- F->more = handler;
- *pstate = (F + 1);
- return F;
-}
-
-iof * iof_filter_writer_with_buffer_new (iof_handler handler, size_t statesize, void **pstate, void *buffer, size_t buffersize)
-{
- iof *F;
- void *filter;
-
- iof_filters_init();
- filter = iof_heap_take(&iof_filters_heap, sizeof(iof) + statesize);
- F = (iof *)memset(filter, 0, sizeof(iof) + statesize);
- iof_setup_writer(F, buffer, buffersize);
- F->flags |= IOF_HEAP;
- F->more = handler;
- *pstate = (F + 1);
- return F;
-}
-
-/**/
-
-#define iof_filter_free(F) iof_heap_back(F)
-#define iof_filter_buffer_free(data) iof_heap_back(data)
-
-/* close */
-
-#define iof_close_next(F) ((void)(iof_decref((F)->next), (F)->next = NULL, 0))
-/* when filter creation fails, we should take care to destroy the filter but leave ->next intact */
-#define iof_clear_next(F) ((void)(iof_unref((F)->next), (F)->next = NULL, 0))
-
-#define iof_close_buffer(F) ((void)\
- ((F)->buf != NULL ? \
- ((F->flags & IOF_BUFFER_ALLOC) ? (util_free((F)->buf), (F)->buf = NULL, 0) : \
- ((F->flags & IOF_BUFFER_HEAP) ? (iof_filter_buffer_free((F)->buf), (F)->buf = NULL, 0) : ((F)->buf = NULL, 0))) : 0))
-
-/* closing underlying file handle */
-
-static void iof_close_file (iof *F)
-{
- FILE *file;
- //if (F->flags & IOF_FILE_HANDLE)
- //{
- if ((file = F->file) != NULL)
- {
- if (F->flags & IOF_CLOSE_FILE)
- fclose(F->file);
- F->file = NULL;
- }
- //}
-}
-
-/* a very special variant for reader filters initiated with iof_file_reopen(). It also calls
- iof_file_reclose(), which takes an effect only if previously reopened, but better to keep
- all this thin ice separated. Used in filters: iofile_reader, iofile_stream_reader, image
- decoders. */
-
-static void iof_close_iofile (iof *F)
-{
- iof_file *iofile;
- //if (F->flags & IOF_FILE)
- //{
- if ((iofile = F->iofile) != NULL)
- {
- iof_file_unsync(iofile, NULL);
- iof_file_reclose(iofile); // takes an effect iff prevoiusly reopened
- iof_file_decref(iofile);
- F->iofile = NULL;
- }
- //}
-}
-
-void iof_free (iof *F)
-{
- if (F->flags & IOF_FILE_HANDLE)
- iof_close_file(F);
- else if (F->flags & IOF_FILE)
- iof_close_iofile(F);
- else if (F->flags & IOF_NEXT)
- iof_close_next(F);
- iof_close_buffer(F);
- if (F->flags & IOF_HEAP)
- iof_filter_free(F);
- else if (F->flags & IOF_ALLOC)
- util_free(F);
-}
-
-void iof_discard (iof *F)
-{ // so far used only on failed filters creation; as iof_free() but don't dare to release ->next
- if (F->flags & IOF_FILE_HANDLE)
- iof_close_file(F);
- else if (F->flags & IOF_FILE)
- iof_close_iofile(F);
- //else if (F->flags & IOF_NEXT)
- // iof_close_next(F);
- iof_close_buffer(F);
- if (F->flags & IOF_HEAP)
- iof_filter_free(F);
- else if (F->flags & IOF_ALLOC)
- util_free(F);
-}
-
-/* resizing buffer */
-
-size_t iof_resize_buffer_to (iof *O, size_t space)
-{
- uint8_t *buf;
-
- if (O->flags & IOF_BUFFER_ALLOC)
- {
- buf = (uint8_t *)util_realloc(O->buf, space);
- }
- else
- {
- buf = (uint8_t *)util_malloc(space);
- memcpy(buf, O->buf, iof_size(O));
- if (O->flags & IOF_BUFFER_HEAP)
- {
- iof_filter_buffer_free(O->buf);
- O->flags &= ~IOF_BUFFER_HEAP;
- }
- O->flags |= IOF_BUFFER_ALLOC;
-
- }
- O->pos = buf + iof_size(O);
- O->end = buf + space;
- O->buf = buf;
- O->space = space;
- return iof_left(O);
-}
-
-/* */
-
-size_t iof_decoder_retval (iof *I, const char *type, iof_status status)
-{
- switch (status)
- {
- case IOFERR:
- case IOFEMPTY: // should never happen as we set state.flush = 1 on decoders init
- loggerf("%s decoder error (%d, %s)", type, status, iof_status_kind(status));
- I->flags |= IOF_STOPPED;
- return 0;
- case IOFEOF: // this is the last chunk,
- I->flags |= IOF_STOPPED; // so stop it and fall
- FALLTHRU // fall through
- case IOFFULL: // prepare pointers to read from I->buf
- I->end = I->pos;
- I->pos = I->buf;
- return I->end - I->buf;
- }
- loggerf("%s decoder bug, invalid retval %d", type, status);
- return 0;
-}
-
-size_t iof_encoder_retval (iof *O, const char *type, iof_status status)
-{
- switch (status)
- {
- case IOFERR:
- case IOFFULL:
- loggerf("%s encoder error (%d, %s)", type, status, iof_status_kind(status));
- return 0;
- case IOFEMPTY:
- O->pos = O->buf;
- O->end = O->buf + O->space;
- return O->space;
- case IOFEOF:
- return 0;
- }
- loggerf("%s encoder bug, invalid retval %d", type, status);
- return 0;
-}
-
-/* file/stream state */
-
-typedef struct {
- size_t length;
- size_t offset;
-} file_state;
-
-#define file_state_init(state, off, len) ((state)->offset = off, (state)->length = len)
-
-typedef struct {
- size_t length;
- size_t offset;
-} stream_state;
-
-#define stream_state_init(state, off, len) ((state)->offset = off, (state)->length = len)
-
-/* union type to avoid 'dereferencing type-punned .. ' warnings on (void **) case */
-
-typedef union { file_state *filestate; stream_state *streamstate; void *voidstate; } fs_state_pointer;
-
-/**/
-
-static size_t file_read (iof *I)
-{
- size_t bytes, tail;
- if (I->flags & IOF_STOPPED)
- return 0;
- tail = iof_tail(I);
- if ((bytes = tail + fread(I->buf + tail, sizeof(uint8_t), I->space - tail, I->file)) < I->space)
- I->flags |= IOF_STOPPED;
- I->pos = I->buf;
- I->end = I->buf + bytes;
- return bytes;
-}
-
-static size_t iofile_read (iof *I, size_t *poffset)
-{
- size_t bytes, tail;
- if (I->flags & IOF_STOPPED)
- return 0;
- iof_file_sync(I->iofile, poffset);
- tail = iof_tail(I);
- if ((bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), I->space - tail, I->iofile)) < I->space)
- {
- I->flags |= IOF_STOPPED;
- iof_file_unsync(I->iofile, poffset);
- }
- I->pos = I->buf;
- I->end = I->buf + bytes;
- return bytes;
-}
-
-static size_t file_load (iof *I)
-{
- size_t bytes, left, tail;
- if (I->flags & IOF_STOPPED)
- return 0;
- tail = iof_tail(I);
- I->pos = I->buf + tail;
- I->end = I->buf + I->space; /* don't assume its done when initializing the filter */
- left = I->space - tail;
- do {
- bytes = fread(I->pos, sizeof(uint8_t), left, I->file);
- I->pos += bytes;
- } while (bytes == left && (left = iof_resize_buffer(I)) > 0);
- I->flags |= IOF_STOPPED;
- return iof_loaded(I);
-}
-
-static size_t iofile_load (iof *I, size_t *poffset)
-{
- size_t bytes, left, tail;
- if (I->flags & IOF_STOPPED)
- return 0;
- tail = iof_tail(I);
- I->pos = I->buf + tail;
- I->end = I->buf + I->space; /* don't assume its done when initializing the filter */
- left = I->space - tail;
- iof_file_sync(I->iofile, poffset);
- do {
- bytes = iof_file_read(I->pos, sizeof(uint8_t), left, I->iofile);
- I->pos += bytes;
- } while (bytes == left && (left = iof_resize_buffer(I)) > 0);
- I->flags |= IOF_STOPPED;
- iof_file_unsync(I->iofile, poffset);
- return iof_loaded(I);
-}
-
-static size_t filter_file_reader (iof *I, iof_mode mode)
-{
- switch (mode)
- {
- case IOFREAD:
- return file_read(I);
- case IOFLOAD:
- return file_load(I);
- case IOFCLOSE:
- iof_free(I);
- return 0;
- default:
- return 0;
- }
-}
-
-static size_t filter_iofile_reader (iof *I, iof_mode mode)
-{
- file_state *state;
- state = iof_filter_state(file_state *, I);
- switch (mode)
- {
- case IOFREAD:
- return iofile_read(I, &state->offset);
- case IOFLOAD:
- return iofile_load(I, &state->offset);
- case IOFCLOSE:
- iof_free(I);
- return 0;
- default:
- return 0;
- }
-}
-
-static size_t file_write (iof *O, int flush)
-{
- size_t bytes;
- if ((bytes = iof_size(O)) > 0)
- if (bytes != fwrite(O->buf, sizeof(uint8_t), bytes, O->file))
- return 0;
- if (flush)
- fflush(O->file);
- O->end = O->buf + O->space; // remains intact actually
- O->pos = O->buf;
- return O->space;
-}
-
-static size_t iofile_write (iof *O, size_t *poffset, int flush)
-{
- size_t bytes;
- iof_file_sync(O->iofile, poffset);
- if ((bytes = iof_size(O)) > 0)
- {
- if (bytes != iof_file_write(O->buf, sizeof(uint8_t), bytes, O->iofile))
- {
- iof_file_unsync(O->iofile, poffset);
- return 0;
- }
- }
- if (flush)
- iof_file_flush(O->iofile);
- O->end = O->buf + O->space; // remains intact actually
- O->pos = O->buf;
- return O->space;
-}
-
-static size_t filter_file_writer (iof *O, iof_mode mode)
-{
- switch (mode)
- {
- case IOFWRITE:
- return file_write(O, 0);
- case IOFFLUSH:
- return file_write(O, 1);
- case IOFCLOSE:
- file_write(O, 1);
- iof_free(O);
- return 0;
- default:
- return 0;
- }
-}
-
-static size_t filter_iofile_writer (iof *O, iof_mode mode)
-{
- file_state *state;
- state = iof_filter_state(file_state *, O);
- switch (mode)
- {
- case IOFWRITE:
- return iofile_write(O, &state->offset, 0);
- case IOFFLUSH:
- return iofile_write(O, &state->offset, 1);
- case IOFCLOSE:
- iofile_write(O, &state->offset, 1);
- iof_free(O);
- return 0;
- default:
- return 0;
- }
-}
-
-/* filter from FILE* */
-
-iof * iof_filter_file_handle_reader (FILE *file)
-{
- iof *I;
- fs_state_pointer P;
- if (file == NULL)
- return NULL;
- I = iof_filter_reader(filter_file_reader, sizeof(file_state), &P.voidstate);
- iof_setup_file(I, file);
- file_state_init(P.filestate, 0, 0);
- return I;
-}
-
-iof * iof_filter_file_handle_writer (FILE *file)
-{
- iof *O;
- fs_state_pointer P;
- if (file == NULL)
- return NULL;
- O = iof_filter_writer(filter_file_writer, sizeof(file_state), &P.voidstate);
- iof_setup_file(O, file);
- file_state_init(P.filestate, 0, 0);
- return O;
-}
-
-/* filter from iof_file * */
-
-iof * iof_filter_iofile_reader (iof_file *iofile, size_t offset)
-{
- iof *I;
- fs_state_pointer P;
- if (!iof_file_reopen(iofile))
- return NULL;
- I = iof_filter_reader(filter_iofile_reader, sizeof(file_state), &P.voidstate);
- iof_setup_iofile(I, iofile);
- file_state_init(P.filestate, offset, 0);
- return I;
-}
-
-iof * iof_filter_iofile_writer (iof_file *iofile, size_t offset)
-{
- iof *O;
- fs_state_pointer P;
- O = iof_filter_writer(filter_iofile_writer, sizeof(file_state), &P.voidstate);
- iof_setup_iofile(O, iofile);
- file_state_init(P.filestate, offset, 0);
- return O;
-}
-
-/* filter from filename */
-
-iof * iof_filter_file_reader (const char *filename)
-{
- iof *I;
- fs_state_pointer P;
- FILE *file;
- if ((file = fopen(filename, "rb")) == NULL)
- return NULL;
- I = iof_filter_reader(filter_file_reader, sizeof(file_state), &P.voidstate);
- iof_setup_file(I, file);
- file_state_init(P.filestate, 0, 0);
- I->flags |= IOF_CLOSE_FILE;
- return I;
-}
-
-iof * iof_filter_file_writer (const char *filename)
-{
- iof *O;
- fs_state_pointer P;
- FILE *file;
- if ((file = fopen(filename, "wb")) == NULL)
- return NULL;
- O = iof_filter_writer(filter_file_writer, sizeof(file_state), &P.voidstate);
- iof_setup_file(O, file);
- file_state_init(P.filestate, 0, 0);
- O->flags |= IOF_CLOSE_FILE;
- return O;
-}
-
-/* from string */
-
-static size_t dummy_handler (iof *I, iof_mode mode)
-{
- switch (mode)
- {
- case IOFCLOSE:
- iof_free(I);
- return 0;
- default:
- return 0;
- }
-}
-
-iof * iof_filter_string_reader (const void *s, size_t length)
-{
- iof *I;
- void *dummy;
- I = iof_filter_reader_with_buffer(dummy_handler, 0, &dummy, NULL, 0);
- I->rbuf = I->rpos = (const uint8_t *)s;
- I->rend = (const uint8_t *)s + length;
- // I->space = length;
- return I;
-}
-
-iof * iof_filter_string_writer (const void *s, size_t length)
-{
- iof *O;
- void *dummy;
- O = iof_filter_reader_with_buffer(dummy_handler, 0, &dummy, NULL, 0);
- O->rbuf = O->rpos = (const uint8_t *)s;
- O->rend = (const uint8_t *)s + length;
- // O->space = length;
- return O;
-}
-
-iof * iof_filter_buffer_writer (size_t size)
-{ // cmp iof_buffer_create()
- iof *O;
- fs_state_pointer dummy;
- uint8_t *buffer;
- if (size > IOF_BUFFER_SIZE)
- {
- buffer = (uint8_t *)util_malloc(size);
- O = iof_filter_writer_with_buffer(iof_mem_handler, 0, &dummy.voidstate, buffer, size);
- O->flags |= IOF_BUFFER_ALLOC;
- return O;
- }
- return iof_filter_writer(iof_mem_handler, 0, &dummy.voidstate);
-}
-
-/* stream */
-
-static size_t file_stream_read (iof *I, size_t *plength)
-{
- size_t bytes, tail;
- if (I->flags & IOF_STOPPED || *plength == 0)
- return 0;
- tail = iof_tail(I);
- if (I->space - tail >= *plength)
- {
- bytes = tail + fread(I->buf + tail, sizeof(uint8_t), *plength, I->file);
- I->flags |= IOF_STOPPED;
- *plength = 0;
- }
- else
- {
- bytes = tail + fread(I->buf + tail, sizeof(uint8_t), I->space - tail, I->file);
- *plength -= bytes - tail;
- }
- I->pos = I->buf;
- I->end = I->buf + bytes;
- return bytes;
-}
-
-static size_t iofile_stream_read (iof *I, size_t *plength, size_t *poffset)
-{
- size_t bytes, tail;
- if (I->flags & IOF_STOPPED || *plength == 0)
- return 0;
- tail = iof_tail(I);
- iof_file_sync(I->iofile, poffset);
- if (I->space - tail >= *plength)
- {
- bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), *plength, I->iofile);
- iof_file_unsync(I->iofile, poffset);
- I->flags |= IOF_STOPPED;
- *plength = 0;
- }
- else
- {
- bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), I->space - tail, I->iofile);
- *plength -= bytes - tail;
- }
- I->pos = I->buf;
- I->end = I->buf + bytes;
- return bytes;
-}
-
-static size_t file_stream_load (iof *I, size_t *plength)
-{
- size_t bytes, tail;
- if (I->flags & IOF_STOPPED || *plength == 0)
- return 0;
- tail = iof_tail(I);
- if (I->space - tail < *plength)
- if (iof_resize_buffer_to(I, tail + *plength) == 0)
- return 0;
- bytes = tail + fread(I->buf + tail, sizeof(uint8_t), *plength, I->file);
- I->flags |= IOF_STOPPED;
- *plength = 0;
- I->pos = I->buf;
- I->end = I->buf + bytes;
- return bytes;
-}
-
-static size_t iofile_stream_load (iof *I, size_t *plength, size_t *poffset)
-{
- size_t bytes, tail;
- if (I->flags & IOF_STOPPED || *plength == 0)
- return 0;
- iof_file_sync(I->iofile, poffset);
- tail = iof_tail(I);
- if (I->space - tail < *plength)
- if (iof_resize_buffer_to(I, tail + *plength) == 0)
- return 0;
- bytes = tail + iof_file_read(I->buf + tail, sizeof(uint8_t), *plength, I->iofile);
- iof_file_unsync(I->iofile, poffset);
- I->flags |= IOF_STOPPED;
- *plength = 0;
- I->pos = I->buf;
- I->end = I->buf + bytes;
- return bytes;
-}
-
-static size_t filter_file_stream_reader (iof *I, iof_mode mode)
-{
- stream_state *state;
- state = iof_filter_state(stream_state *, I);
- switch(mode)
- {
- case IOFREAD:
- return file_stream_read(I, &state->length);
- case IOFLOAD:
- return file_stream_load(I, &state->length);
- case IOFCLOSE:
- iof_free(I);
- return 0;
- default:
- return 0;
- }
-}
-
-static size_t filter_iofile_stream_reader (iof *I, iof_mode mode)
-{
- stream_state *state;
- state = iof_filter_state(stream_state *, I);
- switch(mode)
- {
- case IOFREAD:
- return iofile_stream_read(I, &state->length, &state->offset);
- case IOFLOAD:
- return iofile_stream_load(I, &state->length, &state->offset);
- case IOFCLOSE:
- iof_free(I);
- return 0;
- default:
- return 0;
- }
-}
-
-iof * iof_filter_stream_reader (FILE *file, size_t offset, size_t length)
-{
- iof *I;
- fs_state_pointer P;
- I = iof_filter_reader(filter_file_stream_reader, sizeof(stream_state), &P.voidstate);
- iof_setup_file(I, file);
- stream_state_init(P.streamstate, offset, length);
- fseek(file, (long)offset, SEEK_SET); // or perhaps it should be call in file_stream_read(), like iof_file_sync()?
- return I;
-}
-
-iof * iof_filter_stream_coreader (iof_file *iofile, size_t offset, size_t length)
-{
- iof *I;
- fs_state_pointer P;
- if (!iof_file_reopen(iofile))
- return NULL;
- I = iof_filter_reader(filter_iofile_stream_reader, sizeof(stream_state), &P.voidstate);
- iof_setup_iofile(I, iofile);
- stream_state_init(P.streamstate, offset, length);
- return I;
-}
-
-static size_t file_stream_write (iof *O, size_t *plength, int flush)
-{
- size_t bytes;
- if ((bytes = iof_size(O)) > 0)
- {
- if (bytes != fwrite(O->buf, sizeof(uint8_t), bytes, O->file))
- {
- *plength += bytes;
- return 0;
- }
- }
- if (flush)
- fflush(O->file);
- *plength += bytes;
- O->end = O->buf + O->space; // remains intact
- O->pos = O->buf;
- return O->space;
-}
-
-static size_t iofile_stream_write (iof *O, size_t *plength, size_t *poffset, int flush)
-{
- size_t bytes;
- if ((bytes = iof_size(O)) > 0)
- {
- iof_file_sync(O->iofile, poffset);
- if (bytes != iof_file_write(O->buf, sizeof(uint8_t), bytes, O->iofile))
- {
- *plength += bytes;
- iof_file_unsync(O->iofile, poffset);
- return 0;
- }
- }
- if (flush)
- iof_file_flush(O->iofile);
- *plength += bytes;
- O->end = O->buf + O->space; // remains intact
- O->pos = O->buf;
- return O->space;
-}
-
-static size_t filter_file_stream_writer (iof *O, iof_mode mode)
-{
- stream_state *state;
- state = iof_filter_state(stream_state *, O);
- switch (mode)
- {
- case IOFWRITE:
- return file_stream_write(O, &state->length, 0);
- case IOFFLUSH:
- return file_stream_write(O, &state->length, 1);
- case IOFCLOSE:
- file_stream_write(O, &state->length, 1);
- iof_free(O);
- return 0;
- default:
- return 0;
- }
-}
-
-static size_t filter_iofile_stream_writer (iof *O, iof_mode mode)
-{
- stream_state *state;
- state = iof_filter_state(stream_state *, O);
- switch (mode)
- {
- case IOFWRITE:
- return iofile_stream_write(O, &state->length, &state->offset, 0);
- case IOFFLUSH:
- return iofile_stream_write(O, &state->length, &state->offset, 1);
- case IOFCLOSE:
- iofile_stream_write(O, &state->length, &state->offset, 1);
- iof_free(O);
- return 0;
- default:
- return 0;
- }
-}
-
-iof * iof_filter_stream_writer (FILE *file)
-{
- iof *O;
- fs_state_pointer P;
- O = iof_filter_writer(filter_file_stream_writer, sizeof(stream_state), &P.voidstate);
- iof_setup_file(O, file);
- stream_state_init(P.streamstate, 0, 0);
- return O;
-}
-
-iof * iof_filter_stream_cowriter (iof_file *iofile, size_t offset)
-{
- iof *O;
- fs_state_pointer P;
- O = iof_filter_writer(filter_iofile_stream_writer, sizeof(stream_state), &P.voidstate);
- iof_setup_iofile(O, iofile);
- stream_state_init(P.streamstate, offset, 0);
- return O;
-}
-
-/* very specific for images; get input from already created strem filter, exchange the filter but keep the buffer */
-
-FILE * iof_filter_file_reader_source (iof *I, size_t *poffset, size_t *plength)
-{
- fs_state_pointer P;
- if (I->more == filter_file_stream_reader) // I is the result of iof_filter_stream_reader()
- {
- P.streamstate = iof_filter_state(stream_state *, I);
- *poffset = P.streamstate->offset;
- *plength = P.streamstate->length; // might be 0 but it is ok for file readers
- return I->file;
- }
- if (I->more == filter_file_reader)
- {
- P.filestate = iof_filter_state(file_state *, I);
- *poffset = P.filestate->offset;
- *plength = P.filestate->length; // might be 0 but it is ok for file readers
- return I->file;
- }
- return NULL;
-}
-
-iof_file * iof_filter_file_coreader_source (iof *I, size_t *poffset, size_t *plength)
-{
- fs_state_pointer P;
- if (I->more == filter_iofile_stream_reader) // I is the result of iof_filter_stream_coreader()
- {
- P.streamstate = iof_filter_state(stream_state *, I);
- *poffset = P.streamstate->offset;
- *plength = P.streamstate->length;
- return I->iofile;
- }
- if (I->more == filter_iofile_reader)
- {
- P.filestate = iof_filter_state(file_state *, I);
- *poffset = P.filestate->offset;
- *plength = P.filestate->length;
- return I->iofile;
- }
- return NULL;
-}
-
-iof * iof_filter_reader_replacement (iof *P, iof_handler handler, size_t statesize, void **pstate)
-{ // called after iof_filter_file_reader_source(), no need to check if F is filter from iof heap and if has buffer from iof heap
- iof *F;
- F = iof_filter_reader_with_buffer(handler, statesize, pstate, P->buf, P->space);
- F->flags |= IOF_BUFFER_HEAP;
- //iof_setup_reader(P, NULL, 0);
- //P->flags &= ~IOF_BUFFER_HEAP;
- iof_filter_free(P);
- return F;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-