reader: introduce archive_read_filter_bidder::vtable
Provides a clear separation between RW data and RO executable code. Signed-off-by: Emil Velikov <emil.l.velikov@gmail.com>
This commit is contained in:
1 parent
0e0d31a7d2
commit
64b82ac5c8
15 files changed
+128
-66
No files matched your search
+16
-15
@@ -561,12 +561,12 @@ choose_filters(struct archive_read *a)
|
||||
|
||||
bidder = a->bidders;
|
||||
for (i = 0; i < number_bidders; i++, bidder++) {
|
||||
if (bidder->bid != NULL) {
|
||||
bid = (bidder->bid)(bidder, a->filter);
|
||||
if (bid > best_bid) {
|
||||
best_bid = bid;
|
||||
best_bidder = bidder;
|
||||
}
|
||||
if (bidder->vtable == NULL)
|
||||
continue;
|
||||
bid = (bidder->vtable->bid)(bidder, a->filter);
|
||||
if (bid > best_bid) {
|
||||
best_bid = bid;
|
||||
best_bidder = bidder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,7 +591,7 @@ choose_filters(struct archive_read *a)
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r = (best_bidder->init)(a->filter);
|
||||
r = (best_bidder->vtable->init)(a->filter);
|
||||
if (r != ARCHIVE_OK) {
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
@@ -1103,9 +1103,10 @@ _archive_read_free(struct archive *_a)
|
||||
/* Release the bidder objects. */
|
||||
n = sizeof(a->bidders)/sizeof(a->bidders[0]);
|
||||
for (i = 0; i < n; i++) {
|
||||
if (a->bidders[i].free != NULL) {
|
||||
(a->bidders[i].free)(&a->bidders[i]);
|
||||
}
|
||||
if (a->bidders[i].vtable == NULL ||
|
||||
a->bidders[i].vtable->free == NULL)
|
||||
continue;
|
||||
(a->bidders[i].vtable->free)(&a->bidders[i]);
|
||||
}
|
||||
|
||||
/* Release passphrase list. */
|
||||
@@ -1238,11 +1239,11 @@ __archive_read_get_bidder(struct archive_read *a,
|
||||
number_slots = sizeof(a->bidders) / sizeof(a->bidders[0]);
|
||||
|
||||
for (i = 0; i < number_slots; i++) {
|
||||
if (a->bidders[i].bid == NULL) {
|
||||
memset(a->bidders + i, 0, sizeof(a->bidders[0]));
|
||||
*bidder = (a->bidders + i);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
if (a->bidders[i].vtable != NULL)
|
||||
continue;
|
||||
memset(a->bidders + i, 0, sizeof(a->bidders[0]));
|
||||
*bidder = (a->bidders + i);
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
archive_set_error(&a->archive, ENOMEM,
|
||||
|
||||
@@ -135,7 +135,7 @@ archive_read_append_filter(struct archive *_a, int code)
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r2 = (bidder->init)(a->filter);
|
||||
r2 = (bidder->vtable->init)(a->filter);
|
||||
if (r2 != ARCHIVE_OK) {
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
@@ -192,7 +192,7 @@ archive_read_append_filter_program_signature(struct archive *_a,
|
||||
filter->archive = a;
|
||||
filter->upstream = a->filter;
|
||||
a->filter = filter;
|
||||
r = (bidder->init)(a->filter);
|
||||
r = (bidder->vtable->init)(a->filter);
|
||||
if (r != ARCHIVE_OK) {
|
||||
__archive_read_free_filters(a);
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
@@ -42,6 +42,16 @@ struct archive_read;
|
||||
struct archive_read_filter_bidder;
|
||||
struct archive_read_filter;
|
||||
|
||||
struct archive_read_filter_bidder_vtable {
|
||||
/* Taste the upstream filter to see if we handle this. */
|
||||
int (*bid)(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
/* Initialize a newly-created filter. */
|
||||
int (*init)(struct archive_read_filter *);
|
||||
/* Release the bidder's configuration data. */
|
||||
void (*free)(struct archive_read_filter_bidder *);
|
||||
};
|
||||
|
||||
/*
|
||||
* How bidding works for filters:
|
||||
* * The bid manager initializes the client-provided reader as the
|
||||
@@ -62,13 +72,7 @@ struct archive_read_filter_bidder {
|
||||
void *data;
|
||||
/* Name of the filter */
|
||||
const char *name;
|
||||
/* Taste the upstream filter to see if we handle this. */
|
||||
int (*bid)(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
/* Initialize a newly-created filter. */
|
||||
int (*init)(struct archive_read_filter *);
|
||||
/* Release the bidder's configuration data. */
|
||||
void (*free)(struct archive_read_filter_bidder *);
|
||||
const struct archive_read_filter_bidder_vtable *vtable;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -80,6 +80,12 @@ archive_read_support_compression_bzip2(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
bzip2_bidder_vtable = {
|
||||
.bid = bzip2_reader_bid,
|
||||
.init = bzip2_reader_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_bzip2(struct archive *_a)
|
||||
{
|
||||
@@ -94,9 +100,7 @@ archive_read_support_filter_bzip2(struct archive *_a)
|
||||
|
||||
reader->data = NULL;
|
||||
reader->name = "bzip2";
|
||||
reader->bid = bzip2_reader_bid;
|
||||
reader->init = bzip2_reader_init;
|
||||
reader->free = NULL;
|
||||
reader->vtable = &bzip2_bidder_vtable;
|
||||
#if defined(HAVE_BZLIB_H) && defined(BZ_CONFIG_ERROR)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
|
||||
@@ -149,6 +149,12 @@ archive_read_support_compression_compress(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
compress_bidder_vtable = {
|
||||
.bid = compress_bidder_bid,
|
||||
.init = compress_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_compress(struct archive *_a)
|
||||
{
|
||||
@@ -163,9 +169,7 @@ archive_read_support_filter_compress(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "compress (.Z)";
|
||||
bidder->bid = compress_bidder_bid;
|
||||
bidder->init = compress_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &compress_bidder_vtable;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -54,6 +54,12 @@ static int grzip_bidder_bid(struct archive_read_filter_bidder *,
|
||||
static int grzip_bidder_init(struct archive_read_filter *);
|
||||
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
grzip_bidder_vtable = {
|
||||
.bid = grzip_bidder_bid,
|
||||
.init = grzip_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_grzip(struct archive *_a)
|
||||
{
|
||||
@@ -67,9 +73,7 @@ archive_read_support_filter_grzip(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->bid = grzip_bidder_bid;
|
||||
reader->init = grzip_bidder_init;
|
||||
reader->free = NULL;
|
||||
reader->vtable = &grzip_bidder_vtable;
|
||||
/* This filter always uses an external program. */
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external grzip program for grzip decompression");
|
||||
|
||||
@@ -94,6 +94,12 @@ archive_read_support_compression_gzip(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
gzip_bidder_vtable = {
|
||||
.bid = gzip_bidder_bid,
|
||||
.init = gzip_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_gzip(struct archive *_a)
|
||||
{
|
||||
@@ -108,9 +114,7 @@ archive_read_support_filter_gzip(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "gzip";
|
||||
bidder->bid = gzip_bidder_bid;
|
||||
bidder->init = gzip_bidder_init;
|
||||
bidder->free = NULL; /* No data, so no cleanup necessary. */
|
||||
bidder->vtable = &gzip_bidder_vtable;
|
||||
/* Signal the extent of gzip support with the return value here. */
|
||||
#if HAVE_ZLIB_H
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
@@ -53,6 +53,12 @@ static int lrzip_bidder_bid(struct archive_read_filter_bidder *,
|
||||
static int lrzip_bidder_init(struct archive_read_filter *);
|
||||
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
lrzip_bidder_vtable = {
|
||||
.bid = lrzip_bidder_bid,
|
||||
.init = lrzip_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_lrzip(struct archive *_a)
|
||||
{
|
||||
@@ -67,9 +73,7 @@ archive_read_support_filter_lrzip(struct archive *_a)
|
||||
|
||||
reader->data = NULL;
|
||||
reader->name = "lrzip";
|
||||
reader->bid = lrzip_bidder_bid;
|
||||
reader->init = lrzip_bidder_init;
|
||||
reader->free = NULL;
|
||||
reader->vtable = &lrzip_bidder_vtable;
|
||||
/* This filter always uses an external program. */
|
||||
archive_set_error(_a, ARCHIVE_ERRNO_MISC,
|
||||
"Using external lrzip program for lrzip decompression");
|
||||
|
||||
@@ -106,6 +106,12 @@ static ssize_t lz4_filter_read_legacy_stream(struct archive_read_filter *,
|
||||
const void **);
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
lz4_bidder_vtable = {
|
||||
.bid = lz4_reader_bid,
|
||||
.init = lz4_reader_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_lz4(struct archive *_a)
|
||||
{
|
||||
@@ -120,9 +126,7 @@ archive_read_support_filter_lz4(struct archive *_a)
|
||||
|
||||
reader->data = NULL;
|
||||
reader->name = "lz4";
|
||||
reader->bid = lz4_reader_bid;
|
||||
reader->init = lz4_reader_init;
|
||||
reader->free = NULL;
|
||||
reader->vtable = &lz4_bidder_vtable;
|
||||
#if defined(HAVE_LIBLZ4)
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
|
||||
@@ -101,6 +101,12 @@ static int lzop_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int lzop_bidder_init(struct archive_read_filter *);
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
lzop_bidder_vtable = {
|
||||
.bid = lzop_bidder_bid,
|
||||
.init = lzop_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_lzop(struct archive *_a)
|
||||
{
|
||||
@@ -114,9 +120,7 @@ archive_read_support_filter_lzop(struct archive *_a)
|
||||
return (ARCHIVE_FATAL);
|
||||
|
||||
reader->data = NULL;
|
||||
reader->bid = lzop_bidder_bid;
|
||||
reader->init = lzop_bidder_init;
|
||||
reader->free = NULL;
|
||||
reader->vtable = &lzop_bidder_vtable;
|
||||
/* Signal the extent of lzop support with the return value here. */
|
||||
#if defined(HAVE_LZO_LZOCONF_H) && defined(HAVE_LZO_LZO1X_H)
|
||||
return (ARCHIVE_OK);
|
||||
|
||||
@@ -123,6 +123,13 @@ static ssize_t program_filter_read(struct archive_read_filter *,
|
||||
static int program_filter_close(struct archive_read_filter *);
|
||||
static void free_state(struct program_bidder *);
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
program_bidder_vtable = {
|
||||
.bid = program_bidder_bid,
|
||||
.init = program_bidder_init,
|
||||
.free = program_bidder_free,
|
||||
};
|
||||
|
||||
static int
|
||||
set_bidder_signature(struct archive_read_filter_bidder *bidder,
|
||||
struct program_bidder *state, const void *signature, size_t signature_len)
|
||||
@@ -138,9 +145,7 @@ set_bidder_signature(struct archive_read_filter_bidder *bidder,
|
||||
* Fill in the bidder object.
|
||||
*/
|
||||
bidder->data = state;
|
||||
bidder->bid = program_bidder_bid;
|
||||
bidder->init = program_bidder_init;
|
||||
bidder->free = program_bidder_free;
|
||||
bidder->vtable = &program_bidder_vtable;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,12 @@ archive_read_support_compression_rpm(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
rpm_bidder_vtable = {
|
||||
.bid = rpm_bidder_bid,
|
||||
.init = rpm_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_rpm(struct archive *_a)
|
||||
{
|
||||
@@ -86,9 +92,7 @@ archive_read_support_filter_rpm(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "rpm";
|
||||
bidder->bid = rpm_bidder_bid;
|
||||
bidder->init = rpm_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &rpm_bidder_vtable;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -76,6 +76,12 @@ archive_read_support_compression_uu(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
uudecode_bidder_vtable = {
|
||||
.bid = uudecode_bidder_bid,
|
||||
.init = uudecode_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_uu(struct archive *_a)
|
||||
{
|
||||
@@ -90,9 +96,7 @@ archive_read_support_filter_uu(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "uu";
|
||||
bidder->bid = uudecode_bidder_bid;
|
||||
bidder->init = uudecode_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &uudecode_bidder_vtable;
|
||||
return (ARCHIVE_OK);
|
||||
}
|
||||
|
||||
|
||||
@@ -108,6 +108,12 @@ archive_read_support_compression_xz(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
xz_bidder_vtable = {
|
||||
.bid = xz_bidder_bid,
|
||||
.init = xz_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_xz(struct archive *_a)
|
||||
{
|
||||
@@ -122,9 +128,7 @@ archive_read_support_filter_xz(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "xz";
|
||||
bidder->bid = xz_bidder_bid;
|
||||
bidder->init = xz_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &xz_bidder_vtable;
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
@@ -142,6 +146,12 @@ archive_read_support_compression_lzma(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
lzma_bidder_vtable = {
|
||||
.bid = lzma_bidder_bid,
|
||||
.init = lzma_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_lzma(struct archive *_a)
|
||||
{
|
||||
@@ -156,9 +166,7 @@ archive_read_support_filter_lzma(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "lzma";
|
||||
bidder->bid = lzma_bidder_bid;
|
||||
bidder->init = lzma_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &lzma_bidder_vtable;
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
@@ -177,6 +185,12 @@ archive_read_support_compression_lzip(struct archive *a)
|
||||
}
|
||||
#endif
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
lzip_bidder_vtable = {
|
||||
.bid = lzip_bidder_bid,
|
||||
.init = lzip_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_lzip(struct archive *_a)
|
||||
{
|
||||
@@ -191,9 +205,7 @@ archive_read_support_filter_lzip(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "lzip";
|
||||
bidder->bid = lzip_bidder_bid;
|
||||
bidder->init = lzip_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &lzip_bidder_vtable;
|
||||
#if HAVE_LZMA_H && HAVE_LIBLZMA
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
|
||||
@@ -79,6 +79,12 @@ static int zstd_bidder_bid(struct archive_read_filter_bidder *,
|
||||
struct archive_read_filter *);
|
||||
static int zstd_bidder_init(struct archive_read_filter *);
|
||||
|
||||
static const struct archive_read_filter_bidder_vtable
|
||||
zstd_bidder_vtable = {
|
||||
.bid = zstd_bidder_bid,
|
||||
.init = zstd_bidder_init,
|
||||
};
|
||||
|
||||
int
|
||||
archive_read_support_filter_zstd(struct archive *_a)
|
||||
{
|
||||
@@ -93,9 +99,7 @@ archive_read_support_filter_zstd(struct archive *_a)
|
||||
|
||||
bidder->data = NULL;
|
||||
bidder->name = "zstd";
|
||||
bidder->bid = zstd_bidder_bid;
|
||||
bidder->init = zstd_bidder_init;
|
||||
bidder->free = NULL;
|
||||
bidder->vtable = &zstd_bidder_vtable;
|
||||
#if HAVE_ZSTD_H && HAVE_LIBZSTD
|
||||
return (ARCHIVE_OK);
|
||||
#else
|
||||
|
||||
Reference in new issue
Block a user