Allow calls to implementation of copy and write even if the type of the
authorAlexander Larsson <alexl@redhat.com>
Thu, 17 Jan 2008 10:57:48 +0000 (10:57 +0000)
committerAlexander Larsson <alexl@src.gnome.org>
Thu, 17 Jan 2008 10:57:48 +0000 (10:57 +0000)
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

gio/ChangeLog
gio/gfile.c
gio/glocalfile.c

index c884a237c1556c362966cf4210945d66692ef5cb..605750e85144098e7579672cab7fa4ddcdadd53c 100644 (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:
index 303915907fa17de4c1f72c8982cd49a6d45ea2c9..12b148c29109ac595a005dc7e3e206ad51c80938 100644 (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)
     {
-      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,
index 2b4b35e709bded517abbbb3f5720db41a4eca46f..d6bbec805f959bec2014e3db4db13dfd4ae71b86 100644 (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;
 }