Allow calls to implementation of copy and write even if the type of the

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

        * 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
This commit is contained in:
Alexander Larsson 2008-01-17 10:57:48 +00:00 committed by Alexander Larsson
parent f1332511ee
commit 0026537f37
3 changed files with 95 additions and 11 deletions

View File

@ -1,3 +1,22 @@
2008-01-17 Alexander Larsson <alexl@redhat.com>
* 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 <murrayc@murrayc.com>
* gappinfo.c:

View File

@ -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)
{
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)
{
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,

View File

@ -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;
}