summaryrefslogtreecommitdiffstats
path: root/libarchive/archive_read_private.h
diff options
context:
space:
mode:
Diffstat (limited to 'libarchive/archive_read_private.h')
-rw-r--r--libarchive/archive_read_private.h55
1 files changed, 33 insertions, 22 deletions
diff --git a/libarchive/archive_read_private.h b/libarchive/archive_read_private.h
index 5a85018..76d0b91 100644
--- a/libarchive/archive_read_private.h
+++ b/libarchive/archive_read_private.h
@@ -42,13 +42,18 @@ struct archive_read_filter;
/*
* How bidding works for filters:
- * * The bid manager reads the first block from the current source.
- * * It shows that block to each registered bidder.
+ * * The bid manager initializes the client-provided reader as the
+ * first filter.
+ * * It invokes the bidder for each registered filter with the
+ * current head filter.
+ * * The bidders can use archive_read_filter_ahead() to peek ahead
+ * at the incoming data to compose their bids.
* * The bid manager creates a new filter structure for the winning
* bidder and gives the winning bidder a chance to initialize it.
- * * The new filter becomes the top filter in the archive_read structure
- * and we repeat the process.
- * This ends only when no bidder provides a non-zero bid.
+ * * The new filter becomes the new top filter and we repeat the
+ * process.
+ * This ends only when no bidder provides a non-zero bid. Then
+ * we perform a similar dance with the registered format handlers.
*/
struct archive_read_filter_bidder {
/* Configuration data for the bidder. */
@@ -71,6 +76,7 @@ struct archive_read_filter_bidder {
* corresponding bidder above.
*/
struct archive_read_filter {
+ int64_t position;
/* Essentially all filters will need these values, so
* just declare them here. */
struct archive_read_filter_bidder *bidder; /* My bidder. */
@@ -80,6 +86,8 @@ struct archive_read_filter {
ssize_t (*read)(struct archive_read_filter *, const void **);
/* Skip forward this many bytes. */
int64_t (*skip)(struct archive_read_filter *self, int64_t request);
+ /* Seek to an absolute location. */
+ int64_t (*seek)(struct archive_read_filter *self, int64_t offset, int whence);
/* Close (just this filter) and free(self). */
int (*close)(struct archive_read_filter *self);
/* My private data. */
@@ -97,8 +105,8 @@ struct archive_read_filter {
size_t client_total;
const char *client_next;
size_t client_avail;
- int64_t position;
char end_of_file;
+ char closed;
char fatal;
};
@@ -111,9 +119,12 @@ struct archive_read_filter {
* so should be deferred at least until libarchive 3.0.
*/
struct archive_read_client {
+ archive_open_callback *opener;
archive_read_callback *reader;
archive_skip_callback *skipper;
+ archive_seek_callback *seeker;
archive_close_callback *closer;
+ void *data;
};
struct archive_read {
@@ -122,6 +133,7 @@ struct archive_read {
struct archive_entry *entry;
/* Dev/ino of the archive being read/written. */
+ int skip_file_set;
dev_t skip_file_dev;
ino_t skip_file_ino;
@@ -130,21 +142,21 @@ struct archive_read {
* data to client buffers, filling gaps with zero bytes.
*/
const char *read_data_block;
- off_t read_data_offset;
- off_t read_data_output_offset;
+ int64_t read_data_offset;
+ int64_t read_data_output_offset;
size_t read_data_remaining;
/* Callbacks to open/read/write/close client archive stream. */
struct archive_read_client client;
/* Registered filter bidders. */
- struct archive_read_filter_bidder bidders[8];
+ struct archive_read_filter_bidder bidders[9];
/* Last filter in chain */
struct archive_read_filter *filter;
/* File offset of beginning of most recently-read header. */
- off_t header_position;
+ int64_t header_position;
/*
* Format detection is mostly the same as compression
@@ -157,14 +169,14 @@ struct archive_read {
struct archive_format_descriptor {
void *data;
const char *name;
- int (*bid)(struct archive_read *);
+ int (*bid)(struct archive_read *, int best_bid);
int (*options)(struct archive_read *, const char *key,
const char *value);
int (*read_header)(struct archive_read *, struct archive_entry *);
- int (*read_data)(struct archive_read *, const void **, size_t *, off_t *);
+ int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *);
int (*read_data_skip)(struct archive_read *);
int (*cleanup)(struct archive_read *);
- } formats[9];
+ } formats[16];
struct archive_format_descriptor *format; /* Active format. */
/*
@@ -177,23 +189,22 @@ struct archive_read {
int __archive_read_register_format(struct archive_read *a,
void *format_data,
const char *name,
- int (*bid)(struct archive_read *),
+ int (*bid)(struct archive_read *, int),
int (*options)(struct archive_read *, const char *, const char *),
int (*read_header)(struct archive_read *, struct archive_entry *),
- int (*read_data)(struct archive_read *, const void **, size_t *, off_t *),
+ int (*read_data)(struct archive_read *, const void **, size_t *, int64_t *),
int (*read_data_skip)(struct archive_read *),
int (*cleanup)(struct archive_read *));
-struct archive_read_filter_bidder
- *__archive_read_get_bidder(struct archive_read *a);
+int __archive_read_get_bidder(struct archive_read *a,
+ struct archive_read_filter_bidder **bidder);
const void *__archive_read_ahead(struct archive_read *, size_t, ssize_t *);
const void *__archive_read_filter_ahead(struct archive_read_filter *,
size_t, ssize_t *);
-ssize_t __archive_read_consume(struct archive_read *, size_t);
-ssize_t __archive_read_filter_consume(struct archive_read_filter *, size_t);
-int64_t __archive_read_skip(struct archive_read *, int64_t);
-int64_t __archive_read_skip_lenient(struct archive_read *, int64_t);
-int64_t __archive_read_filter_skip(struct archive_read_filter *, int64_t);
+int64_t __archive_read_seek(struct archive_read*, int64_t, int);
+int64_t __archive_read_filter_seek(struct archive_read_filter *, int64_t, int);
+int64_t __archive_read_consume(struct archive_read *, int64_t);
+int64_t __archive_read_filter_consume(struct archive_read_filter *, int64_t);
int __archive_read_program(struct archive_read_filter *, const char *);
#endif
OpenPOWER on IntegriCloud