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