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