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>
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)
{
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;
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);
}
/*
/* 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;
*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;
/* 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;
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
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;
#else
+static const struct archive_read_filter_vtable
+bzip2_reader_vtable = {
+ .read = bzip2_filter_read,
+ .close = bzip2_filter_close,
+};
+
/*
* Setup the callbacks.
*/
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);
}
return (bits_checked);
}
+static const struct archive_read_filter_vtable
+compress_reader_vtable = {
+ .read = compress_filter_read,
+ .close = compress_filter_close,
+};
+
/*
* Setup the callbacks.
*/
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 */
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.
*/
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. */
#else
+static const struct archive_read_filter_vtable
+lz4_reader_vtable = {
+ .read = lz4_filter_read,
+ .close = lz4_filter_close,
+};
+
/*
* Setup the callbacks.
*/
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);
}
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.
*/
}
self->data = state;
- self->read = lzop_filter_read;
- self->close = lzop_filter_close;
+ self->vtable = &lzop_reader_vtable;
return (ARCHIVE_OK);
}
}
}
+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)
{
}
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);
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)
{
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) {
self->data = rpm;
rpm->state = ST_LEAD;
+ self->vtable = &rpm_reader_vtable;
return (ARCHIVE_OK);
}
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)
{
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);
uudecode->in_allocated = IN_BUFF_SIZE;
uudecode->out_buff = out_buff;
uudecode->state = ST_FIND_HEAD;
+ self->vtable = &uudecode_reader_vtable;
return (ARCHIVE_OK);
}
}
}
+static const struct archive_read_filter_vtable
+xz_lzma_reader_vtable = {
+ .read = xz_filter_read,
+ .close = xz_filter_close,
+};
+
/*
* Setup the callbacks.
*/
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;
#else
+static const struct archive_read_filter_vtable
+zstd_reader_vtable = {
+ .read = zstd_filter_read,
+ .close = zstd_filter_close,
+};
+
/*
* Initialize the filter object
*/
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;