]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
First step in transitioning the current decompression code to
authorTim Kientzle <kientzle@gmail.com>
Wed, 29 Oct 2008 22:07:37 +0000 (18:07 -0400)
committerTim Kientzle <kientzle@gmail.com>
Wed, 29 Oct 2008 22:07:37 +0000 (18:07 -0400)
a more generic system of stackable stream transforms.
In particular, I believe I've edited every place that called the
decompressor directly to go through new __archive_read_ahead(),
__archive_read_consume() and __archive_read_skip() functions, so
the rest of the work here will not require any changes to the
format handlers.

I've also laid out the new types that will be needed for this.
Next step is to rewrite the decompressors to the new interface,
and overhaul the decompression auction to juggle generic "sources."
Then I'll be able to consolidate reblocking into a single place;
the transforms can emit arbitrary-sized blocks and the current
decompress_none logic will be used to reblock as needed by the
consumer format.

The initial impetus for this was to simplify the decompressors by
consolidating the reblocking logic.  I recently came up with
some other transforms I'd like to implement (including new
decompressors, an encryption filter for secure backup, and
uudecode handling to simplify test harnesses) that would also
benefit from this.  Eventually, I think I might be able to
standardize the interface for new transforms enough to allow
libarchive clients to register their own transforms complete
with bidding logic (the old interface was too wired into libarchive
internals for the API to be exported).  In the very long term,
this might divorce the transformation logic from the rest of
libarchive enough to allow it to be packaged as an independent
library.

SVN-Revision: 234

14 files changed:
libarchive/archive_read.c
libarchive/archive_read_private.h
libarchive/archive_read_support_compression_bzip2.c
libarchive/archive_read_support_compression_compress.c
libarchive/archive_read_support_compression_gzip.c
libarchive/archive_read_support_compression_none.c
libarchive/archive_read_support_compression_program.c
libarchive/archive_read_support_format_ar.c
libarchive/archive_read_support_format_cpio.c
libarchive/archive_read_support_format_empty.c
libarchive/archive_read_support_format_iso9660.c
libarchive/archive_read_support_format_mtree.c
libarchive/archive_read_support_format_tar.c
libarchive/archive_read_support_format_zip.c

index 327969f41852bfba4c5c5c7147e6fab666c50480..223d7679d259fdb38f315fa555a83cebe2b88f5c 100644 (file)
@@ -108,6 +108,32 @@ archive_read_open(struct archive *a, void *client_data,
            client_reader, NULL, client_closer);
 }
 
+static ssize_t
+client_read_proxy(struct archive_read_source *self, const void **buff)
+{
+       return (self->archive->client.reader)((struct archive *)self->archive,
+           self->data, buff);
+}
+
+static int64_t
+client_skip_proxy(struct archive_read_source *self, int64_t request)
+{
+       return (self->archive->client.skipper)((struct archive *)self->archive,
+           self->data, request);
+}
+
+static ssize_t
+client_close_proxy(struct archive_read_source *self)
+{
+       int r;
+
+       r = (self->archive->client.closer)((struct archive *)self->archive,
+           self->data);
+       free(self);
+       return (r);
+}
+
+
 int
 archive_read_open2(struct archive *_a, void *client_data,
     archive_open_callback *client_opener,
@@ -120,7 +146,8 @@ archive_read_open2(struct archive *_a, void *client_data,
        ssize_t bytes_read;
        int e;
 
-       __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW, "archive_read_open");
+       __archive_check_magic(_a, ARCHIVE_READ_MAGIC, ARCHIVE_STATE_NEW,
+           "archive_read_open");
 
        if (client_reader == NULL)
                __archive_errx(1,
@@ -132,11 +159,11 @@ archive_read_open2(struct archive *_a, void *client_data,
         * (In particular, this helps ensure that the closer doesn't
         * get called more than once.)
         */
-       a->client_opener = NULL;
-       a->client_reader = NULL;
-       a->client_skipper = NULL;
-       a->client_closer = NULL;
-       a->client_data = NULL;
+       a->client.opener = NULL;
+       a->client.reader = NULL;
+       a->client.skipper = NULL;
+       a->client.closer = NULL;
+       a->client.data = NULL;
 
        /* Open data source. */
        if (client_opener != NULL) {
@@ -161,11 +188,27 @@ archive_read_open2(struct archive *_a, void *client_data,
        }
 
        /* Now that the client callbacks have worked, remember them. */
-       a->client_opener = client_opener; /* Do we need to remember this? */
-       a->client_reader = client_reader;
-       a->client_skipper = client_skipper;
-       a->client_closer = client_closer;
-       a->client_data = client_data;
+       a->client.opener = client_opener; /* Do we need to remember this? */
+       a->client.reader = client_reader;
+       a->client.skipper = client_skipper;
+       a->client.closer = client_closer;
+       a->client.data = client_data;
+
+       {
+               struct archive_read_source *source;
+
+               source = calloc(1, sizeof(*source));
+               if (source == NULL)
+                       return (ARCHIVE_FATAL);
+               source->reader = NULL;
+               source->source = NULL;
+               source->archive = a;
+               source->data = client_data;
+               source->read = client_read_proxy;
+               source->skip = client_skip_proxy;
+               source->close = client_close_proxy;
+               a->source = source;
+       }
 
        /* Select a decompression routine. */
        choose_decompressor(a, buffer, (size_t)bytes_read);
@@ -182,8 +225,8 @@ archive_read_open2(struct archive *_a, void *client_data,
         * If the decompressor didn't register a skip function, provide a
         * dummy compression-layer skip function.
         */
-       if (a->decompressor->skip == NULL)
-               a->decompressor->skip = dummy_skip;
+       if (a->decompressor->skip2 == NULL)
+               a->decompressor->skip2 = dummy_skip;
 
        return (e);
 }
@@ -254,7 +297,7 @@ dummy_skip(struct archive_read * a, off_t request)
        off_t bytes_skipped;
 
        for (bytes_skipped = 0; request > 0;) {
-               bytes_read = (a->decompressor->read_ahead)(a, &dummy_buffer, 1);
+               bytes_read = (a->decompressor->read_ahead2)(a, &dummy_buffer, 1);
                if (bytes_read < 0)
                        return (bytes_read);
                if (bytes_read == 0) {
@@ -266,7 +309,7 @@ dummy_skip(struct archive_read * a, off_t request)
                }
                if (bytes_read > request)
                        bytes_read = (ssize_t)request;
-               (a->decompressor->consume)(a, (size_t)bytes_read);
+               (a->decompressor->consume2)(a, (size_t)bytes_read);
                request -= bytes_read;
                bytes_skipped += bytes_read;
        }
@@ -609,8 +652,8 @@ archive_read_close(struct archive *_a)
        }
 
        /* Close the client stream. */
-       if (a->client_closer != NULL) {
-               r1 = ((a->client_closer)(&a->archive, a->client_data));
+       if (a->client.closer != NULL) {
+               r1 = ((a->client.closer)(&a->archive, a->client.data));
                if (r1 < r)
                        r = r1;
        }
@@ -729,11 +772,29 @@ __archive_read_register_compression(struct archive_read *a,
 
 /* used internally to simplify read-ahead */
 const void *
-__archive_read_ahead(struct archive_read *a, size_t len)
+__archive_read_ahead(struct archive_read *a, size_t len, size_t *avail)
 {
+       ssize_t av;
        const void *h;
 
-       if ((a->decompressor->read_ahead)(a, &h, len) < (ssize_t)len)
+       av = (a->decompressor->read_ahead2)(a, &h, len);
+       /* Return # bytes avail (also error code) regardless. */
+       if (avail != NULL && av >= 0)
+               *avail = av;
+       /* If it was a short read, return NULL. */
+       if (av < (ssize_t)len)
                return (NULL);
        return (h);
 }
+
+ssize_t
+__archive_read_consume(struct archive_read *a, size_t s)
+{
+       return (a->decompressor->consume2)(a, s);
+}
+
+int64_t
+__archive_read_skip(struct archive_read *a, uint64_t s)
+{
+       return (a->decompressor->skip2)(a, s);
+}
index af25b043eb4516240847c2684d1dbde9d8591ab7..efa3482427962b799ae7fdf53fcc3e979ca9e761 100644 (file)
 #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)(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_read_source *source, const void *, size_t);
+       /* Release the reader and any configuration data it allocated. */
+       void (*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 *source; /* 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,12 +118,14 @@ 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;
@@ -82,10 +152,10 @@ struct archive_read {
                int     (*init)(struct archive_read *,
                            const void *buff, size_t);
                int     (*finish)(struct archive_read *);
-               ssize_t (*read_ahead)(struct archive_read *,
+               ssize_t (*read_ahead2)(struct archive_read *,
                            const void **, size_t);
-               ssize_t (*consume)(struct archive_read *, size_t);
-               off_t   (*skip)(struct archive_read *, off_t);
+               ssize_t (*consume2)(struct archive_read *, size_t);
+               off_t   (*skip2)(struct archive_read *, off_t);
        }       decompressors[5];
 
        /* Pointer to current decompressor. */
@@ -128,8 +198,10 @@ 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));
-
 const void
-       *__archive_read_ahead(struct archive_read *, size_t);
-
+       *__archive_read_ahead(struct archive_read *, size_t, size_t *);
+ssize_t
+       __archive_read_consume(struct archive_read *, size_t);
+int64_t
+       __archive_read_skip(struct archive_read *, uint64_t);
 #endif
index 824b0cdeb5617929f18c7c003627fbd1ec0327ca..279c3755af065acbf8e5019310a56d3364c97a8e 100644 (file)
@@ -209,9 +209,9 @@ init(struct archive_read *a, const void *buff, size_t n)
        state->stream.next_in = (char *)(uintptr_t)(const void *)buff;
        state->stream.avail_in = n;
 
-       a->decompressor->read_ahead = read_ahead;
-       a->decompressor->consume = read_consume;
-       a->decompressor->skip = NULL; /* not supported */
+       a->decompressor->read_ahead2 = read_ahead;
+       a->decompressor->consume2 = read_consume;
+       a->decompressor->skip2 = NULL; /* not supported */
        a->decompressor->finish = finish;
 
        /* Initialize compression library. */
@@ -272,13 +272,6 @@ read_ahead(struct archive_read *a, const void **p, size_t min)
        int ret;
 
        state = (struct private_data *)a->decompressor->data;
-       if (!a->client_reader) {
-               archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
-                   "No read callback is registered?  "
-                   "This is probably an internal programming error.");
-               return (ARCHIVE_FATAL);
-       }
-
        read_avail = state->stream.next_out - state->read_next;
 
        if (read_avail + state->stream.avail_out < min) {
@@ -369,8 +362,7 @@ drive_decompressor(struct archive_read *a, struct private_data *state)
        for (;;) {
                if (state->stream.avail_in == 0) {
                        read_buf = state->stream.next_in;
-                       ret = (a->client_reader)(&a->archive, a->client_data,
-                           &read_buf);
+                       ret = (a->source->read)(a->source, &read_buf);
                        state->stream.next_in = (void *)(uintptr_t)read_buf;
                        if (ret < 0) {
                                /*
index 050099b210edc80ca273ba15317b876cd17e7045..e1c9896dcb22eab54641a43b86bb80d8a033f47d 100644 (file)
@@ -199,9 +199,9 @@ init(struct archive_read *a, const void *buff, size_t n)
        a->archive.compression_code = ARCHIVE_COMPRESSION_COMPRESS;
        a->archive.compression_name = "compress (.Z)";
 
-       a->decompressor->read_ahead = read_ahead;
-       a->decompressor->consume = read_consume;
-       a->decompressor->skip = NULL; /* not supported */
+       a->decompressor->read_ahead2 = read_ahead;
+       a->decompressor->consume2 = read_consume;
+       a->decompressor->skip2 = NULL; /* not supported */
        a->decompressor->finish = finish;
 
        state = (struct private_data *)malloc(sizeof(*state));
@@ -281,13 +281,6 @@ read_ahead(struct archive_read *a, const void **p, size_t min)
        int ret;
 
        state = (struct private_data *)a->decompressor->data;
-       if (!a->client_reader) {
-               archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
-                   "No read callback is registered?  "
-                   "This is probably an internal programming error.");
-               return (ARCHIVE_FATAL);
-       }
-
        read_avail = state->next_out - state->read_next;
 
        if (read_avail < min  &&  state->end_of_stream) {
@@ -469,8 +462,7 @@ getbits(struct archive_read *a, struct private_data *state, int n)
        while (state->bits_avail < n) {
                if (state->avail_in <= 0) {
                        read_buf = state->next_in;
-                       ret = (a->client_reader)(&a->archive, a->client_data,
-                           &read_buf);
+                       ret = (a->source->read)(a->source, &read_buf);
                        state->next_in = read_buf;
                        if (ret < 0)
                                return (ARCHIVE_FATAL);
index 2dac54da0cd7271c4a3f4d2bfa3071ae1e71eb5c..25f4a3254e6d2c4e49c3fe54bc4201c3225aa2b4 100644 (file)
@@ -201,9 +201,9 @@ init(struct archive_read *a, const void *buff, size_t n)
        state->stream.next_in = (Bytef *)(uintptr_t)(const void *)buff;
        state->stream.avail_in = n;
 
-       a->decompressor->read_ahead = read_ahead;
-       a->decompressor->consume = read_consume;
-       a->decompressor->skip = NULL; /* not supported */
+       a->decompressor->read_ahead2 = read_ahead;
+       a->decompressor->consume2 = read_consume;
+       a->decompressor->skip2 = NULL; /* not supported */
        a->decompressor->finish = finish;
 
        /*
@@ -265,13 +265,6 @@ read_ahead(struct archive_read *a, const void **p, size_t min)
        int ret;
 
        state = (struct private_data *)a->decompressor->data;
-       if (!a->client_reader) {
-               archive_set_error(&a->archive, ARCHIVE_ERRNO_PROGRAMMER,
-                   "No read callback is registered?  "
-                   "This is probably an internal programming error.");
-               return (ARCHIVE_FATAL);
-       }
-
        read_avail = state->stream.next_out - state->read_next;
 
        if (read_avail + state->stream.avail_out < min) {
@@ -367,8 +360,7 @@ drive_decompressor(struct archive_read *a, struct private_data *state)
        for (;;) {
                if (state->stream.avail_in == 0) {
                        read_buf = state->stream.next_in;
-                       ret = (a->client_reader)(&a->archive, a->client_data,
-                           &read_buf);
+                       ret = (a->source->read)(a->source, &read_buf);
                        state->stream.next_in = (unsigned char *)(uintptr_t)read_buf;
                        if (ret < 0) {
                                /*
index 1ee38f64c620178b05025e728201d5b2aaa656d1..2c5c987c04e42e1cf0f4687421dfe6c66dbe10cf 100644 (file)
@@ -130,9 +130,9 @@ archive_decompressor_none_init(struct archive_read *a, const void *buff, size_t
        state->client_avail = state->client_total;
 
        a->decompressor->data = state;
-       a->decompressor->read_ahead = archive_decompressor_none_read_ahead;
-       a->decompressor->consume = archive_decompressor_none_read_consume;
-       a->decompressor->skip = archive_decompressor_none_skip;
+       a->decompressor->read_ahead2 = archive_decompressor_none_read_ahead;
+       a->decompressor->consume2 = archive_decompressor_none_read_consume;
+       a->decompressor->skip2 = archive_decompressor_none_skip;
        a->decompressor->finish = archive_decompressor_none_finish;
 
        return (ARCHIVE_OK);
@@ -205,8 +205,8 @@ archive_decompressor_none_read_ahead(struct archive_read *a, const void **buff,
                                /* TODO: Change this to return(0) consistent
                                 * with new eof handling commented below. */
                        }
-                       bytes_read = (a->client_reader)(&a->archive,
-                           a->client_data, &state->client_buff);
+                       bytes_read = (a->source->read)(a->source,
+                           &state->client_buff);
                        if (bytes_read < 0) {           /* Read error. */
                                state->client_total = state->client_avail = 0;
                                state->client_next = state->client_buff = NULL;
@@ -354,12 +354,11 @@ archive_decompressor_none_skip(struct archive_read *a, off_t request)
         * If a client_skipper was provided, try that first.
         */
 #if ARCHIVE_API_VERSION < 2
-       if ((a->client_skipper != NULL) && (request < SSIZE_MAX)) {
+       if ((a->source->skip != NULL) && (request < SSIZE_MAX)) {
 #else
-       if (a->client_skipper != NULL) {
+       if (a->source->skip != NULL) {
 #endif
-               bytes_skipped = (a->client_skipper)(&a->archive,
-                   a->client_data, request);
+               bytes_skipped = (a->source->skip)(a->source, request);
                if (bytes_skipped < 0) {        /* error */
                        state->client_total = state->client_avail = 0;
                        state->client_next = state->client_buff = NULL;
index 7b54d1ead064cd427f3574bf12576ed2469d2333..ca35125b1862bfc34525a5ab51551d42d5e67c44 100644 (file)
@@ -161,8 +161,7 @@ restart_read:
 
        if (state->child_in_buf_avail == 0) {
                child_buf = state->child_in_buf;
-               ret = (a->client_reader)(&a->archive,
-                   a->client_data,&child_buf);
+               ret = (a->source->read)(a->source, &child_buf);
                state->child_in_buf = (const char *)child_buf;
 
                if (ret < 0) {
@@ -255,9 +254,9 @@ archive_decompressor_program_init(struct archive_read *a, const void *buff, size
        }
 
        a->decompressor->data = state;
-       a->decompressor->read_ahead = archive_decompressor_program_read_ahead;
-       a->decompressor->consume = archive_decompressor_program_read_consume;
-       a->decompressor->skip = NULL;
+       a->decompressor->read_ahead2 = archive_decompressor_program_read_ahead;
+       a->decompressor->consume2 = archive_decompressor_program_read_consume;
+       a->decompressor->skip2 = NULL;
        a->decompressor->finish = archive_decompressor_program_finish;
 
        /* XXX Check that we can read at least one byte? */
index baf80bd62fc4c21deaa4766b5aac57a2e336e567..a91b29850aa71f2a418655a2a4985e322cb0c50e 100644 (file)
@@ -135,7 +135,6 @@ static int
 archive_read_format_ar_bid(struct archive_read *a)
 {
        struct ar *ar;
-       ssize_t bytes_read;
        const void *h;
 
        if (a->archive.archive_format != 0 &&
@@ -149,8 +148,7 @@ archive_read_format_ar_bid(struct archive_read *a)
         * Verify the 8-byte file signature.
         * TODO: Do we need to check more than this?
         */
-       bytes_read = (a->decompressor->read_ahead)(a, &h, 8);
-       if (bytes_read < 8)
+       if ((h = __archive_read_ahead(a, 8, NULL)) == NULL)
                return (-1);
        if (strncmp((const char*)h, "!<arch>\n", 8) == 0) {
                return (64);
@@ -166,7 +164,7 @@ archive_read_format_ar_read_header(struct archive_read *a,
        struct ar *ar;
        uint64_t number; /* Used to hold parsed numbers before validation. */
        ssize_t bytes_read;
-       size_t bsd_name_length, entry_size, s;
+       size_t bsd_name_length, entry_size;
        char *p, *st;
        const void *b;
        const char *h;
@@ -179,18 +177,16 @@ archive_read_format_ar_read_header(struct archive_read *a,
                 * We are now at the beginning of the archive,
                 * so we need first consume the ar global header.
                 */
-               (a->decompressor->consume)(a, 8);
+               __archive_read_consume(a, 8);
                /* Set a default format code for now. */
                a->archive.archive_format = ARCHIVE_FORMAT_AR;
        }
 
        /* Read the header for the next file entry. */
-       bytes_read = (a->decompressor->read_ahead)(a, &b, 60);
-       if (bytes_read < 60) {
+       if ((b = __archive_read_ahead(a, 60, &bytes_read)) == NULL)
                /* Broken header. */
                return (ARCHIVE_EOF);
-       }
-       (a->decompressor->consume)(a, 60);
+       __archive_read_consume(a, 60);
        h = (const char *)b;
 
        /* Verify the magic signature on the file header. */
@@ -296,16 +292,10 @@ archive_read_format_ar_read_header(struct archive_read *a,
                }
                ar->strtab = st;
                ar->strtab_size = entry_size;
-               for (s = entry_size; s > 0; s -= bytes_read) {
-                       bytes_read = (a->decompressor->read_ahead)(a, &b, s);
-                       if (bytes_read <= 0)
-                               return (ARCHIVE_FATAL);
-                       if (bytes_read > (ssize_t)s)
-                               bytes_read = s;
-                       memcpy(st, b, bytes_read);
-                       st += bytes_read;
-                       (a->decompressor->consume)(a, bytes_read);
-               }
+               if ((b = __archive_read_ahead(a, entry_size, NULL)) == NULL)
+                       return (ARCHIVE_FATAL);
+               memcpy(st, b, entry_size);
+               __archive_read_consume(a, entry_size);
                /* All contents are consumed. */
                ar->entry_bytes_remaining = 0;
                archive_entry_set_size(entry, ar->entry_bytes_remaining);
@@ -365,15 +355,12 @@ archive_read_format_ar_read_header(struct archive_read *a,
                archive_entry_set_size(entry, ar->entry_bytes_remaining);
 
                /* Read the long name into memory. */
-               bytes_read = (a->decompressor->read_ahead)(a, &b, bsd_name_length);
-               if (bytes_read <= 0)
-                       return (ARCHIVE_FATAL);
-               if ((size_t)bytes_read < bsd_name_length) {
+               if ((b = __archive_read_ahead(a, bsd_name_length, NULL)) == NULL) {
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                            "Truncated input file");
                        return (ARCHIVE_FATAL);
                }
-               (a->decompressor->consume)(a, bsd_name_length);
+               __archive_read_consume(a, bsd_name_length);
 
                /* Store it in the entry. */
                p = (char *)malloc(bsd_name_length + 1);
@@ -453,7 +440,7 @@ archive_read_format_ar_read_data(struct archive_read *a,
        ar = (struct ar *)(a->format->data);
 
        if (ar->entry_bytes_remaining > 0) {
-               bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
+               *buff = __archive_read_ahead(a, 1, &bytes_read);
                if (bytes_read == 0) {
                        archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                            "Truncated ar archive");
@@ -467,16 +454,16 @@ archive_read_format_ar_read_data(struct archive_read *a,
                *offset = ar->entry_offset;
                ar->entry_offset += bytes_read;
                ar->entry_bytes_remaining -= bytes_read;
-               (a->decompressor->consume)(a, (size_t)bytes_read);
+               __archive_read_consume(a, (size_t)bytes_read);
                return (ARCHIVE_OK);
        } else {
                while (ar->entry_padding > 0) {
-                       bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
+                       *buff = __archive_read_ahead(a, 1, &bytes_read);
                        if (bytes_read <= 0)
                                return (ARCHIVE_FATAL);
                        if (bytes_read > ar->entry_padding)
                                bytes_read = (ssize_t)ar->entry_padding;
-                       (a->decompressor->consume)(a, (size_t)bytes_read);
+                       __archive_read_consume(a, (size_t)bytes_read);
                        ar->entry_padding -= bytes_read;
                }
                *buff = NULL;
@@ -491,20 +478,11 @@ archive_read_format_ar_skip(struct archive_read *a)
 {
        off_t bytes_skipped;
        struct ar* ar;
-       int r = ARCHIVE_OK;
-       const void *b;          /* Dummy variables */
-       size_t s;
-       off_t o;
 
        ar = (struct ar *)(a->format->data);
-       if (a->decompressor->skip == NULL) {
-               while (r == ARCHIVE_OK)
-                       r = archive_read_format_ar_read_data(a, &b, &s, &o);
-               return (r);
-       }
 
-       bytes_skipped = (a->decompressor->skip)(a, ar->entry_bytes_remaining +
-           ar->entry_padding);
+       bytes_skipped = __archive_read_skip(a,
+           ar->entry_bytes_remaining + ar->entry_padding);
        if (bytes_skipped < 0)
                return (ARCHIVE_FATAL);
 
index 3734b3863335d29ccd16da27568aaef9df12ff54..9c3f2944bba2901d35c72116e9e5f0d9f19513a6 100644 (file)
@@ -165,7 +165,6 @@ archive_read_support_format_cpio(struct archive *_a)
 static int
 archive_read_format_cpio_bid(struct archive_read *a)
 {
-       int bytes_read;
        const void *h;
        const unsigned char *p;
        struct cpio *cpio;
@@ -173,11 +172,7 @@ archive_read_format_cpio_bid(struct archive_read *a)
 
        cpio = (struct cpio *)(a->format->data);
 
-       bytes_read = (a->decompressor->read_ahead)(a, &h, 6);
-       /* Convert error code into error return. */
-       if (bytes_read < 0)
-               return ((int)bytes_read);
-       if (bytes_read < 6)
+       if ((h = __archive_read_ahead(a, 6, NULL)) == NULL)
                return (-1);
 
        p = (const unsigned char *)h;
@@ -228,7 +223,6 @@ archive_read_format_cpio_read_header(struct archive_read *a,
     struct archive_entry *entry)
 {
        struct cpio *cpio;
-       size_t bytes;
        const void *h;
        size_t namelength;
        size_t name_pad;
@@ -241,21 +235,20 @@ archive_read_format_cpio_read_header(struct archive_read *a,
                return (r);
 
        /* Read name from buffer. */
-       bytes = (a->decompressor->read_ahead)(a, &h, namelength + name_pad);
-       if (bytes < namelength + name_pad)
+       h = __archive_read_ahead(a, namelength + name_pad, NULL);
+       if (h == NULL)
            return (ARCHIVE_FATAL);
-       (a->decompressor->consume)(a, namelength + name_pad);
+       __archive_read_consume(a, namelength + name_pad);
        archive_strncpy(&cpio->entry_name, (const char *)h, namelength);
        archive_entry_set_pathname(entry, cpio->entry_name.s);
        cpio->entry_offset = 0;
 
        /* If this is a symlink, read the link contents. */
        if (archive_entry_filetype(entry) == AE_IFLNK) {
-               bytes = (a->decompressor->read_ahead)(a, &h,
-                   cpio->entry_bytes_remaining);
-               if ((off_t)bytes < cpio->entry_bytes_remaining)
+               h = __archive_read_ahead(a, cpio->entry_bytes_remaining, NULL);
+               if (h == NULL)
                        return (ARCHIVE_FATAL);
-               (a->decompressor->consume)(a, cpio->entry_bytes_remaining);
+               __archive_read_consume(a, cpio->entry_bytes_remaining);
                archive_strncpy(&cpio->entry_linkname, (const char *)h,
                    cpio->entry_bytes_remaining);
                archive_entry_set_symlink(entry, cpio->entry_linkname.s);
@@ -284,7 +277,7 @@ archive_read_format_cpio_read_data(struct archive_read *a,
 
        cpio = (struct cpio *)(a->format->data);
        if (cpio->entry_bytes_remaining > 0) {
-               bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
+               *buff = __archive_read_ahead(a, 1, &bytes_read);
                if (bytes_read <= 0)
                        return (ARCHIVE_FATAL);
                if (bytes_read > cpio->entry_bytes_remaining)
@@ -293,16 +286,16 @@ archive_read_format_cpio_read_data(struct archive_read *a,
                *offset = cpio->entry_offset;
                cpio->entry_offset += bytes_read;
                cpio->entry_bytes_remaining -= bytes_read;
-               (a->decompressor->consume)(a, bytes_read);
+               __archive_read_consume(a, bytes_read);
                return (ARCHIVE_OK);
        } else {
                while (cpio->entry_padding > 0) {
-                       bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
+                       *buff = __archive_read_ahead(a, 1, &bytes_read);
                        if (bytes_read <= 0)
                                return (ARCHIVE_FATAL);
                        if (bytes_read > cpio->entry_padding)
                                bytes_read = cpio->entry_padding;
-                       (a->decompressor->consume)(a, bytes_read);
+                       __archive_read_consume(a, bytes_read);
                        cpio->entry_padding -= bytes_read;
                }
                *buff = NULL;
@@ -339,9 +332,8 @@ find_newc_header(struct archive_read *a)
        size_t skip, bytes, skipped = 0;
 
        for (;;) {
-               bytes = (a->decompressor->read_ahead)(a, &h,
-                   sizeof(struct cpio_newc_header));
-               if (bytes < sizeof(struct cpio_newc_header))
+               h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), &bytes);
+               if (h == NULL)
                        return (ARCHIVE_FATAL);
                p = h;
                q = p + bytes;
@@ -363,7 +355,7 @@ find_newc_header(struct archive_read *a)
                                if (memcmp("07070", p, 5) == 0
                                        && is_hex(p, sizeof(struct cpio_newc_header))) {
                                        skip = p - (const char *)h;
-                                       (a->decompressor->consume)(a, skip);
+                                       __archive_read_consume(a, skip);
                                        skipped += skip;
                                        if (skipped > 0) {
                                                archive_set_error(&a->archive,
@@ -386,7 +378,7 @@ find_newc_header(struct archive_read *a)
                        }
                }
                skip = p - (const char *)h;
-               (a->decompressor->consume)(a, skip);
+               __archive_read_consume(a, skip);
                skipped += skip;
        }
 }
@@ -397,7 +389,6 @@ header_newc(struct archive_read *a, struct cpio *cpio,
 {
        const void *h;
        const struct cpio_newc_header *header;
-       size_t bytes;
        int r;
 
        r = find_newc_header(a);
@@ -405,11 +396,10 @@ header_newc(struct archive_read *a, struct cpio *cpio,
                return (r);
 
        /* Read fixed-size portion of header. */
-       bytes = (a->decompressor->read_ahead)(a, &h,
-           sizeof(struct cpio_newc_header));
-       if (bytes < sizeof(struct cpio_newc_header))
+       h = __archive_read_ahead(a, sizeof(struct cpio_newc_header), NULL);
+       if (h == NULL)
            return (ARCHIVE_FATAL);
-       (a->decompressor->consume)(a, sizeof(struct cpio_newc_header));
+       __archive_read_consume(a, sizeof(struct cpio_newc_header));
 
        /* Parse out hex fields. */
        header = (const struct cpio_newc_header *)h;
@@ -476,9 +466,8 @@ find_odc_header(struct archive_read *a)
        size_t skip, bytes, skipped = 0;
 
        for (;;) {
-               bytes = (a->decompressor->read_ahead)(a, &h,
-                   sizeof(struct cpio_odc_header));
-               if (bytes < sizeof(struct cpio_odc_header))
+               h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), &bytes);
+               if (h == NULL)
                        return (ARCHIVE_FATAL);
                p = h;
                q = p + bytes;
@@ -498,7 +487,7 @@ find_odc_header(struct archive_read *a)
                                if (memcmp("070707", p, 6) == 0
                                        && is_octal(p, sizeof(struct cpio_odc_header))) {
                                        skip = p - (const char *)h;
-                                       (a->decompressor->consume)(a, skip);
+                                       __archive_read_consume(a, skip);
                                        skipped += skip;
                                        if (skipped > 0) {
                                                archive_set_error(&a->archive,
@@ -521,7 +510,7 @@ find_odc_header(struct archive_read *a)
                        }
                }
                skip = p - (const char *)h;
-               (a->decompressor->consume)(a, skip);
+               __archive_read_consume(a, skip);
                skipped += skip;
        }
 }
@@ -533,7 +522,6 @@ header_odc(struct archive_read *a, struct cpio *cpio,
        const void *h;
        int r;
        const struct cpio_odc_header *header;
-       size_t bytes;
 
        a->archive.archive_format = ARCHIVE_FORMAT_CPIO_POSIX;
        a->archive.archive_format_name = "POSIX octet-oriented cpio";
@@ -544,11 +532,10 @@ header_odc(struct archive_read *a, struct cpio *cpio,
                return (r);
 
        /* Read fixed-size portion of header. */
-       bytes = (a->decompressor->read_ahead)(a, &h,
-           sizeof(struct cpio_odc_header));
-       if (bytes < sizeof(struct cpio_odc_header))
+       h = __archive_read_ahead(a, sizeof(struct cpio_odc_header), NULL);
+       if (h == NULL)
            return (ARCHIVE_FATAL);
-       (a->decompressor->consume)(a, sizeof(struct cpio_odc_header));
+       __archive_read_consume(a, sizeof(struct cpio_odc_header));
 
        /* Parse out octal fields. */
        header = (const struct cpio_odc_header *)h;
@@ -582,17 +569,15 @@ header_bin_le(struct archive_read *a, struct cpio *cpio,
 {
        const void *h;
        const struct cpio_bin_header *header;
-       size_t bytes;
 
        a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_LE;
        a->archive.archive_format_name = "cpio (little-endian binary)";
 
        /* Read fixed-size portion of header. */
-       bytes = (a->decompressor->read_ahead)(a, &h,
-           sizeof(struct cpio_bin_header));
-       if (bytes < sizeof(struct cpio_bin_header))
+       h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL);
+       if (h == NULL)
            return (ARCHIVE_FATAL);
-       (a->decompressor->consume)(a, sizeof(struct cpio_bin_header));
+       __archive_read_consume(a, sizeof(struct cpio_bin_header));
 
        /* Parse out binary fields. */
        header = (const struct cpio_bin_header *)h;
@@ -620,17 +605,15 @@ header_bin_be(struct archive_read *a, struct cpio *cpio,
 {
        const void *h;
        const struct cpio_bin_header *header;
-       size_t bytes;
 
        a->archive.archive_format = ARCHIVE_FORMAT_CPIO_BIN_BE;
        a->archive.archive_format_name = "cpio (big-endian binary)";
 
        /* Read fixed-size portion of header. */
-       bytes = (a->decompressor->read_ahead)(a, &h,
-           sizeof(struct cpio_bin_header));
-       if (bytes < sizeof(struct cpio_bin_header))
+       h = __archive_read_ahead(a, sizeof(struct cpio_bin_header), NULL);
+       if (h == NULL)
            return (ARCHIVE_FATAL);
-       (a->decompressor->consume)(a, sizeof(struct cpio_bin_header));
+       __archive_read_consume(a, sizeof(struct cpio_bin_header));
 
        /* Parse out binary fields. */
        header = (const struct cpio_bin_header *)h;
index 837fdef997c12ef7c8a27beca84c5c682af685d8..d0d18cfa490d6a592542270870c0be2c25bb8c16 100644 (file)
@@ -57,11 +57,10 @@ archive_read_support_format_empty(struct archive *_a)
 static int
 archive_read_format_empty_bid(struct archive_read *a)
 {
-       int bytes_read;
        const void *h;
 
-       bytes_read = (a->decompressor->read_ahead)(a, &h, 1);
-       if (bytes_read > 0)
+       h = __archive_read_ahead(a, 1, NULL);
+       if (h != NULL)
                return (-1);
        return (1);
 }
index 481220dd47b5f76f7673cf9adc14947862fdc1d7..191ab210c7e5552eea34e6a114b35f5faaeec2b8 100644 (file)
@@ -288,8 +288,8 @@ archive_read_format_iso9660_bid(struct archive_read *a)
         * 8 sectors of the volume descriptor table.  Of course,
         * if the I/O layer gives us more, we'll take it.
         */
-       bytes_read = (a->decompressor->read_ahead)(a, &h, 32768 + 8*2048);
-       if (bytes_read < 32768 + 8*2048)
+       h = __archive_read_ahead(a, 32768 + 8*2048, &bytes_read);
+       if (h == NULL)
            return (-1);
        p = (const unsigned char *)h;
 
@@ -334,7 +334,6 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
 {
        struct iso9660 *iso9660;
        struct file_info *file;
-       ssize_t bytes_read;
        int r;
 
        iso9660 = (struct iso9660 *)(a->format->data);
@@ -407,20 +406,18 @@ archive_read_format_iso9660_read_header(struct archive_read *a,
                        ssize_t step = iso9660->logical_block_size;
                        if (step > iso9660->entry_bytes_remaining)
                                step = iso9660->entry_bytes_remaining;
-                       bytes_read = (a->decompressor->read_ahead)(a, &block, step);
-                       if (bytes_read < step) {
+                       block = __archive_read_ahead(a, step, NULL);
+                       if (block == NULL) {
                                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
            "Failed to read full block when scanning ISO9660 directory list");
                                release_file(iso9660, file);
                                return (ARCHIVE_FATAL);
                        }
-                       if (bytes_read > step)
-                               bytes_read = step;
-                       (a->decompressor->consume)(a, bytes_read);
-                       iso9660->current_position += bytes_read;
-                       iso9660->entry_bytes_remaining -= bytes_read;
+                       __archive_read_consume(a, step);
+                       iso9660->current_position += step;
+                       iso9660->entry_bytes_remaining -= step;
                        for (p = (const unsigned char *)block;
-                            *p != 0 && p < (const unsigned char *)block + bytes_read;
+                            *p != 0 && p < (const unsigned char *)block + step;
                             p += *p) {
                                struct file_info *child;
 
@@ -472,11 +469,11 @@ archive_read_format_iso9660_read_data(struct archive_read *a,
                return (ARCHIVE_EOF);
        }
 
-       bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
+       *buff = __archive_read_ahead(a, 1, &bytes_read);
        if (bytes_read == 0)
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                    "Truncated input file");
-       if (bytes_read <= 0)
+       if (buff == NULL)
                return (ARCHIVE_FATAL);
        if (bytes_read > iso9660->entry_bytes_remaining)
                bytes_read = iso9660->entry_bytes_remaining;
@@ -485,7 +482,7 @@ archive_read_format_iso9660_read_data(struct archive_read *a,
        iso9660->entry_sparse_offset += bytes_read;
        iso9660->entry_bytes_remaining -= bytes_read;
        iso9660->current_position += bytes_read;
-       (a->decompressor->consume)(a, bytes_read);
+       __archive_read_consume(a, bytes_read);
        return (ARCHIVE_OK);
 }
 
@@ -926,7 +923,7 @@ fprintf(stderr, " *** Discarding CE data.\n");
                if (iso9660->current_position < offset) {
                        off_t step = offset - iso9660->current_position;
                        off_t bytes_read;
-                       bytes_read = (a->decompressor->skip)(a, step);
+                       bytes_read = __archive_read_skip(a, step);
                        if (bytes_read < 0)
                                return (bytes_read);
                        iso9660->current_position = offset;
@@ -940,19 +937,18 @@ fprintf(stderr, " *** Discarding CE data.\n");
                if (offset == file->ce_offset) {
                        const void *p;
                        ssize_t size = file->ce_size;
-                       ssize_t bytes_read;
                        const unsigned char *rr_start;
 
                        file->ce_offset = 0;
                        file->ce_size = 0;
-                       bytes_read = (a->decompressor->read_ahead)(a, &p, size);
-                       if (bytes_read > size)
-                               bytes_read = size;
+                       p = __archive_read_ahead(a, size, NULL);
+                       if (p == NULL)
+                               return (ARCHIVE_FATAL);
                        rr_start = (const unsigned char *)p;
                        parse_rockridge(iso9660, file, rr_start,
-                           rr_start + bytes_read);
-                       (a->decompressor->consume)(a, bytes_read);
-                       iso9660->current_position += bytes_read;
+                           rr_start + size);
+                       __archive_read_consume(a, size);
+                       iso9660->current_position += size;
                        add_entry(iso9660, file);
                }
        }
index 1c0a45bdce3ee0895d2036392d6d1ffcfc8dca03..65ec2d6995bf8b661b5fd78bbcafbc1792f4ca20 100644 (file)
@@ -187,32 +187,17 @@ cleanup(struct archive_read *a)
 static int
 mtree_bid(struct archive_read *a)
 {
-       struct mtree *mtree;
-       ssize_t bytes_read;
-       const void *h;
        const char *signature = "#mtree";
        const char *p;
-       int bid;
-
-       mtree = (struct mtree *)(a->format->data);
 
        /* Now let's look at the actual header and see if it matches. */
-       bytes_read = (a->decompressor->read_ahead)(a, &h, strlen(signature));
-
-       if (bytes_read <= 0)
-               return (bytes_read);
-
-       p = h;
-       bid = 0;
-       while (bytes_read > 0 && *signature != '\0') {
-               if (*p != *signature)
-                       return (bid = 0);
-               bid += 8;
-               p++;
-               signature++;
-               bytes_read--;
-       }
-       return (bid);
+       p = __archive_read_ahead(a, strlen(signature), NULL);
+       if (p == NULL)
+               return (-1);
+
+       if (strncmp(p, signature, strlen(signature)) == 0)
+               return (8 * strlen(signature));
+       return (0);
 }
 
 /*
@@ -1239,8 +1224,8 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
        /* Accumulate line in a line buffer. */
        for (;;) {
                /* Read some more. */
-               bytes_read = (a->decompressor->read_ahead)(a, &t, 1);
-               if (bytes_read == 0)
+               t = __archive_read_ahead(a, 1, &bytes_read);
+               if (t == NULL)
                        return (0);
                if (bytes_read < 0)
                        return (ARCHIVE_FATAL);
@@ -1263,7 +1248,7 @@ readline(struct archive_read *a, struct mtree *mtree, char **start, ssize_t limi
                        return (ARCHIVE_FATAL);
                }
                memcpy(mtree->line.s + total_size, t, bytes_read);
-               (a->decompressor->consume)(a, bytes_read);
+               __archive_read_consume(a, bytes_read);
                total_size += bytes_read;
                /* Null terminate. */
                mtree->line.s[total_size] = '\0';
index 0a649791a31dde133ebdea0c5640be332c1146d2..b461e0b53187422fe648c506dde0fd94948eed7a 100644 (file)
@@ -294,21 +294,15 @@ static int
 archive_read_format_tar_bid(struct archive_read *a)
 {
        int bid;
-       ssize_t bytes_read;
        const void *h;
        const struct archive_entry_header_ustar *header;
 
        bid = 0;
 
        /* Now let's look at the actual header and see if it matches. */
-       if (a->decompressor->read_ahead != NULL)
-               bytes_read = (a->decompressor->read_ahead)(a, &h, 512);
-       else
-               bytes_read = 0; /* Empty file. */
-       if (bytes_read < 0)
-               return (ARCHIVE_FATAL);
-       if (bytes_read < 512)
-               return (0);
+       h = __archive_read_ahead(a, 512, NULL);
+       if (h == NULL)
+               return (-1);
 
        /* If it's an end-of-archive mark, we can handle it. */
        if ((*(const char *)h) == 0
@@ -479,7 +473,7 @@ archive_read_format_tar_read_data(struct archive_read *a,
 
        /* If we're at end of file, return EOF. */
        if (tar->sparse_list == NULL || tar->entry_bytes_remaining == 0) {
-               if ((a->decompressor->skip)(a, tar->entry_padding) < 0)
+               if (__archive_read_skip(a, tar->entry_padding) < 0)
                        return (ARCHIVE_FATAL);
                tar->entry_padding = 0;
                *buff = NULL;
@@ -488,14 +482,14 @@ archive_read_format_tar_read_data(struct archive_read *a,
                return (ARCHIVE_EOF);
        }
 
-       bytes_read = (a->decompressor->read_ahead)(a, buff, 1);
-       if (bytes_read == 0) {
+       *buff = __archive_read_ahead(a, 1, &bytes_read);
+       if (bytes_read < 0)
+               return (ARCHIVE_FATAL);
+       if (*buff == NULL) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC,
                    "Truncated tar archive");
                return (ARCHIVE_FATAL);
        }
-       if (bytes_read < 0)
-               return (ARCHIVE_FATAL);
        if (bytes_read > tar->entry_bytes_remaining)
                bytes_read = tar->entry_bytes_remaining;
        /* Don't read more than is available in the
@@ -507,7 +501,7 @@ archive_read_format_tar_read_data(struct archive_read *a,
        tar->sparse_list->remaining -= bytes_read;
        tar->sparse_list->offset += bytes_read;
        tar->entry_bytes_remaining -= bytes_read;
-       (a->decompressor->consume)(a, bytes_read);
+       __archive_read_consume(a, bytes_read);
        return (ARCHIVE_OK);
 }
 
@@ -524,8 +518,8 @@ archive_read_format_tar_skip(struct archive_read *a)
         * length requested or fail, so we can rely upon the entire entry
         * plus padding being skipped.
         */
-       bytes_skipped = (a->decompressor->skip)(a, tar->entry_bytes_remaining +
-           tar->entry_padding);
+       bytes_skipped = __archive_read_skip(a,
+           tar->entry_bytes_remaining + tar->entry_padding);
        if (bytes_skipped < 0)
                return (ARCHIVE_FATAL);
 
@@ -552,12 +546,12 @@ tar_read_header(struct archive_read *a, struct tar *tar,
        const struct archive_entry_header_ustar *header;
 
        /* Read 512-byte header record */
-       bytes = (a->decompressor->read_ahead)(a, &h, 512);
+       h = __archive_read_ahead(a, 512, &bytes);
        if (bytes < 0)
                return (bytes);
        if (bytes < 512) {  /* Short read or EOF. */
                /* Try requesting just one byte and see what happens. */
-               bytes = (a->decompressor->read_ahead)(a, &h, 1);
+               h = __archive_read_ahead(a, 1, &bytes);
                if (bytes == 0) {
                        /*
                         * The archive ends at a 512-byte boundary but
@@ -572,15 +566,15 @@ tar_read_header(struct archive_read *a, struct tar *tar,
                    "Truncated tar archive");
                return (ARCHIVE_FATAL);
        }
-       (a->decompressor->consume)(a, 512);
+       __archive_read_consume(a, 512);
 
 
        /* Check for end-of-archive mark. */
        if (((*(const char *)h)==0) && archive_block_is_null((const unsigned char *)h)) {
                /* Try to consume a second all-null record, as well. */
-               bytes = (a->decompressor->read_ahead)(a, &h, 512);
-               if (bytes > 0)
-                       (a->decompressor->consume)(a, bytes);
+               h = __archive_read_ahead(a, 512, NULL);
+               if (h != NULL)
+                       __archive_read_consume(a, 512);
                archive_set_error(&a->archive, 0, NULL);
                if (a->archive.archive_format_name == NULL) {
                        a->archive.archive_format = ARCHIVE_FORMAT_TAR;
@@ -841,10 +835,8 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
     struct archive_string *as, const void *h)
 {
        off_t size, padded_size;
-       ssize_t bytes_read, bytes_to_copy;
        const struct archive_entry_header_ustar *header;
        const void *src;
-       char *dest;
 
        (void)tar; /* UNUSED */
        header = (const struct archive_entry_header_ustar *)h;
@@ -862,27 +854,14 @@ read_body_to_string(struct archive_read *a, struct tar *tar,
                return (ARCHIVE_FATAL);
        }
 
-       /* Read the body into the string. */
+       /* Read the body into the string. */
        padded_size = (size + 511) & ~ 511;
-       dest = as->s;
-       while (padded_size > 0) {
-               bytes_read = (a->decompressor->read_ahead)(a, &src, padded_size);
-               if (bytes_read == 0)
-                       return (ARCHIVE_EOF);
-               if (bytes_read < 0)
-                       return (ARCHIVE_FATAL);
-               if (bytes_read > padded_size)
-                       bytes_read = padded_size;
-               (a->decompressor->consume)(a, bytes_read);
-               bytes_to_copy = bytes_read;
-               if ((off_t)bytes_to_copy > size)
-                       bytes_to_copy = (ssize_t)size;
-               memcpy(dest, src, bytes_to_copy);
-               dest += bytes_to_copy;
-               size -= bytes_to_copy;
-               padded_size -= bytes_read;
-       }
-       *dest = '\0';
+       src = __archive_read_ahead(a, padded_size, NULL);
+       if (src == NULL)
+               return (ARCHIVE_FATAL);
+       memcpy(as->s, src, size);
+       __archive_read_consume(a, padded_size);
+       as->s[size] = '\0';
        return (ARCHIVE_OK);
 }
 
@@ -1770,7 +1749,7 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
                return (ARCHIVE_OK);
 
        do {
-               bytes_read = (a->decompressor->read_ahead)(a, &data, 512);
+               data = __archive_read_ahead(a, 512, &bytes_read);
                if (bytes_read < 0)
                        return (ARCHIVE_FATAL);
                if (bytes_read < 512) {
@@ -1779,7 +1758,7 @@ gnu_sparse_old_read(struct archive_read *a, struct tar *tar,
                            "detected while reading sparse file data");
                        return (ARCHIVE_FATAL);
                }
-               (a->decompressor->consume)(a, 512);
+               __archive_read_consume(a, 512);
                ext = (const struct extended *)data;
                gnu_sparse_old_parse(tar, ext->sparse, 21);
        } while (ext->isextended[0] != 0);
@@ -1957,7 +1936,7 @@ gnu_sparse_10_read(struct archive_read *a, struct tar *tar)
        /* Skip rest of block... */
        bytes_read = tar->entry_bytes_remaining - remaining;
        to_skip = 0x1ff & -bytes_read;
-       if (to_skip != (a->decompressor->skip)(a, to_skip))
+       if (to_skip != __archive_read_skip(a, to_skip))
                return (ARCHIVE_FATAL);
        return (bytes_read + to_skip);
 }
@@ -2112,7 +2091,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
        const char *s;
        void *p;
 
-       bytes_read = (a->decompressor->read_ahead)(a, &t, 1);
+       t = __archive_read_ahead(a, 1, &bytes_read);
        if (bytes_read <= 0)
                return (ARCHIVE_FATAL);
        s = t;  /* Start of line? */
@@ -2126,7 +2105,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
                            "Line too long");
                        return (ARCHIVE_FATAL);
                }
-               (a->decompressor->consume)(a, bytes_read);
+               __archive_read_consume(a, bytes_read);
                *start = s;
                return (bytes_read);
        }
@@ -2144,7 +2123,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
                        return (ARCHIVE_FATAL);
                }
                memcpy(tar->line.s + total_size, t, bytes_read);
-               (a->decompressor->consume)(a, bytes_read);
+               __archive_read_consume(a, bytes_read);
                total_size += bytes_read;
                /* If we found '\n', clean up and return. */
                if (p != NULL) {
@@ -2152,7 +2131,7 @@ readline(struct archive_read *a, struct tar *tar, const char **start,
                        return (total_size);
                }
                /* Read some more. */
-               bytes_read = (a->decompressor->read_ahead)(a, &t, 1);
+               t = __archive_read_ahead(a, 1, &bytes_read);
                if (bytes_read <= 0)
                        return (ARCHIVE_FATAL);
                s = t;  /* Start of line? */
index a7703502b214426953886622cdf440a5714fc861..a22eaa0a3fda9765ef76e3beb05227c534dc3c8c 100644 (file)
@@ -169,7 +169,7 @@ archive_read_format_zip_bid(struct archive_read *a)
        const void *buff;
        size_t bytes_avail, offset;
 
-       if ((p = __archive_read_ahead(a, 4)) == NULL)
+       if ((p = __archive_read_ahead(a, 4, NULL)) == NULL)
                return (-1);
 
        /*
@@ -203,8 +203,8 @@ archive_read_format_zip_bid(struct archive_read *a)
                offset = 0;
                while (offset < 124000) {
                        /* Get 4k of data beyond where we stopped. */
-                       bytes_avail = (a->decompressor->read_ahead)(a, &buff,
-                           offset + 4096);
+                       buff = __archive_read_ahead(a, offset + 4096,
+                           &bytes_avail);
                        if (bytes_avail < offset + 1)
                                break;
                        p = (const char *)buff + offset;
@@ -246,7 +246,7 @@ skip_sfx(struct archive_read *a)
         * reduce the chance of a false positive.
         */
        for (;;) {
-               bytes = (a->decompressor->read_ahead)(a, &h, 4);
+               h = __archive_read_ahead(a, 4, &bytes);
                if (bytes < 4)
                        return (ARCHIVE_FATAL);
                p = h;
@@ -262,7 +262,7 @@ skip_sfx(struct archive_read *a)
                                /* TODO: Additional verification here. */
                                if (memcmp("PK\003\004", p, 4) == 0) {
                                        skip = p - (const char *)h;
-                                       (a->decompressor->consume)(a, skip);
+                                       __archive_read_consume(a, skip);
                                        return (ARCHIVE_OK);
                                }
                                p += 4;
@@ -274,7 +274,7 @@ skip_sfx(struct archive_read *a)
                        }
                }
                skip = p - (const char *)h;
-               (a->decompressor->consume)(a, skip);
+               __archive_read_consume(a, skip);
        }
 }
 
@@ -298,7 +298,7 @@ archive_read_format_zip_read_header(struct archive_read *a,
        zip->entry_uncompressed_bytes_read = 0;
        zip->entry_compressed_bytes_read = 0;
        zip->entry_crc32 = crc32(0, NULL, 0);
-       if ((h = __archive_read_ahead(a, 4)) == NULL)
+       if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
                return (ARCHIVE_FATAL);
 
        signature = (const char *)h;
@@ -307,7 +307,7 @@ archive_read_format_zip_read_header(struct archive_read *a,
                r = skip_sfx(a);
                if (r < ARCHIVE_WARN)
                        return (r);
-               if ((h = __archive_read_ahead(a, 4)) == NULL)
+               if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
                        return (ARCHIVE_FATAL);
                signature = (const char *)h;
        }
@@ -324,8 +324,8 @@ archive_read_format_zip_read_header(struct archive_read *a,
         * skip the PK00; the first real file header should follow.
         */
        if (signature[2] == '0' && signature[3] == '0') {
-               (a->decompressor->consume)(a, 4);
-               if ((h = __archive_read_ahead(a, 4)) == NULL)
+               __archive_read_consume(a, 4);
+               if ((h = __archive_read_ahead(a, 4, NULL)) == NULL)
                        return (ARCHIVE_FATAL);
                signature = (const char *)h;
                if (signature[0] != 'P' || signature[1] != 'K') {
@@ -376,7 +376,7 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
        const struct zip_file_header *p;
        const void *h;
 
-       if ((p = __archive_read_ahead(a, sizeof *p)) == NULL) {
+       if ((p = __archive_read_ahead(a, sizeof *p, NULL)) == NULL) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                    "Truncated ZIP file header");
                return (ARCHIVE_FATAL);
@@ -403,11 +403,11 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
        zip->uncompressed_size = archive_le32dec(p->uncompressed_size);
        zip->compressed_size = archive_le32dec(p->compressed_size);
 
-       (a->decompressor->consume)(a, sizeof(struct zip_file_header));
+       __archive_read_consume(a, sizeof(struct zip_file_header));
 
 
        /* Read the filename. */
-       if ((h = __archive_read_ahead(a, zip->filename_length)) == NULL) {
+       if ((h = __archive_read_ahead(a, zip->filename_length, NULL)) == NULL) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                    "Truncated ZIP file header");
                return (ARCHIVE_FATAL);
@@ -415,7 +415,7 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
        if (archive_string_ensure(&zip->pathname, zip->filename_length) == NULL)
                __archive_errx(1, "Out of memory");
        archive_strncpy(&zip->pathname, h, zip->filename_length);
-       (a->decompressor->consume)(a, zip->filename_length);
+       __archive_read_consume(a, zip->filename_length);
        archive_entry_set_pathname(entry, zip->pathname.s);
 
        if (zip->pathname.s[archive_strlen(&zip->pathname) - 1] == '/')
@@ -424,13 +424,13 @@ zip_read_file_header(struct archive_read *a, struct archive_entry *entry,
                zip->mode = AE_IFREG | 0777;
 
        /* Read the extra data. */
-       if ((h = __archive_read_ahead(a, zip->extra_length)) == NULL) {
+       if ((h = __archive_read_ahead(a, zip->extra_length, NULL)) == NULL) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                    "Truncated ZIP file header");
                return (ARCHIVE_FATAL);
        }
        process_extra(h, zip);
-       (a->decompressor->consume)(a, zip->extra_length);
+       __archive_read_consume(a, zip->extra_length);
 
        /* Populate some additional entry fields: */
        archive_entry_set_mode(entry, zip->mode);
@@ -499,7 +499,7 @@ archive_read_format_zip_read_data(struct archive_read *a,
                        if (zip->flags & ZIP_LENGTH_AT_END) {
                                const char *p;
 
-                               if ((p = __archive_read_ahead(a, 16)) == NULL) {
+                               if ((p = __archive_read_ahead(a, 16, NULL)) == NULL) {
                                        archive_set_error(&a->archive,
                                            ARCHIVE_ERRNO_FILE_FORMAT,
                                            "Truncated ZIP end-of-file record");
@@ -508,7 +508,7 @@ archive_read_format_zip_read_data(struct archive_read *a,
                                zip->crc32 = archive_le32dec(p + 4);
                                zip->compressed_size = archive_le32dec(p + 8);
                                zip->uncompressed_size = archive_le32dec(p + 12);
-                               (a->decompressor->consume)(a, 16);
+                               __archive_read_consume(a, 16);
                        }
 
                        /* Check file size, CRC against these values. */
@@ -617,7 +617,7 @@ zip_read_data_none(struct archive_read *a, const void **buff,
         * available bytes; asking for more than that forces the
         * decompressor to combine reads by copying data.
         */
-       bytes_avail = (a->decompressor->read_ahead)(a, buff, 1);
+       *buff = __archive_read_ahead(a, 1, &bytes_avail);
        if (bytes_avail <= 0) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                    "Truncated ZIP file data");
@@ -625,7 +625,7 @@ zip_read_data_none(struct archive_read *a, const void **buff,
        }
        if (bytes_avail > zip->entry_bytes_remaining)
                bytes_avail = zip->entry_bytes_remaining;
-       (a->decompressor->consume)(a, bytes_avail);
+       __archive_read_consume(a, bytes_avail);
        *size = bytes_avail;
        *offset = zip->entry_offset;
        zip->entry_offset += *size;
@@ -683,7 +683,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
         * available bytes; asking for more than that forces the
         * decompressor to combine reads by copying data.
         */
-       bytes_avail = (a->decompressor->read_ahead)(a, &compressed_buff, 1);
+       compressed_buff = __archive_read_ahead(a, 1, &bytes_avail);
        if (bytes_avail <= 0) {
                archive_set_error(&a->archive, ARCHIVE_ERRNO_FILE_FORMAT,
                    "Truncated ZIP file body");
@@ -722,7 +722,7 @@ zip_read_data_deflate(struct archive_read *a, const void **buff,
 
        /* Consume as much as the compressor actually used. */
        bytes_avail = zip->stream.total_in;
-       (a->decompressor->consume)(a, bytes_avail);
+       __archive_read_consume(a, bytes_avail);
        zip->entry_bytes_remaining -= bytes_avail;
        zip->entry_compressed_bytes_read += bytes_avail;
 
@@ -779,7 +779,7 @@ archive_read_format_zip_read_data_skip(struct archive_read *a)
         * If the length is at the beginning, we can skip the
         * compressed data much more quickly.
         */
-       bytes_skipped = (a->decompressor->skip)(a, zip->entry_bytes_remaining);
+       bytes_skipped = __archive_read_skip(a, zip->entry_bytes_remaining);
        if (bytes_skipped < 0)
                return (ARCHIVE_FATAL);