summaryrefslogtreecommitdiffstats
path: root/lib/libarchive/archive_read_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libarchive/archive_read_private.h')
-rw-r--r--lib/libarchive/archive_read_private.h138
1 files changed, 96 insertions, 42 deletions
diff --git a/lib/libarchive/archive_read_private.h b/lib/libarchive/archive_read_private.h
index 4353983..da0b83f 100644
--- a/lib/libarchive/archive_read_private.h
+++ b/lib/libarchive/archive_read_private.h
@@ -32,6 +32,75 @@
#include "archive_string.h"
#include "archive_private.h"
+struct archive_read;
+struct archive_reader;
+struct archive_read_source;
+
+/*
+ * A "reader" knows how to provide blocks. That can include something
+ * that reads blocks from disk or socket or a transformation layer
+ * that reads blocks from another source and transforms them. This
+ * includes decompression and decryption filters.
+ *
+ * How bidding works:
+ * * The bid manager reads the first block from the current source.
+ * * It shows that block to each registered bidder.
+ * * The winning bidder is initialized (with the block and information
+ * about the source)
+ * * The winning bidder becomes the new source and the process repeats
+ * This ends only when no reader provides a non-zero bid.
+ */
+struct archive_reader {
+ /* Configuration data for the reader. */
+ void *data;
+ /* Bidder is handed the initial block from its source. */
+ int (*bid)(struct archive_reader *, const void *buff, size_t);
+ /* Init() is given the archive, upstream source, and the initial
+ * block above. It returns a populated source structure. */
+ struct archive_read_source *(*init)(struct archive_read *,
+ struct archive_reader *, struct archive_read_source *source,
+ const void *, size_t);
+ /* Release the reader and any configuration data it allocated. */
+ int (*free)(struct archive_reader *);
+};
+
+/*
+ * A "source" is an instance of a reader. This structure is
+ * allocated and initialized by the init() method of a reader
+ * above.
+ */
+struct archive_read_source {
+ /* Essentially all sources will need these values, so
+ * just declare them here. */
+ struct archive_reader *reader; /* Reader that I'm an instance of. */
+ struct archive_read_source *upstream; /* Who I get blocks from. */
+ struct archive_read *archive; /* associated archive. */
+ /* Return next block. */
+ ssize_t (*read)(struct archive_read_source *, const void **);
+ /* Skip forward this many bytes. */
+ int64_t (*skip)(struct archive_read_source *self, int64_t request);
+ /* Close (recursively) and free(self). */
+ int (*close)(struct archive_read_source *self);
+ /* My private data. */
+ void *data;
+};
+
+/*
+ * The client source is almost the same as an internal source.
+ *
+ * TODO: Make archive_read_source and archive_read_client identical so
+ * that users of the library can easily register their own
+ * transformation filters. This will probably break the API/ABI and
+ * so should be deferred until libarchive 3.0.
+ */
+struct archive_read_client {
+ archive_open_callback *opener;
+ archive_read_callback *reader;
+ archive_skip_callback *skipper;
+ archive_close_callback *closer;
+ void *data;
+};
+
struct archive_read {
struct archive archive;
@@ -50,46 +119,30 @@ struct archive_read {
off_t read_data_output_offset;
size_t read_data_remaining;
- /* Callbacks to open/read/write/close archive stream. */
- archive_open_callback *client_opener;
- archive_read_callback *client_reader;
- archive_skip_callback *client_skipper;
- archive_close_callback *client_closer;
- void *client_data;
+ /* Callbacks to open/read/write/close client archive stream. */
+ struct archive_read_client client;
+
+ /* Registered readers. */
+ struct archive_reader readers[8];
+
+ /* Source */
+ struct archive_read_source *source;
/* File offset of beginning of most recently-read header. */
off_t header_position;
- /*
- * Decompressors have a very specific lifecycle:
- * public setup function initializes a slot in this table
- * 'config' holds minimal configuration data
- * bid() examines a block of data and returns a bid [1]
- * init() is called for successful bidder
- * 'data' is initialized by init()
- * read() returns a pointer to the next block of data
- * consume() indicates how much data is used
- * skip() ignores bytes of data
- * finish() cleans up and frees 'data' and 'config'
- *
- * [1] General guideline: bid the number of bits that you actually
- * test, e.g., 16 if you test a 2-byte magic value.
- */
- struct decompressor_t {
- void *config;
- void *data;
- int (*bid)(const void *buff, size_t);
- int (*init)(struct archive_read *,
- const void *buff, size_t);
- int (*finish)(struct archive_read *);
- ssize_t (*read_ahead)(struct archive_read *,
- const void **, size_t);
- ssize_t (*consume)(struct archive_read *, size_t);
- off_t (*skip)(struct archive_read *, off_t);
- } decompressors[4];
-
- /* Pointer to current decompressor. */
- struct decompressor_t *decompressor;
+
+ /* Used by reblocking logic. */
+ char *buffer;
+ size_t buffer_size;
+ char *next; /* Current read location. */
+ size_t avail; /* Bytes in my buffer. */
+ const void *client_buff; /* Client buffer information. */
+ size_t client_total;
+ const char *client_next;
+ size_t client_avail;
+ char end_of_file;
+ char fatal;
/*
* Format detection is mostly the same as compression
@@ -124,12 +177,13 @@ int __archive_read_register_format(struct archive_read *a,
int (*read_data_skip)(struct archive_read *),
int (*cleanup)(struct archive_read *));
-struct decompressor_t
- *__archive_read_register_compression(struct archive_read *a,
- int (*bid)(const void *, size_t),
- int (*init)(struct archive_read *, const void *, size_t));
+struct archive_reader
+ *__archive_read_get_reader(struct archive_read *a);
const void
- *__archive_read_ahead(struct archive_read *, size_t);
-
+ *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
+ssize_t
+ __archive_read_consume(struct archive_read *, size_t);
+int64_t
+ __archive_read_skip(struct archive_read *, int64_t);
#endif
OpenPOWER on IntegriCloud