[file-roller: 70/123] move fr_archive_libarchive_extract_files before _fr_archive_libarchive_save



commit f1876178a86ca5e5ae4e35994153c0fa83876af3
Author: Paolo Bacchilega <paobac src gnome org>
Date:   Sun Jul 29 11:59:57 2012 +0200

    move fr_archive_libarchive_extract_files before _fr_archive_libarchive_save

 src/fr-archive-libarchive.c |  778 +++++++++++++++++++++---------------------
 1 files changed, 389 insertions(+), 389 deletions(-)
---
diff --git a/src/fr-archive-libarchive.c b/src/fr-archive-libarchive.c
index 33a39c7..4dfe99e 100644
--- a/src/fr-archive-libarchive.c
+++ b/src/fr-archive-libarchive.c
@@ -284,6 +284,273 @@ fr_archive_libarchive_load (FrArchive           *archive,
 }
 
 
+/* -- extract -- */
+
+
+typedef struct {
+	LoadData    parent;
+	GList      *file_list;
+	GFile      *destination;
+	char       *base_dir;
+	gboolean    skip_older;
+	gboolean    overwrite;
+	gboolean    junk_paths;
+	GHashTable *files_to_extract;
+	int         n_files_to_extract;
+} ExtractData;
+
+
+static void
+extract_data_free (ExtractData *extract_data)
+{
+	g_free (extract_data->base_dir);
+	_g_object_unref (extract_data->destination);
+	_g_string_list_free (extract_data->file_list);
+	g_hash_table_unref (extract_data->files_to_extract);
+	load_data_free (LOAD_DATA (extract_data));
+}
+
+
+static gboolean
+extract_data_get_extraction_requested (ExtractData *extract_data,
+				       const char  *pathname)
+{
+	if (extract_data->file_list != NULL)
+		return g_hash_table_lookup (extract_data->files_to_extract, pathname) != NULL;
+	else
+		return TRUE;
+}
+
+
+static void
+extract_archive_thread (GSimpleAsyncResult *result,
+			GObject            *object,
+			GCancellable       *cancellable)
+{
+	ExtractData          *extract_data;
+	LoadData             *load_data;
+	GHashTable           *checked_folders;
+	struct archive       *a;
+	struct archive_entry *entry;
+	int                   r;
+
+	extract_data = g_simple_async_result_get_op_res_gpointer (result);
+	load_data = LOAD_DATA (extract_data);
+
+	checked_folders = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
+	fr_archive_progress_set_total_files (load_data->archive, extract_data->n_files_to_extract);
+
+	a = archive_read_new ();
+	archive_read_support_filter_all (a);
+	archive_read_support_format_all (a);
+	archive_read_open (a, load_data, load_data_open, load_data_read, load_data_close);
+	while ((r = archive_read_next_header (a, &entry)) == ARCHIVE_OK) {
+		const char    *pathname;
+		char          *fullpath;
+		GFile         *file;
+		GFile         *parent;
+		GOutputStream *ostream;
+		const void    *buffer;
+		size_t         buffer_size;
+		int64_t        offset;
+		GError        *local_error = NULL;
+
+		if (g_cancellable_is_cancelled (cancellable))
+			break;
+
+		pathname = archive_entry_pathname (entry);
+		if (! extract_data_get_extraction_requested (extract_data, pathname)) {
+			archive_read_data_skip (a);
+			continue;
+		}
+
+		fullpath = (*pathname == '/') ? g_strdup (pathname) : g_strconcat ("/", pathname, NULL);
+		file = g_file_get_child (extract_data->destination, _g_path_get_basename (fullpath, extract_data->base_dir, extract_data->junk_paths));
+
+		/* honor the skip_older and overwrite options */
+
+		if (extract_data->skip_older || ! extract_data->overwrite) {
+			GFileInfo *info;
+
+			info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, cancellable, &local_error);
+			if (info != NULL) {
+				gboolean skip = FALSE;
+
+				if (! extract_data->overwrite) {
+					skip = TRUE;
+				}
+				else if (extract_data->skip_older) {
+					GTimeVal modification_time;
+
+					g_file_info_get_modification_time (info, &modification_time);
+					if (archive_entry_mtime (entry) < modification_time.tv_sec)
+						skip = TRUE;
+				}
+
+				g_object_unref (info);
+
+				if (skip) {
+					g_object_unref (file);
+
+					archive_read_data_skip (a);
+					fr_archive_progress_inc_completed_bytes (load_data->archive, archive_entry_size_is_set (entry) ? archive_entry_size (entry) : 0);
+
+					if ((extract_data->file_list != NULL) && (--extract_data->n_files_to_extract == 0)) {
+						r = ARCHIVE_EOF;
+						break;
+					}
+
+					continue;
+				}
+			}
+			else {
+				if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
+					load_data->error = local_error;
+					g_object_unref (info);
+					break;
+				}
+				g_error_free (local_error);
+			}
+		}
+
+		fr_archive_progress_inc_completed_files (load_data->archive, 1);
+
+		/* create the file parents */
+
+		parent = g_file_get_parent (file);
+		if ((parent != NULL)
+		    && (g_hash_table_lookup (checked_folders, parent) == NULL)
+		    && ! g_file_query_exists (parent, cancellable))
+		{
+			if (g_file_make_directory_with_parents (parent, cancellable, &load_data->error)) {
+				GFile *grandparent;
+
+				grandparent = g_object_ref (parent);
+				while (grandparent != NULL) {
+					if (g_hash_table_lookup (checked_folders, grandparent) == NULL)
+						g_hash_table_insert (checked_folders, grandparent, GINT_TO_POINTER (1));
+					grandparent = g_file_get_parent (grandparent);
+				}
+			}
+		}
+		g_object_unref (parent);
+
+		/* create the file */
+
+		if (load_data->error == NULL) {
+			switch (archive_entry_filetype (entry)) {
+			case AE_IFDIR:
+				if (! g_file_make_directory (file, cancellable, &local_error)) {
+					if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+						load_data->error = g_error_copy (local_error);
+					g_error_free (local_error);
+				}
+				archive_read_data_skip (a);
+				break;
+
+			case AE_IFREG:
+				ostream = (GOutputStream *) g_file_replace (file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, cancellable, &load_data->error);
+				if (ostream == NULL)
+					break;
+
+				while ((r = archive_read_data_block (a, &buffer, &buffer_size, &offset)) == ARCHIVE_OK) {
+					if (g_output_stream_write (ostream, buffer, buffer_size, cancellable, &load_data->error) == -1)
+						break;
+					fr_archive_progress_inc_completed_bytes (load_data->archive, buffer_size);
+				}
+
+				if (r != ARCHIVE_EOF)
+					load_data->error = g_error_new_literal (FR_ERROR, FR_ERROR_COMMAND_ERROR, archive_error_string (a));
+
+				_g_object_unref (ostream);
+				break;
+
+			case AE_IFLNK:
+				if (! g_file_make_symbolic_link (file, archive_entry_symlink (entry), cancellable, &local_error)) {
+					if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
+						load_data->error = g_error_copy (local_error);
+					g_error_free (local_error);
+				}
+				archive_read_data_skip (a);
+				break;
+			}
+		}
+
+		g_object_unref (file);
+		g_free (fullpath);
+
+		if (load_data->error != NULL)
+			break;
+
+		if ((extract_data->file_list != NULL) && (--extract_data->n_files_to_extract == 0)) {
+			r = ARCHIVE_EOF;
+			break;
+		}
+	}
+
+	if ((load_data->error == NULL) && (r != ARCHIVE_EOF))
+		load_data->error = g_error_new_literal (FR_ERROR, FR_ERROR_COMMAND_ERROR, archive_error_string (a));
+	if (load_data->error == NULL)
+		g_cancellable_set_error_if_cancelled (cancellable, &load_data->error);
+	if (load_data->error != NULL)
+		g_simple_async_result_set_from_error (result, load_data->error);
+
+	g_hash_table_unref (checked_folders);
+	archive_read_free (a);
+	extract_data_free (extract_data);
+}
+
+
+static void
+fr_archive_libarchive_extract_files (FrArchive           *archive,
+				     GList               *file_list,
+				     const char          *destination,
+				     const char          *base_dir,
+				     gboolean             skip_older,
+				     gboolean             overwrite,
+				     gboolean             junk_paths,
+				     const char          *password,
+				     GCancellable        *cancellable,
+				     GAsyncReadyCallback  callback,
+				     gpointer             user_data)
+{
+	ExtractData *extract_data;
+	LoadData    *load_data;
+	GList       *scan;
+
+	extract_data = g_new0 (ExtractData, 1);
+
+	load_data = LOAD_DATA (extract_data);
+	load_data->archive = g_object_ref (archive);
+	load_data->cancellable = _g_object_ref (cancellable);
+	load_data->result = g_simple_async_result_new (G_OBJECT (archive),
+						       callback,
+						       user_data,
+						       fr_archive_load);
+	load_data->buffer_size = BUFFER_SIZE;
+	load_data->buffer = g_new (char, load_data->buffer_size);
+
+	extract_data->file_list = _g_string_list_dup (file_list);
+	extract_data->destination = g_file_new_for_uri (destination);
+	extract_data->base_dir = g_strdup (base_dir);
+	extract_data->skip_older = skip_older;
+	extract_data->overwrite = overwrite;
+	extract_data->junk_paths = junk_paths;
+	extract_data->files_to_extract = g_hash_table_new (g_str_hash, g_str_equal);
+	extract_data->n_files_to_extract = 0;
+	for (scan = extract_data->file_list; scan; scan = scan->next) {
+		g_hash_table_insert (extract_data->files_to_extract, scan->data, GINT_TO_POINTER (1));
+		extract_data->n_files_to_extract++;
+	}
+
+	g_simple_async_result_set_op_res_gpointer (load_data->result, extract_data, NULL);
+	g_simple_async_result_run_in_thread (load_data->result,
+					     extract_archive_thread,
+					     G_PRIORITY_DEFAULT,
+					     cancellable);
+}
+
+
 /* --  AddFile -- */
 
 
@@ -904,423 +1171,156 @@ _add_files_end (SaveData *save_data,
 	}
 
 	g_list_free (remaining_files);
-}
-
-
-static void
-fr_archive_libarchive_add_files (FrArchive           *archive,
-				 GList               *file_list,
-				 const char          *base_dir,
-				 const char          *dest_dir,
-				 gboolean             update,
-				 gboolean             recursive,
-				 const char          *password,
-				 gboolean             encrypt_header,
-				 FrCompression        compression,
-				 guint                volume_size,
-				 GCancellable        *cancellable,
-				 GAsyncReadyCallback  callback,
-				 gpointer             user_data)
-{
-	AddData *add_data;
-	GList   *scan;
-
-	g_return_if_fail (base_dir != NULL);
-
-	add_data = g_new0 (AddData, 1);
-	add_data->file_list = _g_string_list_dup (file_list);
-	add_data->base_dir = g_file_new_for_uri (base_dir);
-	add_data->dest_dir = g_strdup (dest_dir[0] == '/' ? dest_dir + 1 : dest_dir);
-	add_data->files_to_add = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) add_file_free);
-	add_data->n_files_to_add = 0;
-	for (scan = add_data->file_list; scan; scan = scan->next) {
-		char  *relative_pathname = scan->data;
-		char  *full_pathname;
-		GFile *file;
-
-		full_pathname = g_build_filename (add_data->dest_dir, relative_pathname, NULL);
-		file = g_file_get_child (add_data->base_dir, relative_pathname);
-		g_hash_table_insert (add_data->files_to_add, full_pathname, add_file_new (file, full_pathname));
-		add_data->n_files_to_add++;
-
-		g_object_unref (file);
-		g_free (full_pathname);
-	}
-
-	_fr_archive_libarchive_save (archive,
-				     update,
-				     password,
-				     encrypt_header,
-				     compression,
-				     volume_size,
-				     cancellable,
-				     g_simple_async_result_new (G_OBJECT (archive),
-				     				callback,
-				     				user_data,
-				     				fr_archive_add_files),
-				     _add_files_begin,
-				     _add_files_end,
-				     _add_files_entry_action,
-				     add_data,
-				     (GDestroyNotify) add_data_free);
-}
-
-
-/* -- remove -- */
-
-
-typedef struct {
-	GList      *file_list;
-	GHashTable *files_to_remove;
-	int         n_files_to_remove;
-} RemoveData;
-
-
-static void
-remove_data_free (RemoveData *remove_data)
-{
-	g_hash_table_unref (remove_data->files_to_remove);
-	_g_string_list_free (remove_data->file_list);
-	g_free (remove_data);
-}
-
-
-static void
-_remove_files_begin (SaveData *save_data,
-		     gpointer  user_data)
-{
-	RemoveData *remove_data = user_data;
-
-	fr_archive_progress_set_total_files (LOAD_DATA (save_data)->archive, remove_data->n_files_to_remove);
-}
-
-
-static WriteAction
-_remove_files_entry_action (SaveData             *save_data,
-			    struct archive_entry *w_entry,
-			    gpointer              user_data)
-{
-	RemoveData  *remove_data = user_data;
-	LoadData    *load_data = LOAD_DATA (save_data);
-	WriteAction  action;
-	const char  *pathname;
-
-	action = WRITE_ACTION_WRITE_ENTRY;
-	pathname = archive_entry_pathname (w_entry);
-	if (g_hash_table_lookup (remove_data->files_to_remove, pathname)) {
-		fr_archive_progress_inc_completed_files (load_data->archive, 1);
-		remove_data->n_files_to_remove--;
-		g_hash_table_remove (remove_data->files_to_remove, pathname);
-		action = WRITE_ACTION_SKIP_ENTRY;
-	}
-
-	return action;
-}
-
-
-static void
-fr_archive_libarchive_remove_files (FrArchive           *archive,
-				    GList               *file_list,
-				    FrCompression        compression,
-				    GCancellable        *cancellable,
-				    GAsyncReadyCallback  callback,
-				    gpointer             user_data)
-{
-	RemoveData *remove_data;
-	GList      *scan;
-
-	remove_data = g_new0 (RemoveData, 1);
-	remove_data->file_list = _g_string_list_dup (file_list);
-	remove_data->files_to_remove = g_hash_table_new (g_str_hash, g_str_equal);
-	remove_data->n_files_to_remove = 0;
-	for (scan = remove_data->file_list; scan; scan = scan->next) {
-		g_hash_table_insert (remove_data->files_to_remove, scan->data, GINT_TO_POINTER (1));
-		remove_data->n_files_to_remove++;
-	}
-
-	_fr_archive_libarchive_save (archive,
-				     FALSE,
-				     NULL,
-				     FALSE,
-				     compression,
-				     0,
-				     cancellable,
-				     g_simple_async_result_new (G_OBJECT (archive),
-				     				callback,
-				     				user_data,
-				     				fr_archive_remove),
-     				     _remove_files_begin,
-				     NULL,
-				     _remove_files_entry_action,
-				     remove_data,
-				     (GDestroyNotify) remove_data_free);
-}
-
-
-/* -- extract -- */
-
-
-typedef struct {
-	LoadData    parent;
-	GList      *file_list;
-	GFile      *destination;
-	char       *base_dir;
-	gboolean    skip_older;
-	gboolean    overwrite;
-	gboolean    junk_paths;
-	GHashTable *files_to_extract;
-	int         n_files_to_extract;
-} ExtractData;
-
-
-static void
-extract_data_free (ExtractData *extract_data)
-{
-	g_free (extract_data->base_dir);
-	_g_object_unref (extract_data->destination);
-	_g_string_list_free (extract_data->file_list);
-	g_hash_table_unref (extract_data->files_to_extract);
-	load_data_free (LOAD_DATA (extract_data));
-}
-
-
-static gboolean
-extract_data_get_extraction_requested (ExtractData *extract_data,
-				       const char  *pathname)
-{
-	if (extract_data->file_list != NULL)
-		return g_hash_table_lookup (extract_data->files_to_extract, pathname) != NULL;
-	else
-		return TRUE;
-}
-
-
-static void
-extract_archive_thread (GSimpleAsyncResult *result,
-			GObject            *object,
-			GCancellable       *cancellable)
-{
-	ExtractData          *extract_data;
-	LoadData             *load_data;
-	GHashTable           *checked_folders;
-	struct archive       *a;
-	struct archive_entry *entry;
-	int                   r;
-
-	extract_data = g_simple_async_result_get_op_res_gpointer (result);
-	load_data = LOAD_DATA (extract_data);
-
-	checked_folders = g_hash_table_new_full (g_file_hash, (GEqualFunc) g_file_equal, g_object_unref, NULL);
-	fr_archive_progress_set_total_files (load_data->archive, extract_data->n_files_to_extract);
-
-	a = archive_read_new ();
-	archive_read_support_filter_all (a);
-	archive_read_support_format_all (a);
-	archive_read_open (a, load_data, load_data_open, load_data_read, load_data_close);
-	while ((r = archive_read_next_header (a, &entry)) == ARCHIVE_OK) {
-		const char    *pathname;
-		char          *fullpath;
-		GFile         *file;
-		GFile         *parent;
-		GOutputStream *ostream;
-		const void    *buffer;
-		size_t         buffer_size;
-		int64_t        offset;
-		GError        *local_error = NULL;
-
-		if (g_cancellable_is_cancelled (cancellable))
-			break;
-
-		pathname = archive_entry_pathname (entry);
-		if (! extract_data_get_extraction_requested (extract_data, pathname)) {
-			archive_read_data_skip (a);
-			continue;
-		}
-
-		fullpath = (*pathname == '/') ? g_strdup (pathname) : g_strconcat ("/", pathname, NULL);
-		file = g_file_get_child (extract_data->destination, _g_path_get_basename (fullpath, extract_data->base_dir, extract_data->junk_paths));
-
-		/* honor the skip_older and overwrite options */
-
-		if (extract_data->skip_older || ! extract_data->overwrite) {
-			GFileInfo *info;
-
-			info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME "," G_FILE_ATTRIBUTE_TIME_MODIFIED, 0, cancellable, &local_error);
-			if (info != NULL) {
-				gboolean skip = FALSE;
-
-				if (! extract_data->overwrite) {
-					skip = TRUE;
-				}
-				else if (extract_data->skip_older) {
-					GTimeVal modification_time;
-
-					g_file_info_get_modification_time (info, &modification_time);
-					if (archive_entry_mtime (entry) < modification_time.tv_sec)
-						skip = TRUE;
-				}
+}
 
-				g_object_unref (info);
 
-				if (skip) {
-					g_object_unref (file);
+static void
+fr_archive_libarchive_add_files (FrArchive           *archive,
+				 GList               *file_list,
+				 const char          *base_dir,
+				 const char          *dest_dir,
+				 gboolean             update,
+				 gboolean             recursive,
+				 const char          *password,
+				 gboolean             encrypt_header,
+				 FrCompression        compression,
+				 guint                volume_size,
+				 GCancellable        *cancellable,
+				 GAsyncReadyCallback  callback,
+				 gpointer             user_data)
+{
+	AddData *add_data;
+	GList   *scan;
 
-					archive_read_data_skip (a);
-					fr_archive_progress_inc_completed_bytes (load_data->archive, archive_entry_size_is_set (entry) ? archive_entry_size (entry) : 0);
+	g_return_if_fail (base_dir != NULL);
 
-					if ((extract_data->file_list != NULL) && (--extract_data->n_files_to_extract == 0)) {
-						r = ARCHIVE_EOF;
-						break;
-					}
+	add_data = g_new0 (AddData, 1);
+	add_data->file_list = _g_string_list_dup (file_list);
+	add_data->base_dir = g_file_new_for_uri (base_dir);
+	add_data->dest_dir = g_strdup (dest_dir[0] == '/' ? dest_dir + 1 : dest_dir);
+	add_data->files_to_add = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) add_file_free);
+	add_data->n_files_to_add = 0;
+	for (scan = add_data->file_list; scan; scan = scan->next) {
+		char  *relative_pathname = scan->data;
+		char  *full_pathname;
+		GFile *file;
 
-					continue;
-				}
-			}
-			else {
-				if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
-					load_data->error = local_error;
-					g_object_unref (info);
-					break;
-				}
-				g_error_free (local_error);
-			}
-		}
+		full_pathname = g_build_filename (add_data->dest_dir, relative_pathname, NULL);
+		file = g_file_get_child (add_data->base_dir, relative_pathname);
+		g_hash_table_insert (add_data->files_to_add, full_pathname, add_file_new (file, full_pathname));
+		add_data->n_files_to_add++;
 
-		fr_archive_progress_inc_completed_files (load_data->archive, 1);
+		g_object_unref (file);
+		g_free (full_pathname);
+	}
 
-		/* create the file parents */
+	_fr_archive_libarchive_save (archive,
+				     update,
+				     password,
+				     encrypt_header,
+				     compression,
+				     volume_size,
+				     cancellable,
+				     g_simple_async_result_new (G_OBJECT (archive),
+				     				callback,
+				     				user_data,
+				     				fr_archive_add_files),
+				     _add_files_begin,
+				     _add_files_end,
+				     _add_files_entry_action,
+				     add_data,
+				     (GDestroyNotify) add_data_free);
+}
 
-		parent = g_file_get_parent (file);
-		if ((parent != NULL)
-		    && (g_hash_table_lookup (checked_folders, parent) == NULL)
-		    && ! g_file_query_exists (parent, cancellable))
-		{
-			if (g_file_make_directory_with_parents (parent, cancellable, &load_data->error)) {
-				GFile *grandparent;
 
-				grandparent = g_object_ref (parent);
-				while (grandparent != NULL) {
-					if (g_hash_table_lookup (checked_folders, grandparent) == NULL)
-						g_hash_table_insert (checked_folders, grandparent, GINT_TO_POINTER (1));
-					grandparent = g_file_get_parent (grandparent);
-				}
-			}
-		}
-		g_object_unref (parent);
+/* -- remove -- */
 
-		/* create the file */
 
-		if (load_data->error == NULL) {
-			switch (archive_entry_filetype (entry)) {
-			case AE_IFDIR:
-				if (! g_file_make_directory (file, cancellable, &local_error)) {
-					if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
-						load_data->error = g_error_copy (local_error);
-					g_error_free (local_error);
-				}
-				archive_read_data_skip (a);
-				break;
+typedef struct {
+	GList      *file_list;
+	GHashTable *files_to_remove;
+	int         n_files_to_remove;
+} RemoveData;
 
-			case AE_IFREG:
-				ostream = (GOutputStream *) g_file_replace (file, NULL, FALSE, G_FILE_CREATE_REPLACE_DESTINATION, cancellable, &load_data->error);
-				if (ostream == NULL)
-					break;
 
-				while ((r = archive_read_data_block (a, &buffer, &buffer_size, &offset)) == ARCHIVE_OK) {
-					if (g_output_stream_write (ostream, buffer, buffer_size, cancellable, &load_data->error) == -1)
-						break;
-					fr_archive_progress_inc_completed_bytes (load_data->archive, buffer_size);
-				}
+static void
+remove_data_free (RemoveData *remove_data)
+{
+	g_hash_table_unref (remove_data->files_to_remove);
+	_g_string_list_free (remove_data->file_list);
+	g_free (remove_data);
+}
 
-				if (r != ARCHIVE_EOF)
-					load_data->error = g_error_new_literal (FR_ERROR, FR_ERROR_COMMAND_ERROR, archive_error_string (a));
 
-				_g_object_unref (ostream);
-				break;
+static void
+_remove_files_begin (SaveData *save_data,
+		     gpointer  user_data)
+{
+	RemoveData *remove_data = user_data;
 
-			case AE_IFLNK:
-				if (! g_file_make_symbolic_link (file, archive_entry_symlink (entry), cancellable, &local_error)) {
-					if (! g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_EXISTS))
-						load_data->error = g_error_copy (local_error);
-					g_error_free (local_error);
-				}
-				archive_read_data_skip (a);
-				break;
-			}
-		}
+	fr_archive_progress_set_total_files (LOAD_DATA (save_data)->archive, remove_data->n_files_to_remove);
+}
 
-		g_object_unref (file);
-		g_free (fullpath);
 
-		if (load_data->error != NULL)
-			break;
+static WriteAction
+_remove_files_entry_action (SaveData             *save_data,
+			    struct archive_entry *w_entry,
+			    gpointer              user_data)
+{
+	RemoveData  *remove_data = user_data;
+	LoadData    *load_data = LOAD_DATA (save_data);
+	WriteAction  action;
+	const char  *pathname;
 
-		if ((extract_data->file_list != NULL) && (--extract_data->n_files_to_extract == 0)) {
-			r = ARCHIVE_EOF;
-			break;
-		}
+	action = WRITE_ACTION_WRITE_ENTRY;
+	pathname = archive_entry_pathname (w_entry);
+	if (g_hash_table_lookup (remove_data->files_to_remove, pathname)) {
+		fr_archive_progress_inc_completed_files (load_data->archive, 1);
+		remove_data->n_files_to_remove--;
+		g_hash_table_remove (remove_data->files_to_remove, pathname);
+		action = WRITE_ACTION_SKIP_ENTRY;
 	}
 
-	if ((load_data->error == NULL) && (r != ARCHIVE_EOF))
-		load_data->error = g_error_new_literal (FR_ERROR, FR_ERROR_COMMAND_ERROR, archive_error_string (a));
-	if (load_data->error == NULL)
-		g_cancellable_set_error_if_cancelled (cancellable, &load_data->error);
-	if (load_data->error != NULL)
-		g_simple_async_result_set_from_error (result, load_data->error);
-
-	g_hash_table_unref (checked_folders);
-	archive_read_free (a);
-	extract_data_free (extract_data);
+	return action;
 }
 
 
 static void
-fr_archive_libarchive_extract_files (FrArchive           *archive,
-				     GList               *file_list,
-				     const char          *destination,
-				     const char          *base_dir,
-				     gboolean             skip_older,
-				     gboolean             overwrite,
-				     gboolean             junk_paths,
-				     const char          *password,
-				     GCancellable        *cancellable,
-				     GAsyncReadyCallback  callback,
-				     gpointer             user_data)
+fr_archive_libarchive_remove_files (FrArchive           *archive,
+				    GList               *file_list,
+				    FrCompression        compression,
+				    GCancellable        *cancellable,
+				    GAsyncReadyCallback  callback,
+				    gpointer             user_data)
 {
-	ExtractData *extract_data;
-	LoadData    *load_data;
-	GList       *scan;
-
-	extract_data = g_new0 (ExtractData, 1);
-
-	load_data = LOAD_DATA (extract_data);
-	load_data->archive = g_object_ref (archive);
-	load_data->cancellable = _g_object_ref (cancellable);
-	load_data->result = g_simple_async_result_new (G_OBJECT (archive),
-						       callback,
-						       user_data,
-						       fr_archive_load);
-	load_data->buffer_size = BUFFER_SIZE;
-	load_data->buffer = g_new (char, load_data->buffer_size);
+	RemoveData *remove_data;
+	GList      *scan;
 
-	extract_data->file_list = _g_string_list_dup (file_list);
-	extract_data->destination = g_file_new_for_uri (destination);
-	extract_data->base_dir = g_strdup (base_dir);
-	extract_data->skip_older = skip_older;
-	extract_data->overwrite = overwrite;
-	extract_data->junk_paths = junk_paths;
-	extract_data->files_to_extract = g_hash_table_new (g_str_hash, g_str_equal);
-	extract_data->n_files_to_extract = 0;
-	for (scan = extract_data->file_list; scan; scan = scan->next) {
-		g_hash_table_insert (extract_data->files_to_extract, scan->data, GINT_TO_POINTER (1));
-		extract_data->n_files_to_extract++;
+	remove_data = g_new0 (RemoveData, 1);
+	remove_data->file_list = _g_string_list_dup (file_list);
+	remove_data->files_to_remove = g_hash_table_new (g_str_hash, g_str_equal);
+	remove_data->n_files_to_remove = 0;
+	for (scan = remove_data->file_list; scan; scan = scan->next) {
+		g_hash_table_insert (remove_data->files_to_remove, scan->data, GINT_TO_POINTER (1));
+		remove_data->n_files_to_remove++;
 	}
 
-	g_simple_async_result_set_op_res_gpointer (load_data->result, extract_data, NULL);
-	g_simple_async_result_run_in_thread (load_data->result,
-					     extract_archive_thread,
-					     G_PRIORITY_DEFAULT,
-					     cancellable);
+	_fr_archive_libarchive_save (archive,
+				     FALSE,
+				     NULL,
+				     FALSE,
+				     compression,
+				     0,
+				     cancellable,
+				     g_simple_async_result_new (G_OBJECT (archive),
+				     				callback,
+				     				user_data,
+				     				fr_archive_remove),
+     				     _remove_files_begin,
+				     NULL,
+				     _remove_files_entry_action,
+				     remove_data,
+				     (GDestroyNotify) remove_data_free);
 }
 
 
@@ -1541,9 +1541,9 @@ fr_archive_libarchive_class_init (FrArchiveLibarchiveClass *klass)
 	archive_class->get_capabilities = fr_archive_libarchive_get_capabilities;
 	archive_class->get_packages = fr_archive_libarchive_get_packages;
 	archive_class->load = fr_archive_libarchive_load;
+	archive_class->extract_files = fr_archive_libarchive_extract_files;
 	archive_class->add_files = fr_archive_libarchive_add_files;
 	archive_class->remove_files = fr_archive_libarchive_remove_files;
-	archive_class->extract_files = fr_archive_libarchive_extract_files;
 	archive_class->rename = fr_archive_libarchive_rename;
 	archive_class->paste_clipboard = fr_archive_libarchive_paste_clipboard;
 	archive_class->add_dropped_items = fr_archive_libarchive_add_dropped_items;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]