diff options
Diffstat (limited to '')
-rw-r--r-- | src/archive/bz2_archive_plugin.c (renamed from src/archive/bz2_plugin.c) | 174 |
1 files changed, 86 insertions, 88 deletions
diff --git a/src/archive/bz2_plugin.c b/src/archive/bz2_archive_plugin.c index 0ef042e90..b3a9027af 100644 --- a/src/archive/bz2_plugin.c +++ b/src/archive/bz2_archive_plugin.c @@ -21,9 +21,10 @@ * single bz2 archive handling (requires libbz2) */ +#include "config.h" +#include "archive/bz2_archive_plugin.h" #include "archive_api.h" #include "input_plugin.h" -#include "config.h" #include <stdint.h> #include <stddef.h> @@ -32,30 +33,40 @@ #include <bzlib.h> #ifdef HAVE_OLDER_BZIP2 -#define BZ2_bzDecompressInit bzDecompressInit -#define BZ2_bzDecompress bzDecompress +#define BZ2_bzDecompressInit bzDecompressInit +#define BZ2_bzDecompress bzDecompress #endif #define BZ_BUFSIZE 5000 -typedef struct { - char *name; - bool reset; +struct bz2_archive_file { + struct archive_file base; + + char *name; + bool reset; struct input_stream istream; - int last_bz_result; - int last_parent_result; - bz_stream bzstream; - char *buffer; -} bz2_context; + bool eof; + + bz_stream bzstream; + char *buffer; +}; static const struct input_plugin bz2_inputplugin; +static inline GQuark +bz2_quark(void) +{ + return g_quark_from_static_string("bz2"); +} + /* single archive handling allocation helpers */ static bool -bz2_alloc(bz2_context *data) +bz2_alloc(struct bz2_archive_file *data, GError **error_r) { + int ret; + data->bzstream.bzalloc = NULL; data->bzstream.bzfree = NULL; data->bzstream.opaque = NULL; @@ -64,19 +75,21 @@ bz2_alloc(bz2_context *data) data->bzstream.next_in = (void *) data->buffer; data->bzstream.avail_in = 0; - if (BZ2_bzDecompressInit(&data->bzstream, 0, 0) != BZ_OK) { + ret = BZ2_bzDecompressInit(&data->bzstream, 0, 0); + if (ret != BZ_OK) { g_free(data->buffer); g_free(data); + + g_set_error(error_r, bz2_quark(), ret, + "BZ2_bzDecompressInit() has failed"); return false; } - data->last_bz_result = BZ_OK; - data->last_parent_result = 0; return true; } static void -bz2_destroy(bz2_context *data) +bz2_destroy(struct bz2_archive_file *data) { BZ2_bzDecompressEnd(&data->bzstream); g_free(data->buffer); @@ -85,61 +98,56 @@ bz2_destroy(bz2_context *data) /* archive open && listing routine */ static struct archive_file * -bz2_open(char * pathname) +bz2_open(const char *pathname, GError **error_r) { - bz2_context *context; - char *name; + struct bz2_archive_file *context; int len; - context = g_malloc(sizeof(bz2_context)); - if (!context) { - return NULL; - } + context = g_malloc(sizeof(*context)); + archive_file_init(&context->base, &bz2_archive_plugin); + //open archive - if (!input_stream_open(&context->istream, pathname)) { - g_warning("failed to open an bzip2 archive %s\n",pathname); - g_free(context); - return NULL; - } - //capture filename - name = strrchr(pathname, '/'); - if (name == NULL) { - g_warning("failed to get bzip2 name from %s\n",pathname); + if (!input_stream_open(&context->istream, pathname, error_r)) { g_free(context); return NULL; } - context->name = g_strdup(name+1); + + context->name = g_path_get_basename(pathname); + //remove suffix len = strlen(context->name); if (len > 4) { - context->name[len-4] = 0; //remove .bz2 suffix + context->name[len - 4] = 0; //remove .bz2 suffix } - return (struct archive_file *) context; + + return &context->base; } static void bz2_scan_reset(struct archive_file *file) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; context->reset = true; } static char * bz2_scan_next(struct archive_file *file) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; char *name = NULL; + if (context->reset) { name = context->name; context->reset = false; } + return name; } static void bz2_close(struct archive_file *file) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; g_free(context->name); @@ -151,35 +159,36 @@ bz2_close(struct archive_file *file) static bool bz2_open_stream(struct archive_file *file, struct input_stream *is, - G_GNUC_UNUSED const char *path) + G_GNUC_UNUSED const char *path, GError **error_r) { - bz2_context *context = (bz2_context *) file; + struct bz2_archive_file *context = (struct bz2_archive_file *) file; + //setup file ops is->plugin = &bz2_inputplugin; //insert back reference is->data = context; is->seekable = false; - if (!bz2_alloc(context)) { - g_warning("alloc bz2 failed\n"); + if (!bz2_alloc(context, error_r)) return false; - } + + context->eof = false; + return true; } static void bz2_is_close(struct input_stream *is) { - bz2_context *context = (bz2_context *) is->data; + struct bz2_archive_file *context = (struct bz2_archive_file *) is->data; bz2_destroy(context); is->data = NULL; bz2_close((struct archive_file *)context); } -static int -bz2_fillbuffer(bz2_context *context, - size_t numBytes) +static bool +bz2_fillbuffer(struct bz2_archive_file *context, GError **error_r) { size_t count; bz_stream *bzstream; @@ -187,76 +196,65 @@ bz2_fillbuffer(bz2_context *context, bzstream = &context->bzstream; if (bzstream->avail_in > 0) - return 0; + return true; count = input_stream_read(&context->istream, - context->buffer, BZ_BUFSIZE); - - if (count == 0) { - if (bzstream->avail_out == numBytes) - return -1; - if (!input_stream_eof(&context->istream)) - context->last_parent_result = 1; - } else { - bzstream->next_in = context->buffer; - bzstream->avail_in = count; - } + context->buffer, BZ_BUFSIZE, + error_r); + if (count == 0) + return false; - return 0; + bzstream->next_in = context->buffer; + bzstream->avail_in = count; + return true; } static size_t -bz2_is_read(struct input_stream *is, void *ptr, size_t size) +bz2_is_read(struct input_stream *is, void *ptr, size_t length, + GError **error_r) { - bz2_context *context = (bz2_context *) is->data; + struct bz2_archive_file *context = (struct bz2_archive_file *) is->data; bz_stream *bzstream; int bz_result; - size_t numBytes = size; - size_t bytesRead = 0; + size_t nbytes = 0; - if (context->last_bz_result != BZ_OK) - return 0; - if (context->last_parent_result != 0) + if (context->eof) return 0; bzstream = &context->bzstream; bzstream->next_out = ptr; - bzstream->avail_out = numBytes; + bzstream->avail_out = length; - while (bzstream->avail_out != 0) { - if (bz2_fillbuffer(context, numBytes) != 0) - break; + do { + if (!bz2_fillbuffer(context, error_r)) + return 0; bz_result = BZ2_bzDecompress(bzstream); - if (context->last_bz_result != BZ_OK - && bzstream->avail_out == numBytes) { - context->last_bz_result = bz_result; + if (bz_result == BZ_STREAM_END) { + context->eof = true; break; } - if (bz_result == BZ_STREAM_END) { - context->last_bz_result = bz_result; - break; + if (bz_result != BZ_OK) { + g_set_error(error_r, bz2_quark(), bz_result, + "BZ2_bzDecompress() has failed"); + return 0; } - } + } while (bzstream->avail_out == length); - bytesRead = numBytes - bzstream->avail_out; - is->offset += bytesRead; + nbytes = length - bzstream->avail_out; + is->offset += nbytes; - return bytesRead; + return nbytes; } static bool bz2_is_eof(struct input_stream *is) { - bz2_context *context = (bz2_context *) is->data; - - if (context->last_bz_result == BZ_STREAM_END) { - return true; - } + struct bz2_archive_file *context = (struct bz2_archive_file *) is->data; - return false; + return context->eof; } /* exported structures */ @@ -272,7 +270,7 @@ static const struct input_plugin bz2_inputplugin = { .eof = bz2_is_eof, }; -const struct archive_plugin bz2_plugin = { +const struct archive_plugin bz2_archive_plugin = { .name = "bz2", .open = bz2_open, .scan_reset = bz2_scan_reset, |