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:
1 parent
70ee6cb826
commit
4b7558e108
12 files changed
+97
-38
No files matched your search
@@ -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;
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
@@ -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. */
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user