glib r6324 - trunk/gio



Author: alexl
Date: Thu Jan 17 10:57:48 2008
New Revision: 6324
URL: http://svn.gnome.org/viewvc/glib?rev=6324&view=rev

Log:
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.



Modified:
   trunk/gio/ChangeLog
   trunk/gio/gfile.c
   trunk/gio/glocalfile.c

Modified: trunk/gio/gfile.c
==============================================================================
--- trunk/gio/gfile.c	(original)
+++ trunk/gio/gfile.c	Thu Jan 17 10:57:48 2008
@@ -2115,14 +2115,38 @@
   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 @@
 	    }
 	}
     }
-
+  
   return file_copy_fallback (source, destination, flags, cancellable,
 			     progress_callback, progress_callback_data,
 			     error);
@@ -2209,14 +2233,38 @@
   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 @@
 	    }
 	}
     }
-
+  
   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
     {  
       g_set_error (error, G_IO_ERROR,

Modified: trunk/gio/glocalfile.c
==============================================================================
--- trunk/gio/glocalfile.c	(original)
+++ trunk/gio/glocalfile.c	Thu Jan 17 10:57:48 2008
@@ -1753,13 +1753,24 @@
 		   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 @@
     }
   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 @@
 		     _("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;
 }
 



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