reader: introduce struct archive_read_filter_vtable

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>
This commit is contained in:
Emil Velikov committed 2021-10-23 19:26:23 +01:00
1 parent 70ee6cb826
commit 4b7558e108
12 files changed
+97 -38

No files matched your search

+13 -9
View 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;
+10 -6
View 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;
@@ -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);
}
@@ -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 */
+10 -5
View 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. */
+7 -2
View 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);
}
@@ -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);
}
@@ -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);
+7 -2
View 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);
}
+7 -2
View 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);
}
+7 -2
View 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;
@@ -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;