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