Add new error codes for when compilation fails and make compilation error
[platform/upstream/glib.git] / gio / gfile.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Alexander Larsson <alexl@redhat.com>
21  */
22
23 #include <config.h>
24 #include <string.h>
25 #include <sys/types.h>
26 #ifdef HAVE_PWD_H
27 #include <pwd.h>
28 #endif
29 #include "gfile.h"
30 #include "gvfs.h"
31 #include "gioscheduler.h"
32 #include <glocalfile.h>
33 #include "gsimpleasyncresult.h"
34 #include "gpollfilemonitor.h"
35 #include "glibintl.h"
36
37 #include "gioalias.h"
38
39 /**
40  * SECTION:gfile
41  * @short_description: File and Directory Handling
42  * @see_also: #GFileInfo, #GFileEnumerator
43  * @include: gio/gfile.h
44  * 
45  * #GFile is a high level abstraction for manipulating files on a 
46  * virtual file system. #GFile<!-- -->s are lightweight, immutable 
47  * objects that do no I/O upon creation. It is necessary to understand that
48  * #GFile objects do not represent files, merely a handle to a file. All
49  * file I/O is implemented as streaming operations (see #GInputStream and 
50  * #GOutputStream).
51  * 
52  * To construct a #GFile, you can use: 
53  * g_file_new_for_path() if you have a path.
54  * g_file_new_for_uri() if you have a URI.
55  * 
56  * You can move through the filesystem with #GFile handles with
57  * g_file_get_parent() to get a handle to the parent directory.
58  * g_file_get_child() to get a handle to a child within a directory.
59  * g_file_resolve_relative_path() to resolve a relative path between
60  * two #GFile<!-- -->s.
61  * 
62  * Many #GFile operations have both synchronous and asynchronous versions 
63  * to suit your application. Asynchronous versions of synchronous functions 
64  * simply have _async() appended to their function names. The asynchronous 
65  * I/O functions call a #GAsyncReadyCallback which is then used to finalize 
66  * the operation, which is then passed to the function's matching _finish() 
67  * operation. 
68  *
69  * Some #GFile operations do not have synchronous analogs, as they may
70  * take a very long time to finish, and blocking may leave an application
71  * unusable. Notable cases include:
72  * g_file_mount_mountable() to mount a mountable file.
73  * g_file_unmount_mountable() to unmount a mountable file.
74  * g_file_eject_mountable() to eject a mountable file.
75  * 
76  * <para id="gfile-etag"><indexterm><primary>entity tag</primary></indexterm>
77  * One notable feature of #GFile<!-- -->s are entity tags, or "etags" for 
78  * short. Entity tags are somewhat like a more abstract version of the 
79  * traditional mtime, and can be used to quickly determine if the file has
80  * been modified from the version on the file system. See the HTTP 1.1 
81  * <ulink url="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html">specification</ulink>
82  * for HTTP Etag headers, which are a very similar concept.
83  * </para>
84  **/
85
86 static void g_file_base_init (gpointer g_class);
87 static void g_file_class_init (gpointer g_class,
88                                gpointer class_data);
89
90 static void               g_file_real_query_info_async          (GFile                *file,
91                                                                  const char           *attributes,
92                                                                  GFileQueryInfoFlags   flags,
93                                                                  int                   io_priority,
94                                                                  GCancellable         *cancellable,
95                                                                  GAsyncReadyCallback   callback,
96                                                                  gpointer              user_data);
97 static GFileInfo *        g_file_real_query_info_finish         (GFile                *file,
98                                                                  GAsyncResult         *res,
99                                                                  GError              **error);
100 static void               g_file_real_enumerate_children_async  (GFile                *file,
101                                                                  const char           *attributes,
102                                                                  GFileQueryInfoFlags   flags,
103                                                                  int                   io_priority,
104                                                                  GCancellable         *cancellable,
105                                                                  GAsyncReadyCallback   callback,
106                                                                  gpointer              user_data);
107 static GFileEnumerator *  g_file_real_enumerate_children_finish (GFile                *file,
108                                                                  GAsyncResult         *res,
109                                                                  GError              **error);
110 static void               g_file_real_read_async                (GFile                *file,
111                                                                  int                   io_priority,
112                                                                  GCancellable         *cancellable,
113                                                                  GAsyncReadyCallback   callback,
114                                                                  gpointer              user_data);
115 static GFileInputStream * g_file_real_read_finish               (GFile                *file,
116                                                                  GAsyncResult         *res,
117                                                                  GError              **error);
118 static void               g_file_real_append_to_async           (GFile                *file,
119                                                                  GFileCreateFlags      flags,
120                                                                  int                   io_priority,
121                                                                  GCancellable         *cancellable,
122                                                                  GAsyncReadyCallback   callback,
123                                                                  gpointer              user_data);
124 static GFileOutputStream *g_file_real_append_to_finish          (GFile                *file,
125                                                                  GAsyncResult         *res,
126                                                                  GError              **error);
127 static void               g_file_real_create_async              (GFile                *file,
128                                                                  GFileCreateFlags      flags,
129                                                                  int                   io_priority,
130                                                                  GCancellable         *cancellable,
131                                                                  GAsyncReadyCallback   callback,
132                                                                  gpointer              user_data);
133 static GFileOutputStream *g_file_real_create_finish             (GFile                *file,
134                                                                  GAsyncResult         *res,
135                                                                  GError              **error);
136 static void               g_file_real_replace_async             (GFile                *file,
137                                                                  const char           *etag,
138                                                                  gboolean              make_backup,
139                                                                  GFileCreateFlags      flags,
140                                                                  int                   io_priority,
141                                                                  GCancellable         *cancellable,
142                                                                  GAsyncReadyCallback   callback,
143                                                                  gpointer              user_data);
144 static GFileOutputStream *g_file_real_replace_finish            (GFile                *file,
145                                                                  GAsyncResult         *res,
146                                                                  GError              **error);
147 static gboolean           g_file_real_set_attributes_from_info  (GFile                *file,
148                                                                  GFileInfo            *info,
149                                                                  GFileQueryInfoFlags   flags,
150                                                                  GCancellable         *cancellable,
151                                                                  GError              **error);
152 static void               g_file_real_set_display_name_async    (GFile                *file,
153                                                                  const char           *display_name,
154                                                                  int                   io_priority,
155                                                                  GCancellable         *cancellable,
156                                                                  GAsyncReadyCallback   callback,
157                                                                  gpointer              user_data);
158 static GFile *            g_file_real_set_display_name_finish   (GFile                *file,
159                                                                  GAsyncResult         *res,
160                                                                  GError              **error);
161 static void               g_file_real_set_attributes_async      (GFile                *file,
162                                                                  GFileInfo            *info,
163                                                                  GFileQueryInfoFlags   flags,
164                                                                  int                   io_priority,
165                                                                  GCancellable         *cancellable,
166                                                                  GAsyncReadyCallback   callback,
167                                                                  gpointer              user_data);
168 static gboolean           g_file_real_set_attributes_finish     (GFile                *file,
169                                                                  GAsyncResult         *res,
170                                                                  GFileInfo           **info,
171                                                                  GError              **error);
172
173 GType
174 g_file_get_type (void)
175 {
176   static GType file_type = 0;
177
178   if (! file_type)
179     {
180       static const GTypeInfo file_info =
181       {
182         sizeof (GFileIface), /* class_size */
183         g_file_base_init,   /* base_init */
184         NULL,           /* base_finalize */
185         g_file_class_init,
186         NULL,           /* class_finalize */
187         NULL,           /* class_data */
188         0,
189         0,              /* n_preallocs */
190         NULL
191       };
192
193       file_type =
194         g_type_register_static (G_TYPE_INTERFACE, I_("GFile"),
195                                 &file_info, 0);
196
197       g_type_interface_add_prerequisite (file_type, G_TYPE_OBJECT);
198     }
199
200   return file_type;
201 }
202
203 static void
204 g_file_class_init (gpointer g_class,
205                    gpointer class_data)
206 {
207   GFileIface *iface = g_class;
208
209   iface->enumerate_children_async = g_file_real_enumerate_children_async;
210   iface->enumerate_children_finish = g_file_real_enumerate_children_finish;
211   iface->set_display_name_async = g_file_real_set_display_name_async;
212   iface->set_display_name_finish = g_file_real_set_display_name_finish;
213   iface->query_info_async = g_file_real_query_info_async;
214   iface->query_info_finish = g_file_real_query_info_finish;
215   iface->set_attributes_async = g_file_real_set_attributes_async;
216   iface->set_attributes_finish = g_file_real_set_attributes_finish;
217   iface->read_async = g_file_real_read_async;
218   iface->read_finish = g_file_real_read_finish;
219   iface->append_to_async = g_file_real_append_to_async;
220   iface->append_to_finish = g_file_real_append_to_finish;
221   iface->create_async = g_file_real_create_async;
222   iface->create_finish = g_file_real_create_finish;
223   iface->replace_async = g_file_real_replace_async;
224   iface->replace_finish = g_file_real_replace_finish;
225   iface->set_attributes_from_info = g_file_real_set_attributes_from_info;
226 }
227
228 static void
229 g_file_base_init (gpointer g_class)
230 {
231 }
232
233
234 /**
235  * g_file_is_native:
236  * @file: input #GFile.
237  *
238  * Checks to see if a file is native to the platform.
239  *
240  * Returns: %TRUE if file is native. (If the #GFile<!---->'s expressed in 
241  * the platform-native filename format, e.g. "C:\Windows", "/usr/bin/").
242  **/
243 gboolean
244 g_file_is_native (GFile *file)
245 {
246   GFileIface *iface;
247
248   g_return_val_if_fail (G_IS_FILE (file), FALSE);
249
250   iface = G_FILE_GET_IFACE (file);
251
252   return (* iface->is_native) (file);
253 }
254
255
256 /**
257  * g_file_has_uri_scheme: 
258  * @file: input #GFile.
259  * @uri_scheme: a string containing a URI scheme.
260  *
261  * Checks to see if a #GFile has a given URI scheme.
262  *
263  * Returns: %TRUE if #GFile's backend supports the
264  *     given URI scheme, %FALSE if URI scheme is %NULL,
265  *     not supported, or #GFile is invalid.
266  **/
267 gboolean
268 g_file_has_uri_scheme (GFile      *file,
269                        const char *uri_scheme)
270 {
271   GFileIface *iface;
272   
273   g_return_val_if_fail (G_IS_FILE (file), FALSE);
274   g_return_val_if_fail (uri_scheme != NULL, FALSE);
275
276   iface = G_FILE_GET_IFACE (file);
277
278   return (* iface->has_uri_scheme) (file, uri_scheme);
279 }
280
281
282 /**
283  * g_file_get_uri_scheme:
284  * @file: input #GFile.
285  *
286  * Gets the URI scheme for a #GFile.
287  * RFC 3986 decodes the scheme as:
288  * <programlisting>
289  * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 
290  * </programlisting>
291  * Common schemes include "file", "http", "svn", etc. 
292  *
293  * Returns: a string containing the URI scheme for the given 
294  *     #GFile. The returned string should be freed with g_free() 
295  *     when no longer needed.
296  **/
297 char *
298 g_file_get_uri_scheme (GFile *file)
299 {
300   GFileIface *iface;
301
302   g_return_val_if_fail (G_IS_FILE (file), NULL);
303
304   iface = G_FILE_GET_IFACE (file);
305
306   return (* iface->get_uri_scheme) (file);
307 }
308
309
310 /**
311  * g_file_get_basename:
312  * @file: input #GFile.
313  *
314  * Gets the basename for a given #GFile.
315  *
316  * Returns: string containing the #GFile's base name, or %NULL 
317  *     if given #GFile is invalid. The returned string should be 
318  *     freed with g_free() when no longer needed.
319  **/
320 char *
321 g_file_get_basename (GFile *file)
322 {
323   GFileIface *iface;
324   
325   g_return_val_if_fail (G_IS_FILE (file), NULL);
326
327   iface = G_FILE_GET_IFACE (file);
328
329   return (* iface->get_basename) (file);
330 }
331
332 /**
333  * g_file_get_path:
334  * @file: input #GFile.
335  *
336  * Gets the current path within a #GFile. 
337  *
338  * Returns: string containing the #GFile's path, or %NULL if 
339  *     given #GFile is invalid. The returned string should be 
340  *     freed with g_free() when no longer needed.
341  **/
342 char *
343 g_file_get_path (GFile *file)
344 {
345   GFileIface *iface;
346
347   g_return_val_if_fail (G_IS_FILE (file), NULL);
348
349   iface = G_FILE_GET_IFACE (file);
350
351   return (* iface->get_path) (file);
352 }
353
354 /**
355  * g_file_get_uri:
356  * @file: input #GFile.
357  *
358  * Gets a URI for the path within a #GFile.
359  *
360  * Returns: a string containing the #GFile's URI or %NULL 
361  *     if given #GFile is invalid. The returned string should 
362  *     be freed with g_free() when no longer needed.
363  **/
364 char *
365 g_file_get_uri (GFile *file)
366 {
367   GFileIface *iface;
368   
369   g_return_val_if_fail (G_IS_FILE (file), NULL);
370
371   iface = G_FILE_GET_IFACE (file);
372
373   return (* iface->get_uri) (file);
374 }
375
376 /**
377  * g_file_get_parse_name:
378  * @file: input #GFile.
379  *
380  * Gets the UTF-8 parsed name for the #GFile.
381  *
382  * Returns: a string containing the #GFile's parsed name, 
383  *     or %NULL if given #GFile is invalid. The returned 
384  *     string should be freed with g_free() when no longer needed.
385  **/
386 char *
387 g_file_get_parse_name (GFile *file)
388 {
389   GFileIface *iface;
390   
391   g_return_val_if_fail (G_IS_FILE (file), NULL);
392
393   iface = G_FILE_GET_IFACE (file);
394
395   return (* iface->get_parse_name) (file);
396 }
397
398 /**
399  * g_file_dup:
400  * @file: input #GFile.
401  *
402  * Duplicates a #GFile handle. This operation does not duplicate 
403  * the actual file or directory represented by the #GFile; see 
404  * g_file_copy() if attempting to copy a file. 
405  *
406  * Returns: #GFile that is a duplicate of the given #GFile, 
407  *     or %NULL if given #GFile is invalid. 
408  **/
409 GFile *
410 g_file_dup (GFile *file)
411 {
412   GFileIface *iface;
413   
414   g_return_val_if_fail (G_IS_FILE (file), NULL);
415
416   iface = G_FILE_GET_IFACE (file);
417
418   return (* iface->dup) (file);
419 }
420
421 /**
422  * g_file_hash:
423  * @file: #gconstpointer to a #GFile.
424  *
425  * Creates a hash value for a #GFile.
426  *
427  * Returns: 0 if @file is not a valid #GFile, otherwise an 
428  * integer that can be used as hash value for the #GFile. 
429  * This function is intended for easily hashing a #GFile to 
430  * add to a #GHashTable or similar data structure.
431  **/
432 guint
433 g_file_hash (gconstpointer file)
434 {
435   GFileIface *iface;
436   
437   g_return_val_if_fail (G_IS_FILE (file), 0);
438
439   iface = G_FILE_GET_IFACE (file);
440
441   return (* iface->hash) ((GFile *)file);
442 }
443
444 /**
445  * g_file_equal:
446  * @file1: the first #GFile.
447  * @file2: the second #GFile.
448  *
449  * Checks equality of two given #GFile<!-- -->s
450  *
451  * Returns: %TRUE if @file1 and @file2 are equal.
452  * %FALSE if either is not a #GFile.
453  **/
454 gboolean
455 g_file_equal (GFile *file1,
456               GFile *file2)
457 {
458   GFileIface *iface;
459   
460   g_return_val_if_fail (G_IS_FILE (file1), FALSE);
461   g_return_val_if_fail (G_IS_FILE (file2), FALSE);
462   
463   if (G_TYPE_FROM_INSTANCE (file1) != G_TYPE_FROM_INSTANCE (file2))
464     return FALSE;
465
466   iface = G_FILE_GET_IFACE (file1);
467   
468   return (* iface->equal) (file1, file2);
469 }
470
471
472 /**
473  * g_file_get_parent:
474  * @file: input #GFile.
475  *
476  * Gets the parent directory for the @file. 
477  * If the @file represents the root directory of the 
478  * file system, then %NULL will be returned.
479  *
480  * Returns: a #GFile structure to the parent of the given
481  * #GFile or %NULL. 
482  **/
483 GFile *
484 g_file_get_parent (GFile *file)
485 {
486   GFileIface *iface;
487   
488   g_return_val_if_fail (G_IS_FILE (file), NULL);
489
490   iface = G_FILE_GET_IFACE (file);
491
492   return (* iface->get_parent) (file);
493 }
494
495 /**
496  * g_file_get_child:
497  * @file: input #GFile.
498  * @name: string containing the child's name.
499  *
500  * Gets a specific child of @file with name equal to @name if
501  * it exists.
502  *
503  * Returns: a #GFile to a child specified by 
504  * @name or %NULL if @name is %NULL, or the specified
505  * child doesn't exist.
506  **/
507 GFile *
508 g_file_get_child (GFile      *file,
509                   const char *name)
510 {
511   g_return_val_if_fail (G_IS_FILE (file), NULL);
512   g_return_val_if_fail (name != NULL, NULL);
513
514   return g_file_resolve_relative_path (file, name);
515 }
516
517 /**
518  * g_file_get_child_for_display_name:
519  * @file: input #GFile.
520  * @display_name: string to a possible child.
521  * @error: #GError.
522  *
523  * Gets the child of @file for a given @display_name. If
524  * this function fails, it returns %NULL and @error will be 
525  * set with %G_IO_ERROR_INVALID_FILENAME.
526  * 
527  * Returns: a #GFile to the specified child, or 
528  * %NULL if @display_name is %NULL.  
529  **/
530 GFile *
531 g_file_get_child_for_display_name (GFile      *file,
532                                    const char *display_name,
533                                    GError **error)
534 {
535   GFileIface *iface;
536   
537   g_return_val_if_fail (G_IS_FILE (file), NULL);
538   g_return_val_if_fail (display_name != NULL, NULL);
539
540   iface = G_FILE_GET_IFACE (file);
541
542   return (* iface->get_child_for_display_name) (file, display_name, error);
543 }
544
545 /**
546  * g_file_contains_file:
547  * @parent: input #GFile.
548  * @descendant: input #GFile.
549  * 
550  * Checks whether @parent contains the specified @descendent.
551  * 
552  * Returns:  %TRUE if the @descendent's parent is @parent. %FALSE otherwise.
553  **/
554 gboolean
555 g_file_contains_file (GFile *parent,
556                       GFile *descendant)
557 {
558   GFileIface *iface;
559   
560   g_return_val_if_fail (G_IS_FILE (parent), FALSE);
561   g_return_val_if_fail (G_IS_FILE (descendant), FALSE);
562
563   if (G_TYPE_FROM_INSTANCE (parent) != G_TYPE_FROM_INSTANCE (descendant))
564     return FALSE;
565   
566   iface = G_FILE_GET_IFACE (parent);
567
568   return (* iface->contains_file) (parent, descendant);
569 }
570
571 /**
572  * g_file_get_relative_path:
573  * @parent: input #GFile.
574  * @descendant: input #GFile.
575  *
576  * Gets the path for @descendant relative to @parent. 
577  *
578  * Returns: string with the relative path from @descendant 
579  *     to @parent. The returned string should be freed with 
580  *     g_free() when no longer needed.
581  **/
582 char *
583 g_file_get_relative_path (GFile *parent,
584                           GFile *descendant)
585 {
586   GFileIface *iface;
587   
588   g_return_val_if_fail (G_IS_FILE (parent), NULL);
589   g_return_val_if_fail (G_IS_FILE (descendant), NULL);
590
591   if (G_TYPE_FROM_INSTANCE (parent) != G_TYPE_FROM_INSTANCE (descendant))
592     return NULL;
593   
594   iface = G_FILE_GET_IFACE (parent);
595
596   return (* iface->get_relative_path) (parent, descendant);
597 }
598
599 /**
600  * g_file_resolve_relative_path:
601  * @file: input #GFile.
602  * @relative_path: a given relative path string.
603  *
604  * Resolves a relative path for @file to an absolute path.
605  *
606  * Returns: #GFile to the resolved path. %NULL if @relative_path 
607  *     is %NULL or if @file is invalid.
608  **/
609 GFile *
610 g_file_resolve_relative_path (GFile      *file,
611                               const char *relative_path)
612 {
613   GFileIface *iface;
614
615   g_return_val_if_fail (G_IS_FILE (file), NULL);
616   g_return_val_if_fail (relative_path != NULL, NULL);
617
618   iface = G_FILE_GET_IFACE (file);
619
620   return (* iface->resolve_relative_path) (file, relative_path);
621 }
622
623 /**
624  * g_file_enumerate_children:
625  * @file: input #GFile.
626  * @attributes: a string containing a #GFileAttributeInfo query.
627  * @flags: a set of #GFileQueryInfoFlags.
628  * @cancellable: optional #GCancellable object, %NULL to ignore.
629  * @error: #GError for error reporting.
630  *
631  * Gets a #GFileEnumerator for the children of @file that match @attributes, 
632  * where attributes is a #GFileAttributeInfo query string (e.g. "std:type", 
633  * "std:*").
634  * 
635  * If @cancellable is not %NULL, then the operation can be cancelled by
636  * triggering the cancellable object from another thread. If the operation
637  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
638  *
639  * If the #GFileIface for the given @file does not support #GFileEnumerator,
640  * then %NULL will be returned and the error %G_IO_ERROR_NOT_SUPPORTED will 
641  * be set in @error.
642  * 
643  * Returns: A #GFileEnumerator if successful. %NULL if cancelled or if #GFile's 
644  *     backend doesn't support #GFileEnumerator. 
645  **/
646 GFileEnumerator *
647 g_file_enumerate_children (GFile                *file,
648                            const char           *attributes,
649                            GFileQueryInfoFlags   flags,
650                            GCancellable         *cancellable,
651                            GError              **error)
652                            
653 {
654   GFileIface *iface;
655   
656   g_return_val_if_fail (G_IS_FILE (file), NULL);
657
658   if (g_cancellable_set_error_if_cancelled (cancellable, error))
659     return NULL;
660   
661   iface = G_FILE_GET_IFACE (file);
662
663   if (iface->enumerate_children == NULL)
664     {
665       g_set_error (error, G_IO_ERROR,
666                    G_IO_ERROR_NOT_SUPPORTED,
667                    _("Operation not supported"));
668       return NULL;
669     }
670
671   return (* iface->enumerate_children) (file, attributes, flags,
672                                         cancellable, error);
673 }
674
675 /**
676  * g_file_enumerate_children_async:
677  * @file: input #GFile.
678  * @attributes: a string containing a #GFileAttributeInfo query.
679  * @flags: a set of #GFileQueryInfoFlags.
680  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
681  *     of the request.
682  * @cancellable: optional #GCancellable object, %NULL to ignore.
683  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
684  * @user_data: the data to pass to callback function
685  *
686  * Asynchronously gets a #GFileEnumerator for the children of @file that 
687  * match @attributes, where attributes is a #GFileAttributeInfo query 
688  * string (e.g. "std:type", "std:*"). For the synchronous version of this 
689  * function, see g_file_enumerate_children().
690  * 
691  * To finish this asynchronous operation, see g_file_enumerate_children_finish().
692  **/
693 void
694 g_file_enumerate_children_async (GFile               *file,
695                                  const char          *attributes,
696                                  GFileQueryInfoFlags  flags,
697                                  int                  io_priority,
698                                  GCancellable        *cancellable,
699                                  GAsyncReadyCallback  callback,
700                                  gpointer             user_data)
701 {
702   GFileIface *iface;
703
704   g_return_if_fail (G_IS_FILE (file));
705
706   iface = G_FILE_GET_IFACE (file);
707   (* iface->enumerate_children_async) (file,
708                                        attributes,
709                                        flags,
710                                        io_priority,
711                                        cancellable,
712                                        callback,
713                                        user_data);
714 }
715
716 /**
717  * g_file_enumerate_children_finish:
718  * @file: input #GFile.
719  * @res: a #GAsyncResult.
720  * @error: a #GError.
721  * 
722  * Finishes an async enumerate children operation.
723  *
724  * If @cancellable was not %NULL when g_file_enumerate_children_async() 
725  * was called, then the operation could have been cancelled by triggering 
726  * the cancellable object from another thread. If the operation was cancelled, 
727  * the @error will be set to %G_IO_ERROR_CANCELLED and this function will 
728  * return %NULL. 
729  *
730  * If the #GFileIface for the given @file does not support enumerating files,
731  * then %NULL will be returned and the error %G_IO_ERROR_NOT_SUPPORTED will 
732  * be set in @error.
733  * 
734  * Returns: a #GFileEnumerator or %NULL if an error occurred.
735  **/
736 GFileEnumerator *
737 g_file_enumerate_children_finish (GFile         *file,
738                                   GAsyncResult  *res,
739                                   GError       **error)
740 {
741   GFileIface *iface;
742   
743   g_return_val_if_fail (G_IS_FILE (file), NULL);
744   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
745
746   if (G_IS_SIMPLE_ASYNC_RESULT (res))
747     {
748       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
749       if (g_simple_async_result_propagate_error (simple, error))
750         return NULL;
751     }
752   
753   iface = G_FILE_GET_IFACE (file);
754   return (* iface->enumerate_children_finish) (file, res, error);
755 }
756
757
758 /**
759  * g_file_query_info:
760  * @file: input #GFile.
761  * @attributes: a string containing a #GFileAttributeInfo query.
762  * @flags: a set of #GFileQueryInfoFlags.
763  * @cancellable: optional #GCancellable object, %NULL to ignore.
764  * @error: a #GError.
765  * 
766  * If @cancellable is not %NULL, then the operation can be cancelled by
767  * triggering the cancellable object from another thread. If the operation
768  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
769  * 
770  * If the #GFileIface for the given @file does not support querying file 
771  * information, then %NULL will be returned and the error 
772  * %G_IO_ERROR_NOT_SUPPORTED will be set in @error.
773  * 
774  * Returns: a #GFileInfo for the given @file, or %NULL on error.
775  **/
776 GFileInfo *
777 g_file_query_info (GFile                *file,
778                    const char           *attributes,
779                    GFileQueryInfoFlags   flags,
780                    GCancellable         *cancellable,
781                    GError              **error)
782 {
783   GFileIface *iface;
784   
785   g_return_val_if_fail (G_IS_FILE (file), NULL);
786
787   if (g_cancellable_set_error_if_cancelled (cancellable, error))
788     return NULL;
789   
790   iface = G_FILE_GET_IFACE (file);
791
792   if (iface->query_info == NULL)
793     {
794       g_set_error (error, G_IO_ERROR,
795                    G_IO_ERROR_NOT_SUPPORTED,
796                    _("Operation not supported"));
797       return NULL;
798     }
799   
800   return (* iface->query_info) (file, attributes, flags, cancellable, error);
801 }
802
803 /**
804  * g_file_query_info_async:
805  * @file: input #GFile.
806  * @attributes: a string containing a #GFileAttributeInfo query.
807  * @flags: a set of #GFileQueryInfoFlags.
808  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
809  *     of the request.
810  * @cancellable: optional #GCancellable object, %NULL to ignore. 
811  * @callback: a #GAsyncReadyCallback to call when the request is satisfied
812  * @user_data: the data to pass to callback function
813  * 
814  * If @cancellable is not %NULL, then the operation can be cancelled by
815  * triggering the cancellable object from another thread. If the operation
816  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.
817  * 
818  * To finish this asynchronous operation, see g_file_query_info_finish().
819  **/
820 void
821 g_file_query_info_async (GFile               *file,
822                          const char          *attributes,
823                          GFileQueryInfoFlags  flags,
824                          int                  io_priority,
825                          GCancellable        *cancellable,
826                          GAsyncReadyCallback  callback,
827                          gpointer             user_data)
828 {
829   GFileIface *iface;
830   
831   g_return_if_fail (G_IS_FILE (file));
832
833   iface = G_FILE_GET_IFACE (file);
834   (* iface->query_info_async) (file,
835                                attributes,
836                                flags,
837                                io_priority,
838                                cancellable,
839                                callback,
840                                user_data);
841 }
842
843 /**
844  * g_file_query_info_finish:
845  * @file: input #GFile.
846  * @res: a #GAsyncResult. 
847  * @error: a #GError. 
848  * 
849  * Finishes an asynchronous file info query. 
850  *
851  * If @cancellable was not %NULL when g_file_query_info_async() was called, 
852  * then the operation could have been cancelled by triggering the cancellable 
853  * object from another thread. If the operation was cancelled, the @error will 
854  * be set to %G_IO_ERROR_CANCELLED and this function will return %NULL. 
855  * 
856  * If the #GFileIface for the given @file does not support querying file 
857  * information, then %NULL will be returned and the error 
858  * %G_IO_ERROR_NOT_SUPPORTED will be set in @error.
859  * 
860  * Returns: #GFileInfo for given @file or %NULL on error.
861  **/
862 GFileInfo *
863 g_file_query_info_finish (GFile         *file,
864                           GAsyncResult  *res,
865                           GError       **error)
866 {
867   GFileIface *iface;
868
869   g_return_val_if_fail (G_IS_FILE (file), NULL);
870   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
871
872   if (G_IS_SIMPLE_ASYNC_RESULT (res))
873     {
874       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
875       if (g_simple_async_result_propagate_error (simple, error))
876         return NULL;
877     }
878   
879   iface = G_FILE_GET_IFACE (file);
880   return (* iface->query_info_finish) (file, res, error);
881 }
882
883 /**
884  * g_file_query_filesystem_info:
885  * @file: input #GFile.
886  * @attributes: a string containing a #GFileAttributeInfo query.
887  * @cancellable: optional #GCancellable object, %NULL to ignore. 
888  * @error: a #GError. 
889  * 
890  * Obtains attributes of a #GFile.
891  *
892  * If @cancellable is not %NULL, then the operation can be cancelled by
893  * triggering the cancellable object from another thread. If the operation
894  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
895  * 
896  * If the #GFileIface for the given @file does not support querying file system 
897  * information, then %NULL will be returned and the error 
898  * %G_IO_ERROR_NOT_SUPPORTED will be set in @error.
899  * 
900  * Returns: a #GFileInfo or %NULL if there was an error.
901  **/
902 GFileInfo *
903 g_file_query_filesystem_info (GFile         *file,
904                               const char    *attributes,
905                               GCancellable  *cancellable,
906                               GError       **error)
907 {
908   GFileIface *iface;
909   
910   g_return_val_if_fail (G_IS_FILE (file), NULL);
911
912   if (g_cancellable_set_error_if_cancelled (cancellable, error))
913     return NULL;
914   
915   iface = G_FILE_GET_IFACE (file);
916
917   if (iface->query_filesystem_info == NULL)
918     {
919       g_set_error (error, G_IO_ERROR,
920                    G_IO_ERROR_NOT_SUPPORTED,
921                    _("Operation not supported"));
922       return NULL;
923     }
924   
925   return (* iface->query_filesystem_info) (file, attributes, cancellable, error);
926 }
927
928 /**
929  * g_file_find_enclosing_volume:
930  * @file: input #GFile.
931  * @cancellable: optional #GCancellable object, %NULL to ignore. 
932  * @error: a #GError. 
933  *
934  * Gets a #GVolume for the #GFile. 
935  *
936  * If the #GFileIface for @file does not have a volume (e.g. possibly a 
937  * remote share), @error will be set to %G_IO_ERROR_NOT_FOUND and %NULL
938  * will be returned.
939  * 
940  * If @cancellable is not %NULL, then the operation can be cancelled by
941  * triggering the cancellable object from another thread. If the operation
942  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
943  * 
944  * Returns: a #GVolume where the @file is located or %NULL on error.
945  **/
946 GVolume *
947 g_file_find_enclosing_volume (GFile         *file,
948                               GCancellable  *cancellable,
949                               GError       **error)
950 {
951   GFileIface *iface;
952
953   g_return_val_if_fail (G_IS_FILE (file), NULL);
954   
955   if (g_cancellable_set_error_if_cancelled (cancellable, error))
956     return NULL;
957
958   iface = G_FILE_GET_IFACE (file);
959   if (iface->find_enclosing_volume == NULL)
960     {
961       g_set_error (error, G_IO_ERROR,
962                    G_IO_ERROR_NOT_FOUND,
963                    _("Containing volume does not exist"));
964       return NULL;
965     }
966   
967   return (* iface->find_enclosing_volume) (file, cancellable, error);
968 }
969
970 /**
971  * g_file_read:
972  * @file: #GFile to read.
973  * @cancellable: a #GCancellable
974  * @error: a #GError, or %NULL
975  *
976  * Reads a whole file into a #GFileInputStream. Fails returning %NULL if 
977  * given #GFile points to a directory. 
978  *
979  * If the #GFileIface for @file does not support reading files, then
980  * @error will be set to %G_IO_ERROR_NOT_SUPPORTED and %NULL will be returned. 
981  * 
982  * If @cancellable is not %NULL, then the operation can be cancelled by
983  * triggering the cancellable object from another thread. If the operation
984  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
985  * 
986  * Returns: #GFileInputStream or %NULL on error.
987  **/
988 GFileInputStream *
989 g_file_read (GFile         *file,
990              GCancellable  *cancellable,
991              GError       **error)
992 {
993   GFileIface *iface;
994   
995   g_return_val_if_fail (G_IS_FILE (file), NULL);
996
997   if (g_cancellable_set_error_if_cancelled (cancellable, error))
998     return NULL;
999
1000   iface = G_FILE_GET_IFACE (file);
1001
1002   if (iface->read == NULL)
1003     {
1004       g_set_error (error, G_IO_ERROR,
1005                    G_IO_ERROR_NOT_SUPPORTED,
1006                    _("Operation not supported"));
1007       return NULL;
1008     }
1009   
1010   return (* iface->read) (file, cancellable, error);
1011 }
1012
1013 /**
1014  * g_file_append_to:
1015  * @file: input #GFile.
1016  * @flags: a set of #GFileCreateFlags.
1017  * @cancellable: optional #GCancellable object, %NULL to ignore.
1018  * @error: a #GError, or %NULL
1019  *
1020  * Gets an output stream for appending to the file.
1021  *
1022  * If the #GFileIface for @file does not support appending to files, 
1023  * then @error will be set to %G_IO_ERROR_NOT_SUPPORTED and %NULL will 
1024  * be returned. 
1025  * 
1026  * If @cancellable is not %NULL, then the operation can be cancelled by
1027  * triggering the cancellable object from another thread. If the operation
1028  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1029  * 
1030  * Returns: a #GFileOutputStream.
1031  **/
1032 GFileOutputStream *
1033 g_file_append_to (GFile             *file,
1034                   GFileCreateFlags   flags,
1035                   GCancellable      *cancellable,
1036                   GError           **error)
1037 {
1038   GFileIface *iface;
1039
1040   g_return_val_if_fail (G_IS_FILE (file), NULL);
1041
1042   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1043     return NULL;
1044   
1045   iface = G_FILE_GET_IFACE (file);
1046
1047   if (iface->append_to == NULL)
1048     {
1049       g_set_error (error, G_IO_ERROR,
1050                    G_IO_ERROR_NOT_SUPPORTED,
1051                    _("Operation not supported"));
1052       return NULL;
1053     }
1054   
1055   return (* iface->append_to) (file, flags, cancellable, error);
1056 }
1057
1058 /**
1059  * g_file_create:
1060  * @file: input #GFile.
1061  * @flags: a set of #GFileCreateFlags.
1062  * @cancellable: optional #GCancellable object, %NULL to ignore.
1063  * @error: a #GError, or %NULL
1064  *
1065  * Creates the file and returns an output stream for writing to it.
1066  *
1067  * If the #GFileIface for @file does not support creating files, then
1068  * @error will be set to %G_IO_ERROR_NOT_SUPPORTED and %NULL will be returned. 
1069  *
1070  * If @cancellable is not %NULL, then the operation can be cancelled by
1071  * triggering the cancellable object from another thread. If the operation
1072  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1073  * 
1074  * Returns: a #GFileOutputStream for the newly created file, or 
1075  * %NULL on error.
1076  **/
1077 GFileOutputStream *
1078 g_file_create (GFile             *file,
1079                GFileCreateFlags   flags,
1080                GCancellable      *cancellable,
1081                GError           **error)
1082 {
1083   GFileIface *iface;
1084   
1085   g_return_val_if_fail (G_IS_FILE (file), NULL);
1086
1087   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1088     return NULL;
1089   
1090   iface = G_FILE_GET_IFACE (file);
1091
1092   if (iface->create == NULL)
1093     {
1094       g_set_error (error, G_IO_ERROR,
1095                    G_IO_ERROR_NOT_SUPPORTED,
1096                    _("Operation not supported"));
1097       return NULL;
1098     }
1099   
1100   return (* iface->create) (file, flags, cancellable, error);
1101 }
1102
1103 /**
1104  * g_file_replace:
1105  * @file: input #GFile.
1106  * @etag: an <link linkend="gfile-etag">entity tag</link> for the 
1107  *     current #GFile.
1108  * @make_backup: %TRUE if a backup should be created`.
1109  * @flags: a set of #GFileCreateFlags.
1110  * @cancellable: optional #GCancellable object, %NULL to ignore.
1111  * @error: a #GError, or %NULL
1112  *
1113  * Returns an output stream for overwriting the file, possibly
1114  * creating a backup copy of the file first.
1115  *
1116  * If the #GFileIface for @file does not support streaming operations, 
1117  * then @error will be set to %G_IO_ERROR_NOT_SUPPORTED and %NULL will 
1118  * be returned. 
1119  * 
1120  * If @cancellable is not %NULL, then the operation can be cancelled by
1121  * triggering the cancellable object from another thread. If the operation
1122  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1123  * 
1124  * @etag will replace the entity tag for the current file.
1125  * 
1126  * Returns: a #GFileOutputStream or %NULL on error. If @make_backup is 
1127  *     %TRUE, this function will attempt to make a backup of the current 
1128  *     file.
1129  **/
1130 GFileOutputStream *
1131 g_file_replace (GFile             *file,
1132                 const char        *etag,
1133                 gboolean           make_backup,
1134                 GFileCreateFlags   flags,
1135                 GCancellable      *cancellable,
1136                 GError           **error)
1137 {
1138   GFileIface *iface;
1139
1140   g_return_val_if_fail (G_IS_FILE (file), NULL);
1141
1142   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1143     return NULL;
1144   
1145   iface = G_FILE_GET_IFACE (file);
1146
1147   if (iface->replace == NULL)
1148     {
1149       g_set_error (error, G_IO_ERROR,
1150                    G_IO_ERROR_NOT_SUPPORTED,
1151                    _("Operation not supported"));
1152       return NULL;
1153     }
1154   
1155   
1156   /* Handle empty tag string as NULL in consistent way. */
1157   if (etag && *etag == 0)
1158     etag = NULL;
1159   
1160   return (* iface->replace) (file, etag, make_backup, flags, cancellable, error);
1161 }
1162
1163 /**
1164  * g_file_read_async:
1165  * @file: input #GFile.
1166  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1167  *     of the request. 
1168  * @cancellable: optional #GCancellable object, %NULL to ignore.
1169  * @callback: a #GAsyncReadyCallback.
1170  * @user_data: a #gpointer. 
1171  *
1172  * Asynchronously reads @file. 
1173  *
1174  * For the synchronous version of this function, see g_file_read().
1175  **/
1176 void
1177 g_file_read_async (GFile               *file,
1178                    int                  io_priority,
1179                    GCancellable        *cancellable,
1180                    GAsyncReadyCallback  callback,
1181                    gpointer             user_data)
1182 {
1183   GFileIface *iface;
1184   
1185   g_return_if_fail (G_IS_FILE (file));
1186
1187   iface = G_FILE_GET_IFACE (file);
1188   (* iface->read_async) (file,
1189                          io_priority,
1190                          cancellable,
1191                          callback,
1192                          user_data);
1193 }
1194
1195 /**
1196  * g_file_read_finish:
1197  * @file: input #GFile.
1198  * @res: a #GAsyncResult. 
1199  * @error: a #GError, or %NULL
1200  *
1201  * Finishes an asynchronous file read operation started with 
1202  * g_file_read_async(). 
1203  *  
1204  * If the #GFileIface for @file does not support streaming operations, 
1205  * then @error will be set to %G_IO_ERROR_NOT_SUPPORTED and %NULL will 
1206  * be returned. 
1207  *
1208  * If @cancellable is not %NULL, then the operation can be cancelled by
1209  * triggering the cancellable object from another thread. If the operation
1210  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned.  
1211  * 
1212  * Returns: a #GFileInputStream or %NULL on error.
1213  **/
1214 GFileInputStream *
1215 g_file_read_finish (GFile         *file,
1216                     GAsyncResult  *res,
1217                     GError       **error)
1218 {
1219   GFileIface *iface;
1220   
1221   g_return_val_if_fail (G_IS_FILE (file), NULL);
1222   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1223
1224   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1225     {
1226       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1227       if (g_simple_async_result_propagate_error (simple, error))
1228         return NULL;
1229     }
1230   
1231   iface = G_FILE_GET_IFACE (file);
1232   return (* iface->read_finish) (file, res, error);
1233 }
1234
1235 /**
1236  * g_file_append_to_async:
1237  * @file: input #GFile.
1238  * @flags: a set of #GFileCreateFlags.
1239  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1240  *     of the request. 
1241  * @cancellable: optional #GCancellable object, %NULL to ignore.
1242  * @callback: a #GAsyncReadyCallback. 
1243  * @user_data: a #gpointer. 
1244  * 
1245  * Readies a file for appending data asynchronously. 
1246  *
1247  * For the synchronous version of this function, see g_file_append_to().
1248  * To finish this operation, see g_file_append_to_finish().
1249  * 
1250  * If @cancellable is not %NULL, then the operation can be cancelled by
1251  * triggering the cancellable object from another thread. If the operation
1252  * was cancelled, the error %G_IO_ERROR_CANCELLED will be set when 
1253  * g_file_append_to_finish() is called, and %NULL will be returned.
1254  **/
1255 void
1256 g_file_append_to_async (GFile               *file,
1257                         GFileCreateFlags     flags,
1258                         int                  io_priority,
1259                         GCancellable        *cancellable,
1260                         GAsyncReadyCallback  callback,
1261                         gpointer             user_data)
1262 {
1263   GFileIface *iface;
1264   
1265   g_return_if_fail (G_IS_FILE (file));
1266
1267   iface = G_FILE_GET_IFACE (file);
1268   (* iface->append_to_async) (file,
1269                               flags,
1270                               io_priority,
1271                               cancellable,
1272                               callback,
1273                               user_data);
1274 }
1275
1276 /**
1277  * g_file_append_to_finish:
1278  * @file: input #GFile.
1279  * @res: #GAsyncResult
1280  * @error: a #GError, or %NULL
1281  * 
1282  * Finishes appending to a file. See g_file_append_to_async().
1283  * 
1284  * If @cancellable was not %NULL when g_file_append_to_async() was called, 
1285  * then the operation could have been be cancelled by triggering the cancellable 
1286  * object from another thread. If the operation was cancelled, the error 
1287  * %G_IO_ERROR_CANCELLED will be set in @error, and %NULL will be returned. 
1288  * 
1289  * Returns: a valid #GFileOutputStream or %NULL on error.
1290  **/
1291 GFileOutputStream *
1292 g_file_append_to_finish (GFile         *file,
1293                          GAsyncResult  *res,
1294                          GError       **error)
1295 {
1296   GFileIface *iface;
1297   
1298   g_return_val_if_fail (G_IS_FILE (file), NULL);
1299   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1300
1301   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1302     {
1303       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1304       if (g_simple_async_result_propagate_error (simple, error))
1305         return NULL;
1306     }
1307   
1308   iface = G_FILE_GET_IFACE (file);
1309   return (* iface->append_to_finish) (file, res, error);
1310 }
1311
1312 /**
1313  * g_file_create_async:
1314  * @file: input #GFile.
1315  * @flags: a set of #GFileCreateFlags.
1316  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1317  *     of the request.
1318  * @cancellable: optional #GCancellable object, %NULL to ignore.
1319  * @callback: a #GAsyncReadyCallback. 
1320  * @user_data: a #gpointer. 
1321  * 
1322  * Creates a new file asynchronously. 
1323  *
1324  * For the synchronous version of this function, see g_file_create(). 
1325  * To finish this operation, see g_file_create_finish().
1326  * 
1327  * If @cancellable is not %NULL, then the operation can be cancelled by
1328  * triggering the cancellable object from another thread. If the operation
1329  * was cancelled, the error %G_IO_ERROR_CANCELLED will be set, and %NULL
1330  * will be returned by g_file_create_finish(). 
1331  **/
1332 void
1333 g_file_create_async (GFile               *file,
1334                      GFileCreateFlags     flags,
1335                      int                  io_priority,
1336                      GCancellable        *cancellable,
1337                      GAsyncReadyCallback  callback,
1338                      gpointer             user_data)
1339 {
1340   GFileIface *iface;
1341   
1342   g_return_if_fail (G_IS_FILE (file));
1343
1344   iface = G_FILE_GET_IFACE (file);
1345   (* iface->create_async) (file,
1346                            flags,
1347                            io_priority,
1348                            cancellable,
1349                            callback,
1350                            user_data);
1351 }
1352
1353 /**
1354  * g_file_create_finish:
1355  * @file: input #GFile.
1356  * @res: a #GAsyncResult. 
1357  * @error: a #GError, or %NULL
1358  * 
1359  * Finishes creating a file. See g_file_create_async().
1360  * 
1361  * If @cancellable was not %NULL when g_file_create_async() was called, 
1362  * then the operation could have been be cancelled by triggering the cancellable 
1363  * object from another thread. If the operation was cancelled, the error 
1364  * %G_IO_ERROR_CANCELLED will be set in @error, and %NULL will be returned. 
1365  * 
1366  * Returns: a #GFileOutputStream or %NULL on error.
1367  **/
1368 GFileOutputStream *
1369 g_file_create_finish (GFile         *file,
1370                       GAsyncResult  *res,
1371                       GError       **error)
1372 {
1373   GFileIface *iface;
1374   
1375   g_return_val_if_fail (G_IS_FILE (file), NULL);
1376   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1377
1378   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1379     {
1380       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1381       if (g_simple_async_result_propagate_error (simple, error))
1382         return NULL;
1383     }
1384   
1385   iface = G_FILE_GET_IFACE (file);
1386   return (* iface->create_finish) (file, res, error);
1387 }
1388
1389 /**
1390  * g_file_replace_async:
1391  * @file: input #GFile.
1392  * @etag: an <link linkend="gfile-etag">entity tag</link> for the 
1393  *     current #GFile.
1394  * @make_backup: a #gboolean.
1395  * @flags: a set of #GFileCreateFlags.
1396  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
1397  *     of the request.
1398  * @cancellable: optional #GCancellable object, %NULL to ignore.
1399  * @callback: a #GAsyncReadyCallback. 
1400  * @user_data: a #gpointer. 
1401  * 
1402  * Replaces a file's contents asynchronously. If @make_backup is 
1403  * %TRUE, this function will attempt to make a backup of the current file.
1404  *
1405  * For the synchronous version of this function, see g_file_replace(). 
1406  * To finish this operation, see g_file_replace_finish().
1407  *
1408  * If @cancellable is not %NULL, then the operation can be cancelled by
1409  * triggering the cancellable object from another thread. If the operation
1410  * was cancelled, the error %G_IO_ERROR_CANCELLED will be set, and 
1411  * %NULL will be returned in g_file_replace_finish(). 
1412  **/
1413 void
1414 g_file_replace_async (GFile               *file,
1415                       const char          *etag,
1416                       gboolean             make_backup,
1417                       GFileCreateFlags     flags,
1418                       int                  io_priority,
1419                       GCancellable        *cancellable,
1420                       GAsyncReadyCallback  callback,
1421                       gpointer             user_data)
1422 {
1423   GFileIface *iface;
1424   
1425   g_return_if_fail (G_IS_FILE (file));
1426
1427   iface = G_FILE_GET_IFACE (file);
1428   (* iface->replace_async) (file,
1429                             etag,
1430                             make_backup,
1431                             flags,
1432                             io_priority,
1433                             cancellable,
1434                             callback,
1435                             user_data);
1436 }
1437
1438 /**
1439  * g_file_replace_finish:
1440  * @file: input #GFile.
1441  * @res: a #GAsyncResult. 
1442  * @error: a #GError, or %NULL
1443  * 
1444  * Finishes replacing the contents of the file. See g_file_replace_async().
1445  * 
1446  * If @cancellable was not %NULL when g_file_replace_async() was called, 
1447  * then the operation could have been be cancelled by triggering the cancellable 
1448  * object from another thread. If the operation was cancelled, the error 
1449  * %G_IO_ERROR_CANCELLED will be set in @error, and %NULL will be returned. 
1450  * 
1451  * Returns: a #GFileOutputStream, or %NULL if an error has occured.
1452  **/
1453 GFileOutputStream *
1454 g_file_replace_finish (GFile         *file,
1455                        GAsyncResult  *res,
1456                        GError       **error)
1457 {
1458   GFileIface *iface;
1459   
1460   g_return_val_if_fail (G_IS_FILE (file), NULL);
1461   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
1462
1463   if (G_IS_SIMPLE_ASYNC_RESULT (res))
1464     {
1465       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
1466       if (g_simple_async_result_propagate_error (simple, error))
1467         return NULL;
1468     }
1469   
1470   iface = G_FILE_GET_IFACE (file);
1471   return (* iface->replace_finish) (file, res, error);
1472 }
1473
1474 static gboolean
1475 copy_symlink (GFile           *destination,
1476               GFileCopyFlags   flags,
1477               GCancellable    *cancellable,
1478               const char      *target,
1479               GError         **error)
1480 {
1481   GError *my_error;
1482   gboolean tried_delete;
1483   GFileInfo *info;
1484   GFileType file_type;
1485
1486   tried_delete = FALSE;
1487
1488  retry:
1489   my_error = NULL;
1490   if (!g_file_make_symbolic_link (destination, target, cancellable, &my_error))
1491     {
1492       /* Maybe it already existed, and we want to overwrite? */
1493       if (!tried_delete && (flags & G_FILE_COPY_OVERWRITE) && 
1494           my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_EXISTS)
1495         {
1496           g_error_free (my_error);
1497
1498
1499           /* Don't overwrite if the destination is a directory */
1500           info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STD_TYPE,
1501                                     G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1502                                     cancellable, &my_error);
1503           if (info != NULL)
1504             {
1505               file_type = g_file_info_get_file_type (info);
1506               g_object_unref (info);
1507               
1508               if (file_type == G_FILE_TYPE_DIRECTORY)
1509                 {
1510                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY,
1511                                _("Can't copy over directory"));
1512                   return FALSE;
1513                 }
1514             }
1515           
1516           if (!g_file_delete (destination, cancellable, error))
1517             return FALSE;
1518           
1519           tried_delete = TRUE;
1520           goto retry;
1521         }
1522             /* Nah, fail */
1523       g_propagate_error (error, my_error);
1524       return FALSE;
1525     }
1526
1527   return TRUE;
1528 }
1529
1530 static GInputStream *
1531 open_source_for_copy (GFile           *source,
1532                       GFile           *destination,
1533                       GFileCopyFlags   flags,
1534                       GCancellable    *cancellable,
1535                       GError         **error)
1536 {
1537   GError *my_error;
1538   GInputStream *in;
1539   GFileInfo *info;
1540   GFileType file_type;
1541   
1542   my_error = NULL;
1543   in = (GInputStream *)g_file_read (source, cancellable, &my_error);
1544   if (in != NULL)
1545     return in;
1546
1547   /* There was an error opening the source, try to set a good error for it: */
1548
1549   if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_IS_DIRECTORY)
1550     {
1551       /* The source is a directory, don't fail with WOULD_RECURSE immediately, 
1552        * as that is less useful to the app. Better check for errors on the 
1553        * target instead. 
1554        */
1555       g_error_free (my_error);
1556       my_error = NULL;
1557       
1558       info = g_file_query_info (destination, G_FILE_ATTRIBUTE_STD_TYPE,
1559                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1560                                 cancellable, &my_error);
1561       if (info != NULL)
1562         {
1563           file_type = g_file_info_get_file_type (info);
1564           g_object_unref (info);
1565           
1566           if (flags & G_FILE_COPY_OVERWRITE)
1567             {
1568               if (file_type == G_FILE_TYPE_DIRECTORY)
1569                 {
1570                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_MERGE,
1571                                _("Can't copy directory over directory"));
1572                   return NULL;
1573                 }
1574               /* continue to would_recurse error */
1575             }
1576           else
1577             {
1578               g_set_error (error, G_IO_ERROR, G_IO_ERROR_EXISTS,
1579                            _("Target file exists"));
1580               return NULL;
1581             }
1582         }
1583       else
1584         {
1585           /* Error getting info from target, return that error 
1586            * (except for NOT_FOUND, which is no error here) 
1587            */
1588           if (my_error->domain != G_IO_ERROR && my_error->code != G_IO_ERROR_NOT_FOUND)
1589             {
1590               g_propagate_error (error, my_error);
1591               return NULL;
1592             }
1593           g_error_free (my_error);
1594         }
1595       
1596       g_set_error (error, G_IO_ERROR, G_IO_ERROR_WOULD_RECURSE,
1597                    _("Can't recursively copy directory"));
1598       return NULL;
1599     }
1600
1601   g_propagate_error (error, my_error);
1602   return NULL;
1603 }
1604
1605 static gboolean
1606 should_copy (GFileAttributeInfo *info, 
1607              gboolean            as_move)
1608 {
1609   if (as_move)
1610     return info->flags & G_FILE_ATTRIBUTE_FLAGS_COPY_WHEN_MOVED;
1611   return info->flags & G_FILE_ATTRIBUTE_FLAGS_COPY_WITH_FILE;
1612 }
1613
1614 static char *
1615 build_attribute_list_for_copy (GFileAttributeInfoList *attributes,
1616                                GFileAttributeInfoList *namespaces,
1617                                gboolean                as_move)
1618 {
1619   GString *s;
1620   gboolean first;
1621   int i;
1622   
1623   first = TRUE;
1624   s = g_string_new ("");
1625
1626   if (attributes)
1627     {
1628       for (i = 0; i < attributes->n_infos; i++)
1629         {
1630           if (should_copy (&attributes->infos[i], as_move))
1631             {
1632               if (first)
1633                 first = FALSE;
1634               else
1635                 g_string_append_c (s, ',');
1636                 
1637               g_string_append (s, attributes->infos[i].name);
1638             }
1639         }
1640     }
1641
1642   if (namespaces)
1643     {
1644       for (i = 0; i < namespaces->n_infos; i++)
1645         {
1646           if (should_copy (&namespaces->infos[i], as_move))
1647             {
1648               if (first)
1649                 first = FALSE;
1650               else
1651                 g_string_append_c (s, ',');
1652                 
1653               g_string_append (s, namespaces->infos[i].name);
1654               g_string_append (s, ":*");
1655             }
1656         }
1657     }
1658
1659   return g_string_free (s, FALSE);
1660 }
1661
1662 gboolean
1663 g_file_copy_attributes (GFile           *source,
1664                         GFile           *destination,
1665                         GFileCopyFlags   flags,
1666                         GCancellable    *cancellable,
1667                         GError         **error)
1668 {
1669   GFileAttributeInfoList *attributes, *namespaces;
1670   char *attrs_to_read;
1671   gboolean res;
1672   GFileInfo *info;
1673   gboolean as_move;
1674   gboolean source_nofollow_symlinks;
1675
1676   as_move = flags & G_FILE_COPY_ALL_METADATA;
1677   source_nofollow_symlinks = flags & G_FILE_COPY_NOFOLLOW_SYMLINKS;
1678
1679   /* Ignore errors here, if the target supports no attributes there is nothing to copy */
1680   attributes = g_file_query_settable_attributes (destination, cancellable, NULL);
1681   namespaces = g_file_query_writable_namespaces (destination, cancellable, NULL);
1682
1683   if (attributes == NULL && namespaces == NULL)
1684     return TRUE;
1685
1686   attrs_to_read = build_attribute_list_for_copy (attributes, namespaces, as_move);
1687
1688   /* Ignore errors here, if we can't read some info (e.g. if it doesn't exist)
1689    * we just don't copy it. 
1690    */
1691   info = g_file_query_info (source, attrs_to_read,
1692                             source_nofollow_symlinks ? G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS:0,
1693                             cancellable,
1694                             NULL);
1695
1696   g_free (attrs_to_read);
1697   
1698   res = TRUE;
1699   if  (info)
1700     {
1701       res = g_file_set_attributes_from_info (destination,
1702                                              info, 0,
1703                                              cancellable,
1704                                              error);
1705       g_object_unref (info);
1706     }
1707   
1708   g_file_attribute_info_list_unref (attributes);
1709   g_file_attribute_info_list_unref (namespaces);
1710   
1711   return res;
1712 }
1713
1714 /* Closes the streams */
1715 static gboolean
1716 copy_stream_with_progress (GInputStream           *in,
1717                            GOutputStream          *out,
1718                            GCancellable           *cancellable,
1719                            GFileProgressCallback   progress_callback,
1720                            gpointer                progress_callback_data,
1721                            GError                **error)
1722 {
1723   gssize n_read, n_written;
1724   goffset current_size;
1725   char buffer[8192], *p;
1726   gboolean res;
1727   goffset total_size;
1728   GFileInfo *info;
1729
1730   total_size = 0;
1731   info = g_file_input_stream_query_info (G_FILE_INPUT_STREAM (in),
1732                                          G_FILE_ATTRIBUTE_STD_SIZE,
1733                                          cancellable, NULL);
1734   if (info)
1735     {
1736       total_size = g_file_info_get_size (info);
1737       g_object_unref (info);
1738     }
1739   
1740   current_size = 0;
1741   res = TRUE;
1742   while (TRUE)
1743     {
1744       n_read = g_input_stream_read (in, buffer, sizeof (buffer), cancellable, error);
1745       if (n_read == -1)
1746         {
1747           res = FALSE;
1748           break;
1749         }
1750         
1751       if (n_read == 0)
1752         break;
1753
1754       current_size += n_read;
1755
1756       p = buffer;
1757       while (n_read > 0)
1758         {
1759           n_written = g_output_stream_write (out, p, n_read, cancellable, error);
1760           if (n_written == -1)
1761             {
1762               res = FALSE;
1763               break;
1764             }
1765
1766           p += n_written;
1767           n_read -= n_written;
1768         }
1769
1770       if (!res)
1771         break;
1772       
1773       if (progress_callback)
1774         progress_callback (current_size, total_size, progress_callback_data);
1775     }
1776
1777   if (!res)
1778     error = NULL; /* Ignore further errors */
1779
1780   /* Make sure we send full copied size */
1781   if (progress_callback)
1782     progress_callback (current_size, total_size, progress_callback_data);
1783
1784   
1785   /* Don't care about errors in source here */
1786   g_input_stream_close (in, cancellable, NULL);
1787
1788   /* But write errors on close are bad! */
1789   if (!g_output_stream_close (out, cancellable, error))
1790     res = FALSE;
1791
1792   g_object_unref (in);
1793   g_object_unref (out);
1794       
1795   return res;
1796 }
1797
1798 static gboolean
1799 file_copy_fallback (GFile                  *source,
1800                     GFile                  *destination,
1801                     GFileCopyFlags          flags,
1802                     GCancellable           *cancellable,
1803                     GFileProgressCallback   progress_callback,
1804                     gpointer                progress_callback_data,
1805                     GError                **error)
1806 {
1807   GInputStream *in;
1808   GOutputStream *out;
1809   GFileInfo *info;
1810   const char *target;
1811
1812   /* Maybe copy the symlink? */
1813   if (flags & G_FILE_COPY_NOFOLLOW_SYMLINKS)
1814     {
1815       info = g_file_query_info (source,
1816                                 G_FILE_ATTRIBUTE_STD_TYPE "," G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET,
1817                                 G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS,
1818                                 cancellable,
1819                                 error);
1820       if (info == NULL)
1821         return FALSE;
1822
1823       if (g_file_info_get_file_type (info) == G_FILE_TYPE_SYMBOLIC_LINK &&
1824           (target = g_file_info_get_symlink_target (info)) != NULL)
1825         {
1826           if (!copy_symlink (destination, flags, cancellable, target, error))
1827             {
1828               g_object_unref (info);
1829               return FALSE;
1830             }
1831           
1832           g_object_unref (info);
1833           goto copied_file;
1834         }
1835       
1836       g_object_unref (info);
1837     }
1838   
1839   in = open_source_for_copy (source, destination, flags, cancellable, error);
1840   if (in == NULL)
1841     return FALSE;
1842   
1843   if (flags & G_FILE_COPY_OVERWRITE)
1844     {
1845       out = (GOutputStream *)g_file_replace (destination,
1846                                              NULL, 0,
1847                                              flags & G_FILE_COPY_BACKUP,
1848                                              cancellable, error);
1849     }
1850   else
1851     {
1852       out = (GOutputStream *)g_file_create (destination, 0, cancellable, error);
1853     }
1854
1855   if (out == NULL)
1856     {
1857       g_object_unref (in);
1858       return FALSE;
1859     }
1860
1861   if (!copy_stream_with_progress (in, out, cancellable,
1862                                   progress_callback, progress_callback_data,
1863                                   error))
1864     return FALSE;
1865
1866  copied_file:
1867
1868   /* Ignore errors here. Failure to copy metadata is not a hard error */
1869   g_file_copy_attributes (source, destination,
1870                           flags, cancellable, NULL);
1871   
1872   return TRUE;
1873 }
1874
1875 /**
1876  * g_file_copy:
1877  * @source: input #GFile.
1878  * @destination: destination #GFile
1879  * @flags: set of #GFileCopyFlags
1880  * @cancellable: optional #GCancellable object, %NULL to ignore.
1881  * @progress_callback: function to callback with progress information
1882  * @progress_callback_data: userdata to pass to @progress_callback
1883  * @error: #GError to set on error, or %NULL
1884  * 
1885  * <!-- Source Friendly Version
1886  * List of possible errors resulting from g_file_copy():
1887  * source    dest    flags   res
1888  *  -        *       *       G_IO_ERROR_NOT_FOUND
1889  *  file     -       *       ok
1890  *  file     *       0       G_IO_ERROR_EXISTS
1891  *  file     file    overwr  ok
1892  *  file     dir     overwr  G_IO_ERROR_IS_DIRECTORY
1893  *  
1894  *  dir      -       *       G_IO_ERROR_WOULD_RECURSE
1895  *  dir      *       0       G_IO_ERROR_EXISTS
1896  *  dir      dir     overwr  G_IO_ERROR_WOULD_MERGE
1897  *  dir      file    overwr  G_IO_ERROR_WOULD_RECURSE
1898  * Docbook version below -->
1899  * 
1900  * Copies a file or directory from @source to @destination, with the given 
1901  * @flags. This operation may fail, and @error will be set appropriately with 
1902  * the given error result (see the following table). 
1903  * File copies are always asynchronous. 
1904  * 
1905  * If @cancellable is not %NULL, then the operation can be cancelled by
1906  * triggering the cancellable object from another thread. If the operation
1907  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
1908  * 
1909  * If @progress_callback is not %NULL, then the operation can be monitored by
1910  * setting this to a #GFileProgressCallback function. @progress_callback_data
1911  * will be passed to this function.
1912  * 
1913  * <table>
1914  * <title>g_file_copy() Error Conditions</title>
1915  * <tgroup cols='4' align='left'><thead>
1916  * <row><entry>Source</entry><entry>Destination</entry><entry>Flags</entry><entry>Results in</entry></row>
1917  * </thead><tbody>
1918  * <row><entry>%NULL</entry><entry>Anything</entry><entry>Anything</entry><entry>%G_IO_ERROR_NOT_FOUND</entry></row>
1919  * <row><entry>File</entry><entry>%NULL</entry><entry>Anything</entry><entry>No Error</entry></row>
1920  * <row><entry>File</entry><entry>Anything</entry><entry>0</entry><entry>%G_IO_ERROR_EXISTS</entry></row>
1921  * <row><entry>File</entry><entry>File</entry><entry>%G_FILE_COPY_OVERWRITE</entry><entry>No Error</entry></row>
1922  * <row><entry>File</entry><entry>Directory</entry><entry>%G_FILE_COPY_OVERWRITE</entry><entry>%G_IO_ERROR_IS_DIRECTORY</entry></row>
1923  * <row><entry>Directory</entry><entry>%NULL</entry><entry>Anything</entry><entry>%G_IO_ERROR_WOULD_RECURSE</entry></row>
1924  * <row><entry>Directory</entry><entry>Anything</entry><entry>0</entry><entry>%G_IO_ERROR_EXISTS</entry></row>
1925  * <row><entry>Directory</entry><entry>Directory</entry><entry>%G_FILE_COPY_OVERWRITE</entry><entry>%G_IO_ERROR_IS_DIRECTORY</entry></row>
1926  * <row><entry>Directory</entry><entry>File</entry><entry>%G_FILE_COPY_OVERWRITE</entry><entry>%G_IO_ERROR_WOULD_RECURSE</entry></row>
1927  * </tbody>
1928  * </tgroup>
1929  * </table>
1930  *
1931  * If you are interested in copying the #GFile object itself (not the on-disk
1932  * file), see g_file_dup().
1933  *
1934  * Returns: %TRUE on success, %FALSE otherwise.
1935  **/
1936 gboolean
1937 g_file_copy (GFile                  *source,
1938              GFile                  *destination,
1939              GFileCopyFlags          flags,
1940              GCancellable           *cancellable,
1941              GFileProgressCallback   progress_callback,
1942              gpointer                progress_callback_data,
1943              GError                **error)
1944 {
1945   GFileIface *iface;
1946   GError *my_error;
1947   gboolean res;
1948
1949   g_return_val_if_fail (G_IS_FILE (source), FALSE);
1950   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
1951
1952   if (g_cancellable_set_error_if_cancelled (cancellable, error))
1953     return FALSE;
1954   
1955   if (G_OBJECT_TYPE (source) == G_OBJECT_TYPE (destination))
1956     {
1957       iface = G_FILE_GET_IFACE (source);
1958
1959       if (iface->copy)
1960         {
1961           my_error = NULL;
1962           res = (* iface->copy) (source, destination, flags, cancellable, progress_callback, progress_callback_data, &my_error);
1963           
1964           if (res)
1965             return TRUE;
1966           
1967           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
1968             {
1969               g_propagate_error (error, my_error);
1970               return FALSE;
1971             }
1972         }
1973     }
1974
1975   return file_copy_fallback (source, destination, flags, cancellable,
1976                              progress_callback, progress_callback_data,
1977                              error);
1978 }
1979
1980
1981 /**
1982  * g_file_move:
1983  * @source: #GFile pointing to the source location.
1984  * @destination: #GFile pointing to the destination location.
1985  * @flags: set of #GFileCopyFlags.
1986  * @cancellable: optional #GCancellable object, %NULL to ignore.
1987  * @progress_callback: #GFileProgressCallback function for updates.
1988  * @progress_callback_data: gpointer to user data for the callback function.
1989  * @error: #GError for returning error conditions, or %NULL
1990  *
1991  * <!-- Source version
1992  * source   dest    flags   results in
1993  * -        *       *       G_IO_ERROR_NOT_FOUND
1994  * file     -       *       ok
1995  * file     *       0       G_IO_ERROR_EXISTS
1996  * file     file    overwr  ok
1997  * file     dir     overwr  G_IO_ERROR_IS_DIRECTORY
1998  * 
1999  * dir      -       *       ok || G_IO_ERROR_WOULD_RECURSE
2000  * dir      *       0       G_IO_ERROR_EXISTS
2001  * dir      dir     overwr  G_IO_ERROR_WOULD_MERGE
2002  * dir      file    overwr  ok || G_IO_ERROR_WOULD_RECURSE
2003  * Docbook version below -->
2004  *
2005  * Moves a file or directory from @source to @destination, with the given 
2006  * @flags. This operation may fail, and @error will be set appropriately with 
2007  * the given error result (see the following table). 
2008  * File moves are always asynchronous. 
2009  * 
2010  * If @cancellable is not %NULL, then the operation can be cancelled by
2011  * triggering the cancellable object from another thread. If the operation
2012  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2013  * 
2014  * If @progress_callback is not %NULL, then the operation can be monitored by
2015  * setting this to a #GFileProgressCallback function. @progress_callback_data
2016  * will be passed to this function.
2017  *
2018  * <table>
2019  * <title>g_file_move() Error Conditions</title>
2020  * <tgroup cols='4' align='left'><thead>
2021  * <row><entry>Source</entry><entry>Destination</entry>
2022  * <entry>Flags</entry><entry>Results in</entry></row>
2023  * </thead><tbody>
2024  * <row><entry> %NULL </entry><entry> Anything </entry>
2025  * <entry> Anything </entry><entry> %G_IO_ERROR_NOT_FOUND </entry></row>
2026  * <row><entry> File </entry><entry> %NULL </entry>
2027  * <entry> Anything </entry><entry> No Error </entry></row>
2028  * <row><entry> File </entry><entry> Anything </entry>
2029  * <entry> 0 </entry><entry> %G_IO_ERROR_EXISTS </entry></row>
2030  * <row><entry> File </entry><entry> File </entry>
2031  * <entry> %G_FILE_COPY_OVERWRITE </entry><entry> No Error </entry></row>
2032  * <row><entry> File </entry><entry> Directory </entry>
2033  * <entry> %G_FILE_COPY_OVERWRITE </entry><entry> %G_IO_ERROR_IS_DIRECTORY </entry></row>
2034  * <row><entry> Directory </entry><entry> %NULL </entry>
2035  * <entry> Anything </entry><entry> No Error or %G_IO_ERROR_WOULD_RECURSE </entry></row>
2036  * <row><entry> Directory </entry><entry> Anything </entry>
2037  * <entry> 0 </entry><entry> %G_IO_ERROR_EXISTS </entry></row>
2038  * <row><entry> Directory </entry><entry> Directory </entry>
2039  * <entry> %G_FILE_COPY_OVERWRITE </entry><entry> %G_IO_ERROR_IS_DIRECTORY </entry></row>
2040  * <row><entry> Directory </entry><entry> File </entry>
2041  * <entry> %G_FILE_COPY_OVERWRITE </entry><entry> No Error or %G_IO_ERROR_WOULD_RECURSE </entry></row>
2042  * </tbody>
2043  * </tgroup>
2044  * </table>
2045  *
2046  * Returns: %TRUE on successful move, %FALSE otherwise.
2047  **/
2048 gboolean
2049 g_file_move (GFile                  *source,
2050              GFile                  *destination,
2051              GFileCopyFlags          flags,
2052              GCancellable           *cancellable,
2053              GFileProgressCallback   progress_callback,
2054              gpointer                progress_callback_data,
2055              GError                **error)
2056 {
2057   GFileIface *iface;
2058   GError *my_error;
2059   gboolean res;
2060
2061   g_return_val_if_fail (G_IS_FILE (source), FALSE);
2062   g_return_val_if_fail (G_IS_FILE (destination), FALSE);
2063
2064   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2065     return FALSE;
2066   
2067   if (G_OBJECT_TYPE (source) == G_OBJECT_TYPE (destination))
2068     {
2069       iface = G_FILE_GET_IFACE (source);
2070
2071       if (iface->move)
2072         {
2073           my_error = NULL;
2074           res = (* iface->move) (source, destination, flags, cancellable, progress_callback, progress_callback_data, &my_error);
2075           
2076           if (res)
2077             return TRUE;
2078           
2079           if (my_error->domain != G_IO_ERROR || my_error->code != G_IO_ERROR_NOT_SUPPORTED)
2080             {
2081               g_propagate_error (error, my_error);
2082               return FALSE;
2083             }
2084         }
2085     }
2086
2087   if (flags & G_FILE_COPY_NO_FALLBACK_FOR_MOVE)
2088     {  
2089       g_set_error (error, G_IO_ERROR,
2090                    G_IO_ERROR_NOT_SUPPORTED,
2091                    _("Operation not supported"));
2092       return FALSE;
2093     }
2094   
2095   flags |= G_FILE_COPY_ALL_METADATA;
2096   if (!g_file_copy (source, destination, flags, cancellable,
2097                     progress_callback, progress_callback_data,
2098                     error))
2099     return FALSE;
2100
2101   return g_file_delete (source, cancellable, error);
2102 }
2103
2104 /**
2105  * g_file_make_directory
2106  * @file: input #GFile.
2107  * @cancellable: optional #GCancellable object, %NULL to ignore.
2108  * @error: a #GError, or %NULL 
2109  *
2110  * Creates a directory.
2111  * 
2112  * If @cancellable is not %NULL, then the operation can be cancelled by
2113  * triggering the cancellable object from another thread. If the operation
2114  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2115  * 
2116  * Returns: %TRUE on successful creation, %FALSE otherwise.
2117  **/
2118 gboolean
2119 g_file_make_directory (GFile         *file,
2120                        GCancellable  *cancellable,
2121                        GError       **error)
2122 {
2123   GFileIface *iface;
2124
2125   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2126
2127   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2128     return FALSE;
2129   
2130   iface = G_FILE_GET_IFACE (file);
2131
2132   if (iface->make_directory == NULL)
2133     {
2134       g_set_error (error, G_IO_ERROR,
2135                    G_IO_ERROR_NOT_SUPPORTED,
2136                    _("Operation not supported"));
2137       return FALSE;
2138     }
2139   
2140   return (* iface->make_directory) (file, cancellable, error);
2141 }
2142
2143 /**
2144  * g_file_make_symbolic_link:
2145  * @file: input #GFile.
2146  * @symlink_value: a string with the name of the new symlink.
2147  * @cancellable: optional #GCancellable object, %NULL to ignore.
2148  * @error: a #GError. 
2149  * 
2150  * Creates a symbolic link.
2151  *
2152  * If @cancellable is not %NULL, then the operation can be cancelled by
2153  * triggering the cancellable object from another thread. If the operation
2154  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2155  * 
2156  * Returns: %TRUE on the creation of a new symlink, %FALSE otherwise.
2157  **/
2158 gboolean
2159 g_file_make_symbolic_link (GFile         *file,
2160                            const char    *symlink_value,
2161                            GCancellable  *cancellable,
2162                            GError       **error)
2163 {
2164   GFileIface *iface;
2165
2166   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2167   g_return_val_if_fail (symlink_value != NULL, FALSE);
2168
2169   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2170     return FALSE;
2171
2172   if (*symlink_value == '\0')
2173     {
2174       g_set_error (error, G_IO_ERROR,
2175                    G_IO_ERROR_INVALID_ARGUMENT,
2176                    _("Invalid symlink value given"));
2177       return FALSE;
2178     }
2179   
2180   iface = G_FILE_GET_IFACE (file);
2181
2182   if (iface->make_symbolic_link == NULL)
2183     {
2184       g_set_error (error, G_IO_ERROR,
2185                    G_IO_ERROR_NOT_SUPPORTED,
2186                    _("Operation not supported"));
2187       return FALSE;
2188     }
2189   
2190   return (* iface->make_symbolic_link) (file, symlink_value, cancellable, error);
2191 }
2192
2193 /**
2194  * g_file_delete:
2195  * @file: input #GFile.
2196  * @cancellable: optional #GCancellable object, %NULL to ignore.
2197  * @error: a #GError, or %NULL 
2198  * 
2199  * Deletes a file.
2200  * 
2201  * If @cancellable is not %NULL, then the operation can be cancelled by
2202  * triggering the cancellable object from another thread. If the operation
2203  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2204  * 
2205  * Returns: %TRUE if the file was deleted. %FALSE otherwise.
2206  **/
2207 gboolean
2208 g_file_delete (GFile         *file,
2209                GCancellable  *cancellable,
2210                GError       **error)
2211 {
2212   GFileIface *iface;
2213   
2214   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2215
2216   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2217     return FALSE;
2218   
2219   iface = G_FILE_GET_IFACE (file);
2220
2221   if (iface->delete_file == NULL)
2222     {
2223       g_set_error (error, G_IO_ERROR,
2224                    G_IO_ERROR_NOT_SUPPORTED,
2225                    _("Operation not supported"));
2226       return FALSE;
2227     }
2228   
2229   return (* iface->delete_file) (file, cancellable, error);
2230 }
2231
2232 /**
2233  * g_file_trash:
2234  * @file: #GFile to send to trash.
2235  * @cancellable: optional #GCancellable object, %NULL to ignore.
2236  * @error: a #GError, or %NULL
2237  *
2238  * Sends @file to the virtual file system "Trash" location. If the
2239  * virtual file system does not have support having a "Trash" location, 
2240  * %FALSE will be returned, and @error will be set to 
2241  * %G_IO_ERROR_NOT_SUPPORTED. 
2242  *
2243  * If @cancellable is not %NULL, then the operation can be cancelled by
2244  * triggering the cancellable object from another thread. If the operation
2245  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2246  * 
2247  * Returns: %TRUE on successful trash, %FALSE otherwise.
2248  **/
2249 gboolean
2250 g_file_trash (GFile         *file,
2251               GCancellable  *cancellable,
2252               GError       **error)
2253 {
2254   GFileIface *iface;
2255   
2256   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2257
2258   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2259     return FALSE;
2260   
2261   iface = G_FILE_GET_IFACE (file);
2262
2263   if (iface->trash == NULL)
2264     {
2265       g_set_error (error,
2266                    G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
2267                    _("Trash not supported"));
2268       return FALSE;
2269     }
2270   
2271   return (* iface->trash) (file, cancellable, error);
2272 }
2273
2274 /**
2275  * g_file_set_display_name:
2276  * @file: input #GFile.
2277  * @display_name: a string.
2278  * @cancellable: optional #GCancellable object, %NULL to ignore.
2279  * @error: a #GError, or %NULL
2280  * 
2281  * Sets the display name for @file. If the display name contains invalid
2282  * characters, @error will be set to %G_IO_ERROR_INVALID_ARGUMENT. For the 
2283  * asynchronous version of this function, see g_file_set_display_name_async().
2284  * 
2285  * If @cancellable is not %NULL, then the operation can be cancelled by
2286  * triggering the cancellable object from another thread. If the operation
2287  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2288  * 
2289  * Returns: a #GFile, or %NULL if there was an error.
2290  **/
2291 GFile *
2292 g_file_set_display_name (GFile         *file,
2293                          const char    *display_name,
2294                          GCancellable  *cancellable,
2295                          GError       **error)
2296 {
2297   GFileIface *iface;
2298   
2299   g_return_val_if_fail (G_IS_FILE (file), NULL);
2300   g_return_val_if_fail (display_name != NULL, NULL);
2301
2302   if (strchr (display_name, '/') != NULL)
2303     {
2304       g_set_error (error,
2305                    G_IO_ERROR,
2306                    G_IO_ERROR_INVALID_ARGUMENT,
2307                    _("File names cannot contain '/'"));
2308       return NULL;
2309     }
2310   
2311   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2312     return NULL;
2313   
2314   iface = G_FILE_GET_IFACE (file);
2315
2316   return (* iface->set_display_name) (file, display_name, cancellable, error);
2317 }
2318
2319 /**
2320  * g_file_set_display_name_async:
2321  * @file: input #GFile.
2322  * @display_name: a string.
2323  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2324  *     of the request. 
2325  * @cancellable: optional #GCancellable object, %NULL to ignore.
2326  * @callback: a #GAsyncReadyCallback. 
2327  * @user_data: a #gpointer. 
2328  * 
2329  * Asynchronously sets the display name for a given #GFile.
2330  * For the synchronous version of this function, see g_file_set_display_name().
2331  * 
2332  * If @cancellable is not %NULL, then the operation can be cancelled by
2333  * triggering the cancellable object from another thread. If the operation
2334  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2335  **/
2336 void
2337 g_file_set_display_name_async (GFile               *file,
2338                                const char          *display_name,
2339                                int                  io_priority,
2340                                GCancellable        *cancellable,
2341                                GAsyncReadyCallback  callback,
2342                                gpointer             user_data)
2343 {
2344   GFileIface *iface;
2345   
2346   g_return_if_fail (G_IS_FILE (file));
2347   g_return_if_fail (display_name != NULL);
2348
2349   iface = G_FILE_GET_IFACE (file);
2350   (* iface->set_display_name_async) (file,
2351                                      display_name,
2352                                      io_priority,
2353                                      cancellable,
2354                                      callback,
2355                                      user_data);
2356 }
2357
2358 /**
2359  * g_file_set_display_name_finish:
2360  * @file: input #GFile.
2361  * @res: a #GAsyncResult. 
2362  * @error: a #GError, or %NULL
2363  * 
2364  * Finishes setting a display name started with 
2365  * g_file_set_display_name_async().
2366  * 
2367  * Returns: a #GFile or %NULL on error.
2368  **/
2369 GFile *
2370 g_file_set_display_name_finish (GFile         *file,
2371                                 GAsyncResult  *res,
2372                                 GError       **error)
2373 {
2374   GFileIface *iface;
2375   
2376   g_return_val_if_fail (G_IS_FILE (file), NULL);
2377   g_return_val_if_fail (G_IS_ASYNC_RESULT (res), NULL);
2378
2379   if (G_IS_SIMPLE_ASYNC_RESULT (res))
2380     {
2381       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
2382       if (g_simple_async_result_propagate_error (simple, error))
2383         return NULL;
2384     }
2385   
2386   iface = G_FILE_GET_IFACE (file);
2387   return (* iface->set_display_name_finish) (file, res, error);
2388 }
2389
2390 /**
2391  * g_file_query_settable_attributes:
2392  * @file: input #GFile.
2393  * @cancellable: optional #GCancellable object, %NULL to ignore.
2394  * @error: a #GError, or %NULL
2395  * 
2396  * Obtain the list of settable attributes for the file.
2397  *
2398  * If @cancellable is not %NULL, then the operation can be cancelled by
2399  * triggering the cancellable object from another thread. If the operation
2400  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2401  * 
2402  * Returns: the type and full attribute name of all the attributes 
2403  *     that the file can set. This doesn't mean setting it will always 
2404  *     succeed though, you might get an access failure, or some specific 
2405  *     file may not support a specific attribute.
2406  **/
2407 GFileAttributeInfoList *
2408 g_file_query_settable_attributes (GFile         *file,
2409                                   GCancellable  *cancellable,
2410                                   GError       **error)
2411 {
2412   GFileIface *iface;
2413   GError *my_error;
2414   GFileAttributeInfoList *list;
2415
2416   g_return_val_if_fail (G_IS_FILE (file), NULL);
2417
2418   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2419     return NULL;
2420   
2421   iface = G_FILE_GET_IFACE (file);
2422
2423   if (iface->query_settable_attributes == NULL)
2424     return g_file_attribute_info_list_new ();
2425
2426   my_error = NULL;
2427   list = (* iface->query_settable_attributes) (file, cancellable, &my_error);
2428   
2429   if (list == NULL)
2430     {
2431       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
2432         {
2433           list = g_file_attribute_info_list_new ();
2434           g_error_free (my_error);
2435         }
2436       else
2437         g_propagate_error (error, my_error);
2438     }
2439   
2440   return list;
2441 }
2442
2443 /**
2444  * g_file_query_writable_namespaces:
2445  * @file: input #GFile.
2446  * @cancellable: optional #GCancellable object, %NULL to ignore.
2447  * @error: a #GError, or %NULL
2448  * 
2449  * Obtain the list of attribute namespaces where new attributes 
2450  * can be created.
2451  *
2452  * If @cancellable is not %NULL, then the operation can be cancelled by
2453  * triggering the cancellable object from another thread. If the operation
2454  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2455  * 
2456  * Returns: a #GFileAttributeInfoList of attribute namespaces 
2457  *     where the user can create their own attribute names, such 
2458  *     as extended attributes.
2459  **/
2460 GFileAttributeInfoList *
2461 g_file_query_writable_namespaces (GFile         *file,
2462                                   GCancellable  *cancellable,
2463                                   GError       **error)
2464 {
2465   GFileIface *iface;
2466   GError *my_error;
2467   GFileAttributeInfoList *list;
2468   
2469   g_return_val_if_fail (G_IS_FILE (file), NULL);
2470
2471   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2472     return NULL;
2473   
2474   iface = G_FILE_GET_IFACE (file);
2475
2476   if (iface->query_writable_namespaces == NULL)
2477     return g_file_attribute_info_list_new ();
2478
2479   my_error = NULL;
2480   list = (* iface->query_writable_namespaces) (file, cancellable, &my_error);
2481   
2482   if (list == NULL)
2483     {
2484       if (my_error->domain == G_IO_ERROR && my_error->code == G_IO_ERROR_NOT_SUPPORTED)
2485         {
2486           list = g_file_attribute_info_list_new ();
2487           g_error_free (my_error);
2488         }
2489       else
2490         g_propagate_error (error, my_error);
2491     }
2492   
2493   return list;
2494 }
2495
2496 /**
2497  * g_file_set_attribute:
2498  * @file: input #GFile.
2499  * @attribute: a string containing the attribute's name.
2500  * @value: a set of #GFileAttributeValue.
2501  * @flags: a set of #GFileQueryInfoFlags.
2502  * @cancellable: optional #GCancellable object, %NULL to ignore.
2503  * @error: a #GError, or %NULL
2504  * 
2505  * Sets an attribute in the file with attribute name @attribute to @value.
2506  * If setting attributes is not suppored by the #GFileIface for @file, 
2507  * then @error will be set to %G_IO_ERROR_NOT_SUPPORTED.
2508  * 
2509  * If @cancellable is not %NULL, then the operation can be cancelled by
2510  * triggering the cancellable object from another thread. If the operation
2511  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2512  * 
2513  * Returns: %TRUE if the attribute was set, %FALSE otherwise.
2514  **/
2515 gboolean
2516 g_file_set_attribute (GFile                      *file,
2517                       const char                 *attribute,
2518                       const GFileAttributeValue  *value,
2519                       GFileQueryInfoFlags         flags,
2520                       GCancellable               *cancellable,
2521                       GError                    **error)
2522 {
2523   GFileIface *iface;
2524   
2525   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2526   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
2527
2528   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2529     return FALSE;
2530   
2531   iface = G_FILE_GET_IFACE (file);
2532
2533   if (iface->set_attribute == NULL)
2534     {
2535       g_set_error (error, G_IO_ERROR,
2536                    G_IO_ERROR_NOT_SUPPORTED,
2537                    _("Operation not supported"));
2538       return FALSE;
2539     }
2540
2541   return (* iface->set_attribute) (file, attribute, value, flags, cancellable, error);
2542 }
2543
2544 /**
2545  * g_file_set_attributes_from_info:
2546  * @file: input #GFile.
2547  * @info: a #GFileInfo.
2548  * @flags: #GFileQueryInfoFlags
2549  * @cancellable: optional #GCancellable object, %NULL to ignore.
2550  * @error: a #GError, or %NULL 
2551  * 
2552  * Tries to set all attributes in the #GFileInfo on the target values, 
2553  * not stopping on the first error.
2554  * 
2555  * If @cancellable is not %NULL, then the operation can be cancelled by
2556  * triggering the cancellable object from another thread. If the operation
2557  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2558  * 
2559  * Returns: %TRUE if there was any error, and @error will be set to
2560  *     the first error. Error on particular fields are flagged by setting 
2561  *     the "status" field in the attribute value to 
2562  *     %G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING.
2563  **/
2564 gboolean
2565 g_file_set_attributes_from_info (GFile                *file,
2566                                  GFileInfo            *info,
2567                                  GFileQueryInfoFlags   flags,
2568                                  GCancellable         *cancellable,
2569                                  GError              **error)
2570 {
2571   GFileIface *iface;
2572
2573   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2574   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
2575
2576   if (g_cancellable_set_error_if_cancelled (cancellable, error))
2577     return FALSE;
2578   
2579   g_file_info_clear_status (info);
2580   
2581   iface = G_FILE_GET_IFACE (file);
2582
2583   return (* iface->set_attributes_from_info) (file, 
2584                                               info, 
2585                                               flags, 
2586                                               cancellable, 
2587                                               error);
2588 }
2589
2590
2591 static gboolean
2592 g_file_real_set_attributes_from_info (GFile                *file,
2593                                       GFileInfo            *info,
2594                                       GFileQueryInfoFlags   flags,
2595                                       GCancellable         *cancellable,
2596                                       GError              **error)
2597 {
2598   char **attributes;
2599   int i;
2600   gboolean res;
2601   GFileAttributeValue *value;
2602   
2603   res = TRUE;
2604   
2605   attributes = g_file_info_list_attributes (info, NULL);
2606
2607   for (i = 0; attributes[i] != NULL; i++)
2608     {
2609       value = (GFileAttributeValue *)g_file_info_get_attribute (info, attributes[i]);
2610
2611       if (value->status != G_FILE_ATTRIBUTE_STATUS_UNSET)
2612         continue;
2613
2614       if (!g_file_set_attribute (file, attributes[i], value, flags, cancellable, error))
2615         {
2616           value->status = G_FILE_ATTRIBUTE_STATUS_ERROR_SETTING;
2617           res = FALSE;
2618           /* Don't set error multiple times */
2619           error = NULL;
2620         }
2621       else
2622         value->status = G_FILE_ATTRIBUTE_STATUS_SET;
2623     }
2624   
2625   g_strfreev (attributes);
2626   
2627   return res;
2628 }
2629
2630 /**
2631  * g_file_set_attributes_async:
2632  * @file: input #GFile.
2633  * @info: a #GFileInfo.
2634  * @flags: a #GFileQueryInfoFlags.
2635  * @io_priority: the <link linkend="io-priority">I/O priority</link> 
2636  *     of the request. 
2637  * @cancellable: optional #GCancellable object, %NULL to ignore.
2638  * @callback: a #GAsyncReadyCallback. 
2639  * @user_data: a #gpointer.
2640  *
2641  * Asynchronously sets the attributes of @file with @info.
2642  * For the synchronous version of this function, see g_file_set_attributes(). 
2643  * 
2644  * If @cancellable is not %NULL, then the operation can be cancelled by
2645  * triggering the cancellable object from another thread. If the operation
2646  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2647  **/
2648 void
2649 g_file_set_attributes_async (GFile               *file,
2650                              GFileInfo           *info,
2651                              GFileQueryInfoFlags  flags,
2652                              int                  io_priority,
2653                              GCancellable        *cancellable,
2654                              GAsyncReadyCallback  callback,
2655                              gpointer             user_data)
2656 {
2657   GFileIface *iface;
2658   
2659   g_return_if_fail (G_IS_FILE (file));
2660   g_return_if_fail (G_IS_FILE_INFO (info));
2661
2662   iface = G_FILE_GET_IFACE (file);
2663   (* iface->set_attributes_async) (file, 
2664                                    info, 
2665                                    flags, 
2666                                    io_priority, 
2667                                    cancellable, 
2668                                    callback, 
2669                                    user_data);
2670 }
2671
2672 /**
2673  * g_file_set_attributes_finish:
2674  * @file: input #GFile.
2675  * @result: a #GAsyncResult.
2676  * @info: a #GFileInfo.
2677  * @error: a #GError, or %NULL
2678  * 
2679  * Finishes setting an attribute started in g_file_set_attributes_async().
2680  * 
2681  * Returns: %TRUE if the attributes were set correctly, %FALSE otherwise.
2682  **/
2683 gboolean
2684 g_file_set_attributes_finish (GFile         *file,
2685                               GAsyncResult  *result,
2686                               GFileInfo    **info,
2687                               GError       **error)
2688 {
2689   GFileIface *iface;
2690   
2691   g_return_val_if_fail (G_IS_FILE (file), FALSE);
2692   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
2693
2694   /* No standard handling of errors here, as we must set info even
2695    * on errors 
2696    */
2697   iface = G_FILE_GET_IFACE (file);
2698   return (* iface->set_attributes_finish) (file, result, info, error);
2699 }
2700
2701 /**
2702  * g_file_set_attribute_string:
2703  * @file: input #GFile.
2704  * @attribute: a string containing the attribute's name.
2705  * @value: a string containing the attribute's value.
2706  * @flags: #GFileQueryInfoFlags.
2707  * @cancellable: optional #GCancellable object, %NULL to ignore.
2708  * @error: a #GError, or %NULL
2709  * 
2710  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_STRING to @value. 
2711  * If @attribute is of a different type, this operation will fail.
2712  * 
2713  * If @cancellable is not %NULL, then the operation can be cancelled by
2714  * triggering the cancellable object from another thread. If the operation
2715  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2716  * 
2717  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
2718  **/
2719 gboolean
2720 g_file_set_attribute_string (GFile                *file,
2721                              const char           *attribute,
2722                              const char           *value,
2723                              GFileQueryInfoFlags   flags,
2724                              GCancellable         *cancellable,
2725                              GError              **error)
2726 {
2727   GFileAttributeValue v;
2728
2729   v.type = G_FILE_ATTRIBUTE_TYPE_STRING;
2730   v.u.string = (char *)value;
2731   return g_file_set_attribute (file, attribute, &v, flags, cancellable, error);
2732 }
2733
2734 /**
2735  * g_file_set_attribute_byte_string:
2736  * @file: input #GFile.
2737  * @attribute: a string containing the attribute's name.
2738  * @value: a string containing the attribute's new value.
2739  * @flags: a #GFileQueryInfoFlags.
2740  * @cancellable: optional #GCancellable object, %NULL to ignore.
2741  * @error: a #GError, or %NULL
2742  * 
2743  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_BYTE_STRING to @value. 
2744  * If @attribute is of a different type, this operation will fail, 
2745  * returning %FALSE. 
2746  * 
2747  * If @cancellable is not %NULL, then the operation can be cancelled by
2748  * triggering the cancellable object from another thread. If the operation
2749  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2750  * 
2751  * Returns: %TRUE if the @attribute was successfully set to @value 
2752  * in the @file, %FALSE otherwise.
2753  **/
2754 gboolean
2755 g_file_set_attribute_byte_string  (GFile                *file,
2756                                    const char           *attribute,
2757                                    const char           *value,
2758                                    GFileQueryInfoFlags   flags,
2759                                    GCancellable         *cancellable,
2760                                    GError              **error)
2761 {
2762   GFileAttributeValue v;
2763
2764   v.type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING;
2765   v.u.string = (char *)value;
2766   return g_file_set_attribute (file, attribute, &v, flags, cancellable, error);
2767 }
2768
2769 /**
2770  * g_file_set_attribute_uint32:
2771  * @file: input #GFile.
2772  * @attribute: a string containing the attribute's name.
2773  * @value: a #guint32 containing the attribute's new value.
2774  * @flags: a #GFileQueryInfoFlags.
2775  * @cancellable: optional #GCancellable object, %NULL to ignore.
2776  * @error: a #GError, or %NULL
2777  * 
2778  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT32 to @value. 
2779  * If @attribute is of a different type, this operation will fail.
2780  * 
2781  * If @cancellable is not %NULL, then the operation can be cancelled by
2782  * triggering the cancellable object from another thread. If the operation
2783  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2784  * 
2785  * Returns: %TRUE if the @attribute was successfully set to @value 
2786  * in the @file, %FALSE otherwise.
2787  **/
2788 gboolean
2789 g_file_set_attribute_uint32 (GFile                *file,
2790                              const char           *attribute,
2791                              guint32               value,
2792                              GFileQueryInfoFlags   flags,
2793                              GCancellable         *cancellable,
2794                              GError              **error)
2795 {
2796   GFileAttributeValue v;
2797
2798   v.type = G_FILE_ATTRIBUTE_TYPE_UINT32;
2799   v.u.uint32 = value;
2800   return g_file_set_attribute (file, attribute, &v, flags, cancellable, error);
2801 }
2802
2803 /**
2804  * g_file_set_attribute_int32:
2805  * @file: input #GFile.
2806  * @attribute: a string containing the attribute's name.
2807  * @value: a #gint32 containing the attribute's new value.
2808  * @flags: a #GFileQueryInfoFlags.
2809  * @cancellable: optional #GCancellable object, %NULL to ignore.
2810  * @error: a #GError, or %NULL
2811  * 
2812  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT32 to @value. 
2813  * If @attribute is of a different type, this operation will fail.
2814  * 
2815  * If @cancellable is not %NULL, then the operation can be cancelled by
2816  * triggering the cancellable object from another thread. If the operation
2817  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2818  * 
2819  * Returns: %TRUE if the @attribute was successfully set to @value 
2820  * in the @file, %FALSE otherwise. 
2821  **/
2822 gboolean
2823 g_file_set_attribute_int32 (GFile                *file,
2824                             const char           *attribute,
2825                             gint32                value,
2826                             GFileQueryInfoFlags   flags,
2827                             GCancellable         *cancellable,
2828                             GError              **error)
2829 {
2830   GFileAttributeValue v;
2831
2832   v.type = G_FILE_ATTRIBUTE_TYPE_INT32;
2833   v.u.int32 = value;
2834   return g_file_set_attribute (file, attribute, &v, flags, cancellable, error);
2835 }
2836
2837 /**
2838  * g_file_set_attribute_uint64:
2839  * @file: input #GFile. 
2840  * @attribute: a string containing the attribute's name.
2841  * @value: a #guint64 containing the attribute's new value.
2842  * @flags: a #GFileQueryInfoFlags.
2843  * @cancellable: optional #GCancellable object, %NULL to ignore.
2844  * @error: a #GError, or %NULL
2845  * 
2846  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_UINT64 to @value. 
2847  * If @attribute is of a different type, this operation will fail.
2848  * 
2849  * If @cancellable is not %NULL, then the operation can be cancelled by
2850  * triggering the cancellable object from another thread. If the operation
2851  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2852  * 
2853  * Returns: %TRUE if the @attribute was successfully set to @value 
2854  * in the @file, %FALSE otherwise.
2855  **/
2856 gboolean
2857 g_file_set_attribute_uint64 (GFile                *file,
2858                              const char           *attribute,
2859                              guint64               value,
2860                              GFileQueryInfoFlags   flags,
2861                              GCancellable         *cancellable,
2862                              GError              **error)
2863  {
2864   GFileAttributeValue v;
2865
2866   v.type = G_FILE_ATTRIBUTE_TYPE_UINT64;
2867   v.u.uint64 = value;
2868   return g_file_set_attribute (file, attribute, &v, flags, cancellable, error);
2869 }
2870
2871 /**
2872  * g_file_set_attribute_int64:
2873  * @file: input #GFile.
2874  * @attribute: a string containing the attribute's name.
2875  * @value: a #guint64 containing the attribute's new value.
2876  * @flags: a #GFileQueryInfoFlags.
2877  * @cancellable: optional #GCancellable object, %NULL to ignore.
2878  * @error: a #GError, or %NULL
2879  * 
2880  * Sets @attribute of type %G_FILE_ATTRIBUTE_TYPE_INT64 to @value. 
2881  * If @attribute is of a different type, this operation will fail.
2882  * 
2883  * If @cancellable is not %NULL, then the operation can be cancelled by
2884  * triggering the cancellable object from another thread. If the operation
2885  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2886  * 
2887  * Returns: %TRUE if the @attribute was successfully set, %FALSE otherwise.
2888  **/
2889 gboolean
2890 g_file_set_attribute_int64 (GFile                *file,
2891                             const char           *attribute,
2892                             gint64                value,
2893                             GFileQueryInfoFlags   flags,
2894                             GCancellable         *cancellable,
2895                             GError              **error)
2896 {
2897  GFileAttributeValue v;
2898
2899   v.type = G_FILE_ATTRIBUTE_TYPE_INT64;
2900   v.u.int64 = value;
2901   return g_file_set_attribute (file, attribute, &v, flags, cancellable, error);
2902 }
2903
2904 /**
2905  * g_file_mount_mountable:
2906  * @file: input #GFile.
2907  * @mount_operation: a #GMountOperation.
2908  * @cancellable: optional #GCancellable object, %NULL to ignore.
2909  * @callback: a #GAsyncReadyCallback. 
2910  * @user_data: a #gpointer. 
2911  * 
2912  * Mounts a mountable file using @mount_operation, if possible. 
2913  *
2914  * If @cancellable is not %NULL, then the operation can be cancelled by
2915  * triggering the cancellable object from another thread. If the operation
2916  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2917  **/
2918 void
2919 g_file_mount_mountable (GFile               *file,
2920                         GMountOperation     *mount_operation,
2921                         GCancellable        *cancellable,
2922                         GAsyncReadyCallback  callback,
2923                         gpointer             user_data)
2924 {
2925   GFileIface *iface;
2926
2927   g_return_if_fail (G_IS_FILE (file));
2928   g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
2929
2930   iface = G_FILE_GET_IFACE (file);
2931
2932   if (iface->mount_mountable == NULL)
2933     g_simple_async_report_error_in_idle (G_OBJECT (file),
2934                                          callback,
2935                                          user_data,
2936                                          G_IO_ERROR,
2937                                          G_IO_ERROR_NOT_SUPPORTED,
2938                                          _("Operation not supported"));
2939   
2940   (* iface->mount_mountable) (file,
2941                               mount_operation,
2942                               cancellable,
2943                               callback,
2944                               user_data);
2945 }
2946
2947 /**
2948  * g_file_mount_mountable_finish:
2949  * @file: input #GFile.
2950  * @result: a #GAsyncResult.
2951  * @error: a #GError, or %NULL
2952  *
2953  * Finishes a mount operation. See g_file_mount_mountable() for details.
2954  * 
2955  * Finish an asynchronous mount operation that was started 
2956  * with g_file_mount_mountable().
2957  *
2958  * Returns: a #GFile or %NULL on error.
2959  **/
2960 GFile *
2961 g_file_mount_mountable_finish (GFile         *file,
2962                                GAsyncResult  *result,
2963                                GError       **error)
2964 {
2965   GFileIface *iface;
2966
2967   g_return_val_if_fail (G_IS_FILE (file), NULL);
2968   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), NULL);
2969
2970   if (G_IS_SIMPLE_ASYNC_RESULT (result))
2971     {
2972       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
2973       if (g_simple_async_result_propagate_error (simple, error))
2974         return NULL;
2975     }
2976   
2977   iface = G_FILE_GET_IFACE (file);
2978   return (* iface->mount_mountable_finish) (file, result, error);
2979 }
2980
2981 /**
2982  * g_file_unmount_mountable:
2983  * @file: input #GFile.
2984  * @cancellable: optional #GCancellable object, %NULL to ignore.
2985  * @callback: a #GAsyncReadyCallback. 
2986  * @user_data: a #gpointer. 
2987  *
2988  * Starts an asynchronous unmount operation. 
2989  * 
2990  * Unmounts a mounted file.
2991  *
2992  * If @cancellable is not %NULL, then the operation can be cancelled by
2993  * triggering the cancellable object from another thread. If the operation
2994  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
2995  **/
2996 void
2997 g_file_unmount_mountable (GFile               *file,
2998                           GCancellable        *cancellable,
2999                           GAsyncReadyCallback  callback,
3000                           gpointer             user_data)
3001 {
3002   GFileIface *iface;
3003   
3004   g_return_if_fail (G_IS_FILE (file));
3005
3006   iface = G_FILE_GET_IFACE (file);
3007   
3008   if (iface->unmount_mountable == NULL)
3009     g_simple_async_report_error_in_idle (G_OBJECT (file),
3010                                          callback,
3011                                          user_data,
3012                                          G_IO_ERROR,
3013                                          G_IO_ERROR_NOT_SUPPORTED,
3014                                          _("Operation not supported"));
3015   
3016   (* iface->unmount_mountable) (file,
3017                                 cancellable,
3018                                 callback,
3019                                 user_data);
3020 }
3021
3022 /**
3023  * g_file_unmount_mountable_finish:
3024  * @file: input #GFile.
3025  * @result: a #GAsyncResult.
3026  * @error: a #GError, or %NULL
3027  *
3028  * Finishes an unmount operation, see g_file_unmount_mountable() for details.
3029  * 
3030  * Finish an asynchronous unmount operation that was started 
3031  * with g_file_unmount_mountable().
3032  *
3033  * Returns: %TRUE if the operation finished successfully. %FALSE
3034  * otherwise.
3035  **/
3036 gboolean
3037 g_file_unmount_mountable_finish (GFile         *file,
3038                                  GAsyncResult  *result,
3039                                  GError       **error)
3040 {
3041   GFileIface *iface;
3042   
3043   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3044   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3045
3046   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3047     {
3048       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3049       if (g_simple_async_result_propagate_error (simple, error))
3050         return FALSE;
3051     }
3052   
3053   iface = G_FILE_GET_IFACE (file);
3054   return (* iface->unmount_mountable_finish) (file, result, error);
3055 }
3056
3057 /**
3058  * g_file_eject_mountable:
3059  * @file: input #GFile.
3060  * @cancellable: optional #GCancellable object, %NULL to ignore.
3061  * @callback: a #GAsyncReadyCallback. 
3062  * @user_data: a #gpointer. 
3063  * 
3064  * Starts an asynchronous eject on a mountable.  
3065  * When this operation has completed, @callback will be called with
3066  * @user_user data, and the operation can be finalized with 
3067  * g_file_eject_mountable_finish().
3068  * 
3069  * If @cancellable is not %NULL, then the operation can be cancelled by
3070  * triggering the cancellable object from another thread. If the operation
3071  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3072  **/
3073 void
3074 g_file_eject_mountable (GFile               *file,
3075                         GCancellable        *cancellable,
3076                         GAsyncReadyCallback  callback,
3077                         gpointer             user_data)
3078 {
3079   GFileIface *iface;
3080
3081   g_return_if_fail (G_IS_FILE (file));
3082
3083   iface = G_FILE_GET_IFACE (file);
3084   
3085   if (iface->eject_mountable == NULL)
3086     g_simple_async_report_error_in_idle (G_OBJECT (file),
3087                                          callback,
3088                                          user_data,
3089                                          G_IO_ERROR,
3090                                          G_IO_ERROR_NOT_SUPPORTED,
3091                                          _("Operation not supported"));
3092   
3093   (* iface->eject_mountable) (file,
3094                               cancellable,
3095                               callback,
3096                               user_data);
3097 }
3098
3099 /**
3100  * g_file_eject_mountable_finish:
3101  * @file: input #GFile.
3102  * @result: a #GAsyncResult.
3103  * @error: a #GError, or %NULL
3104  * 
3105  * Finishes an asynchronous eject operation started by 
3106  * g_file_eject_mountable().
3107  * 
3108  * Returns: %TRUE if the @file was ejected successfully. %FALSE 
3109  * otherwise.
3110  **/
3111 gboolean
3112 g_file_eject_mountable_finish (GFile         *file,
3113                                GAsyncResult  *result,
3114                                GError       **error)
3115 {
3116   GFileIface *iface;
3117   
3118   g_return_val_if_fail (G_IS_FILE (file), FALSE);
3119   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3120
3121   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3122     {
3123       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3124       if (g_simple_async_result_propagate_error (simple, error))
3125         return FALSE;
3126     }
3127   
3128   iface = G_FILE_GET_IFACE (file);
3129   return (* iface->eject_mountable_finish) (file, result, error);
3130 }
3131
3132 /**
3133  * g_file_monitor_directory:
3134  * @file: input #GFile.
3135  * @flags: a set of #GFileMonitorFlags.
3136  * @cancellable: optional #GCancellable object, %NULL to ignore.
3137  * 
3138  * Obtains a directory monitor for the given file.
3139  *
3140  * If @cancellable is not %NULL, then the operation can be cancelled by
3141  * triggering the cancellable object from another thread. If the operation
3142  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3143  * 
3144  * Returns: a #GDirectoryMonitor for the given @file, 
3145  * or %NULL on error.
3146  **/
3147 GDirectoryMonitor*
3148 g_file_monitor_directory (GFile             *file,
3149                           GFileMonitorFlags  flags,
3150                           GCancellable      *cancellable)
3151 {
3152   GFileIface *iface;
3153
3154   g_return_val_if_fail (G_IS_FILE (file), NULL);
3155
3156   iface = G_FILE_GET_IFACE (file);
3157
3158   if (iface->monitor_dir == NULL)
3159     return NULL;
3160
3161   return (* iface->monitor_dir) (file, flags, cancellable);
3162 }
3163
3164 /**
3165  * g_file_monitor_file:
3166  * @file: input #GFile.
3167  * @flags: a set of #GFileMonitorFlags.
3168  * @cancellable: optional #GCancellable object, %NULL to ignore.
3169  * 
3170  * Obtains a file monitor for the given file.
3171  *
3172  * If @cancellable is not %NULL, then the operation can be cancelled by
3173  * triggering the cancellable object from another thread. If the operation
3174  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3175  * 
3176  * Returns: a #GFileMonitor for the given @file, 
3177  * or %NULL on error.
3178  **/
3179 GFileMonitor*
3180 g_file_monitor_file (GFile             *file,
3181                      GFileMonitorFlags  flags,
3182                      GCancellable      *cancellable)
3183 {
3184   GFileIface *iface;
3185   GFileMonitor *monitor;
3186   
3187   g_return_val_if_fail (G_IS_FILE (file), NULL);
3188
3189   iface = G_FILE_GET_IFACE (file);
3190
3191   monitor = NULL;
3192   
3193   if (iface->monitor_file)
3194     monitor = (* iface->monitor_file) (file, flags, cancellable);
3195
3196 /* Fallback to polling */
3197   if (monitor == NULL)
3198     monitor = _g_poll_file_monitor_new (file);
3199
3200   return monitor;
3201 }
3202
3203 /********************************************
3204  *   Default implementation of async ops    *
3205  ********************************************/
3206
3207 typedef struct {
3208   char *attributes;
3209   GFileQueryInfoFlags flags;
3210   GFileInfo *info;
3211 } QueryInfoAsyncData;
3212
3213 static void
3214 query_info_data_free (QueryInfoAsyncData *data)
3215 {
3216   if (data->info)
3217     g_object_unref (data->info);
3218   g_free (data->attributes);
3219   g_free (data);
3220 }
3221
3222 static void
3223 query_info_async_thread (GSimpleAsyncResult *res,
3224                          GObject            *object,
3225                          GCancellable       *cancellable)
3226 {
3227   GError *error = NULL;
3228   QueryInfoAsyncData *data;
3229   GFileInfo *info;
3230   
3231   data = g_simple_async_result_get_op_res_gpointer (res);
3232   
3233   info = g_file_query_info (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3234
3235   if (info == NULL)
3236     {
3237       g_simple_async_result_set_from_error (res, error);
3238       g_error_free (error);
3239     }
3240   else
3241     data->info = info;
3242 }
3243
3244 static void
3245 g_file_real_query_info_async (GFile               *file,
3246                               const char          *attributes,
3247                               GFileQueryInfoFlags  flags,
3248                               int                  io_priority,
3249                               GCancellable        *cancellable,
3250                               GAsyncReadyCallback  callback,
3251                               gpointer             user_data)
3252 {
3253   GSimpleAsyncResult *res;
3254   QueryInfoAsyncData *data;
3255
3256   data = g_new0 (QueryInfoAsyncData, 1);
3257   data->attributes = g_strdup (attributes);
3258   data->flags = flags;
3259   
3260   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_query_info_async);
3261   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)query_info_data_free);
3262   
3263   g_simple_async_result_run_in_thread (res, query_info_async_thread, io_priority, cancellable);
3264   g_object_unref (res);
3265 }
3266
3267 static GFileInfo *
3268 g_file_real_query_info_finish (GFile         *file,
3269                                GAsyncResult  *res,
3270                                GError       **error)
3271 {
3272   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3273   QueryInfoAsyncData *data;
3274
3275   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_query_info_async);
3276
3277   data = g_simple_async_result_get_op_res_gpointer (simple);
3278   if (data->info)
3279     return g_object_ref (data->info);
3280   
3281   return NULL;
3282 }
3283
3284 typedef struct {
3285   char *attributes;
3286   GFileQueryInfoFlags flags;
3287   GFileEnumerator *enumerator;
3288 } EnumerateChildrenAsyncData;
3289
3290 static void
3291 enumerate_children_data_free (EnumerateChildrenAsyncData *data)
3292 {
3293   if (data->enumerator)
3294     g_object_unref (data->enumerator);
3295   g_free (data->attributes);
3296   g_free (data);
3297 }
3298
3299 static void
3300 enumerate_children_async_thread (GSimpleAsyncResult *res,
3301                                  GObject            *object,
3302                                  GCancellable       *cancellable)
3303 {
3304   GError *error = NULL;
3305   EnumerateChildrenAsyncData *data;
3306   GFileEnumerator *enumerator;
3307   
3308   data = g_simple_async_result_get_op_res_gpointer (res);
3309   
3310   enumerator = g_file_enumerate_children (G_FILE (object), data->attributes, data->flags, cancellable, &error);
3311
3312   if (enumerator == NULL)
3313     {
3314       g_simple_async_result_set_from_error (res, error);
3315       g_error_free (error);
3316     }
3317   else
3318     data->enumerator = enumerator;
3319 }
3320
3321 static void
3322 g_file_real_enumerate_children_async (GFile               *file,
3323                                       const char          *attributes,
3324                                       GFileQueryInfoFlags  flags,
3325                                       int                  io_priority,
3326                                       GCancellable        *cancellable,
3327                                       GAsyncReadyCallback  callback,
3328                                       gpointer             user_data)
3329 {
3330   GSimpleAsyncResult *res;
3331   EnumerateChildrenAsyncData *data;
3332
3333   data = g_new0 (EnumerateChildrenAsyncData, 1);
3334   data->attributes = g_strdup (attributes);
3335   data->flags = flags;
3336   
3337   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_enumerate_children_async);
3338   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)enumerate_children_data_free);
3339   
3340   g_simple_async_result_run_in_thread (res, enumerate_children_async_thread, io_priority, cancellable);
3341   g_object_unref (res);
3342 }
3343
3344 static GFileEnumerator *
3345 g_file_real_enumerate_children_finish (GFile         *file,
3346                                        GAsyncResult  *res,
3347                                        GError       **error)
3348 {
3349   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3350   EnumerateChildrenAsyncData *data;
3351
3352   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_enumerate_children_async);
3353
3354   data = g_simple_async_result_get_op_res_gpointer (simple);
3355   if (data->enumerator)
3356     return g_object_ref (data->enumerator);
3357   
3358   return NULL;
3359 }
3360
3361 static void
3362 open_read_async_thread (GSimpleAsyncResult *res,
3363                         GObject            *object,
3364                         GCancellable       *cancellable)
3365 {
3366   GFileIface *iface;
3367   GFileInputStream *stream;
3368   GError *error = NULL;
3369
3370   iface = G_FILE_GET_IFACE (object);
3371
3372   stream = iface->read (G_FILE (object), cancellable, &error);
3373
3374   if (stream == NULL)
3375     {
3376       g_simple_async_result_set_from_error (res, error);
3377       g_error_free (error);
3378     }
3379   else
3380     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
3381 }
3382
3383 static void
3384 g_file_real_read_async (GFile               *file,
3385                         int                  io_priority,
3386                         GCancellable        *cancellable,
3387                         GAsyncReadyCallback  callback,
3388                         gpointer             user_data)
3389 {
3390   GSimpleAsyncResult *res;
3391   
3392   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_read_async);
3393   
3394   g_simple_async_result_run_in_thread (res, open_read_async_thread, io_priority, cancellable);
3395   g_object_unref (res);
3396 }
3397
3398 static GFileInputStream *
3399 g_file_real_read_finish (GFile         *file,
3400                          GAsyncResult  *res,
3401                          GError       **error)
3402 {
3403   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3404   gpointer op;
3405
3406   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_read_async);
3407
3408   op = g_simple_async_result_get_op_res_gpointer (simple);
3409   if (op)
3410     return g_object_ref (op);
3411   
3412   return NULL;
3413 }
3414
3415 static void
3416 append_to_async_thread (GSimpleAsyncResult *res,
3417                         GObject            *object,
3418                         GCancellable       *cancellable)
3419 {
3420   GFileIface *iface;
3421   GFileCreateFlags *data;
3422   GFileOutputStream *stream;
3423   GError *error = NULL;
3424
3425   iface = G_FILE_GET_IFACE (object);
3426
3427   data = g_simple_async_result_get_op_res_gpointer (res);
3428
3429   stream = iface->append_to (G_FILE (object), *data, cancellable, &error);
3430
3431   if (stream == NULL)
3432     {
3433       g_simple_async_result_set_from_error (res, error);
3434       g_error_free (error);
3435     }
3436   else
3437     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
3438 }
3439
3440 static void
3441 g_file_real_append_to_async (GFile               *file,
3442                              GFileCreateFlags     flags,
3443                              int                  io_priority,
3444                              GCancellable        *cancellable,
3445                              GAsyncReadyCallback  callback,
3446                              gpointer             user_data)
3447 {
3448   GFileCreateFlags *data;
3449   GSimpleAsyncResult *res;
3450
3451   data = g_new0 (GFileCreateFlags, 1);
3452   *data = flags;
3453
3454   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_append_to_async);
3455   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
3456
3457   g_simple_async_result_run_in_thread (res, append_to_async_thread, io_priority, cancellable);
3458   g_object_unref (res);
3459 }
3460
3461 static GFileOutputStream *
3462 g_file_real_append_to_finish (GFile         *file,
3463                               GAsyncResult  *res,
3464                               GError       **error)
3465 {
3466   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3467   gpointer op;
3468
3469   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_append_to_async);
3470
3471   op = g_simple_async_result_get_op_res_gpointer (simple);
3472   if (op)
3473     return g_object_ref (op);
3474   
3475   return NULL;
3476 }
3477
3478 static void
3479 create_async_thread (GSimpleAsyncResult *res,
3480                      GObject            *object,
3481                      GCancellable       *cancellable)
3482 {
3483   GFileIface *iface;
3484   GFileCreateFlags *data;
3485   GFileOutputStream *stream;
3486   GError *error = NULL;
3487
3488   iface = G_FILE_GET_IFACE (object);
3489
3490   data = g_simple_async_result_get_op_res_gpointer (res);
3491
3492   stream = iface->create (G_FILE (object), *data, cancellable, &error);
3493
3494   if (stream == NULL)
3495     {
3496       g_simple_async_result_set_from_error (res, error);
3497       g_error_free (error);
3498     }
3499   else
3500     g_simple_async_result_set_op_res_gpointer (res, stream, g_object_unref);
3501 }
3502
3503 static void
3504 g_file_real_create_async (GFile               *file,
3505                           GFileCreateFlags     flags,
3506                           int                  io_priority,
3507                           GCancellable        *cancellable,
3508                           GAsyncReadyCallback  callback,
3509                           gpointer             user_data)
3510 {
3511   GFileCreateFlags *data;
3512   GSimpleAsyncResult *res;
3513
3514   data = g_new0 (GFileCreateFlags, 1);
3515   *data = flags;
3516
3517   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_create_async);
3518   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)g_free);
3519
3520   g_simple_async_result_run_in_thread (res, create_async_thread, io_priority, cancellable);
3521   g_object_unref (res);
3522 }
3523
3524 static GFileOutputStream *
3525 g_file_real_create_finish (GFile         *file,
3526                            GAsyncResult  *res,
3527                            GError       **error)
3528 {
3529   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3530   gpointer op;
3531
3532   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_create_async);
3533
3534   op = g_simple_async_result_get_op_res_gpointer (simple);
3535   if (op)
3536     return g_object_ref (op);
3537   
3538   return NULL;
3539 }
3540
3541 typedef struct {
3542   GFileOutputStream *stream;
3543   char *etag;
3544   gboolean make_backup;
3545   GFileCreateFlags flags;
3546 } ReplaceAsyncData;
3547
3548 static void
3549 replace_async_data_free (ReplaceAsyncData *data)
3550 {
3551   if (data->stream)
3552     g_object_unref (data->stream);
3553   g_free (data->etag);
3554   g_free (data);
3555 }
3556
3557 static void
3558 replace_async_thread (GSimpleAsyncResult *res,
3559                       GObject            *object,
3560                       GCancellable       *cancellable)
3561 {
3562   GFileIface *iface;
3563   GFileOutputStream *stream;
3564   GError *error = NULL;
3565   ReplaceAsyncData *data;
3566
3567   iface = G_FILE_GET_IFACE (object);
3568   
3569   data = g_simple_async_result_get_op_res_gpointer (res);
3570
3571   stream = iface->replace (G_FILE (object),
3572                            data->etag,
3573                            data->make_backup,
3574                            data->flags,
3575                            cancellable,
3576                            &error);
3577
3578   if (stream == NULL)
3579     {
3580       g_simple_async_result_set_from_error (res, error);
3581       g_error_free (error);
3582     }
3583   else
3584     data->stream = stream;
3585 }
3586
3587 static void
3588 g_file_real_replace_async (GFile               *file,
3589                            const char          *etag,
3590                            gboolean             make_backup,
3591                            GFileCreateFlags     flags,
3592                            int                  io_priority,
3593                            GCancellable        *cancellable,
3594                            GAsyncReadyCallback  callback,
3595                            gpointer             user_data)
3596 {
3597   GSimpleAsyncResult *res;
3598   ReplaceAsyncData *data;
3599
3600   data = g_new0 (ReplaceAsyncData, 1);
3601   data->etag = g_strdup (etag);
3602   data->make_backup = make_backup;
3603   data->flags = flags;
3604
3605   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_replace_async);
3606   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_async_data_free);
3607
3608   g_simple_async_result_run_in_thread (res, replace_async_thread, io_priority, cancellable);
3609   g_object_unref (res);
3610 }
3611
3612 static GFileOutputStream *
3613 g_file_real_replace_finish (GFile         *file,
3614                             GAsyncResult  *res,
3615                             GError       **error)
3616 {
3617   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3618   ReplaceAsyncData *data;
3619
3620   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_replace_async);
3621
3622   data = g_simple_async_result_get_op_res_gpointer (simple);
3623   if (data->stream)
3624     return g_object_ref (data->stream);
3625   
3626   return NULL;
3627 }
3628
3629 typedef struct {
3630   char *name;
3631   GFile *file;
3632 } SetDisplayNameAsyncData;
3633
3634 static void
3635 set_display_name_data_free (SetDisplayNameAsyncData *data)
3636 {
3637   g_free (data->name);
3638   if (data->file)
3639     g_object_unref (data->file);
3640   g_free (data);
3641 }
3642
3643 static void
3644 set_display_name_async_thread (GSimpleAsyncResult *res,
3645                                GObject            *object,
3646                                GCancellable       *cancellable)
3647 {
3648   GError *error = NULL;
3649   SetDisplayNameAsyncData *data;
3650   GFile *file;
3651   
3652   data = g_simple_async_result_get_op_res_gpointer (res);
3653   
3654   file = g_file_set_display_name (G_FILE (object), data->name, cancellable, &error);
3655
3656   if (file == NULL)
3657     {
3658       g_simple_async_result_set_from_error (res, error);
3659       g_error_free (error);
3660     }
3661   else
3662     data->file = file;
3663 }
3664
3665 static void
3666 g_file_real_set_display_name_async (GFile               *file,  
3667                                     const char          *display_name,
3668                                     int                  io_priority,
3669                                     GCancellable        *cancellable,
3670                                     GAsyncReadyCallback  callback,
3671                                     gpointer             user_data)
3672 {
3673   GSimpleAsyncResult *res;
3674   SetDisplayNameAsyncData *data;
3675
3676   data = g_new0 (SetDisplayNameAsyncData, 1);
3677   data->name = g_strdup (display_name);
3678   
3679   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_display_name_async);
3680   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_display_name_data_free);
3681   
3682   g_simple_async_result_run_in_thread (res, set_display_name_async_thread, io_priority, cancellable);
3683   g_object_unref (res);
3684 }
3685
3686 static GFile *
3687 g_file_real_set_display_name_finish (GFile         *file,
3688                                      GAsyncResult  *res,
3689                                      GError       **error)
3690 {
3691   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3692   SetDisplayNameAsyncData *data;
3693
3694   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_set_display_name_async);
3695
3696   data = g_simple_async_result_get_op_res_gpointer (simple);
3697   if (data->file)
3698     return g_object_ref (data->file);
3699   
3700   return NULL;
3701 }
3702
3703 typedef struct {
3704   GFileQueryInfoFlags flags;
3705   GFileInfo *info;
3706   gboolean res;
3707   GError *error;
3708 } SetInfoAsyncData;
3709
3710 static void
3711 set_info_data_free (SetInfoAsyncData *data)
3712 {
3713   if (data->info)
3714     g_object_unref (data->info);
3715   if (data->error)
3716     g_error_free (data->error);
3717   g_free (data);
3718 }
3719
3720 static void
3721 set_info_async_thread (GSimpleAsyncResult *res,
3722                        GObject            *object,
3723                        GCancellable       *cancellable)
3724 {
3725   SetInfoAsyncData *data;
3726   
3727   data = g_simple_async_result_get_op_res_gpointer (res);
3728   
3729   data->error = NULL;
3730   data->res = g_file_set_attributes_from_info (G_FILE (object),
3731                                                data->info,
3732                                                data->flags,
3733                                                cancellable,
3734                                                &data->error);
3735 }
3736
3737 static void
3738 g_file_real_set_attributes_async (GFile               *file,
3739                                   GFileInfo           *info,
3740                                   GFileQueryInfoFlags  flags,
3741                                   int                  io_priority,
3742                                   GCancellable        *cancellable,
3743                                   GAsyncReadyCallback  callback,
3744                                   gpointer             user_data)
3745 {
3746   GSimpleAsyncResult *res;
3747   SetInfoAsyncData *data;
3748
3749   data = g_new0 (SetInfoAsyncData, 1);
3750   data->info = g_file_info_dup (info);
3751   data->flags = flags;
3752   
3753   res = g_simple_async_result_new (G_OBJECT (file), callback, user_data, g_file_real_set_attributes_async);
3754   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)set_info_data_free);
3755   
3756   g_simple_async_result_run_in_thread (res, set_info_async_thread, io_priority, cancellable);
3757   g_object_unref (res);
3758 }
3759
3760 static gboolean
3761 g_file_real_set_attributes_finish (GFile         *file,
3762                                    GAsyncResult  *res,
3763                                    GFileInfo    **info,
3764                                    GError       **error)
3765 {
3766   GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (res);
3767   SetInfoAsyncData *data;
3768   
3769   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_real_set_attributes_async);
3770
3771   data = g_simple_async_result_get_op_res_gpointer (simple);
3772
3773   if (info) 
3774     *info = g_object_ref (data->info);
3775
3776   if (error != NULL && data->error) 
3777     *error = g_error_copy (data->error);
3778   
3779   return data->res;
3780 }
3781
3782 /********************************************
3783  *   Default VFS operations                 *
3784  ********************************************/
3785
3786 /**
3787  * g_file_new_for_path:
3788  * @path: a string containing a relative or absolute path.
3789  * 
3790  * Constructs a #GFile for a given path. This operation never
3791  * fails, but the returned object might not support any I/O
3792  * operation if @path is malformed.
3793  * 
3794  * Returns: a new #GFile for the given @path. 
3795  **/
3796 GFile *
3797 g_file_new_for_path (const char *path)
3798 {
3799   g_return_val_if_fail (path != NULL, NULL);
3800
3801   return g_vfs_get_file_for_path (g_vfs_get_default (), path);
3802 }
3803  
3804 /**
3805  * g_file_new_for_uri:
3806  * @uri: a string containing a URI.
3807  * 
3808  * Constructs a #GFile for a given URI. This operation never 
3809  * fails, but the returned object might not support any I/O 
3810  * operation if @uri is malformed or if the uri type is 
3811  * not supported.
3812  * 
3813  * Returns: a #GFile for the given @uri.
3814  **/ 
3815 GFile *
3816 g_file_new_for_uri (const char *uri)
3817 {
3818   g_return_val_if_fail (uri != NULL, NULL);
3819
3820   return g_vfs_get_file_for_uri (g_vfs_get_default (), uri);
3821 }
3822   
3823 /**
3824  * g_file_parse_name:
3825  * @parse_name: a file name or path to be parsed.
3826  * 
3827  * Constructs a #GFile with the given @parse_name, 
3828  * looked up by #GVfs. This operation never fails, 
3829  * but the returned object might not support any I/O
3830  * operation if the @parse_name cannot be parsed by #GVfs.
3831  * 
3832  * Returns: a new #GFile.
3833  **/
3834 GFile *
3835 g_file_parse_name (const char *parse_name)
3836 {
3837   g_return_val_if_fail (parse_name != NULL, NULL);
3838
3839   return g_vfs_parse_name (g_vfs_get_default (), parse_name);
3840 }
3841
3842 static gboolean
3843 is_valid_scheme_character (char c)
3844 {
3845   return g_ascii_isalnum (c) || c == '+' || c == '-' || c == '.';
3846 }
3847
3848 static gboolean
3849 has_valid_scheme (const char *uri)
3850 {
3851   const char *p;
3852   
3853   p = uri;
3854   
3855   if (!is_valid_scheme_character (*p))
3856     return FALSE;
3857
3858   do {
3859     p++;
3860   } while (is_valid_scheme_character (*p));
3861
3862   return *p == ':';
3863 }
3864
3865 /**
3866  * g_file_new_for_commandline_arg:
3867  * @arg: a command line string.
3868  * 
3869  * Attempts to generate a #GFile with the given line from
3870  * the command line argument. 
3871  * 
3872  * Returns: a new #GFile. 
3873  **/
3874 GFile *
3875 g_file_new_for_commandline_arg (const char *arg)
3876 {
3877   GFile *file;
3878   char *filename;
3879   char *current_dir;
3880   
3881   g_return_val_if_fail (arg != NULL, NULL);
3882   
3883   if (g_path_is_absolute (arg))
3884     return g_file_new_for_path (arg);
3885
3886   if (has_valid_scheme (arg))
3887     return g_file_new_for_uri (arg);
3888     
3889   current_dir = g_get_current_dir ();
3890   filename = g_build_filename (current_dir, arg, NULL);
3891   g_free (current_dir);
3892   
3893   file = g_file_new_for_path (filename);
3894   g_free (filename);
3895   
3896   return file;
3897 }
3898
3899 /**
3900  * g_mount_for_location:
3901  * @location: input #GFile.
3902  * @mount_operation: a #GMountOperation.
3903  * @cancellable: optional #GCancellable object, %NULL to ignore.
3904  * @callback: a #GAsyncReadyCallback. 
3905  * @user_data: a #gpointer. 
3906  * 
3907  * Starts the @mount_operation, mounting the volume at @location. 
3908  * 
3909  * When this operation has completed, @callback will be called with
3910  * @user_user data, and the operation can be finalized with 
3911  * g_mount_for_location_finish().
3912  * 
3913  * If @cancellable is not %NULL, then the operation can be cancelled by
3914  * triggering the cancellable object from another thread. If the operation
3915  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3916  **/
3917 void
3918 g_mount_for_location (GFile               *location,
3919                       GMountOperation     *mount_operation,
3920                       GCancellable        *cancellable,
3921                       GAsyncReadyCallback  callback,
3922                       gpointer             user_data)
3923 {
3924   GFileIface *iface;
3925
3926   g_return_if_fail (G_IS_FILE (location));
3927   g_return_if_fail (G_IS_MOUNT_OPERATION (mount_operation));
3928
3929   iface = G_FILE_GET_IFACE (location);
3930
3931   if (iface->mount_for_location == NULL)
3932     {
3933       g_simple_async_report_error_in_idle (G_OBJECT (location),
3934                                            callback, user_data,
3935                                            G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
3936                                            _("volume doesn't implement mount"));
3937       
3938       return;
3939     }
3940   
3941   (* iface->mount_for_location) (location, mount_operation, cancellable, callback, user_data);
3942
3943 }
3944
3945 /**
3946  * g_mount_for_location_finish:
3947  * @location: input #GFile.
3948  * @result: a #GAsyncResult.
3949  * @error: a #GError, or %NULL
3950  * 
3951  * Finishes a mount operation started by g_mount_for_location().
3952  * 
3953  * Returns: %TRUE if successful. If an error
3954  * has occured, this function will return %FALSE and set @error
3955  * appropriately if present.
3956  **/
3957 gboolean
3958 g_mount_for_location_finish (GFile         *location,
3959                              GAsyncResult  *result,
3960                              GError       **error)
3961 {
3962   GFileIface *iface;
3963
3964   g_return_val_if_fail (G_IS_FILE (location), FALSE);
3965   g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
3966
3967   if (G_IS_SIMPLE_ASYNC_RESULT (result))
3968     {
3969       GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
3970       if (g_simple_async_result_propagate_error (simple, error))
3971         return FALSE;
3972     }
3973   
3974   iface = G_FILE_GET_IFACE (location);
3975
3976   return (* iface->mount_for_location_finish) (location, result, error);
3977 }
3978
3979 /********************************************
3980  *   Utility functions                      *
3981  ********************************************/
3982
3983 #define GET_CONTENT_BLOCK_SIZE 8192
3984
3985 /**
3986  * g_file_load_contents:
3987  * @file: input #GFile.
3988  * @cancellable: optional #GCancellable object, %NULL to ignore.
3989  * @contents: a location to place the contents of the file.
3990  * @length: a location to place the length of the contents of the file.
3991  * @etag_out: a location to place the current entity tag for the file.
3992  * @error: a #GError, or %NULL
3993  * 
3994  * If @cancellable is not %NULL, then the operation can be cancelled by
3995  * triggering the cancellable object from another thread. If the operation
3996  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
3997  * 
3998  * Returns: %TRUE if the @file's contents were successfully loaded.
3999  * %FALSE if there were errors. The length of the loaded data will be
4000  * put into @length, the contents in @contents.
4001  **/
4002 gboolean
4003 g_file_load_contents (GFile         *file,
4004                       GCancellable  *cancellable,
4005                       char         **contents,
4006                       gsize         *length,
4007                       char         **etag_out,
4008                       GError       **error)
4009 {
4010   GFileInputStream *in;
4011   GByteArray *content;
4012   gsize pos;
4013   gssize res;
4014   GFileInfo *info;
4015
4016   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4017   g_return_val_if_fail (contents != NULL, FALSE);
4018
4019   in = g_file_read (file, cancellable, error);
4020   if (in == NULL)
4021     return FALSE;
4022
4023   content = g_byte_array_new ();
4024   pos = 0;
4025   
4026   g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4027   while ((res = g_input_stream_read (G_INPUT_STREAM (in),
4028                                      content->data + pos,
4029                                      GET_CONTENT_BLOCK_SIZE,
4030                                      cancellable, error)) > 0)
4031     {
4032       pos += res;
4033       g_byte_array_set_size (content, pos + GET_CONTENT_BLOCK_SIZE + 1);
4034     }
4035
4036   if (etag_out)
4037     {
4038       *etag_out = NULL;
4039       
4040       info = g_file_input_stream_query_info (in,
4041                                              G_FILE_ATTRIBUTE_ETAG_VALUE,
4042                                              cancellable,
4043                                              NULL);
4044       if (info)
4045         {
4046           *etag_out = g_strdup (g_file_info_get_etag (info));
4047           g_object_unref (info);
4048         }
4049     } 
4050
4051   /* Ignore errors on close */
4052   g_input_stream_close (G_INPUT_STREAM (in), cancellable, NULL);
4053   g_object_unref (in);
4054
4055   if (res < 0)
4056     {
4057       /* error is set already */
4058       g_byte_array_free (content, TRUE);
4059       return FALSE;
4060     }
4061
4062   if (length)
4063     *length = pos;
4064
4065   /* Zero terminate (we got an extra byte allocated for this */
4066   content->data[pos] = 0;
4067   
4068   *contents = (char *)g_byte_array_free (content, FALSE);
4069   
4070   return TRUE;
4071 }
4072
4073 typedef struct {
4074   GFile *file;
4075   GError *error;
4076   GCancellable *cancellable;
4077   GFileReadMoreCallback read_more_callback;
4078   GAsyncReadyCallback callback;
4079   gpointer user_data;
4080   GByteArray *content;
4081   gsize pos;
4082   char *etag;
4083 } LoadContentsData;
4084
4085
4086 static void
4087 load_contents_data_free (LoadContentsData *data)
4088 {
4089   if (data->error)
4090     g_error_free (data->error);
4091   if (data->cancellable)
4092     g_object_unref (data->cancellable);
4093   if (data->content)
4094     g_byte_array_free (data->content, TRUE);
4095   g_free (data->etag);
4096   g_object_unref (data->file);
4097   g_free (data);
4098 }
4099
4100 static void
4101 load_contents_close_callback (GObject      *obj,
4102                               GAsyncResult *close_res,
4103                               gpointer      user_data)
4104 {
4105   GInputStream *stream = G_INPUT_STREAM (obj);
4106   LoadContentsData *data = user_data;
4107   GSimpleAsyncResult *res;
4108
4109   /* Ignore errors here, we're only reading anyway */
4110   g_input_stream_close_finish (stream, close_res, NULL);
4111   g_object_unref (stream);
4112
4113   res = g_simple_async_result_new (G_OBJECT (data->file),
4114                                    data->callback,
4115                                    data->user_data,
4116                                    g_file_load_contents_async);
4117   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)load_contents_data_free);
4118   g_simple_async_result_complete (res);
4119   g_object_unref (res);
4120 }
4121
4122 static void
4123 load_contents_fstat_callback (GObject      *obj,
4124                               GAsyncResult *stat_res,
4125                               gpointer      user_data)
4126 {
4127   GInputStream *stream = G_INPUT_STREAM (obj);
4128   LoadContentsData *data = user_data;
4129   GFileInfo *info;
4130
4131   info = g_file_input_stream_query_info_finish (G_FILE_INPUT_STREAM (stream),
4132                                                    stat_res, NULL);
4133   if (info)
4134     {
4135       data->etag = g_strdup (g_file_info_get_etag (info));
4136       g_object_unref (info);
4137     }
4138
4139   g_input_stream_close_async (stream, 0,
4140                               data->cancellable,
4141                               load_contents_close_callback, data);
4142 }
4143
4144 static void
4145 load_contents_read_callback (GObject      *obj,
4146                              GAsyncResult *read_res,
4147                              gpointer      user_data)
4148 {
4149   GInputStream *stream = G_INPUT_STREAM (obj);
4150   LoadContentsData *data = user_data;
4151   GError *error = NULL;
4152   gssize read_size;
4153
4154   read_size = g_input_stream_read_finish (stream, read_res, &error);
4155
4156   if (read_size < 0) 
4157     {
4158       /* Error or EOF, close the file */
4159       data->error = error;
4160       g_input_stream_close_async (stream, 0,
4161                                   data->cancellable,
4162                                   load_contents_close_callback, data);
4163     }
4164   else if (read_size == 0)
4165     {
4166       g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
4167                                             G_FILE_ATTRIBUTE_ETAG_VALUE,
4168                                             0,
4169                                             data->cancellable,
4170                                             load_contents_fstat_callback,
4171                                             data);
4172     }
4173   else if (read_size > 0)
4174     {
4175       data->pos += read_size;
4176       
4177       g_byte_array_set_size (data->content,
4178                              data->pos + GET_CONTENT_BLOCK_SIZE);
4179
4180
4181       if (data->read_more_callback &&
4182           !data->read_more_callback ((char *)data->content->data, data->pos, data->user_data))
4183         g_file_input_stream_query_info_async (G_FILE_INPUT_STREAM (stream),
4184                                               G_FILE_ATTRIBUTE_ETAG_VALUE,
4185                                               0,
4186                                               data->cancellable,
4187                                               load_contents_fstat_callback,
4188                                               data);
4189       else 
4190         g_input_stream_read_async (stream,
4191                                    data->content->data + data->pos,
4192                                    GET_CONTENT_BLOCK_SIZE,
4193                                    0,
4194                                    data->cancellable,
4195                                    load_contents_read_callback,
4196                                    data);
4197     }
4198 }
4199
4200 static void
4201 load_contents_open_callback (GObject      *obj,
4202                              GAsyncResult *open_res,
4203                              gpointer      user_data)
4204 {
4205   GFile *file = G_FILE (obj);
4206   GFileInputStream *stream;
4207   LoadContentsData *data = user_data;
4208   GError *error = NULL;
4209   GSimpleAsyncResult *res;
4210
4211   stream = g_file_read_finish (file, open_res, &error);
4212
4213   if (stream)
4214     {
4215       g_byte_array_set_size (data->content,
4216                              data->pos + GET_CONTENT_BLOCK_SIZE);
4217       g_input_stream_read_async (G_INPUT_STREAM (stream),
4218                                  data->content->data + data->pos,
4219                                  GET_CONTENT_BLOCK_SIZE,
4220                                  0,
4221                                  data->cancellable,
4222                                  load_contents_read_callback,
4223                                  data);
4224       
4225     }
4226   else
4227     {
4228       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
4229                                                   data->callback,
4230                                                   data->user_data,
4231                                                   error);
4232       g_simple_async_result_complete (res);
4233       g_error_free (error);
4234       load_contents_data_free (data);
4235       g_object_unref (res);
4236     }
4237 }
4238
4239 /**
4240  * g_file_load_partial_contents_async:
4241  * @file: input #GFile.
4242  * @cancellable: optional #GCancellable object, %NULL to ignore.
4243  * @read_more_callback: a #GFileReadMoreCallback.
4244  * @callback: a #GAsyncReadyCallback. 
4245  * @user_data: a #gpointer. 
4246  * 
4247  * If @cancellable is not %NULL, then the operation can be cancelled by
4248  * triggering the cancellable object from another thread. If the operation
4249  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4250  **/
4251 void
4252 g_file_load_partial_contents_async (GFile                 *file,
4253                                     GCancellable          *cancellable,
4254                                     GFileReadMoreCallback  read_more_callback,
4255                                     GAsyncReadyCallback    callback,
4256                                     gpointer               user_data)
4257 {
4258   LoadContentsData *data;
4259
4260   g_return_if_fail (G_IS_FILE (file));
4261
4262   data = g_new0 (LoadContentsData, 1);
4263
4264   if (cancellable)
4265     data->cancellable = g_object_ref (cancellable);
4266   data->read_more_callback = read_more_callback;
4267   data->callback = callback;
4268   data->user_data = user_data;
4269   data->content = g_byte_array_new ();
4270   data->file = g_object_ref (file);
4271
4272   g_file_read_async (file,
4273                      0,
4274                      cancellable,
4275                      load_contents_open_callback,
4276                      data);
4277 }
4278
4279 /**
4280  * g_file_load_partial_contents_finish:
4281  * @file: input #GFile.
4282  * @res: a #GAsyncResult. 
4283  * @contents: a location to place the contents of the file.
4284  * @length: a location to place the length of the contents of the file.
4285  * @etag_out: a location to place the current entity tag for the file.
4286  * @error: a #GError, or %NULL
4287  * 
4288  * Finishes an asynchronous partial load operation that was started
4289  * with g_file_load_partial_contents_async().
4290  *
4291  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
4292  * present, it will be set appropriately. 
4293  **/
4294 gboolean
4295 g_file_load_partial_contents_finish (GFile         *file,
4296                                      GAsyncResult  *res,
4297                                      char         **contents,
4298                                      gsize         *length,
4299                                      char         **etag_out,
4300                                      GError       **error)
4301 {
4302   GSimpleAsyncResult *simple;
4303   LoadContentsData *data;
4304
4305   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4306   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
4307   g_return_val_if_fail (contents != NULL, FALSE);
4308
4309   simple = G_SIMPLE_ASYNC_RESULT (res);
4310
4311   if (g_simple_async_result_propagate_error (simple, error))
4312     return FALSE;
4313   
4314   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_load_contents_async);
4315   
4316   data = g_simple_async_result_get_op_res_gpointer (simple);
4317
4318   if (data->error)
4319     {
4320       g_propagate_error (error, data->error);
4321       data->error = NULL;
4322       *contents = NULL;
4323       if (length)
4324         *length = 0;
4325       return FALSE;
4326     }
4327
4328   if (length)
4329     *length = data->pos;
4330
4331   if (etag_out)
4332     {
4333       *etag_out = data->etag;
4334       data->etag = NULL;
4335     }
4336
4337   /* Zero terminate */
4338   g_byte_array_set_size (data->content, data->pos + 1);
4339   data->content->data[data->pos] = 0;
4340   
4341   *contents = (char *)g_byte_array_free (data->content, FALSE);
4342   data->content = NULL;
4343
4344   return TRUE;
4345 }
4346
4347 /**
4348  * g_file_load_contents_async:
4349  * @file: input #GFile.
4350  * @cancellable: optional #GCancellable object, %NULL to ignore.
4351  * @callback: a #GAsyncReadyCallback. 
4352  * @user_data: a #gpointer. 
4353  * 
4354  * Starts an asynchronous load of the @file's contents. 
4355  * When the load operation has completed, @callback will be called 
4356  * with @userdata. To finish the operation, call 
4357  * g_file_load_contents_finish() with the #GAsyncResult returned by 
4358  * the @callback.
4359  * 
4360  * If @cancellable is not %NULL, then the operation can be cancelled by
4361  * triggering the cancellable object from another thread. If the operation
4362  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4363  **/
4364 void
4365 g_file_load_contents_async (GFile               *file,
4366                            GCancellable        *cancellable,
4367                            GAsyncReadyCallback  callback,
4368                            gpointer             user_data)
4369 {
4370   g_file_load_partial_contents_async (file,
4371                                       cancellable,
4372                                       NULL,
4373                                       callback, user_data);
4374 }
4375
4376 /**
4377  * g_file_load_contents_finish:
4378  * @file: input #GFile.
4379  * @res: a #GAsyncResult. 
4380  * @contents: a location to place the contents of the file.
4381  * @length: a location to place the length of the contents of the file.
4382  * @etag_out: a location to place the current entity tag for the file.
4383  * @error: a #GError, or %NULL
4384  * 
4385  * Finishes an asynchronous load of the @file's contents. 
4386  * The contents are placed in @contents, and @length is set to the 
4387  * size of the @contents string. If @etag_out is present, it will be 
4388  * set to the new entity tag for the @file.
4389  * 
4390  * Returns: %TRUE if the load was successful. If %FALSE and @error is 
4391  * present, it will be set appropriately. 
4392  **/
4393 gboolean
4394 g_file_load_contents_finish (GFile         *file,
4395                              GAsyncResult  *res,
4396                              char         **contents,
4397                              gsize         *length,
4398                              char         **etag_out,
4399                              GError       **error)
4400 {
4401   return g_file_load_partial_contents_finish (file,
4402                                               res,
4403                                               contents,
4404                                               length,
4405                                               etag_out,
4406                                               error);
4407 }
4408   
4409 /**
4410  * g_file_replace_contents:
4411  * @file: input #GFile.
4412  * @contents: a string containing the new contents for @file.
4413  * @length: the length of @contents in bytes.
4414  * @etag: the old <link linkend="gfile-etag">entity tag</link> 
4415  *     for the document.
4416  * @make_backup: a #gboolean.
4417  * @flags: a set of #GFileCreateFlags.
4418  * @new_etag: a location to a new <link linkend="gfile-etag">entity tag</link>
4419  *      for the document.
4420  * @cancellable: optional #GCancellable object, %NULL to ignore.
4421  * @error: a #GError, or %NULL
4422  *
4423  * Replaces the contents of @file with @contents of @length bytes. 
4424  * The old @etag will be replaced with the @new_etag. If @make_backup 
4425  * is %TRUE, this function will attempt to make a backup of @file.
4426  * 
4427  * If @cancellable is not %NULL, then the operation can be cancelled by
4428  * triggering the cancellable object from another thread. If the operation
4429  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4430  * 
4431  * Returns: %TRUE if successful. If an error
4432  * has occured, this function will return %FALSE and set @error
4433  * appropriately if present.
4434  **/
4435 gboolean
4436 g_file_replace_contents (GFile             *file,
4437                          const char        *contents,
4438                          gsize              length,
4439                          const char        *etag,
4440                          gboolean           make_backup,
4441                          GFileCreateFlags   flags,
4442                          char             **new_etag,
4443                          GCancellable      *cancellable,
4444                          GError           **error)
4445 {
4446   GFileOutputStream *out;
4447   gsize pos, remainder;
4448   gssize res;
4449
4450   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4451   g_return_val_if_fail (contents != NULL, FALSE);
4452
4453   out = g_file_replace (file, etag, make_backup, flags, cancellable, error);
4454   if (out == NULL)
4455     return FALSE;
4456
4457   pos = 0;
4458   remainder = length;
4459   while (remainder > 0 &&
4460          (res = g_output_stream_write (G_OUTPUT_STREAM (out),
4461                                        contents + pos,
4462                                        MIN (remainder, GET_CONTENT_BLOCK_SIZE),
4463                                        cancellable,
4464                                        error)) > 0)
4465     {
4466       pos += res;
4467       remainder -= res;
4468     }
4469   
4470   if (remainder > 0 && res < 0)
4471     {
4472       /* Ignore errors on close */
4473       g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, NULL);
4474       
4475       /* error is set already */
4476       return FALSE;
4477     }
4478   
4479   if (!g_output_stream_close (G_OUTPUT_STREAM (out), cancellable, error))
4480     return FALSE;
4481
4482   if (new_etag)
4483     *new_etag = g_file_output_stream_get_etag (out);
4484   
4485   return TRUE;
4486 }
4487
4488 typedef struct {
4489   GFile *file;
4490   GError *error;
4491   GCancellable *cancellable;
4492   GAsyncReadyCallback callback;
4493   gpointer user_data;
4494   const char *content;
4495   gsize length;
4496   gsize pos;
4497   char *etag;
4498 } ReplaceContentsData;
4499
4500 static void
4501 replace_contents_data_free (ReplaceContentsData *data)
4502 {
4503   if (data->error)
4504     g_error_free (data->error);
4505   if (data->cancellable)
4506     g_object_unref (data->cancellable);
4507   g_object_unref (data->file);
4508   g_free (data->etag);
4509   g_free (data);
4510 }
4511
4512 static void
4513 replace_contents_close_callback (GObject      *obj,
4514                                  GAsyncResult *close_res,
4515                                  gpointer      user_data)
4516 {
4517   GOutputStream *stream = G_OUTPUT_STREAM (obj);
4518   ReplaceContentsData *data = user_data;
4519   GSimpleAsyncResult *res;
4520
4521   /* Ignore errors here, we're only reading anyway */
4522   g_output_stream_close_finish (stream, close_res, NULL);
4523   g_object_unref (stream);
4524
4525   data->etag = g_file_output_stream_get_etag (G_FILE_OUTPUT_STREAM (stream));
4526   
4527   res = g_simple_async_result_new (G_OBJECT (data->file),
4528                                    data->callback,
4529                                    data->user_data,
4530                                    g_file_replace_contents_async);
4531   g_simple_async_result_set_op_res_gpointer (res, data, (GDestroyNotify)replace_contents_data_free);
4532   g_simple_async_result_complete (res);
4533   g_object_unref (res);
4534 }
4535
4536 static void
4537 replace_contents_write_callback (GObject      *obj,
4538                                  GAsyncResult *read_res,
4539                                  gpointer      user_data)
4540 {
4541   GOutputStream *stream = G_OUTPUT_STREAM (obj);
4542   ReplaceContentsData *data = user_data;
4543   GError *error = NULL;
4544   gssize write_size;
4545   
4546   write_size = g_output_stream_write_finish (stream, read_res, &error);
4547
4548   if (write_size <= 0) 
4549     {
4550       /* Error or EOF, close the file */
4551       if (write_size < 0)
4552         data->error = error;
4553       g_output_stream_close_async (stream, 0,
4554                                    data->cancellable,
4555                                    replace_contents_close_callback, data);
4556     }
4557   else if (write_size > 0)
4558     {
4559       data->pos += write_size;
4560
4561       if (data->pos >= data->length)
4562         g_output_stream_close_async (stream, 0,
4563                                      data->cancellable,
4564                                      replace_contents_close_callback, data);
4565       else
4566         g_output_stream_write_async (stream,
4567                                      data->content + data->pos,
4568                                      data->length - data->pos,
4569                                      0,
4570                                      data->cancellable,
4571                                      replace_contents_write_callback,
4572                                      data);
4573     }
4574 }
4575
4576 static void
4577 replace_contents_open_callback (GObject      *obj,
4578                                 GAsyncResult *open_res,
4579                                 gpointer      user_data)
4580 {
4581   GFile *file = G_FILE (obj);
4582   GFileOutputStream *stream;
4583   ReplaceContentsData *data = user_data;
4584   GError *error = NULL;
4585   GSimpleAsyncResult *res;
4586
4587   stream = g_file_replace_finish (file, open_res, &error);
4588
4589   if (stream)
4590     {
4591       g_output_stream_write_async (G_OUTPUT_STREAM (stream),
4592                                    data->content + data->pos,
4593                                    data->length - data->pos,
4594                                    0,
4595                                    data->cancellable,
4596                                    replace_contents_write_callback,
4597                                    data);
4598       
4599     }
4600   else
4601     {
4602       res = g_simple_async_result_new_from_error (G_OBJECT (data->file),
4603                                                   data->callback,
4604                                                   data->user_data,
4605                                                   error);
4606       g_simple_async_result_complete (res);
4607       g_error_free (error);
4608       replace_contents_data_free (data);
4609       g_object_unref (res);
4610     }
4611 }
4612
4613 /**
4614  * g_file_replace_contents_async:
4615  * @file: input #GFile.
4616  * @contents: string of contents to replace the file with.
4617  * @length: the length of @contents in bytes.
4618  * @etag: a new <link linkend="gfile-etag">entity tag</link> for the @file.
4619  * @make_backup: a #gboolean.
4620  * @flags: a set of #GFileCreateFlags.
4621  * @cancellable: optional #GCancellable object, %NULL to ignore.
4622  * @callback: a #GAsyncReadyCallback. 
4623  * @user_data: a #gpointer. 
4624  * 
4625  * Starts an asynchronous replacement of @file with the given 
4626  * @contents of @length bytes. @etag will replace the document's 
4627  * current entity tag.
4628  * 
4629  * When this operation has completed, @callback will be called with
4630  * @user_user data, and the operation can be finalized with 
4631  * g_file_replace_contents_finish().
4632  * 
4633  * If @cancellable is not %NULL, then the operation can be cancelled by
4634  * triggering the cancellable object from another thread. If the operation
4635  * was cancelled, the error %G_IO_ERROR_CANCELLED will be returned. 
4636  * 
4637  * If @make_backup is %TRUE, this function will attempt to 
4638  * make a backup of @file.
4639  **/
4640 void
4641 g_file_replace_contents_async  (GFile               *file,
4642                                 const char          *contents,
4643                                 gsize                length,
4644                                 const char          *etag,
4645                                 gboolean             make_backup,
4646                                 GFileCreateFlags     flags,
4647                                 GCancellable        *cancellable,
4648                                 GAsyncReadyCallback  callback,
4649                                 gpointer             user_data)
4650 {
4651   ReplaceContentsData *data;
4652
4653   g_return_if_fail (G_IS_FILE (file));
4654   g_return_if_fail (contents != NULL);
4655
4656   data = g_new0 (ReplaceContentsData, 1);
4657
4658   if (cancellable)
4659     data->cancellable = g_object_ref (cancellable);
4660   data->callback = callback;
4661   data->user_data = user_data;
4662   data->content = contents;
4663   data->length = length;
4664   data->pos = 0;
4665   data->file = g_object_ref (file);
4666
4667   g_file_replace_async (file,
4668                         etag,
4669                         make_backup,
4670                         flags,
4671                         0,
4672                         cancellable,
4673                         replace_contents_open_callback,
4674                         data);
4675 }
4676   
4677 /**
4678  * g_file_replace_contents_finish:
4679  * @file: input #GFile.
4680  * @res: a #GAsyncResult. 
4681  * @new_etag: a location of a new <link linkend="gfile-etag">entity tag</link> 
4682  *     for the document.
4683  * @error: a #GError, or %NULL 
4684  * 
4685  * Finishes an asynchronous replace of the given @file. See
4686  * g_file_replace_contents_async(). Sets @new_etag to the new entity 
4687  * tag for the document, if present.
4688  * 
4689  * Returns: %TRUE on success, %FALSE on failure.
4690  **/
4691 gboolean
4692 g_file_replace_contents_finish (GFile         *file,
4693                                 GAsyncResult  *res,
4694                                 char         **new_etag,
4695                                 GError       **error)
4696 {
4697   GSimpleAsyncResult *simple;
4698   ReplaceContentsData *data;
4699
4700   g_return_val_if_fail (G_IS_FILE (file), FALSE);
4701   g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (res), FALSE);
4702
4703   simple = G_SIMPLE_ASYNC_RESULT (res);
4704
4705   if (g_simple_async_result_propagate_error (simple, error))
4706     return FALSE;
4707   
4708   g_assert (g_simple_async_result_get_source_tag (simple) == g_file_replace_contents_async);
4709   
4710   data = g_simple_async_result_get_op_res_gpointer (simple);
4711
4712   if (data->error)
4713     {
4714       g_propagate_error (error, data->error);
4715       data->error = NULL;
4716       return FALSE;
4717     }
4718
4719
4720   if (new_etag)
4721     {
4722       *new_etag = data->etag;
4723       data->etag = NULL; /* Take ownership */
4724     }
4725   
4726   return TRUE;
4727 }
4728
4729 #define __G_FILE_C__
4730 #include "gioaliasdef.c"