summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2013-07-12 14:55:36 +0800
committerLAN-TW <lantw44@gmail.com>2013-07-12 14:55:36 +0800
commit11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7 (patch)
tree151f3b1677ca4d4502a65530bd686396a05b1184
parent0a711b9dd29dae3294aabfbf1a65b67f90334409 (diff)
downloadgsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.tar
gsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.tar.gz
gsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.tar.bz2
gsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.tar.lz
gsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.tar.xz
gsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.tar.zst
gsoc2013-libgnome-autoar-11f215ecf9e0ae82f0b8534a541ab0e1cbafdff7.zip
Implement callback functions for archive_read_open
-rw-r--r--autoar-extract.c144
-rw-r--r--autoar-extract.h2
2 files changed, 122 insertions, 24 deletions
diff --git a/autoar-extract.c b/autoar-extract.c
index 2943058..ecaf20d 100644
--- a/autoar-extract.c
+++ b/autoar-extract.c
@@ -27,6 +27,8 @@
#include "autoar-extract.h"
+#include <gio/gio.h>
+#include <string.h>
#include <archive.h>
#include <archive_entry.h>
@@ -35,18 +37,23 @@ G_DEFINE_TYPE (AutoarExtract, autoar_extract, G_TYPE_OBJECT)
#define AUTOAR_EXTRACT_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), AUTOAR_TYPE_EXTRACT, AutoarExtractPrivate))
+#define BUFFER_SIZE (64 * 1024)
+
struct _AutoarExtractPrivate
{
char *source;
char *output;
- struct archive* ar_read;
-
guint64 size;
guint64 completed_size;
guint files;
guint completed_files;
+
+ GInputStream *istream;
+ void *buffer;
+ gssize buffer_size;
+ GError *error;
};
enum
@@ -221,24 +228,109 @@ autoar_extract_finalize (GObject *object)
arextract = AUTOAR_EXTRACT (object);
priv = arextract->priv;
- if (priv->source != NULL) {
- g_free (priv->source);
- priv->source = NULL;
- }
+ g_free (priv->source);
+ priv->source = NULL;
- if (priv->output != NULL) {
- g_free (priv->output);
- priv->output = NULL;
+ g_free (priv->output);
+ priv->output = NULL;
+
+ if (priv->istream != NULL) {
+ if (!g_input_stream_is_closed (priv->istream)) {
+ g_input_stream_close (priv->istream, NULL, NULL);
+ }
+ g_object_unref (priv->istream);
}
- if (priv->ar_read != NULL) {
- archive_read_free (priv->ar_read);
- priv->ar_read = NULL;
+ g_free (priv->buffer);
+ priv->buffer = NULL;
+
+ if (priv->error != NULL) {
+ g_error_free (priv->error);
+ priv->error = NULL;
}
G_OBJECT_CLASS (autoar_extract_parent_class)->finalize (object);
}
+static int
+libarchive_read_open_cb (struct archive *ar_read,
+ void *client_data)
+{
+ AutoarExtract *arextract;
+ GFile *file;
+ GFileInfo *fileinfo;
+
+ arextract = (AutoarExtract*)client_data;
+ if (arextract->priv->error != NULL) {
+ return ARCHIVE_FATAL;
+ }
+
+ file = g_file_new_for_commandline_arg (arextract->priv->source);
+
+ fileinfo = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_SIZE,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ NULL,
+ &(arextract->priv->error));
+ g_return_val_if_fail (arextract->priv->error == NULL, ARCHIVE_FATAL);
+
+ arextract->priv->size = g_file_info_get_size (fileinfo);
+ g_object_unref (fileinfo);
+
+ arextract->priv->istream = (GInputStream*)g_file_read (file,
+ NULL,
+ &(arextract->priv->error));
+ g_return_val_if_fail (arextract->priv->error == NULL, ARCHIVE_FATAL);
+
+ return ARCHIVE_OK;
+}
+
+static int
+libarchive_read_close_cb (struct archive *ar_read,
+ void *client_data)
+{
+ AutoarExtract *arextract;
+
+ arextract = (AutoarExtract*)client_data;
+ if (arextract->priv->error != NULL) {
+ return ARCHIVE_FATAL;
+ }
+
+ if (arextract->priv->istream != NULL) {
+ g_input_stream_close (arextract->priv->istream, NULL, NULL);
+ g_object_unref (arextract->priv->istream);
+ arextract->priv->istream = NULL;
+ }
+
+ return ARCHIVE_OK;
+}
+
+static ssize_t
+libarchive_read_read_cb (struct archive *ar_read,
+ void *client_data,
+ const void **buffer)
+{
+ AutoarExtract *arextract;
+ gssize read_size;
+
+ arextract = (AutoarExtract*)client_data;
+ if (arextract->priv->error != NULL) {
+ return -1;
+ }
+
+ *buffer = &(arextract->priv->buffer);
+ read_size = g_input_stream_read (arextract->priv->istream,
+ arextract->priv->buffer,
+ arextract->priv->buffer_size,
+ NULL,
+ &(arextract->priv->error));
+ g_return_val_if_fail (arextract->priv->error == NULL, -1);
+
+ arextract->priv->completed_size += read_size;
+
+ return read_size;
+}
+
/* Additional marshaller generated by glib-genmarshal
* Command: echo "VOID:DOUBLE,DOUBLE" | glib-genmarshal --header */
@@ -439,10 +531,10 @@ autoar_extract_class_init (AutoarExtractClass *klass)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (AutoarExtractClass, error),
NULL, NULL,
- g_cclosure_marshal_VOID__INT,
+ g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE,
1,
- G_TYPE_INT);
+ G_TYPE_POINTER);
}
static void
@@ -456,23 +548,29 @@ autoar_extract_init (AutoarExtract *arextract)
priv->source = NULL;
priv->output = NULL;
- priv->ar_read = NULL;
-
priv->size = 0;
priv->completed_size = 0;
+ priv->files = 0;
priv->completed_files = 0;
+
+ priv->istream = NULL;
+ priv->buffer_size = BUFFER_SIZE;
+ priv->buffer = g_new (char, priv->buffer_size);
+ priv->error = NULL;
}
AutoarExtract*
autoar_extract_new (const char *source,
const char *output)
{
- AutoarExtract *arextract = g_object_new (AUTOAR_TYPE_EXTRACT,
- "source",
- source,
- "output",
- output,
- NULL);
- return arextract;
+ g_return_val_if_fail (source != NULL, NULL);
+ g_return_val_if_fail (output != NULL, NULL);
+
+ return g_object_new (AUTOAR_TYPE_EXTRACT,
+ "source",
+ source,
+ "output",
+ output,
+ NULL);
}
diff --git a/autoar-extract.h b/autoar-extract.h
index c768531..2d93228 100644
--- a/autoar-extract.h
+++ b/autoar-extract.h
@@ -59,7 +59,7 @@ struct _AutoarExtractClass
gdouble fraction_files);
void (* completed) (AutoarExtract *arextract);
void (* error) (AutoarExtract *arextract,
- gint error_code);
+ GError* error);
};
GType autoar_extract_get_type (void) G_GNUC_CONST;