From 0026537f3711dc843075702345f748a21a45345e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Thu, 17 Jan 2008 10:57:48 +0000 Subject: [PATCH] Allow calls to implementation of copy and write even if the type of the 2008-01-17 Alexander Larsson * gfile.c: (g_file_copy): (g_file_move): Allow calls to implementation of copy and write even if the type of the file implementations is different. This can be used to implement native upload and download calls in a vfs. * glocalfile.c: (g_local_file_move): Protect against the case where move is called with one file not being local. Make sure we call the progress callback once in the native move operation so that the caller knows how many bytes were copied. svn path=/trunk/; revision=6324 --- gio/ChangeLog | 19 +++++++++++++++++ gio/gfile.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++------- gio/glocalfile.c | 23 +++++++++++++++++--- 3 files changed, 95 insertions(+), 11 deletions(-) diff --git a/gio/ChangeLog b/gio/ChangeLog index c884a23..605750e 100644 --- a/gio/ChangeLog +++ b/gio/ChangeLog @@ -1,3 +1,22 @@ +2008-01-17 Alexander Larsson + + * gfile.c: + (g_file_copy): + (g_file_move): + Allow calls to implementation of copy and write + even if the type of the file implementations is + different. This can be used to implement native + upload and download calls in a vfs. + + * glocalfile.c: + (g_local_file_move): + Protect against the case where move is called + with one file not being local. + + Make sure we call the progress callback once + in the native move operation so that the caller + knows how many bytes were copied. + 2008-01-16 Murray Cumming * gappinfo.c: diff --git a/gio/gfile.c b/gio/gfile.c index 3039159..12b148c 100644 --- a/gio/gfile.c +++ b/gio/gfile.c @@ -2115,14 +2115,38 @@ g_file_copy (GFile *source, if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - if (G_OBJECT_TYPE (source) == G_OBJECT_TYPE (destination)) + iface = G_FILE_GET_IFACE (destination); + if (iface->copy) { - iface = G_FILE_GET_IFACE (source); + my_error = NULL; + res = (* iface->copy) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); + + if (res) + return TRUE; + + if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED) + { + g_propagate_error (error, my_error); + return FALSE; + } + } + /* If the types are different, and the destination method failed + also try the source method */ + if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination)) + { + iface = G_FILE_GET_IFACE (source); + if (iface->copy) { my_error = NULL; - res = (* iface->copy) (source, destination, flags, cancellable, progress_callback, progress_callback_data, &my_error); + res = (* iface->copy) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); if (res) return TRUE; @@ -2134,7 +2158,7 @@ g_file_copy (GFile *source, } } } - + return file_copy_fallback (source, destination, flags, cancellable, progress_callback, progress_callback_data, error); @@ -2209,14 +2233,38 @@ g_file_move (GFile *source, if (g_cancellable_set_error_if_cancelled (cancellable, error)) return FALSE; - if (G_OBJECT_TYPE (source) == G_OBJECT_TYPE (destination)) + iface = G_FILE_GET_IFACE (destination); + if (iface->move) { - iface = G_FILE_GET_IFACE (source); + my_error = NULL; + res = (* iface->move) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); + + if (res) + return TRUE; + + if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED) + { + g_propagate_error (error, my_error); + return FALSE; + } + } + /* If the types are different, and the destination method failed + also try the source method */ + if (G_OBJECT_TYPE (source) != G_OBJECT_TYPE (destination)) + { + iface = G_FILE_GET_IFACE (source); + if (iface->move) { my_error = NULL; - res = (* iface->move) (source, destination, flags, cancellable, progress_callback, progress_callback_data, &my_error); + res = (* iface->move) (source, destination, + flags, cancellable, + progress_callback, progress_callback_data, + &my_error); if (res) return TRUE; @@ -2228,7 +2276,7 @@ g_file_move (GFile *source, } } } - + if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE) { g_set_error (error, G_IO_ERROR, diff --git a/gio/glocalfile.c b/gio/glocalfile.c index 2b4b35e..d6bbec8 100644 --- a/gio/glocalfile.c +++ b/gio/glocalfile.c @@ -1753,13 +1753,24 @@ g_local_file_move (GFile *source, gpointer progress_callback_data, GError **error) { - GLocalFile *local_source = G_LOCAL_FILE (source); + GLocalFile *local_source; GLocalFile *local_destination = G_LOCAL_FILE (destination); struct stat statbuf; gboolean destination_exist, source_is_dir; char *backup_name; int res; - + off_t source_size; + + if (!G_IS_LOCAL_FILE (source) || + !G_IS_LOCAL_FILE (destination)) + { + /* Fall back to default move */ + g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "Move not supported"); + return FALSE; + } + + local_source = G_LOCAL_FILE (source); + res = g_lstat (local_source->filename, &statbuf); if (res == -1) { @@ -1771,6 +1782,8 @@ g_local_file_move (GFile *source, } else source_is_dir = S_ISDIR (statbuf.st_mode); + + source_size = statbuf.st_size; destination_exist = FALSE; res = g_lstat (local_destination->filename, &statbuf); @@ -1853,8 +1866,12 @@ g_local_file_move (GFile *source, _("Error moving file: %s"), g_strerror (errsv)); return FALSE; - } + + /* Make sure we send full copied size */ + if (progress_callback) + progress_callback (source_size, source_size, progress_callback_data); + return TRUE; } -- 2.7.4