Add g_file_copy_async() (#511580) Based on patch from Carlos Garcia Campos

2008-01-24  Alexander Larsson  <alexl@redhat.com>

        * gfile.[ch]:
        * gfile.h:
        * gio.symbols:
	Add g_file_copy_async() (#511580)
	Based on patch from Carlos Garcia Campos


svn path=/trunk/; revision=6363
This commit is contained in:
Alexander Larsson 2008-01-24 11:04:05 +00:00 committed by Alexander Larsson
parent bebb750ac2
commit 270df8d3c8
4 changed files with 360 additions and 95 deletions

View File

@ -1,3 +1,11 @@
2008-01-24 Alexander Larsson <alexl@redhat.com>
* gfile.[ch]:
* gfile.h:
* gio.symbols:
Add g_file_copy_async() (#511580)
Based on patch from Carlos Garcia Campos
2008-01-23 Matthias Clasen <mclasen@redhat.com>
* gioscheduler.c: Some documentation additions.

View File

@ -180,7 +180,18 @@ static void g_file_real_find_enclosing_mount_async (GFile
static GMount * g_file_real_find_enclosing_mount_finish (GFile *file,
GAsyncResult *res,
GError **error);
static void g_file_real_copy_async (GFile *source,
GFile *destination,
GFileCopyFlags flags,
int io_priority,
GCancellable *cancellable,
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GAsyncReadyCallback callback,
gpointer user_data);
static gboolean g_file_real_copy_finish (GFile *file,
GAsyncResult *res,
GError **error);
GType
g_file_get_type (void)
@ -237,6 +248,8 @@ g_file_class_init (gpointer g_class,
iface->find_enclosing_mount_async = g_file_real_find_enclosing_mount_async;
iface->find_enclosing_mount_finish = g_file_real_find_enclosing_mount_finish;
iface->set_attributes_from_info = g_file_real_set_attributes_from_info;
iface->copy_async = g_file_real_copy_async;
iface->copy_finish = g_file_real_copy_finish;
}
static void
@ -2243,6 +2256,87 @@ g_file_copy (GFile *source,
error);
}
/**
* g_file_copy_async:
* @source: input #GFile.
* @destination: destination #GFile
* @flags: set of #GFileCopyFlags
* @cancellable: optional #GCancellable object, %NULL to ignore.
* @progress_callback: function to callback with progress information
* @progress_callback_data: user data to pass to @progress_callback
* @callback: a #GAsyncReadyCallback to call when the request is satisfied
* @user_data: the data to pass to callback function
*
* Copies the file @source to the location specified by @destination asynchronously.
* For details of the behaviour, see g_file_copy().
*
* If @progress_callback is not %NULL, then that function that will be called
* just like in g_file_copy(), however the callback will run in the main loop,
* not in the thread that is doing the I/O operation.
*
* When the operation is finished, @callback will be called. You can then call
* g_file_copy_finish() to get the result of the operation.
**/
void
g_file_copy_async (GFile *source,
GFile *destination,
GFileCopyFlags flags,
int io_priority,
GCancellable *cancellable,
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GAsyncReadyCallback callback,
gpointer user_data)
{
GFileIface *iface;
g_return_if_fail (G_IS_FILE (source));
g_return_if_fail (G_IS_FILE (destination));
iface = G_FILE_GET_IFACE (source);
(* iface->copy_async) (source,
destination,
flags,
io_priority,
cancellable,
progress_callback,
progress_callback_data,
callback,
user_data);
}
/**
* g_file_copy_finish:
* @file: input #GFile.
* @res: a #GAsyncResult.
* @error: a #GError, or %NULL
*
* Finishes copying the file started with
* g_file_copy_async().
*
* Returns: a %TRUE on success, %FALSE on error.
**/
gboolean
g_file_copy_finish (GFile *file,
GAsyncResult *res,
GError **error)
{
GFileIface *iface;
g_return_val_if_fail (G_IS_FILE (file), FALSE);
g_return_val_if_fail (G_IS_ASYNC_RESULT (res), FALSE);
if (G_IS_SIMPLE_ASYNC_RESULT (res))
{
GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
if (g_simple_async_result_propagate_error (simple, error))
return FALSE;
}
iface = G_FILE_GET_IFACE (file);
return (* iface->copy_finish) (file, res, error);
}
/**
* g_file_move:
@ -4133,6 +4227,145 @@ g_file_real_find_enclosing_mount_finish (GFile *file,
}
typedef struct {
GFile *source;
GFile *destination;
GFileCopyFlags flags;
GFileProgressCallback progress_cb;
gpointer progress_cb_data;
GIOSchedulerJob *job;
} CopyAsyncData;
static void
copy_async_data_free (CopyAsyncData *data)
{
g_object_unref (data->source);
g_object_unref (data->destination);
g_free (data);
}
typedef struct {
CopyAsyncData *data;
goffset current_num_bytes;
goffset total_num_bytes;
} ProgressData;
static gboolean
copy_async_progress_in_main (gpointer user_data)
{
ProgressData *progress = user_data;
CopyAsyncData *data = progress->data;
data->progress_cb (progress->current_num_bytes,
progress->total_num_bytes,
data->progress_cb_data);
return FALSE;
}
static gboolean
mainloop_barrier (gpointer user_data)
{
/* Does nothing, but ensures all queued idles before
this are run */
return FALSE;
}
static void
copy_async_progress_callback (goffset current_num_bytes,
goffset total_num_bytes,
gpointer user_data)
{
CopyAsyncData *data = user_data;
ProgressData *progress;
progress = g_new (ProgressData, 1);
progress->data = data;
progress->current_num_bytes = current_num_bytes;
progress->total_num_bytes = total_num_bytes;
g_io_scheduler_job_send_to_mainloop_async (data->job,
copy_async_progress_in_main,
progress,
g_free);
}
static void
copy_async_thread (GIOSchedulerJob *job,
GCancellable *cancellable,
gpointer user_data)
{
GSimpleAsyncResult *res;
CopyAsyncData *data;
gboolean result;
GError *error;
res = user_data;
data = g_simple_async_result_get_op_res_gpointer (res);
error = NULL;
data->job = job;
result = g_file_copy (data->source,
data->destination,
data->flags,
cancellable,
(data->progress_cb != NULL) ? copy_async_progress_callback : NULL,
data,
&error);
/* Ensure all progress callbacks are done running in main thread */
if (data->progress_cb != NULL)
g_io_scheduler_job_send_to_mainloop (job,
mainloop_barrier,
NULL, NULL);
if (!result)
{
g_simple_async_result_set_from_error (res, error);
g_error_free (error);
}
g_simple_async_result_complete_in_idle (res);
}
static void
g_file_real_copy_async (GFile *source,
GFile *destination,
GFileCopyFlags flags,
int io_priority,
GCancellable *cancellable,
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GAsyncReadyCallback callback,
gpointer user_data)
{
GSimpleAsyncResult *res;
CopyAsyncData *data;
data = g_new0 (CopyAsyncData, 1);
data->source = g_object_ref (source);
data->destination = g_object_ref (destination);
data->flags = flags;
data->progress_cb = progress_callback;
data->progress_cb_data = progress_callback_data;
res = g_simple_async_result_new (G_OBJECT (source), callback, user_data, g_file_real_copy_async);
g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)copy_async_data_free);
g_io_scheduler_push_job (copy_async_thread, res, g_object_unref, io_priority, cancellable);
}
static gboolean
g_file_real_copy_finish (GFile *file,
GAsyncResult *res,
GError **error)
{
/* Error handled in g_file_copy_finish() */
return TRUE;
}
/********************************************
* Default VFS operations *
********************************************/

View File

@ -228,8 +228,8 @@ typedef gboolean (* GFileReadMoreCallback) (const char *file_contents,
* @_make_symbolic_link_async: Asynchronously makes a symbolic link
* @_make_symbolic_link_finish: Finishes making a symbolic link asynchronously.
* @copy: Copies a file.
* @_copy_async: Asynchronously copies a file.
* @_copy_finish: Finishes an asynchronous copy operation.
* @copy_async: Asynchronously copies a file.
* @copy_finish: Finishes an asynchronous copy operation.
* @move: Moves a file.
* @_move_async: Asynchronously moves a file.
* @_move_finish: Finishes an asynchronous move operation.
@ -466,8 +466,18 @@ struct _GFileIface
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GError **error);
void (*_copy_async) (void);
void (*_copy_finish) (void);
void (*copy_async) (GFile *source,
GFile *destination,
GFileCopyFlags flags,
int io_priority,
GCancellable *cancellable,
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean (*copy_finish) (GFile *file,
GAsyncResult *res,
GError **error);
gboolean (*move) (GFile *source,
GFile *destination,
@ -685,6 +695,18 @@ gboolean g_file_copy (GFile
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GError **error);
void g_file_copy_async (GFile *source,
GFile *destination,
GFileCopyFlags flags,
int io_priority,
GCancellable *cancellable,
GFileProgressCallback progress_callback,
gpointer progress_callback_data,
GAsyncReadyCallback callback,
gpointer user_data);
gboolean g_file_copy_finish (GFile *file,
GAsyncResult *res,
GError **error);
gboolean g_file_move (GFile *source,
GFile *destination,
GFileCopyFlags flags,

View File

@ -260,6 +260,8 @@ g_file_set_display_name_finish
g_file_delete
g_file_trash
g_file_copy
g_file_copy_async
g_file_copy_finish
g_file_move
g_file_make_directory
g_file_make_symbolic_link