]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
reader: introduce struct archive_read_filter_vtable 1603/head
authorEmil Velikov <emil.l.velikov@gmail.com>
Sat, 14 Mar 2020 21:44:48 +0000 (21:44 +0000)
committerEmil Velikov <emil.l.velikov@gmail.com>
Sat, 23 Oct 2021 18:26:23 +0000 (19:26 +0100)
As before - move the dispatch/function pointer so a const data segment.
Separating it from the RW data section.

Note: the close function is _not_ optional - remove the NULL check.

Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
12 files changed:
libarchive/archive_read.c
libarchive/archive_read_private.h
libarchive/archive_read_support_filter_bzip2.c
libarchive/archive_read_support_filter_compress.c
libarchive/archive_read_support_filter_gzip.c
libarchive/archive_read_support_filter_lz4.c
libarchive/archive_read_support_filter_lzop.c
libarchive/archive_read_support_filter_program.c
libarchive/archive_read_support_filter_rpm.c
libarchive/archive_read_support_filter_uu.c
libarchive/archive_read_support_filter_xz.c
libarchive/archive_read_support_filter_zstd.c

index 0ed27a8c0e221cd471c45cb57b18906a32e96cc3..45a38aed02b670d45afb2cba9c98c2e27083b600 100644 (file)
@@ -451,6 +451,12 @@ archive_read_prepend_callback_data(struct archive *_a, void *client_data)
        return archive_read_add_callback_data(_a, client_data, 0);
 }
 
+static const struct archive_read_filter_vtable
+none_reader_vtable = {
+       .read = client_read_proxy,
+       .close = client_close_proxy,
+};
+
 int
 archive_read_open1(struct archive *_a)
 {
@@ -486,8 +492,7 @@ archive_read_open1(struct archive *_a)
        filter->upstream = NULL;
        filter->archive = a;
        filter->data = a->client.dataset[0].data;
-       filter->read = client_read_proxy;
-       filter->close = client_close_proxy;
+       filter->vtable = &none_reader_vtable;
        filter->name = "none";
        filter->code = ARCHIVE_FILTER_NONE;
        filter->can_skip = 1;
@@ -599,10 +604,9 @@ choose_filters(struct archive_read *a)
 int
 __archive_read_header(struct archive_read *a, struct archive_entry *entry)
 {
-       if (a->filter->read_header)
-               return a->filter->read_header(a->filter, entry);
-       else
+       if (!a->filter->vtable->read_header)
                return (ARCHIVE_OK);
+       return a->filter->vtable->read_header(a->filter, entry);
 }
 
 /*
@@ -991,8 +995,8 @@ close_filters(struct archive_read *a)
        /* Close each filter in the pipeline. */
        while (f != NULL) {
                struct archive_read_filter *t = f->upstream;
-               if (!f->closed && f->close != NULL) {
-                       int r1 = (f->close)(f);
+               if (!f->closed && f->vtable != NULL) {
+                       int r1 = (f->vtable->close)(f);
                        f->closed = 1;
                        if (r1 < r)
                                r = r1;
@@ -1382,7 +1386,7 @@ __archive_read_filter_ahead(struct archive_read_filter *filter,
                                        *avail = 0;
                                return (NULL);
                        }
-                       bytes_read = (filter->read)(filter,
+                       bytes_read = (filter->vtable->read)(filter,
                            &filter->client_buff);
                        if (bytes_read < 0) {           /* Read error. */
                                filter->client_total = filter->client_avail = 0;
@@ -1576,7 +1580,7 @@ advance_file_pointer(struct archive_read_filter *filter, int64_t request)
 
        /* Use ordinary reads as necessary to complete the request. */
        for (;;) {
-               bytes_read = (filter->read)(filter, &filter->client_buff);
+               bytes_read = (filter->vtable->read)(filter, &filter->client_buff);
                if (bytes_read < 0) {
                        filter->client_buff = NULL;
                        filter->fatal = 1;
index 98d45fe872e86a5ff932c5e67e1b196321b6378b..383405d52908ffe734d4d867d3ea6426505446a0 100644 (file)
@@ -75,6 +75,15 @@ struct archive_read_filter_bidder {
        const struct archive_read_filter_bidder_vtable *vtable;
 };
 
+struct archive_read_filter_vtable {
+       /* Return next block. */
+       ssize_t (*read)(struct archive_read_filter *, const void **);
+       /* Close (just this filter) and free(self). */
+       int (*close)(struct archive_read_filter *self);
+       /* Read any header metadata if available. */
+       int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
+};
+
 /*
  * This structure is allocated within the archive_read core
  * and initialized by archive_read and the init() method of the
@@ -87,12 +96,7 @@ struct archive_read_filter {
        struct archive_read_filter_bidder *bidder; /* My bidder. */
        struct archive_read_filter *upstream; /* Who I read from. */
        struct archive_read *archive; /* Associated archive. */
-       /* Return next block. */
-       ssize_t (*read)(struct archive_read_filter *, const void **);
-       /* Close (just this filter) and free(self). */
-       int (*close)(struct archive_read_filter *self);
-       /* Read any header metadata if available. */
-       int (*read_header)(struct archive_read_filter *self, struct archive_entry *entry);
+       const struct archive_read_filter_vtable *vtable;
        /* My private data. */
        void *data;
 
index d969383ef14ffc86ec157f8508654909058a77f7..793d605c87250332c2e080f518a5825c0b1153bd 100644 (file)
@@ -173,6 +173,12 @@ bzip2_reader_init(struct archive_read_filter *self)
 
 #else
 
+static const struct archive_read_filter_vtable
+bzip2_reader_vtable = {
+       .read = bzip2_filter_read,
+       .close = bzip2_filter_close,
+};
+
 /*
  * Setup the callbacks.
  */
@@ -199,8 +205,7 @@ bzip2_reader_init(struct archive_read_filter *self)
        self->data = state;
        state->out_block_size = out_block_size;
        state->out_block = out_block;
-       self->read = bzip2_filter_read;
-       self->close = bzip2_filter_close;
+       self->vtable = &bzip2_reader_vtable;
 
        return (ARCHIVE_OK);
 }
index f278ac7d6b0221fec6ae2e2829bb4be75ec6bec5..05b80a576ac1c4043be3fbfc756cfa61b54dde3d 100644 (file)
@@ -198,6 +198,12 @@ compress_bidder_bid(struct archive_read_filter_bidder *self,
        return (bits_checked);
 }
 
+static const struct archive_read_filter_vtable
+compress_reader_vtable = {
+       .read = compress_filter_read,
+       .close = compress_filter_close,
+};
+
 /*
  * Setup the callbacks.
  */
@@ -226,8 +232,7 @@ compress_bidder_init(struct archive_read_filter *self)
        self->data = state;
        state->out_block_size = out_block_size;
        state->out_block = out_block;
-       self->read = compress_filter_read;
-       self->close = compress_filter_close;
+       self->vtable = &compress_reader_vtable;
 
        /* XXX MOVE THE FOLLOWING OUT OF INIT() XXX */
 
index 0a9c065a6ded5082d35c638a2d6bcf9321db9b34..4135a6361802e6a281c50c6b366aecb0b46b9d0c 100644 (file)
@@ -288,6 +288,15 @@ gzip_read_header(struct archive_read_filter *self, struct archive_entry *entry)
        return (ARCHIVE_OK);
 }
 
+static const struct archive_read_filter_vtable
+gzip_reader_vtable = {
+       .read = gzip_filter_read,
+       .close = gzip_filter_close,
+#ifdef HAVE_ZLIB_H
+       .read_header = gzip_read_header,
+#endif
+};
+
 /*
  * Initialize the filter object.
  */
@@ -314,11 +323,7 @@ gzip_bidder_init(struct archive_read_filter *self)
        self->data = state;
        state->out_block_size = out_block_size;
        state->out_block = out_block;
-       self->read = gzip_filter_read;
-       self->close = gzip_filter_close;
-#ifdef HAVE_ZLIB_H
-       self->read_header = gzip_read_header;
-#endif
+       self->vtable = &gzip_reader_vtable;
 
        state->in_stream = 0; /* We're not actually within a stream yet. */
 
index 082bb7fe74ce279053aae899a21fe3678613bc16..ae0b08003f80cb5b0b9c2f6c6bd7d24263822f8b 100644 (file)
@@ -208,6 +208,12 @@ lz4_reader_init(struct archive_read_filter *self)
 
 #else
 
+static const struct archive_read_filter_vtable
+lz4_reader_vtable = {
+       .read = lz4_filter_read,
+       .close = lz4_filter_close,
+};
+
 /*
  * Setup the callbacks.
  */
@@ -228,8 +234,7 @@ lz4_reader_init(struct archive_read_filter *self)
 
        self->data = state;
        state->stage = SELECT_STREAM;
-       self->read = lz4_filter_read;
-       self->close = lz4_filter_close;
+       self->vtable = &lz4_reader_vtable;
 
        return (ARCHIVE_OK);
 }
index 98902bfd8a103c38fa1ecbc11b3ce53e8d515ac5..53850928a75770b4a8761b1a284e1e6fd6622bd9 100644 (file)
@@ -169,6 +169,13 @@ lzop_bidder_init(struct archive_read_filter *self)
        return (r);
 }
 #else
+
+static const struct archive_read_filter_vtable
+lzop_reader_vtable = {
+       .read = lzop_filter_read,
+       .close = lzop_filter_close.
+};
+
 /*
  * Initialize the filter object.
  */
@@ -188,8 +195,7 @@ lzop_bidder_init(struct archive_read_filter *self)
        }
 
        self->data = state;
-       self->read = lzop_filter_read;
-       self->close = lzop_filter_close;
+       self->vtable = &lzop_reader_vtable;
 
        return (ARCHIVE_OK);
 }
index 839354748143b037565ca6729cd99346727c918e..885b2c2056e66e113e33ba63f0d560fc350e9dd9 100644 (file)
@@ -382,6 +382,12 @@ child_read(struct archive_read_filter *self, char *buf, size_t buf_len)
        }
 }
 
+static const struct archive_read_filter_vtable
+program_reader_vtable = {
+       .read = program_filter_read,
+       .close = program_filter_close,
+};
+
 int
 __archive_read_program(struct archive_read_filter *self, const char *cmd)
 {
@@ -428,8 +434,7 @@ __archive_read_program(struct archive_read_filter *self, const char *cmd)
        }
 
        self->data = state;
-       self->read = program_filter_read;
-       self->close = program_filter_close;
+       self->vtable = &program_reader_vtable;
 
        /* XXX Check that we can read at least one byte? */
        return (ARCHIVE_OK);
index 2cce174557663a98a54f41e78c64771b0af0034a..67a979cd78f6022abea69e23cb564d394fe91531 100644 (file)
@@ -127,6 +127,12 @@ rpm_bidder_bid(struct archive_read_filter_bidder *self,
        return (bits_checked);
 }
 
+static const struct archive_read_filter_vtable
+rpm_reader_vtable = {
+       .read = rpm_filter_read,
+       .close = rpm_filter_close,
+};
+
 static int
 rpm_bidder_init(struct archive_read_filter *self)
 {
@@ -134,8 +140,6 @@ rpm_bidder_init(struct archive_read_filter *self)
 
        self->code = ARCHIVE_FILTER_RPM;
        self->name = "rpm";
-       self->read = rpm_filter_read;
-       self->close = rpm_filter_close;
 
        rpm = (struct rpm *)calloc(sizeof(*rpm), 1);
        if (rpm == NULL) {
@@ -146,6 +150,7 @@ rpm_bidder_init(struct archive_read_filter *self)
 
        self->data = rpm;
        rpm->state = ST_LEAD;
+       self->vtable = &rpm_reader_vtable;
 
        return (ARCHIVE_OK);
 }
index 7252a6d6741621445a983db0af31b04dc219d4e3..209b2a1593a096a841fcd139fc5fb19195f82259 100644 (file)
@@ -351,6 +351,12 @@ uudecode_bidder_bid(struct archive_read_filter_bidder *self,
        return (0);
 }
 
+static const struct archive_read_filter_vtable
+uudecode_reader_vtable = {
+       .read = uudecode_filter_read,
+       .close = uudecode_filter_close,
+};
+
 static int
 uudecode_bidder_init(struct archive_read_filter *self)
 {
@@ -360,8 +366,6 @@ uudecode_bidder_init(struct archive_read_filter *self)
 
        self->code = ARCHIVE_FILTER_UU;
        self->name = "uu";
-       self->read = uudecode_filter_read;
-       self->close = uudecode_filter_close;
 
        uudecode = (struct uudecode *)calloc(sizeof(*uudecode), 1);
        out_buff = malloc(OUT_BUFF_SIZE);
@@ -381,6 +385,7 @@ uudecode_bidder_init(struct archive_read_filter *self)
        uudecode->in_allocated = IN_BUFF_SIZE;
        uudecode->out_buff = out_buff;
        uudecode->state = ST_FIND_HEAD;
+       self->vtable = &uudecode_reader_vtable;
 
        return (ARCHIVE_OK);
 }
index e8b5300c58595ad5ba3c7e429e728a717de5e0df..ce89807e108a16d79f0ec1f7316bba55553ae103 100644 (file)
@@ -461,6 +461,12 @@ set_error(struct archive_read_filter *self, int ret)
        }
 }
 
+static const struct archive_read_filter_vtable
+xz_lzma_reader_vtable = {
+       .read = xz_filter_read,
+       .close = xz_filter_close,
+};
+
 /*
  * Setup the callbacks.
  */
@@ -485,8 +491,7 @@ xz_lzma_bidder_init(struct archive_read_filter *self)
        self->data = state;
        state->out_block_size = out_block_size;
        state->out_block = out_block;
-       self->read = xz_filter_read;
-       self->close = xz_filter_close;
+       self->vtable = &xz_lzma_reader_vtable;
 
        state->stream.avail_in = 0;
 
index f7e2923cfd1c4bf7df4bd53bd9413e434a861787..39f25f1bf88e2597a1ebd688ef61fb359c786eab 100644 (file)
@@ -157,6 +157,12 @@ zstd_bidder_init(struct archive_read_filter *self)
 
 #else
 
+static const struct archive_read_filter_vtable
+zstd_reader_vtable = {
+       .read = zstd_filter_read,
+       .close = zstd_filter_close,
+};
+
 /*
  * Initialize the filter object
  */
@@ -189,8 +195,7 @@ zstd_bidder_init(struct archive_read_filter *self)
        state->out_block_size = out_block_size;
        state->out_block = out_block;
        state->dstream = dstream;
-       self->read = zstd_filter_read;
-       self->close = zstd_filter_close;
+       self->vtable = &zstd_reader_vtable;
 
        state->eof = 0;
        state->in_frame = 0;