summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTing-Wei Lan <lantw44@gmail.com>2013-08-29 23:55:34 +0800
committerLAN-TW <lantw44@gmail.com>2013-08-29 23:56:26 +0800
commit2728ab336eda6be405519e46d020e75866662964 (patch)
tree405901b798b8e79bafe4dcdad343f77210843107
parent6a3732447532036174879bd3f4e412dd6ddb94e6 (diff)
downloadgsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.tar
gsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.tar.gz
gsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.tar.bz2
gsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.tar.lz
gsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.tar.xz
gsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.tar.zst
gsoc2013-libgnome-autoar-2728ab336eda6be405519e46d020e75866662964.zip
GFile can be used as source to create archives now
-rw-r--r--gnome-autoar/autoar-common.c17
-rw-r--r--gnome-autoar/autoar-common.h4
-rw-r--r--gnome-autoar/autoar-create.c550
-rw-r--r--gnome-autoar/autoar-create.h11
-rw-r--r--gnome-autoar/autoar-extract.c16
5 files changed, 426 insertions, 172 deletions
diff --git a/gnome-autoar/autoar-common.c b/gnome-autoar/autoar-common.c
index 5feda50..1fd763f 100644
--- a/gnome-autoar/autoar-common.c
+++ b/gnome-autoar/autoar-common.c
@@ -165,6 +165,13 @@ autoar_common_g_signal_emit (gpointer instance,
va_end (ap);
}
+void
+autoar_common_g_object_unref (gpointer object)
+{
+ if (object != NULL)
+ g_object_unref (object);
+}
+
GError*
autoar_common_g_error_new_a (struct archive *a,
const char *pathname)
@@ -186,3 +193,13 @@ autoar_common_g_error_new_a_entry (struct archive *a,
{
return autoar_common_g_error_new_a (a, archive_entry_pathname (entry));
}
+
+char*
+autoar_common_g_file_get_name (GFile *file)
+{
+ char *name;
+ name = g_file_get_path (file);
+ if (name == NULL)
+ name = g_file_get_uri (file);
+ return name;
+}
diff --git a/gnome-autoar/autoar-common.h b/gnome-autoar/autoar-common.h
index 59518bf..7b93899 100644
--- a/gnome-autoar/autoar-common.h
+++ b/gnome-autoar/autoar-common.h
@@ -32,6 +32,7 @@
#include <archive.h>
#include <archive_entry.h>
+#include <gio/gio.h>
#include <glib.h>
#include <glib-object.h>
@@ -49,12 +50,15 @@ void autoar_common_g_signal_emit (gpointer instance,
guint signal_id,
GQuark detail,
...);
+void autoar_common_g_object_unref (gpointer object);
GError* autoar_common_g_error_new_a (struct archive *a,
const char *pathname);
GError* autoar_common_g_error_new_a_entry (struct archive *a,
struct archive_entry *entry);
+char* autoar_common_g_file_get_name (GFile *file);
+
G_END_DECLS
#endif /* AUTOAR_COMMON_H */
diff --git a/gnome-autoar/autoar-create.c b/gnome-autoar/autoar-create.c
index 97c179f..92a5f70 100644
--- a/gnome-autoar/autoar-create.c
+++ b/gnome-autoar/autoar-create.c
@@ -47,11 +47,18 @@ G_DEFINE_QUARK (autoar-create, autoar_create)
#define BUFFER_SIZE (64 * 1024)
#define ARCHIVE_WRITE_RETRY_TIMES 5
+#define INVALID_FORMAT 1
+#define INVALID_FILTER 2
+
struct _AutoarCreatePrivate
{
char **source;
char *output;
- GFile *dest;
+
+ GPtrArray *source_file; /* An array of GFile, terminated by NULL */
+ GFile *output_file;
+
+ int output_is_dest : 1;
guint64 size; /* This field is currently unused */
guint64 completed_size;
@@ -71,10 +78,12 @@ struct _AutoarCreatePrivate
struct archive *a;
struct archive_entry *entry;
struct archive_entry_linkresolver *resolver;
+ GFile *dest;
GHashTable *pathname_to_g_file;
char *source_basename_noext;
+ char *extension;
- int in_thread : 1;
+ int in_thread : 1;
int prepend_basename : 1;
};
@@ -92,11 +101,14 @@ enum
{
PROP_0,
PROP_SOURCE,
+ PROP_SOURCE_FILE,
PROP_OUTPUT,
+ PROP_OUTPUT_FILE,
PROP_SIZE, /* This property is currently unused */
PROP_COMPLETED_SIZE,
PROP_FILES,
- PROP_COMPLETED_FILES
+ PROP_COMPLETED_FILES,
+ PROP_OUTPUT_IS_DEST
};
static guint autoar_create_signals[LAST_SIGNAL] = { 0 };
@@ -117,11 +129,18 @@ autoar_create_get_property (GObject *object,
case PROP_SOURCE:
g_value_set_boxed (value, priv->source);
break;
+ case PROP_SOURCE_FILE:
+ g_value_set_boxed (value, priv->source_file);
+ break;
case PROP_OUTPUT:
g_value_set_string (value, priv->output);
break;
+ case PROP_OUTPUT_FILE:
+ g_value_set_object (value, priv->output_file);
+ break;
case PROP_SIZE:
g_value_set_uint64 (value, priv->size);
+ break;
case PROP_COMPLETED_SIZE:
g_value_set_uint64 (value, priv->completed_size);
break;
@@ -131,6 +150,9 @@ autoar_create_get_property (GObject *object,
case PROP_COMPLETED_FILES:
g_value_set_uint (value, priv->completed_files);
break;
+ case PROP_OUTPUT_IS_DEST:
+ g_value_set_boolean (value, priv->output_is_dest);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -166,10 +188,22 @@ autoar_create_set_property (GObject *object,
g_strfreev (priv->source);
priv->source = g_value_dup_boxed (value);
break;
+ case PROP_SOURCE_FILE:
+ if (priv->source_file != NULL)
+ g_ptr_array_unref (priv->source_file);
+ priv->source_file = g_value_dup_boxed (value);
+ break;
case PROP_OUTPUT:
g_free (priv->output);
priv->output = g_value_dup_string (value);
break;
+ case PROP_OUTPUT_FILE:
+ autoar_common_g_object_unref (priv->output_file);
+ priv->output_file = g_object_ref (g_value_get_object (value));
+ break;
+ case PROP_OUTPUT_IS_DEST:
+ priv->output_is_dest = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -183,6 +217,13 @@ autoar_create_get_source (AutoarCreate *arcreate)
return arcreate->priv->source;
}
+GPtrArray*
+autoar_create_get_source_file (AutoarCreate *arcreate)
+{
+ g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), NULL);
+ return arcreate->priv->source_file;
+}
+
char*
autoar_create_get_output (AutoarCreate *arcreate)
{
@@ -190,6 +231,13 @@ autoar_create_get_output (AutoarCreate *arcreate)
return arcreate->priv->output;
}
+GFile*
+autoar_create_get_output_file (AutoarCreate *arcreate)
+{
+ g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), NULL);
+ return arcreate->priv->output_file;
+}
+
guint64
autoar_create_get_size (AutoarCreate *arcreate)
{
@@ -218,6 +266,13 @@ autoar_create_get_completed_files (AutoarCreate *arcreate)
return arcreate->priv->completed_files;
}
+gboolean
+autoar_create_get_output_is_dest (AutoarCreate *arcreate)
+{
+ g_return_val_if_fail (AUTOAR_IS_CREATE (arcreate), 0);
+ return arcreate->priv->output_is_dest;
+}
+
void
autoar_create_set_size (AutoarCreate *arcreate,
guint64 size)
@@ -252,6 +307,14 @@ autoar_create_set_completed_files (AutoarCreate *arcreate,
arcreate->priv->completed_files = completed_files;
}
+void
+autoar_create_set_output_is_dest (AutoarCreate *arcreate,
+ gboolean output_is_dest)
+{
+ g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
+ arcreate->priv->output_is_dest = output_is_dest;
+}
+
static void
autoar_create_dispose (GObject *object)
{
@@ -268,16 +331,24 @@ autoar_create_dispose (GObject *object)
g_output_stream_close (priv->ostream, priv->cancellable, NULL);
}
g_object_unref (priv->ostream);
+ priv->ostream = NULL;
}
+ g_clear_object (&(priv->dest));
g_clear_object (&(priv->arpref));
g_clear_object (&(priv->cancellable));
+ g_clear_object (&(priv->output_file));
if (priv->pathname_to_g_file != NULL) {
g_hash_table_unref (priv->pathname_to_g_file);
priv->pathname_to_g_file = NULL;
}
+ if (priv->source_file != NULL) {
+ g_ptr_array_unref (priv->source_file);
+ priv->source_file = NULL;
+ }
+
G_OBJECT_CLASS (autoar_create_parent_class)->dispose (object);
}
@@ -330,6 +401,9 @@ autoar_create_finalize (GObject *object)
g_free (priv->source_basename_noext);
priv->source_basename_noext = NULL;
+ g_free (priv->extension);
+ priv->extension = NULL;
+
G_OBJECT_CLASS (autoar_create_parent_class)->finalize (object);
}
@@ -817,9 +891,16 @@ autoar_create_class_init (AutoarCreateClass *klass)
G_TYPE_STRV,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_SOURCE_FILE,
+ g_param_spec_boxed ("source-file",
+ "Source archive GFile",
+ "The source GFiles to be compressed",
+ G_TYPE_PTR_ARRAY,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_OUTPUT,
g_param_spec_string ("output",
@@ -828,9 +909,16 @@ autoar_create_class_init (AutoarCreateClass *klass)
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_OUTPUT_FILE,
+ g_param_spec_object ("output-file",
+ "Output directory GFile",
+ "Output directory GFile of created archive",
+ G_TYPE_FILE,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_SIZE, /* This propery is unused! */
g_param_spec_uint64 ("size",
@@ -838,9 +926,7 @@ autoar_create_class_init (AutoarCreateClass *klass)
"Total bytes will be read from disk",
0, G_MAXUINT64, 0,
G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_COMPLETED_SIZE,
g_param_spec_uint64 ("completed-size",
@@ -848,9 +934,7 @@ autoar_create_class_init (AutoarCreateClass *klass)
"Bytes read from disk",
0, G_MAXUINT64, 0,
G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_FILES,
g_param_spec_uint ("files",
@@ -858,9 +942,7 @@ autoar_create_class_init (AutoarCreateClass *klass)
"Number of files to be compressed",
0, G_MAXUINT32, 0,
G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
g_object_class_install_property (object_class, PROP_COMPLETED_FILES,
g_param_spec_uint ("completed-files",
@@ -868,9 +950,15 @@ autoar_create_class_init (AutoarCreateClass *klass)
"Number of files has been read",
0, G_MAXUINT32, 0,
G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB));
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (object_class, PROP_OUTPUT_IS_DEST,
+ g_param_spec_boolean ("output-is-dest",
+ "Output is destination",
+ "Whether output file is used as destination",
+ FALSE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
autoar_create_signals[DECIDE_DEST] =
g_signal_new ("decide-dest",
@@ -938,6 +1026,10 @@ autoar_create_init (AutoarCreate *arcreate)
priv->source = NULL;
priv->output = NULL;
+ priv->source_file = NULL;
+ priv->output_file = NULL;
+
+ priv->size = 0;
priv->completed_size = 0;
priv->files = 0;
@@ -957,28 +1049,73 @@ autoar_create_init (AutoarCreate *arcreate)
priv->resolver = archive_entry_linkresolver_new ();;
priv->pathname_to_g_file = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_object_unref);
priv->source_basename_noext = NULL;
+ priv->extension = NULL;
priv->in_thread = FALSE;
priv->prepend_basename = FALSE;
+ priv->output_is_dest = FALSE;
}
-AutoarCreate*
-autoar_create_newv (AutoarPref *arpref,
- const char *output,
- const char **source)
+static AutoarCreate*
+autoar_create_new_full (const char **source,
+ GFile **source_file,
+ const char *output,
+ GFile *output_file,
+ gboolean output_is_dest,
+ AutoarPref *arpref)
{
AutoarCreate *arcreate;
+ const char **gen_source;
+ char *gen_output;
+ GPtrArray *gen_source_file;
+ GFile *gen_output_file;
+ int i;
+
+ gen_source = NULL;
+ gen_source_file = NULL;
+ gen_output = NULL;
+ gen_output_file = NULL;
+
+ if (source == NULL) {
+ GPtrArray *strv;
+ strv = g_ptr_array_new ();
+ for (i = 0; source_file[i] != NULL; i++)
+ g_ptr_array_add (strv, autoar_common_g_file_get_name (source_file[i]));
+ g_ptr_array_add (strv, NULL);
+ gen_source = (const char**) g_ptr_array_free (strv, FALSE);
+ }
- g_return_val_if_fail (source != NULL, NULL);
- g_return_val_if_fail (*source != NULL, NULL);
- g_return_val_if_fail (output != NULL, NULL);
+ gen_source_file = g_ptr_array_new_with_free_func (g_object_unref);
+ if (source_file == NULL) {
+ for (i = 0; source[i] != NULL; i++)
+ g_ptr_array_add (gen_source_file, g_file_new_for_commandline_arg (source[i]));
+ } else {
+ for (i = 0; source_file[i] != NULL; i++)
+ g_ptr_array_add (gen_source_file, g_object_ref (source_file[i]));
+ }
- arcreate = g_object_new (AUTOAR_TYPE_CREATE,
- "source", source,
- "output", output,
- NULL);
+ if (output == NULL)
+ gen_output = autoar_common_g_file_get_name (output_file);
+ if (output_file == NULL)
+ gen_output_file = g_file_new_for_commandline_arg (output);
+
+ arcreate =
+ g_object_new (AUTOAR_TYPE_CREATE,
+ "source", source != NULL ? source : gen_source,
+ "source-file", gen_source_file,
+ "output", output != NULL ? output : gen_output,
+ "output-file", output_file != NULL ? output_file : gen_output_file,
+ "output-is-dest", output_is_dest, NULL);
arcreate->priv->arpref = g_object_ref (arpref);
+ g_strfreev ((char**)gen_source);
+ g_free (gen_output);
+
+ if (gen_source_file != NULL)
+ g_ptr_array_unref (gen_source_file);
+ if (gen_output_file != NULL)
+ g_object_unref (gen_output_file);
+
return arcreate;
}
@@ -992,151 +1129,200 @@ autoar_create_new (AutoarPref *arpref,
va_list ap;
GPtrArray *strv;
+ g_return_val_if_fail (output != NULL, NULL);
+
va_start (ap, output);
strv = g_ptr_array_new_with_free_func (g_free);
- while ((str = va_arg (ap, char*)) != NULL) {
+ while ((str = va_arg (ap, char*)) != NULL)
g_ptr_array_add (strv, str);
- }
g_ptr_array_add (strv, NULL);
va_end (ap);
- arcreate = autoar_create_newv (arpref, output, (const char**)(strv->pdata));
+ arcreate = autoar_create_new_full ((const char**) strv->pdata, NULL,
+ output, NULL,
+ FALSE, arpref);
g_ptr_array_unref (strv);
return arcreate;
}
+AutoarCreate*
+autoar_create_new_file (AutoarPref *arpref,
+ GFile *output_file,
+ ...)
+{
+ AutoarCreate *arcreate;
+ GFile *file;
+ va_list ap;
+ GPtrArray *filev;
+
+ g_return_val_if_fail (output_file != NULL, NULL);
+
+ va_start (ap, output_file);
+ filev = g_ptr_array_new_with_free_func (autoar_common_g_object_unref);
+ while ((file = va_arg (ap, GFile*)) != NULL)
+ g_ptr_array_add (filev, file);
+ g_ptr_array_add (filev, NULL);
+ va_end (ap);
+
+ arcreate = autoar_create_new_full (NULL, (GFile**)filev->pdata,
+ NULL, output_file,
+ FALSE, arpref);
+ g_ptr_array_unref (filev);
+ return arcreate;
+}
+
+AutoarCreate*
+autoar_create_newv (AutoarPref *arpref,
+ const char *output,
+ const char **source)
+{
+ g_return_val_if_fail (source != NULL, NULL);
+ g_return_val_if_fail (*source != NULL, NULL);
+ g_return_val_if_fail (output != NULL, NULL);
+
+ return autoar_create_new_full (source, NULL,
+ output, NULL,
+ FALSE, arpref);
+
+}
+
+AutoarCreate*
+autoar_create_new_filev (AutoarPref *arpref,
+ GFile *output_file,
+ GFile **source_file)
+{
+ g_return_val_if_fail (source_file != NULL, NULL);
+ g_return_val_if_fail (*source_file != NULL, NULL);
+ g_return_val_if_fail (output_file != NULL, NULL);
+
+ return autoar_create_new_full (NULL, source_file,
+ NULL, output_file,
+ FALSE, arpref);
+}
+
static void
-autoar_create_run (AutoarCreate *arcreate)
+autoar_create_step_initialize_object (AutoarCreate *arcreate)
{
+ /* Step 0: Setup the libarchive object and the file name extension */
+
AutoarFormat format;
AutoarFilter filter;
AutoarCreatePrivate *priv;
- int i, r;
- g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
priv = arcreate->priv;
- g_return_if_fail (priv->source != NULL);
- g_return_if_fail (priv->output != NULL);
-
- /* A string array without a string is not allowed */
- g_return_if_fail (*(priv->source) != NULL);
-
- if (g_cancellable_is_cancelled (priv->cancellable)) {
- autoar_create_signal_cancelled (arcreate);
+ format = autoar_pref_get_default_format (priv->arpref);
+ if (!autoar_format_is_valid (format)) {
+ priv->error = g_error_new (AUTOAR_CREATE_ERROR, INVALID_FORMAT,
+ "Format %d is invalid", format);
return;
}
- format = autoar_pref_get_default_format (priv->arpref);
filter = autoar_pref_get_default_filter (priv->arpref);
- g_return_if_fail (format > 0 && format < AUTOAR_FORMAT_LAST);
- g_return_if_fail (filter > 0 && filter < AUTOAR_FILTER_LAST);
+ if (!autoar_filter_is_valid (filter)) {
+ priv->error = g_error_new (AUTOAR_CREATE_ERROR, INVALID_FILTER,
+ "Filter %d is invalid", filter);
+ return;
+ }
+
+ priv->extension = autoar_format_filter_get_extension (format, filter);
archive_write_set_bytes_in_last_block (priv->a, 1);
archive_write_add_filter (priv->a, autoar_filter_get_filter_libarchive (filter));
archive_write_set_format (priv->a, autoar_format_get_format_libarchive (format));
+}
- if (g_cancellable_is_cancelled (priv->cancellable)) {
- autoar_create_signal_cancelled (arcreate);
- return;
- }
-
+static void
+autoar_create_step_decide_dest (AutoarCreate *arcreate)
+{
/* Step 1: Set the destination file name
* Use the first source file name */
- g_debug ("autoar_extract_run: Step 1, Filename");
+
+ AutoarCreatePrivate *priv;
+
+ g_debug ("autoar_create_step_decide_dest: called");
+
+ priv = arcreate->priv;
+
{
- GFile *file_output;
- GFile *file_dest;
-
- {
- GFile *file_source;
- GFileInfo *source_info;
- char *source_basename;
- const char *basename;
-
- basename = *(priv->source);
- file_source = g_file_new_for_commandline_arg (basename);
- source_info = g_file_query_info (file_source,
- G_FILE_ATTRIBUTE_STANDARD_TYPE,
- G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
- priv->cancellable,
- &(priv->error));
- if (source_info == NULL) {
- g_object_unref (file_source);
- autoar_create_signal_error (arcreate);
- return;
- }
+ GFile *file_source; /* Do not unref */
+ GFileInfo *source_info;
+ char *source_basename;
+
+ file_source = g_ptr_array_index (priv->source_file, 0);
+ source_info = g_file_query_info (file_source,
+ G_FILE_ATTRIBUTE_STANDARD_TYPE,
+ G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
+ priv->cancellable,
+ &(priv->error));
+ if (source_info == NULL)
+ return;
- source_basename = g_file_get_basename (file_source);
- if (g_file_info_get_file_type (source_info) == G_FILE_TYPE_REGULAR)
- priv->source_basename_noext = autoar_common_get_basename_remove_extension (source_basename);
- else
- priv->source_basename_noext = g_strdup (source_basename);
+ source_basename = g_file_get_basename (file_source);
+ if (g_file_info_get_file_type (source_info) == G_FILE_TYPE_REGULAR)
+ priv->source_basename_noext = autoar_common_get_basename_remove_extension (source_basename);
+ else
+ priv->source_basename_noext = g_strdup (source_basename);
- g_object_unref (file_source);
- g_object_unref (source_info);
- g_free (source_basename);
- }
+ g_object_unref (source_info);
+ g_free (source_basename);
+ }
- {
- char *dest_basename;
- char *extension;
-
- file_output = g_file_new_for_commandline_arg (priv->output);
- extension = autoar_format_filter_get_extension (format, filter);
- dest_basename = g_strconcat (priv->source_basename_noext,
- extension, NULL);
- file_dest = g_file_get_child (file_output, dest_basename);
-
- for (i = 1; g_file_query_exists (file_dest, priv->cancellable); i++) {
- g_free (dest_basename);
- g_object_unref (file_dest);
-
- if (g_cancellable_is_cancelled (priv->cancellable)) {
- autoar_create_signal_cancelled (arcreate);
- g_object_unref (file_output);
- g_free (extension);
- return;
- }
+ {
+ char *dest_basename;
+ int i;
- extension = autoar_format_filter_get_extension (format, filter);
- dest_basename = g_strdup_printf ("%s(%d)%s",
- priv->source_basename_noext,
- i, extension);
- file_dest = g_file_get_child (file_output, dest_basename);
- }
+ dest_basename = g_strconcat (priv->source_basename_noext,
+ priv->extension, NULL);
+ priv->dest = g_file_get_child (priv->output_file, dest_basename);
+ for (i = 1; g_file_query_exists (priv->dest, priv->cancellable); i++) {
g_free (dest_basename);
- g_free (extension);
- }
+ g_object_unref (priv->dest);
- {
- if (!g_file_query_exists (file_output, priv->cancellable)) {
- g_file_make_directory_with_parents (file_output, priv->cancellable, &(priv->error));
- if (arcreate->priv->error) {
- autoar_create_signal_error (arcreate);
- g_object_unref (file_output);
- g_object_unref (file_dest);
- return;
- }
- }
- }
+ if (g_cancellable_is_cancelled (priv->cancellable))
+ return;
- arcreate->priv->dest = g_object_ref (file_dest);
- autoar_create_signal_decide_dest (arcreate);
+ dest_basename = g_strdup_printf ("%s(%d)%s",
+ priv->source_basename_noext,
+ i, priv->extension);
+ priv->dest = g_file_get_child (priv->output_file, dest_basename);
+ }
- g_object_unref (file_output);
- g_object_unref (file_dest);
+ g_free (dest_basename);
}
- if (g_cancellable_is_cancelled (priv->cancellable)) {
- autoar_create_signal_cancelled (arcreate);
- return;
+ if (!g_file_query_exists (priv->output_file, priv->cancellable)) {
+ g_file_make_directory_with_parents (priv->output_file,
+ priv->cancellable,
+ &(priv->error));
+ if (priv->error != NULL)
+ return;
}
+ autoar_create_signal_decide_dest (arcreate);
+}
+
+static void
+autoar_create_step_decide_dest_already (AutoarCreate *arcreate)
+{
+ /* Alternative step 1: Output is destination */
+ arcreate->priv->dest = g_object_ref (arcreate->priv->output_file);
+ autoar_create_signal_decide_dest (arcreate);
+}
+
+static void
+autoar_create_step_create (AutoarCreate *arcreate)
+{
/* Step 2: Create and open the new archive file */
- g_debug ("autoar_extract_run: Step 2, Create and Write");
+ AutoarCreatePrivate *priv;
+ int i, r;
+
+ g_debug ("autoar_create_step_create: called");
+
+ priv = arcreate->priv;
+
r = archive_write_open (priv->a, arcreate,
libarchive_write_open_cb,
libarchive_write_write_cb,
@@ -1144,56 +1330,48 @@ autoar_create_run (AutoarCreate *arcreate)
if (r != ARCHIVE_OK) {
if (priv->error == NULL)
priv->error = autoar_common_g_error_new_a (priv->a, NULL);
- autoar_create_signal_error (arcreate);
return;
}
-
/* Check whether we have multiple source files */
- if (arcreate->priv->source[1] == NULL)
+ if (priv->source[1] == NULL)
priv->prepend_basename = FALSE;
else
priv->prepend_basename = TRUE;
archive_entry_linkresolver_set_strategy (priv->resolver, archive_format (priv->a));
- for (i = 0; arcreate->priv->source[i] != NULL; i++) {
- GFile *file;
+ for (i = 0; i < priv->source_file->len; i++) {
+ GFile *file; /* Do not unref */
+ GFileType filetype;
GFileInfo *fileinfo;
- g_debug ("autoar_create_run: source[%d] (%s)", i, arcreate->priv->source[i]);
- file = g_file_new_for_commandline_arg (arcreate->priv->source[i]);
+ g_debug ("autoar_create_run: source[%d] (%s)", i, priv->source[i]);
+ file = g_ptr_array_index (priv->source_file, i);
fileinfo = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_TYPE,
G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
priv->cancellable,
- &(arcreate->priv->error));
- if (arcreate->priv->error != NULL) {
- autoar_create_signal_error (arcreate);
- g_object_unref (file);
- g_object_unref (fileinfo);
+ &(priv->error));
+ if (priv->error != NULL)
return;
- }
+
+ filetype = g_file_info_get_file_type (fileinfo);
+ g_object_unref (fileinfo);
autoar_create_do_add_to_archive (arcreate, file, file);
- if (g_file_info_get_file_type (fileinfo) == G_FILE_TYPE_DIRECTORY)
+ if (filetype == G_FILE_TYPE_DIRECTORY)
autoar_create_do_recursive_read (arcreate, file, file);
- g_object_unref (file);
- g_object_unref (fileinfo);
-
- if (arcreate->priv->error != NULL) {
- autoar_create_signal_error (arcreate);
+ if (priv->error != NULL)
return;
- }
- if (g_cancellable_is_cancelled (priv->cancellable)) {
- autoar_create_signal_cancelled (arcreate);
+ if (g_cancellable_is_cancelled (priv->cancellable))
return;
- }
}
+ /* Process the final entry */
{
struct archive_entry *entry, *sparse;
entry = NULL;
@@ -1208,17 +1386,69 @@ autoar_create_run (AutoarCreate *arcreate)
* because we are going to free the entire hash table. */
}
}
+}
- if (arcreate->priv->error != NULL)
+static void
+autoar_create_step_cleanup (AutoarCreate *arcreate)
+{
+ /* Step 3: Close the libarchive object. We do not have to do other cleanup
+ * because they are handled in dispose and finalize functions. */
+ AutoarCreatePrivate *priv;
+ priv = arcreate->priv;
+ if (archive_write_close (priv->a) != ARCHIVE_OK) {
+ if (priv->error == NULL)
+ priv->error = autoar_common_g_error_new_a (priv->a, priv->output);
return;
+ }
+}
- r = archive_write_close (priv->a);
- if (r != ARCHIVE_OK) {
- if (arcreate->priv->error == NULL)
- priv->error = autoar_common_g_error_new_a (priv->a, NULL);
+static void
+autoar_create_run (AutoarCreate *arcreate)
+{
+ /* Numbers of steps.
+ * The array size must be modified if more steps are added. */
+ void (*steps[5])(AutoarCreate*);
+
+ AutoarCreatePrivate *priv;
+ int i;
+
+ g_return_if_fail (AUTOAR_IS_CREATE (arcreate));
+ priv = arcreate->priv;
+
+ g_return_if_fail (priv->source_file != NULL);
+ g_return_if_fail (priv->output_file != NULL);
+
+ /* A GFile* array without a GFile* is not allowed */
+ g_return_if_fail (*((GFile**)(priv->source_file->pdata)) != NULL);
+
+ if (g_cancellable_is_cancelled (priv->cancellable)) {
+ autoar_create_signal_cancelled (arcreate);
return;
}
+ i = 0;
+ steps[i++] = autoar_create_step_initialize_object;
+ steps[i++] = priv->output_is_dest ?
+ autoar_create_step_decide_dest_already :
+ autoar_create_step_decide_dest;
+ steps[i++] = autoar_create_step_create;
+ steps[i++] = autoar_create_step_cleanup;
+ steps[i++] = NULL;
+
+ for (i = 0; steps[i] != NULL; i++) {
+ g_debug ("autoar_create_run: Step %d Begin", i);
+ (*steps[i])(arcreate);
+ g_debug ("autoar_create_run: Step %d End", i);
+ if (priv->error != NULL) {
+ autoar_create_signal_error (arcreate);
+ return;
+ }
+ if (g_cancellable_is_cancelled (priv->cancellable)) {
+ autoar_create_signal_cancelled (arcreate);
+ return;
+ }
+ }
+
autoar_create_signal_completed (arcreate);
}
diff --git a/gnome-autoar/autoar-create.h b/gnome-autoar/autoar-create.h
index 0d64993..6e5288c 100644
--- a/gnome-autoar/autoar-create.h
+++ b/gnome-autoar/autoar-create.h
@@ -75,9 +75,15 @@ GType autoar_create_get_type (void) G_GNUC_CONST;
AutoarCreate* autoar_create_new (AutoarPref *arpref,
const char *output,
...);
+AutoarCreate* autoar_create_new_file (AutoarPref *arpref,
+ GFile *output_file,
+ ...);
AutoarCreate* autoar_create_newv (AutoarPref *arpref,
const char *output,
const char **source);
+AutoarCreate* autoar_create_new_filev (AutoarPref *arpref,
+ GFile *output_file,
+ GFile **source_file);
void autoar_create_start (AutoarCreate *arcreate,
GCancellable *cancellable);
@@ -85,11 +91,14 @@ void autoar_create_start_async (AutoarCreate *arcreate,
GCancellable *cancellable);
char **autoar_create_get_source (AutoarCreate *arcreate);
+GPtrArray *autoar_create_get_source_file (AutoarCreate *arcreate);
char *autoar_create_get_output (AutoarCreate *arcreate);
+GFile *autoar_create_get_output_file (AutoarCreate *arcreate);
guint64 autoar_create_get_size (AutoarCreate *arcreate);
guint64 autoar_create_get_completed_size (AutoarCreate *arcreate);
guint autoar_create_get_files (AutoarCreate *arcreate);
guint autoar_create_get_completed_files (AutoarCreate *arcreate);
+gboolean autoar_create_get_output_is_dest (AutoarCreate *arcreate);
void autoar_create_set_size (AutoarCreate *arcreate,
guint64 size);
@@ -99,6 +108,8 @@ void autoar_create_set_files (AutoarCreate *arcreate,
guint files);
void autoar_create_set_completed_files (AutoarCreate *arcreate,
guint completed_files);
+void autoar_create_set_output_is_dest (AutoarCreate *arcreate,
+ gboolean output_is_dest);
G_END_DECLS
diff --git a/gnome-autoar/autoar-extract.c b/gnome-autoar/autoar-extract.c
index 507eb5c..529c3f8 100644
--- a/gnome-autoar/autoar-extract.c
+++ b/gnome-autoar/autoar-extract.c
@@ -641,21 +641,13 @@ g_pattern_spec_free_safe (void *pattern_compiled)
}
static void
-g_file_and_info_free (void *g_file_and_info) {
+g_file_and_info_free (void *g_file_and_info)
+{
GFileAndInfo *fi = g_file_and_info;
g_object_unref (fi->file);
g_object_unref (fi->info);
}
-static char*
-g_file_get_name (GFile *file) {
- char *name;
- name = g_file_get_path (file);
- if (name == NULL)
- name = g_file_get_uri (file);
- return name;
-}
-
static inline void
autoar_extract_signal_scanned (AutoarExtract *arextract)
{
@@ -1349,13 +1341,13 @@ autoar_extract_new_full (const char *source,
gen_source_file = g_file_new_for_commandline_arg (gen_source);
} else {
if (source == NULL)
- gen_source = g_file_get_name (source_file);
+ gen_source = autoar_common_g_file_get_name (source_file);
if (source_file == NULL)
gen_source_file = g_file_new_for_commandline_arg (source);
}
if (output == NULL)
- gen_output = g_file_get_name (output_file);
+ gen_output = autoar_common_g_file_get_name (output_file);
if (output_file == NULL)
gen_output_file = g_file_new_for_commandline_arg (output);