diff options
Diffstat (limited to 'extract/include/extract_buffer.h')
-rw-r--r-- | extract/include/extract_buffer.h | 278 |
1 files changed, 278 insertions, 0 deletions
diff --git a/extract/include/extract_buffer.h b/extract/include/extract_buffer.h new file mode 100644 index 00000000..b0abbec3 --- /dev/null +++ b/extract/include/extract_buffer.h @@ -0,0 +1,278 @@ +#ifndef ARTIFEX_EXTRACT_BUFFER_H +#define ARTIFEX_EXTRACT_BUFFER_H + +#include "extract_alloc.h" + +#include <stddef.h> + +/* Work around MSVS issues with our use of 'inline'. */ +#ifdef _MSC_VER + #include "extract_compat_inline.h" +#endif + +/* Reading and writing abstractions. + +We use inline code in the common case where reading or writing can be satisfied +using a cache. +*/ + + +typedef struct extract_buffer_t extract_buffer_t; +/* Abstract state for a buffer. */ + + +static inline int extract_buffer_read( + extract_buffer_t* buffer, + void* data, + size_t numbytes, + size_t* o_actual + ); +/* Reads specified number of bytes from buffer into data..+bytes, making multiple calls to +the underlying extract_buffer_fn_read function until we have read <numbytes> or reached +EOF. If we reach EOF, . Returns +1 if +short read due to EOF. + +buffer: + As returned by earlier call to extract_buffer_open(). +data: + Location of transferred data. +bytes: + Number of bytes transferred. +o_actual: + Optional out-param, set to actual number of bytes read. If we return zero + this will always be <numbytes>; otherwise will be less than <numbytes>. + +For speed reasons, this is implemented in extract_buffer_impl.h and uses only +inline code if the requested data can be read from the cache. +*/ + + +static inline int extract_buffer_write( + extract_buffer_t* buffer, + const void* data, + size_t numbytes, + size_t* o_actual + ); +/* Writes specified data into buffer. Returns +1 if short write due to EOF. + +buffer: + As returned by earlier call to extract_buffer_open(). +data: + Location of source data. +bytes: + Number of bytes to copy. +out_actual: + Optional out-param, set to actual number of bytes written. If we return + zero this will always be <numbytes>; otherwise will be less than <numbytes> + and can even be negative if internal cache-flush using fn_write() fails or + returns EOF. + +For speed reasons, this is implemented in extract_buffer_impl.h and uses only +inline code if there is space in the cache for the data. +*/ + + +size_t extract_buffer_pos(extract_buffer_t* buffer); +/* Returns number of bytes read or number of bytes written so far. */ + + +int extract_buffer_close(extract_buffer_t** io_buffer); +/* Closes down an extract_buffer_t and frees all internal resources. + +Can return error or +1 for EOF if write buffer and fn_write() fails when +flushing cache. + +Always sets *io_buffer to NULL. Does nothing if *io_buffer is already NULL. +*/ + + +typedef int (*extract_buffer_fn_read)(void* handle, void* destination, size_t numbytes, size_t* o_actual); +/* Callback used by read buffer. Should read data from buffer into the supplied +destination. Short reads are not an error. + +E.g. used to fill cache or to handle large reads. + +Should returns 0 on success (including short read or EOF) or -1 with errno set. + +handle: + As passed to extract_buffer_open(). +destination: + Start of destination. +bytes: + Number of bytes in destination. +o_actual: + Out-param, set to zero if EOF. Otherwise set to the number of bytes + transferred in the range 1..<numbytes> inclusive. +*/ + +typedef int (*extract_buffer_fn_write)(void* handle, const void* source, size_t numbytes, size_t* o_actual); +/* Callback used by write buffer. Should write data from the supplied source +into the buffer; short writes are not an error. + +E.g. used to flush cache or to handle large writes. + +Should return 0 on success (including short write or EOF) or -1 with errno set. + +handle: + As passed to extract_buffer_open(). +source: + Start of source. +bytes: + Number of bytes in source. +o_actual: + Out-param, set to zero if EOF. Otherwise set to the number of bytes + transferred in the range 1..<numbytes> inclusive. +*/ + +typedef int (*extract_buffer_fn_cache)(void* handle, void** o_cache, size_t* o_numbytes); +/* Callback to flush/populate cache. + +If the buffer is for writing: + Should return a memory region to which data can be written. Any data + written to a previous cache will have already been passed to fn_write() so + this can overlap or be the same as any previously-returned cache. + +If the buffer is for reading: + Should return a memory region containing more data to be read. All data in + any previously-returned cache has been read so this can overlap or be the + same as any previous cache. + +handle: + As passed to extract_buffer_open(). +o_data: + Out-param, set to point to new cache. +o_numbytes: + Out-param, set to size of new cache. + +If no data is available due to EOF, should return with *o_numbytes set to zero. +*/ + +typedef void (*extract_buffer_fn_close)(void* handle); +/* Called by extract_buffer_close(). + +handle: + As passed to extract_buffer_open(). +*/ + +extract_alloc_t* extract_buffer_alloc(extract_buffer_t* buffer); +/* Returns the extract_alloc_t* originally passed to extract_buffer_open*(). */ + + +int extract_buffer_open( + extract_alloc_t* alloc, + void* handle, + extract_buffer_fn_read fn_read, + extract_buffer_fn_write fn_write, + extract_buffer_fn_cache fn_cache, + extract_buffer_fn_close fn_close, + extract_buffer_t** o_buffer + ); +/* Creates an extract_buffer_t that uses specified callbacks. + +If fn_read is non-NULL the buffer is a read buffer, else if fn_write is +non-NULL the buffer is a write buffer. Passing non-NULL for both or neither is +not supported. + +alloc: + NULL or from extract_alloc_create(). Is only used to allocate the + extract_buffer_t returned in *o_buffer. +handle: + Passed to fn_read, fn_write, fn_cache and fn_close callbacks. +fn_read: + Callback for reading data. +fn_write: + Callback for writing data. +fn_cache: + Optional cache callback. +fn_close: + Optional close callback. +o_buffer: + Out-param. Set to NULL on error. +*/ + + +int extract_buffer_open_simple( + extract_alloc_t* alloc, + const void* data, + size_t numbytes, + void* handle, + extract_buffer_fn_close fn_close, + extract_buffer_t** o_buffer + ); +/* Creates an extract_buffer_t that reads from or writes to a single fixed +block of memory. + +The address region data..+data_length must exist for the lifetime of the +returned extract_buffer_t. + +alloc: + NULL or from extract_alloc_create(). Is only used to allocate the + extract_buffer_t returned in *o_buffer. +data: + Start of memory region. Note that if the extract_buffer_t is used as a + write buffer then data[] will be written-to, despite the 'const'. [This + use of const avoids the need for the caller to use a cast when creating a + read-buffer.] +bytes: + Size of memory region. +handle: + Passed to fn_close. +fn_close: + Optional callback called by extract_buffer_close(). E.g. could copy the + memory region elsewhere if the buffer was used as a write buffer. +o_buffer: + Out-param. +*/ + + +int extract_buffer_open_file( + extract_alloc_t* alloc, + const char* path, + int writable, + extract_buffer_t** o_buffer + ); +/* Creates a buffer that reads from, or writes to, a file. For portability +uses an internal FILE* rather than an integer file descriptor, so doesn't use +extract_buffer's caching support because FILE* already provides caching. + +path: + Path of file to read from. +writable: + We create read buffer if zero, else a write buffer. +o_buffer: + Out-param. Set to NULL on error. +*/ + + +typedef struct +{ + extract_buffer_t* buffer; + char* data; + size_t alloc_size; + size_t data_size; +} extract_buffer_expanding_t; +/* A write buffer that writes to an automatically-growing contiguous area of +memory. */ + +int extract_buffer_expanding_create( + extract_alloc_t* alloc, + extract_buffer_expanding_t* buffer_expanding + ); +/* Creates a writable buffer that writes into an automatically-growing +contiguous area of memory. + +alloc: + NULL or from extract_alloc_create(). +buffer_expanding: + Out-param; *buffer_expanding is initialised. + +Initialises buffer_expanding. buffer_expanding->buffer can be passed to +extract_buffer_*() functions. After buffer_close(), the written data is +available in buffer_expanding->data..+data_size, which will have been allocated +using <alloc>. */ + + +/* Include implementations of inline-functions. */ +#include "extract_buffer_impl.h" + +#endif |