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