summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extract/include/extract_buffer.h')
-rw-r--r--extract/include/extract_buffer.h278
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