aboutsummaryrefslogtreecommitdiffstats
path: root/src/archive/bz2_archive_plugin.c
diff options
context:
space:
mode:
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,