brasero r1317 - in trunk: . src
- From: philippr svn gnome org
- To: svn-commits-list gnome org
- Subject: brasero r1317 - in trunk: . src
- Date: Sun, 28 Sep 2008 18:48:39 +0000 (UTC)
Author: philippr
Date: Sun Sep 28 18:48:39 2008
New Revision: 1317
URL: http://svn.gnome.org/viewvc/brasero?rev=1317&view=rev
Log:
Fix #549852 â Data DVD+RW detected badly as multisession
Greatly improved performance when loading session (now it\'s done async)
and save memory by not loading all nodes
* src/brasero-burn-options.c (brasero_burn_options_valid_media_cb):
* src/brasero-data-project.c
(brasero_data_project_add_imported_session_file):
* src/brasero-data-project.h:
* src/brasero-data-session.c
(brasero_data_session_load_dir_destroy),
(brasero_data_session_load_dir_result),
(brasero_data_session_load_directory_contents_real),
(brasero_data_session_load_directory_contents),
(brasero_data_session_add_last), (brasero_data_session_stop_io),
(brasero_data_session_reset), (brasero_data_session_finalize),
(brasero_data_session_class_init):
* src/brasero-data-session.h:
* src/brasero-data-tree-model.c
(brasero_data_tree_model_node_shown):
* src/brasero-dest-selection.c (brasero_dest_selection_finalize):
* src/brasero-file-node.c
(brasero_file_node_new_imported_session_file):
* src/brasero-file-node.h:
* src/brasero-io.c (brasero_io_image_directory_contents_destroy),
(brasero_io_image_directory_contents_thread),
(brasero_io_load_image_directory):
* src/brasero-io.h:
* src/brasero-tool-dialog.c (brasero_tool_dialog_init):
* src/burn-iso9660.c (brasero_iso9660_get_first_directory_record),
(brasero_iso9660_read_directory_record),
(brasero_iso9660_load_directory_records),
(brasero_iso9660_check_SUSP_RR_use), (brasero_iso9660_ctx_init),
(brasero_iso9660_get_contents), (brasero_iso9660_get_file),
(brasero_iso9660_get_directory_contents):
* src/burn-iso9660.h:
* src/burn-volume.c (brasero_volume_file_free),
(brasero_volume_get_files),
(brasero_volume_load_directory_contents):
* src/burn-volume.h:
Modified:
trunk/ChangeLog
trunk/src/brasero-burn-options.c
trunk/src/brasero-data-project.c
trunk/src/brasero-data-project.h
trunk/src/brasero-data-session.c
trunk/src/brasero-data-session.h
trunk/src/brasero-data-tree-model.c
trunk/src/brasero-dest-selection.c
trunk/src/brasero-file-node.c
trunk/src/brasero-file-node.h
trunk/src/brasero-io.c
trunk/src/brasero-io.h
trunk/src/brasero-tool-dialog.c
trunk/src/burn-iso9660.c
trunk/src/burn-iso9660.h
trunk/src/burn-volume.c
trunk/src/burn-volume.h
Modified: trunk/src/brasero-burn-options.c
==============================================================================
--- trunk/src/brasero-burn-options.c (original)
+++ trunk/src/brasero-burn-options.c Sun Sep 28 18:48:39 2008
@@ -305,13 +305,7 @@
G_CALLBACK (brasero_burn_options_message_response_cb),
self);
}
-/* else if (valid == BRASERO_SESSION_BLANKING) {
-
- }
- else if (valid == BRASERO_SESSION_APPENDING) {
-
- }
-*/
+
gtk_window_resize (GTK_WINDOW (self), 10, 10);
}
Modified: trunk/src/brasero-data-project.c
==============================================================================
--- trunk/src/brasero-data-project.c (original)
+++ trunk/src/brasero-data-project.c Sun Sep 28 18:48:39 2008
@@ -1584,7 +1584,7 @@
BraseroFileNode *
brasero_data_project_add_imported_session_file (BraseroDataProject *self,
- BraseroVolFile *file,
+ GFileInfo *info,
BraseroFileNode *parent)
{
BraseroFileNode *node;
@@ -1592,14 +1592,14 @@
BraseroDataProjectPrivate *priv;
g_return_val_if_fail (BRASERO_IS_DATA_PROJECT (self), NULL);
- g_return_val_if_fail (file != NULL, NULL);
+ g_return_val_if_fail (info != NULL, NULL);
priv = BRASERO_DATA_PROJECT_PRIVATE (self);
if (!parent)
parent = priv->root;
- node = brasero_file_node_check_name_existence (parent, BRASERO_VOLUME_FILE_NAME (file));
+ node = brasero_file_node_check_name_existence (parent, g_file_info_get_name (info));
if (node) {
/* The node exists but it may be that we've loaded the project
* before. Then the necessary directories to hold the grafted
@@ -1642,7 +1642,7 @@
brasero_data_project_remove_real (self, node);
}
- node = brasero_file_node_new_imported_session_file (file, parent, priv->sort_func);
+ node = brasero_file_node_new_imported_session_file (info, parent, priv->sort_func);
/* In this case, there can be no graft, and furthermore the
* lengths of the names are not our problem. Just signal that
Modified: trunk/src/brasero-data-project.h
==============================================================================
--- trunk/src/brasero-data-project.h (original)
+++ trunk/src/brasero-data-project.h Sun Sep 28 18:48:39 2008
@@ -154,7 +154,7 @@
BraseroFileNode *parent);
BraseroFileNode *
brasero_data_project_add_imported_session_file (BraseroDataProject *project,
- BraseroVolFile *file,
+ GFileInfo *info,
BraseroFileNode *parent);
void
Modified: trunk/src/brasero-data-session.c
==============================================================================
--- trunk/src/brasero-data-session.c (original)
+++ trunk/src/brasero-data-session.c Sun Sep 28 18:48:39 2008
@@ -39,12 +39,16 @@
#include "brasero-data-session.h"
#include "brasero-data-project.h"
#include "brasero-file-node.h"
+#include "brasero-io.h"
#include "brasero-marshal.h"
typedef struct _BraseroDataSessionPrivate BraseroDataSessionPrivate;
struct _BraseroDataSessionPrivate
{
+ BraseroIO *io;
+ BraseroIOJobBase *load_dir;
+
/* Multisession drives that are inserted */
GSList *media;
@@ -187,154 +191,155 @@
}
static void
-brasero_data_session_add_children_files (BraseroDataSession *self,
- BraseroFileNode *parent,
- GList *children)
-{
- for (; children; children = children->next) {
- BraseroFileNode *node;
- BraseroVolFile *child;
+brasero_data_session_load_dir_destroy (GObject *object,
+ gboolean cancelled,
+ gpointer data)
+{
+ gint reference;
+ BraseroFileNode *parent;
+
+ /* reference */
+ reference = GPOINTER_TO_INT (data);
+ if (reference <= 0)
+ return;
- child = children->data;
- node = brasero_data_project_add_imported_session_file (BRASERO_DATA_PROJECT (self),
- child,
- parent);
-
- /* There is little chance that a NULL node will be returned and
- * logically that shouldn't be the case. But who knows bugs
- * happen, let's try not to crash. ;) */
- if (node && !node->is_file)
- brasero_data_session_add_children_files (self,
- node,
- child->specific.dir.children);
- }
+ parent = brasero_data_project_reference_get (BRASERO_DATA_PROJECT (object), reference);
+ if (parent)
+ parent->is_exploring = FALSE;
+
+ brasero_data_project_reference_free (BRASERO_DATA_PROJECT (object), reference);
}
-gboolean
-brasero_data_session_add_last (BraseroDataSession *self,
- BraseroMedium *medium,
- GError **error)
+static void
+brasero_data_session_load_dir_result (GObject *owner,
+ GError *error,
+ const gchar *dev_image,
+ GFileInfo *info,
+ gpointer data)
{
BraseroDataSessionPrivate *priv;
- BraseroDeviceHandle *handle;
- BraseroVolFile *volume;
- BraseroScsiErrCode err;
- BraseroDrive *drive;
- const gchar *device;
- BraseroVolSrc *vol;
- gint64 block;
- GList *iter;
+ BraseroFileNode *parent;
+ BraseroFileNode *node;
+ gint reference;
+
+ priv = BRASERO_DATA_SESSION_PRIVATE (owner);
+
+ if (!info) {
+ g_signal_emit (owner,
+ brasero_data_session_signals [LOADED_SIGNAL],
+ 0,
+ priv->loaded,
+ FALSE);
+/* error = g_error_new (BRASERO_BURN_ERROR,
+ BRASERO_BURN_ERROR_GENERAL,
+ _("unknown volume type"));
+*/ return;
+ }
+
+ reference = GPOINTER_TO_INT (data);
+ if (reference > 0)
+ parent = brasero_data_project_reference_get (BRASERO_DATA_PROJECT (owner),
+ reference);
+ else
+ parent = NULL;
- priv = BRASERO_DATA_SESSION_PRIVATE (self);
+ /* add all the files/folders at the root of the session */
+ node = brasero_data_project_add_imported_session_file (BRASERO_DATA_PROJECT (owner),
+ info,
+ parent);
+ if (!node) {
+ /* a problem ? */
+ g_signal_emit (owner,
+ brasero_data_session_signals [LOADED_SIGNAL],
+ 0,
+ priv->loaded,
+ FALSE);
+ return;
+ }
- if (!g_slist_find (priv->media, medium)) {
- g_set_error (error,
- BRASERO_BURN_ERROR,
- BRASERO_BURN_ERROR_GENERAL,
- _("there isn't any available session on the disc"));
- return FALSE;
- }
+ /* Only if we're exploring root directory */
+ if (!parent)
+ priv->nodes = g_slist_prepend (priv->nodes, node);
- if (priv->loaded == medium)
- return TRUE;
+ g_signal_emit (owner,
+ brasero_data_session_signals [LOADED_SIGNAL],
+ 0,
+ priv->loaded,
+ TRUE);
+}
- /* Remove the old imported session if any */
- if (priv->nodes)
- brasero_data_session_remove_last (self);
+static gboolean
+brasero_data_session_load_directory_contents_real (BraseroDataSession *self,
+ BraseroFileNode *node,
+ GError **error)
+{
+ BraseroDataSessionPrivate *priv;
+ gint64 session_block;
+ const gchar *device;
+ gint reference = -1;
- if (priv->loaded) {
- g_object_unref (priv->loaded);
- priv->loaded = NULL;
- }
-
- /* get the address for the last track and retrieve the file list */
- brasero_medium_get_last_data_track_address (medium,
+ if (node && !node->is_fake)
+ return TRUE;
+
+ priv = BRASERO_DATA_SESSION_PRIVATE (self);
+ device = brasero_drive_get_device (brasero_medium_get_drive (priv->loaded));
+ brasero_medium_get_last_data_track_address (priv->loaded,
NULL,
- &block);
- if (block == -1) {
- g_set_error (error,
- BRASERO_BURN_ERROR,
- BRASERO_BURN_ERROR_GENERAL,
- _("there isn't any available session on the disc"));
- return FALSE;
- }
-
- drive = brasero_medium_get_drive (medium);
- device = brasero_drive_get_device (drive);
- handle = brasero_device_handle_open (device, &err);
- if (!handle) {
- g_set_error (error,
- BRASERO_BURN_ERROR,
- BRASERO_BURN_ERROR_GENERAL,
- brasero_scsi_strerror (err));
- return FALSE;
- }
-
- vol = brasero_volume_source_open_device_handle (handle, error);
- volume = brasero_volume_get_files (vol,
- block,
- NULL,
- NULL,
- NULL,
- error);
- brasero_device_handle_close (handle);
- brasero_volume_source_close (vol);
- if (*error) {
- if (volume)
- brasero_volume_file_free (volume);
- return FALSE;
- }
-
- if (!volume) {
- g_set_error (error,
- BRASERO_BURN_ERROR,
- BRASERO_BURN_ERROR_GENERAL,
- _("unknown volume type"));
- return FALSE;
- }
+ &session_block);
+ if (!priv->io)
+ priv->io = brasero_io_get_default ();
+
+ if (!priv->load_dir)
+ priv->load_dir = brasero_io_register (G_OBJECT (self),
+ brasero_data_session_load_dir_result,
+ brasero_data_session_load_dir_destroy,
+ NULL);
+
+ /* If there aren't any node then that's root */
+ if (node) {
+ reference = brasero_data_project_reference_new (BRASERO_DATA_PROJECT (self), node);
+ node->is_exploring = TRUE;
+ }
+
+ brasero_io_load_image_directory (priv->io,
+ device,
+ session_block,
+ BRASERO_FILE_NODE_IMPORTED_ADDRESS (node),
+ priv->load_dir,
+ BRASERO_IO_INFO_URGENT,
+ GINT_TO_POINTER (reference));
- /* add all the files/folders at the root of the session */
- for (iter = volume->specific.dir.children; iter; iter = iter->next) {
- BraseroVolFile *file;
- BraseroFileNode *node;
+ if (node)
+ node->is_fake = FALSE;
- file = iter->data;
- node = brasero_data_project_add_imported_session_file (BRASERO_DATA_PROJECT (self),
- file,
- NULL);
- if (!node)
- continue;
-
- if (!node->is_file)
- brasero_data_session_add_children_files (self,
- node,
- file->specific.dir.children);
+ return TRUE;
+}
- priv->nodes = g_slist_prepend (priv->nodes, node);
- }
+gboolean
+brasero_data_session_load_directory_contents (BraseroDataSession *self,
+ BraseroFileNode *node,
+ GError **error)
+{
+ return brasero_data_session_load_directory_contents_real (self, node, error);
+}
+
+gboolean
+brasero_data_session_add_last (BraseroDataSession *self,
+ BraseroMedium *medium,
+ GError **error)
+{
+ BraseroDataSessionPrivate *priv;
+ priv = BRASERO_DATA_SESSION_PRIVATE (self);
priv->loaded = medium;
g_object_ref (medium);
- brasero_volume_file_free (volume);
-
- g_signal_emit (self,
- brasero_data_session_signals [LOADED_SIGNAL],
- 0,
- priv->loaded,
- TRUE);
-
- /* check the size of the selection to see if it fits the current
- * selected disc and listen for signal "size-changed" */
- priv->is_oversized = FALSE;
- priv->is_overburn = FALSE;
- brasero_data_session_check_size (self);
-
priv->size_changed_sig = g_signal_connect (self,
"size-changed",
G_CALLBACK (brasero_data_session_size_changed),
NULL);
- return TRUE;
+
+ return brasero_data_session_load_directory_contents_real (self, NULL, error);
}
gboolean
@@ -487,6 +492,32 @@
}
static void
+brasero_data_session_stop_io (BraseroDataSession *self)
+{
+ BraseroDataSessionPrivate *priv;
+
+ priv = BRASERO_DATA_SESSION_PRIVATE (self);
+
+ if (priv->io) {
+ brasero_io_cancel_by_base (priv->io, priv->load_dir);
+
+ g_free (priv->load_dir);
+ priv->load_dir = NULL;
+ }
+}
+
+static void
+brasero_data_session_reset (BraseroDataProject *project,
+ guint num_nodes)
+{
+ brasero_data_session_stop_io (BRASERO_DATA_SESSION (project));
+
+ /* chain up this function except if we invalidated the node */
+ if (BRASERO_DATA_PROJECT_CLASS (brasero_data_session_parent_class)->reset)
+ BRASERO_DATA_PROJECT_CLASS (brasero_data_session_parent_class)->reset (project, num_nodes);
+}
+
+static void
brasero_data_session_finalize (GObject *object)
{
BraseroDataSessionPrivate *priv;
@@ -511,6 +542,8 @@
/* NOTE no need to clean up size_changed_sig since it's connected to
* ourselves. It disappears with use. */
+ brasero_data_session_stop_io (BRASERO_DATA_SESSION (object));
+
/* don't care about the nodes since they will be automatically
* destroyed */
@@ -522,11 +555,14 @@
brasero_data_session_class_init (BraseroDataSessionClass *klass)
{
GObjectClass* object_class = G_OBJECT_CLASS (klass);
+ BraseroDataProjectClass *project_class = BRASERO_DATA_PROJECT_CLASS (klass);
g_type_class_add_private (klass, sizeof (BraseroDataSessionPrivate));
object_class->finalize = brasero_data_session_finalize;
+ project_class->reset = brasero_data_session_reset;
+
brasero_data_session_signals [AVAILABLE_SIGNAL] =
g_signal_new ("session_available",
G_TYPE_FROM_CLASS (klass),
Modified: trunk/src/brasero-data-session.h
==============================================================================
--- trunk/src/brasero-data-session.h (original)
+++ trunk/src/brasero-data-session.h Sun Sep 28 18:48:39 2008
@@ -62,6 +62,11 @@
BraseroMedium *
brasero_data_session_get_loaded_medium (BraseroDataSession *session);
+gboolean
+brasero_data_session_load_directory_contents (BraseroDataSession *session,
+ BraseroFileNode *node,
+ GError **error);
+
GSList *
brasero_data_session_get_available_media (BraseroDataSession *session);
Modified: trunk/src/brasero-data-tree-model.c
==============================================================================
--- trunk/src/brasero-data-tree-model.c (original)
+++ trunk/src/brasero-data-tree-model.c Sun Sep 28 18:48:39 2008
@@ -344,8 +344,14 @@
node->is_visible ++;
- if (node->is_imported)
+ if (node->is_imported) {
+ if (node->is_fake && !node->is_file) {
+ /* we don't load all nodes when importing a session do it now */
+ brasero_data_session_load_directory_contents (BRASERO_DATA_SESSION (model), node, NULL);
+ }
+
return;
+ }
if (node->is_visible > 1)
return;
Modified: trunk/src/brasero-dest-selection.c
==============================================================================
--- trunk/src/brasero-dest-selection.c (original)
+++ trunk/src/brasero-dest-selection.c Sun Sep 28 18:48:39 2008
@@ -207,6 +207,11 @@
priv->session = NULL;
}
+ if (priv->locked_drive) {
+ brasero_drive_unlock (priv->locked_drive);
+ g_object_unref (priv->locked_drive);
+ }
+
G_OBJECT_CLASS (brasero_dest_selection_parent_class)->finalize (object);
}
Modified: trunk/src/brasero-file-node.c
==============================================================================
--- trunk/src/brasero-file-node.c (original)
+++ trunk/src/brasero-file-node.c Sun Sep 28 18:48:39 2008
@@ -34,6 +34,7 @@
#include "brasero-file-node.h"
#include "brasero-utils.h"
+#include "brasero-io.h"
BraseroFileNode *
brasero_file_node_root_new (void)
@@ -838,7 +839,7 @@
}
BraseroFileNode *
-brasero_file_node_new_imported_session_file (BraseroVolFile *file,
+brasero_file_node_new_imported_session_file (GFileInfo *info,
BraseroFileNode *parent,
GCompareFunc sort_func)
{
@@ -846,12 +847,16 @@
/* Create the node information */
node = g_new0 (BraseroFileNode, 1);
- node->union1.name = g_strdup (BRASERO_VOLUME_FILE_NAME (file));
- node->is_file = (file->isdir == FALSE);
+ node->union1.name = g_strdup (g_file_info_get_name (info));
+ node->is_file = (g_file_info_get_file_type (info) != G_FILE_TYPE_DIRECTORY);
node->is_imported = TRUE;
- if (node->is_file)
- node->union3.sectors = BRASERO_SIZE_TO_SECTORS (BRASERO_VOLUME_FILE_SIZE (file), 2048);
+ if (!node->is_file) {
+ node->is_fake = TRUE;
+ node->union3.imported_address = g_file_info_get_attribute_int64 (info, BRASERO_IO_DIR_CONTENTS_ADDR);
+ }
+ else
+ node->union3.sectors = BRASERO_SIZE_TO_SECTORS (g_file_info_get_size (info), 2048);
/* Add it (we must add a graft) */
brasero_file_node_add (parent, node, sort_func);
Modified: trunk/src/brasero-file-node.h
==============================================================================
--- trunk/src/brasero-file-node.h (original)
+++ trunk/src/brasero-file-node.h Sun Sep 28 18:48:39 2008
@@ -108,6 +108,9 @@
* discs. */
union {
guint sectors;
+
+ /* stores the address of the children records in image */
+ guint imported_address;
BraseroFileTreeStats *stats;
} union3;
@@ -169,6 +172,9 @@
#define BRASERO_FILE_NODE_STATS(MACRO_root) \
((MACRO_root)->is_root?(MACRO_root)->union3.stats:NULL)
+#define BRASERO_FILE_NODE_IMPORTED_ADDRESS(MACRO_node) \
+ ((MACRO_node) && (MACRO_node)->is_imported && (MACRO_node)->is_fake?(MACRO_node)->union3.imported_address:-1)
+
#define BRASERO_FILE_2G_LIMIT 1048576
BraseroFileNode *
@@ -229,7 +235,7 @@
BraseroFileNode *parent,
GCompareFunc sort_func);
BraseroFileNode *
-brasero_file_node_new_imported_session_file (BraseroVolFile *file,
+brasero_file_node_new_imported_session_file (GFileInfo *info,
BraseroFileNode *parent,
GCompareFunc sort_func);
Modified: trunk/src/brasero-io.c
==============================================================================
--- trunk/src/brasero-io.c (original)
+++ trunk/src/brasero-io.c Sun Sep 28 18:48:39 2008
@@ -40,8 +40,9 @@
#include "burn-basics.h"
#include "burn-debug.h"
-#include "brasero-utils.h"
+#include "burn-volume.h"
+#include "brasero-utils.h"
#include "brasero-io.h"
#include "brasero-metadata.h"
#include "brasero-async-task-manager.h"
@@ -1857,6 +1858,129 @@
}
/**
+ * to evaluate the contents of a medium or image async
+ */
+struct _BraseroIOImageContentsData {
+ BraseroIOJob job;
+ gchar *dev_image;
+
+ gint64 session_block;
+ gint64 block;
+};
+typedef struct _BraseroIOImageContentsData BraseroIOImageContentsData;
+
+static void
+brasero_io_image_directory_contents_destroy (BraseroAsyncTaskManager *manager,
+ gboolean cancelled,
+ gpointer callback_data)
+{
+ BraseroIOImageContentsData *data = callback_data;
+
+ g_free (data->dev_image);
+ brasero_io_job_free (BRASERO_IO (manager), cancelled, BRASERO_IO_JOB (data));
+}
+
+static BraseroAsyncTaskResult
+brasero_io_image_directory_contents_thread (BraseroAsyncTaskManager *manager,
+ GCancellable *cancel,
+ gpointer callback_data)
+{
+ BraseroIOImageContentsData *data = callback_data;
+ BraseroDeviceHandle *handle;
+ GList *children, *iter;
+ GError *error = NULL;
+ BraseroVolSrc *vol;
+
+ handle = brasero_device_handle_open (data->job.uri, NULL);
+ vol = brasero_volume_source_open_device_handle (handle, &error);
+ if (!vol) {
+ brasero_device_handle_close (handle);
+ brasero_io_return_result (BRASERO_IO (manager),
+ data->job.base,
+ data->job.uri,
+ NULL,
+ error,
+ data->job.callback_data);
+ return BRASERO_ASYNC_TASK_FINISHED;
+ }
+
+ children = brasero_volume_load_directory_contents (vol,
+ data->session_block,
+ data->block,
+ &error);
+ brasero_volume_source_close (vol);
+ brasero_device_handle_close (handle);
+
+ for (iter = children; iter; iter = iter->next) {
+ BraseroVolFile *file;
+ GFileInfo *info;
+
+ file = iter->data;
+
+ info = g_file_info_new ();
+ g_file_info_set_file_type (info, file->isdir? G_FILE_TYPE_DIRECTORY:G_FILE_TYPE_REGULAR);
+ g_file_info_set_name (info, BRASERO_VOLUME_FILE_NAME (file));
+
+ if (file->isdir)
+ g_file_info_set_attribute_int64 (info,
+ BRASERO_IO_DIR_CONTENTS_ADDR,
+ file->specific.dir.address);
+ else
+ g_file_info_set_size (info, BRASERO_VOLUME_FILE_SIZE (file));
+
+ brasero_io_return_result (BRASERO_IO (manager),
+ data->job.base,
+ data->job.uri,
+ info,
+ NULL,
+ data->job.callback_data);
+ }
+
+ g_list_foreach (children, (GFunc) brasero_volume_file_free, NULL);
+ g_list_free (children);
+
+ return BRASERO_ASYNC_TASK_FINISHED;
+}
+
+static const BraseroAsyncTaskType image_contents_type = {
+ brasero_io_image_directory_contents_thread,
+ brasero_io_image_directory_contents_destroy
+};
+
+void
+brasero_io_load_image_directory (BraseroIO *self,
+ const gchar *dev_image,
+ gint64 session_block,
+ gint64 block,
+ const BraseroIOJobBase *base,
+ BraseroIOFlags options,
+ gpointer user_data)
+{
+ BraseroIOImageContentsData *data;
+ BraseroIOResultCallbackData *callback_data = NULL;
+
+ if (user_data) {
+ callback_data = g_new0 (BraseroIOResultCallbackData, 1);
+ callback_data->callback_data = user_data;
+ }
+
+ data = g_new0 (BraseroIOImageContentsData, 1);
+ data->block = block;
+ data->session_block = session_block;
+
+ brasero_io_set_job (BRASERO_IO_JOB (data),
+ base,
+ dev_image,
+ options,
+ callback_data);
+
+ brasero_io_push_job (self,
+ BRASERO_IO_JOB (data),
+ &image_contents_type);
+
+}
+
+/**
* That's for file transfer
*/
Modified: trunk/src/brasero-io.h
==============================================================================
--- trunk/src/brasero-io.h (original)
+++ trunk/src/brasero-io.h Sun Sep 28 18:48:39 2008
@@ -95,6 +95,8 @@
#define BRASERO_IO_HAS_VIDEO "metadata::has_video"
#define BRASERO_IO_IS_SEEKABLE "metadata::is_seekable"
+#define BRASERO_IO_DIR_CONTENTS_ADDR "image::directory::address"
+
typedef struct _BraseroIOJobProgress BraseroIOJobProgress;
typedef void (*BraseroIOResultCallback) (GObject *object,
@@ -147,6 +149,15 @@
gpointer callback_data);
void
+brasero_io_load_image_directory (BraseroIO *self,
+ const gchar *dev_image,
+ gint64 session_block,
+ gint64 block,
+ const BraseroIOJobBase *base,
+ BraseroIOFlags options,
+ gpointer user_data);
+
+void
brasero_io_load_directory (BraseroIO *self,
const gchar *uri,
const BraseroIOJobBase *base,
Modified: trunk/src/brasero-tool-dialog.c
==============================================================================
--- trunk/src/brasero-tool-dialog.c (original)
+++ trunk/src/brasero-tool-dialog.c Sun Sep 28 18:48:39 2008
@@ -487,7 +487,6 @@
gchar *title_str;
obj->priv = g_new0 (BraseroToolDialogPrivate, 1);
- gtk_window_set_default_size (GTK_WINDOW (obj), 500, 300);
gtk_dialog_set_has_separator (GTK_DIALOG (obj), FALSE);
/* upper part */
@@ -570,4 +569,6 @@
"changed",
G_CALLBACK (brasero_tool_dialog_drive_changed_cb),
obj);
+
+ gtk_window_resize (GTK_WINDOW (obj), 10, 10);
}
Modified: trunk/src/burn-iso9660.c
==============================================================================
--- trunk/src/burn-iso9660.c (original)
+++ trunk/src/burn-iso9660.c Sun Sep 28 18:48:39 2008
@@ -126,8 +126,11 @@
#define ISO9660_BYTES_TO_BLOCKS(size) BRASERO_SIZE_TO_SECTORS ((size), ISO9660_BLOCK_SIZE)
-static BraseroVolFile *
-brasero_iso9660_read_directory_records (BraseroIsoCtx *ctx, gint address);
+static GList *
+brasero_iso9660_load_directory_records (BraseroIsoCtx *ctx,
+ BraseroVolFile *parent,
+ BraseroIsoDirRec *record,
+ gboolean recursive);
static BraseroVolFile *
brasero_iso9660_lookup_directory_records (BraseroIsoCtx *ctx,
@@ -394,6 +397,27 @@
return BRASERO_ISO_ERROR;
}
+static BraseroIsoResult
+brasero_iso9660_get_first_directory_record (BraseroIsoCtx *ctx,
+ BraseroIsoDirRec **record,
+ gint address)
+{
+ BraseroIsoResult result;
+
+ BRASERO_BURN_LOG ("Reading directory record");
+
+ result = brasero_iso9660_seek (ctx, address);
+ if (result != BRASERO_ISO_OK)
+ return BRASERO_ISO_ERROR;
+
+ /* load "." */
+ result = brasero_iso9660_next_record (ctx, record);
+ if (result != BRASERO_ISO_OK)
+ return BRASERO_ISO_ERROR;
+
+ return BRASERO_ISO_OK;
+}
+
static BraseroVolFile *
brasero_iso9660_read_file_record (BraseroIsoCtx *ctx,
BraseroIsoDirRec *record,
@@ -441,7 +465,8 @@
static BraseroVolFile *
brasero_iso9660_read_directory_record (BraseroIsoCtx *ctx,
- BraseroIsoDirRec *record)
+ BraseroIsoDirRec *record,
+ gboolean recursive)
{
gchar *susp;
gint address;
@@ -456,6 +481,13 @@
return NULL;
}
+ /* create the directory and set information */
+ directory = g_new0 (BraseroVolFile, 1);
+ directory->isdir = TRUE;
+ directory->isdir_loaded = FALSE;
+ directory->name = g_new0 (gchar, record->id_size + 1);
+ memcpy (directory->name, record->id, record->id_size);
+
if (ctx->has_susp && ctx->has_RR) {
/* See if we've got a susp area. Do it now to see if it has a CL
* entry. The rest will be checked later after reading contents.
@@ -463,6 +495,7 @@
susp = brasero_iso9660_get_susp (ctx, record, &susp_len);
if (!brasero_iso9660_read_susp (ctx, &susp_ctx, susp, susp_len)) {
BRASERO_BURN_LOG ("Could not read susp area");
+ brasero_volume_file_free (directory);
return NULL;
}
@@ -473,90 +506,70 @@
}
else
address = brasero_iso9660_get_733_val (record->address);
- }
- else
- address = brasero_iso9660_get_733_val (record->address);
- directory = brasero_iso9660_read_directory_records (ctx, address);
- if (!directory) {
- if (ctx->has_susp && ctx->has_RR)
- brasero_susp_ctx_clean (&susp_ctx);
+ BRASERO_BURN_LOG ("New directory %s with susp area", directory->name);
- return NULL;
- }
+ /* if this directory has a "RE" susp entry then drop it; it's
+ * not at the right place in the Rock Ridge file hierarchy. It
+ * will probably be skipped */
+ if (susp_ctx.has_RE) {
+ BRASERO_BURN_LOG ("Rock Ridge relocated directory. Skipping entry.");
+ directory->relocated = TRUE;
+ }
- directory->name = g_new0 (gchar, record->id_size + 1);
- memcpy (directory->name, record->id, record->id_size);
+ if (susp_ctx.rr_name) {
+ BRASERO_BURN_LOG ("Got a susp (RR) %s", susp_ctx.rr_name);
+ directory->rr_name = susp_ctx.rr_name;
+ susp_ctx.rr_name = NULL;
+ }
- if (!ctx->has_susp || !ctx->has_RR) {
- BRASERO_BURN_LOG ("New directory %s", directory->name);
- return directory;
+ brasero_susp_ctx_clean (&susp_ctx);
}
+ else
+ address = brasero_iso9660_get_733_val (record->address);
- BRASERO_BURN_LOG ("New directory %s with susp area", directory->name);
+ /* load contents if recursive */
+ if (recursive) {
+ GList *children;
+
+ brasero_iso9660_get_first_directory_record (ctx,
+ &record,
+ address);
+ children = brasero_iso9660_load_directory_records (ctx,
+ directory,
+ record,
+ TRUE);
+ if (!children && ctx->error) {
+ brasero_volume_file_free (directory);
+ if (ctx->has_susp && ctx->has_RR)
+ brasero_susp_ctx_clean (&susp_ctx);
- /* if this directory has a "RE" susp entry then drop it; it's not at the
- * right place in the Rock Ridge file hierarchy. */
- if (susp_ctx.has_RE) {
- BRASERO_BURN_LOG ("Rock Ridge relocated directory. Skipping entry.");
- directory->relocated = TRUE;
- }
+ return NULL;
+ }
- if (susp_ctx.rr_name) {
- BRASERO_BURN_LOG ("Got a susp (RR) %s", susp_ctx.rr_name);
- directory->rr_name = susp_ctx.rr_name;
- susp_ctx.rr_name = NULL;
+ directory->isdir_loaded = TRUE;
+ directory->specific.dir.children = children;
}
+ else /* store the address of contents for later use */
+ directory->specific.dir.address = address;
- brasero_susp_ctx_clean (&susp_ctx);
+ BRASERO_BURN_LOG ("New directory %s", directory->name);
return directory;
}
-static BraseroVolFile *
-brasero_iso9660_read_directory_records (BraseroIsoCtx *ctx, gint address)
+static GList *
+brasero_iso9660_load_directory_records (BraseroIsoCtx *ctx,
+ BraseroVolFile *parent,
+ BraseroIsoDirRec *record,
+ gboolean recursive)
{
GSList *iter;
gint max_block;
gint max_record_size;
BraseroVolFile *entry;
+ GList *children = NULL;
BraseroIsoResult result;
- BraseroIsoDirRec *record;
GSList *directories = NULL;
- BraseroVolFile *parent = NULL;
-
- BRASERO_BURN_LOG ("Reading directory record");
-
- result = brasero_iso9660_seek (ctx, address);
- if (result != BRASERO_ISO_OK)
- return NULL;
-
- /* "." */
- result = brasero_iso9660_next_record (ctx, &record);
- if (result != BRASERO_ISO_OK)
- return NULL;
-
- /* look for "SP" SUSP if it's root directory */
- if (ctx->is_root) {
- BraseroSuspCtx susp_ctx;
- guint susp_len = 0;
- gchar *susp;
-
- susp = brasero_iso9660_get_susp (ctx, record, &susp_len);
- brasero_iso9660_read_susp (ctx, &susp_ctx, susp, susp_len);
-
- ctx->has_susp = susp_ctx.has_SP;
- ctx->has_RR = susp_ctx.has_RockRidge;
- ctx->susp_skip = susp_ctx.skip;
- ctx->is_root = FALSE;
-
- if (ctx->has_susp)
- BRASERO_BURN_LOG ("File system supports system use sharing protocol");
-
- if (ctx->has_RR)
- BRASERO_BURN_LOG ("File system has Rock Ridge extension");
-
- brasero_susp_ctx_clean (&susp_ctx);
- }
max_record_size = brasero_iso9660_get_733_val (record->file_size);
max_block = ISO9660_BYTES_TO_BLOCKS (max_record_size);
@@ -568,8 +581,6 @@
return NULL;
BRASERO_BURN_LOG ("Skipped '.' and '..'");
- parent = g_new0 (BraseroVolFile, 1);
- parent->isdir = 1;
while (1) {
BraseroIsoResult result;
@@ -647,10 +658,10 @@
/* check that we don't have another file record for the
* same file (usually files > 4G). It always follows
* its sibling */
- if (parent->specific.dir.children) {
+ if (children) {
BraseroVolFile *last;
- last = parent->specific.dir.children->data;
+ last = children->data;
if (!last->isdir && !strcmp (BRASERO_VOLUME_FILE_NAME (last), BRASERO_VOLUME_FILE_NAME (entry))) {
/* add size and addresses */
ctx->data_blocks += ISO9660_BYTES_TO_BLOCKS (entry->specific.file.size_bytes);
@@ -660,7 +671,7 @@
}
}
- parent->specific.dir.children = g_list_prepend (parent->specific.dir.children, entry);
+ children = g_list_prepend (children, entry);
ctx->data_blocks += ISO9660_BYTES_TO_BLOCKS (entry->specific.file.size_bytes);
}
@@ -669,7 +680,7 @@
for (iter = directories; iter; iter = iter->next) {
record = iter->data;
- entry = brasero_iso9660_read_directory_record (ctx, record);
+ entry = brasero_iso9660_read_directory_record (ctx, record, recursive);
if (!entry)
goto error;
@@ -679,22 +690,50 @@
}
entry->parent = parent;
- parent->specific.dir.children = g_list_prepend (parent->specific.dir.children, entry);
+ children = g_list_prepend (children, entry);
}
g_slist_foreach (directories, (GFunc) g_free, NULL);
g_slist_free (directories);
- return parent;
+ return children;
error:
+ g_list_foreach (children, (GFunc) brasero_volume_file_free, NULL);
+ g_list_free (children);
+
g_slist_foreach (directories, (GFunc) g_free, NULL);
g_slist_free (directories);
- brasero_volume_file_free (parent);
return NULL;
}
+static gboolean
+brasero_iso9660_check_SUSP_RR_use (BraseroIsoCtx *ctx,
+ BraseroIsoDirRec *record)
+{
+ BraseroSuspCtx susp_ctx;
+ guint susp_len = 0;
+ gchar *susp;
+
+ susp = brasero_iso9660_get_susp (ctx, record, &susp_len);
+ brasero_iso9660_read_susp (ctx, &susp_ctx, susp, susp_len);
+
+ ctx->has_susp = susp_ctx.has_SP;
+ ctx->has_RR = susp_ctx.has_RockRidge;
+ ctx->susp_skip = susp_ctx.skip;
+ ctx->is_root = FALSE;
+
+ if (ctx->has_susp)
+ BRASERO_BURN_LOG ("File system supports system use sharing protocol");
+
+ if (ctx->has_RR)
+ BRASERO_BURN_LOG ("File system has Rock Ridge extension");
+
+ brasero_susp_ctx_clean (&susp_ctx);
+ return TRUE;
+}
+
static void
brasero_iso9660_ctx_init (BraseroIsoCtx *ctx, BraseroVolSrc *vol)
{
@@ -703,6 +742,8 @@
ctx->is_root = TRUE;
ctx->vol = vol;
ctx->offset = 0;
+
+ /* to fully initialize the context we need the root directory record */
}
BraseroVolFile *
@@ -712,20 +753,32 @@
GError **error)
{
BraseroIsoPrimary *primary;
+ BraseroIsoDirRec *record;
BraseroVolFile *volfile;
BraseroIsoDirRec *root;
BraseroIsoCtx ctx;
+ GList *children;
gint address;
primary = (BraseroIsoPrimary *) block;
root = primary->root_rec;
- brasero_iso9660_ctx_init (&ctx, vol);
-
+ /* check settings */
address = brasero_iso9660_get_733_val (root->address);
+ brasero_iso9660_ctx_init (&ctx, vol);
+ brasero_iso9660_get_first_directory_record (&ctx, &record, address);
+ brasero_iso9660_check_SUSP_RR_use (&ctx, record);
- BRASERO_BURN_LOG ("Reading root directory record at %i", address);
- volfile = brasero_iso9660_read_directory_records (&ctx, address);
+ /* create volume file */
+ volfile = g_new0 (BraseroVolFile, 1);
+ volfile->isdir = TRUE;
+ volfile->isdir_loaded = FALSE;
+
+ children = brasero_iso9660_load_directory_records (&ctx,
+ volfile,
+ record,
+ TRUE);
+ volfile->specific.dir.children = children;
if (ctx.spare_record)
g_free (ctx.spare_record);
@@ -733,8 +786,13 @@
if (data_blocks)
*data_blocks = ctx.data_blocks;
- if (error && ctx.error)
- g_propagate_error (error, ctx.error);
+ if (!children && ctx.error) {
+ if (error)
+ g_propagate_error (error, ctx.error);
+
+ brasero_volume_file_free (volfile);
+ volfile = NULL;
+ }
return volfile;
}
@@ -835,8 +893,8 @@
static BraseroVolFile *
brasero_iso9660_lookup_directory_records (BraseroIsoCtx *ctx,
- const gchar *path,
- gint address)
+ const gchar *path,
+ gint address)
{
guint len;
gchar *end;
@@ -970,13 +1028,15 @@
primary = (BraseroIsoPrimary *) block;
root = primary->root_rec;
- address = brasero_iso9660_get_733_val (root->address);
+ address = brasero_iso9660_get_733_val (root->address);
brasero_iso9660_ctx_init (&ctx, vol);
/* now that we have root block address, skip first "/" and go. */
path ++;
- entry = brasero_iso9660_lookup_directory_records (&ctx, path, address);
+ entry = brasero_iso9660_lookup_directory_records (&ctx,
+ path,
+ address);
/* clean context */
if (ctx.spare_record)
@@ -987,3 +1047,42 @@
return entry;
}
+
+GList *
+brasero_iso9660_get_directory_contents (BraseroVolSrc *vol,
+ const gchar *vol_desc,
+ gint address,
+ GError **error)
+{
+ BraseroIsoDirRec *record = NULL;
+ BraseroIsoPrimary *primary;
+ BraseroIsoDirRec *root;
+ BraseroIsoCtx ctx;
+ GList *children;
+
+ /* Check root "." for use of RR and things like that */
+ primary = (BraseroIsoPrimary *) vol_desc;
+ root = primary->root_rec;
+
+ brasero_iso9660_ctx_init (&ctx, vol);
+ brasero_iso9660_get_first_directory_record (&ctx,
+ &record,
+ brasero_iso9660_get_733_val (root->address));
+ brasero_iso9660_check_SUSP_RR_use (&ctx, record);
+
+ /* Seek up to the contents of the directory */
+ if (address > 0)
+ brasero_iso9660_get_first_directory_record (&ctx,
+ &record,
+ address);
+
+ /* load */
+ children = brasero_iso9660_load_directory_records (&ctx,
+ NULL,
+ record,
+ FALSE);
+ if (ctx.error && error)
+ g_propagate_error (error, ctx.error);
+
+ return children;
+}
Modified: trunk/src/burn-iso9660.h
==============================================================================
--- trunk/src/burn-iso9660.h (original)
+++ trunk/src/burn-iso9660.h Sun Sep 28 18:48:39 2008
@@ -40,6 +40,11 @@
#define ISO9660_BLOCK_SIZE 2048
+typedef enum {
+ BRASERO_ISO_FLAG_NONE = 0,
+ BRASERO_ISO_FLAG_RR = 1
+} BraseroIsoFlag;
+
gboolean
brasero_iso9660_is_primary_descriptor (const gchar *buffer,
GError **error);
@@ -60,6 +65,15 @@
gint64 *nb_blocks,
GError **error);
+/**
+ * Address to -1 for root
+ */
+GList *
+brasero_iso9660_get_directory_contents (BraseroVolSrc *vol,
+ const gchar *vol_desc,
+ gint address,
+ GError **error);
+
BraseroVolFile *
brasero_iso9660_get_file (BraseroVolSrc *src,
const gchar *path,
Modified: trunk/src/burn-volume.c
==============================================================================
--- trunk/src/burn-volume.c (original)
+++ trunk/src/burn-volume.c Sun Sep 28 18:48:39 2008
@@ -75,10 +75,12 @@
if (file->isdir) {
GList *iter;
- for (iter = file->specific.dir.children; iter; iter = iter->next)
- brasero_volume_file_free (iter->data);
+ if (file->isdir_loaded) {
+ for (iter = file->specific.dir.children; iter; iter = iter->next)
+ brasero_volume_file_free (iter->data);
- g_list_free (file->specific.dir.children);
+ g_list_free (file->specific.dir.children);
+ }
}
else {
g_slist_foreach (file->specific.file.extents,
@@ -175,7 +177,33 @@
&& !brasero_iso9660_get_size (buffer, nb_blocks, error))
return NULL;
- return brasero_iso9660_get_contents (vol, buffer, data_blocks, error);
+ return brasero_iso9660_get_contents (vol,
+ buffer,
+ data_blocks,
+ error);
+}
+
+GList *
+brasero_volume_load_directory_contents (BraseroVolSrc *vol,
+ gint64 session_block,
+ gint64 block,
+ GError **error)
+{
+ gchar buffer [ISO9660_BLOCK_SIZE];
+
+ if (BRASERO_VOL_SRC_SEEK (vol, session_block, SEEK_SET, error) == -1)
+ return FALSE;
+
+ if (!brasero_volume_get_primary_from_file (vol, buffer, error))
+ return NULL;
+
+ if (!brasero_iso9660_is_primary_descriptor (buffer, error))
+ return NULL;
+
+ return brasero_iso9660_get_directory_contents (vol,
+ buffer,
+ block,
+ error);
}
BraseroVolFile *
Modified: trunk/src/burn-volume.h
==============================================================================
--- trunk/src/burn-volume.h (original)
+++ trunk/src/burn-volume.h Sun Sep 28 18:48:39 2008
@@ -62,13 +62,16 @@
struct {
GList *children;
+ guint address;
} dir;
} specific;
guint isdir:1;
+ guint isdir_loaded:1;
/* mainly used internally */
+ guint has_RR:1;
guint relocated:1;
};
@@ -96,6 +99,12 @@
gint64 volume_start_block,
GError **error);
+GList *
+brasero_volume_load_directory_contents (BraseroVolSrc *vol,
+ gint64 session_block,
+ gint64 block,
+ GError **error);
+
#define BRASERO_VOLUME_FILE_NAME(file) ((file)->rr_name?(file)->rr_name:(file)->name)
#define BRASERO_VOLUME_FILE_SIZE(file) ((file)->isdir?0:(file)->specific.file.size_bytes)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]