1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * SPDX-License-Identifier: LGPL-2.1-or-later
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
20 * Author: Alexander Larsson <alexl@redhat.com>
25 * @short_description: File Information and Attributes
27 * @see_also: #GFile, [GFileAttribute][gio-GFileAttribute]
29 * Functionality for manipulating basic metadata for files. #GFileInfo
30 * implements methods for getting information that all files should
31 * contain, and allows for manipulation of extended attributes.
33 * See [GFileAttribute][gio-GFileAttribute] for more information on how
34 * GIO handles file attributes.
36 * To obtain a #GFileInfo for a #GFile, use g_file_query_info() (or its
37 * async variant). To obtain a #GFileInfo for a file input or output
38 * stream, use g_file_input_stream_query_info() or
39 * g_file_output_stream_query_info() (or their async variants).
41 * To change the actual attributes of a file, you should then set the
42 * attribute in the #GFileInfo and call g_file_set_attributes_from_info()
43 * or g_file_set_attributes_async() on a GFile.
45 * However, not all attributes can be changed in the file. For instance,
46 * the actual size of a file cannot be changed via g_file_info_set_size().
47 * You may call g_file_query_settable_attributes() and
48 * g_file_query_writable_namespaces() to discover the settable attributes
49 * of a particular file at runtime.
51 * The direct accessors, such as g_file_info_get_name(), are slightly more
52 * optimized than the generic attribute accessors, such as
53 * g_file_info_get_attribute_byte_string().This optimization will matter
54 * only if calling the API in a tight loop.
56 * It is an error to call these accessors without specifying their required file
57 * attributes when creating the #GFileInfo. Use g_file_info_has_attribute() or
58 * g_file_info_list_attributes() to check what attributes are specified for a
61 * #GFileAttributeMatcher allows for searching through a #GFileInfo for
69 #include "gfileinfo.h"
70 #include "gfileinfo-priv.h"
71 #include "gfileattribute-priv.h"
76 /* We use this nasty thing, because NULL is a valid attribute matcher (matches nothing) */
77 #define NO_ATTRIBUTE_MASK ((GFileAttributeMatcher *)1)
81 GFileAttributeValue value;
86 GObject parent_instance;
89 GFileAttributeMatcher *mask;
92 struct _GFileInfoClass
94 GObjectClass parent_class;
98 G_DEFINE_TYPE (GFileInfo, g_file_info, G_TYPE_OBJECT)
102 guint32 attribute_id_counter;
105 G_LOCK_DEFINE_STATIC (attribute_hash);
106 static int namespace_id_counter = 0;
107 static GHashTable *ns_hash = NULL;
108 static GHashTable *attribute_hash = NULL;
109 static char ***global_attributes = NULL;
111 /* Attribute ids are 32bit, we split it up like this:
112 * |------------|--------------------|
114 * namespace attribute id
116 * This way the attributes gets sorted in namespace order
120 #define NS_MASK ((guint32)((1<<12) - 1))
122 #define ID_MASK ((guint32)((1<<20) - 1))
124 #define GET_NS(_attr_id) \
125 (((guint32) (_attr_id) >> NS_POS) & NS_MASK)
126 #define GET_ID(_attr_id) \
127 (((guint32)(_attr_id) >> ID_POS) & ID_MASK)
129 #define MAKE_ATTR_ID(_ns, _id) \
130 ( ((((guint32) _ns) & NS_MASK) << NS_POS) | \
131 ((((guint32) _id) & ID_MASK) << ID_POS) )
134 _lookup_namespace (const char *namespace)
138 ns_info = g_hash_table_lookup (ns_hash, namespace);
141 ns_info = g_new0 (NSInfo, 1);
142 ns_info->id = ++namespace_id_counter;
143 g_hash_table_insert (ns_hash, g_strdup (namespace), ns_info);
144 global_attributes = g_realloc (global_attributes, (ns_info->id + 1) * sizeof (char **));
145 global_attributes[ns_info->id] = g_new (char *, 1);
146 global_attributes[ns_info->id][0] = g_strconcat (namespace, "::*", NULL);
152 _lookup_attribute (const char *attribute)
159 attr_id = GPOINTER_TO_UINT (g_hash_table_lookup (attribute_hash, attribute));
164 colon = strstr (attribute, "::");
166 ns = g_strndup (attribute, colon - attribute);
170 ns_info = _lookup_namespace (ns);
173 id = ++ns_info->attribute_id_counter;
174 global_attributes[ns_info->id] = g_realloc (global_attributes[ns_info->id], (id + 1) * sizeof (char *));
175 global_attributes[ns_info->id][id] = g_strdup (attribute);
177 attr_id = MAKE_ATTR_ID (ns_info->id, id);
179 g_hash_table_insert (attribute_hash, global_attributes[ns_info->id][id], GUINT_TO_POINTER (attr_id));
185 ensure_attribute_hash (void)
187 if (attribute_hash != NULL)
190 ns_hash = g_hash_table_new (g_str_hash, g_str_equal);
191 attribute_hash = g_hash_table_new (g_str_hash, g_str_equal);
193 #define REGISTER_ATTRIBUTE(name) G_STMT_START{\
194 guint _u G_GNUC_UNUSED /* when compiling with G_DISABLE_ASSERT */; \
195 _u = _lookup_attribute (G_FILE_ATTRIBUTE_ ## name); \
196 /* use for generating the ID: g_print ("#define G_FILE_ATTRIBUTE_ID_%s (%u + %u)\n", #name + 17, _u & ~ID_MASK, _u & ID_MASK); */ \
197 g_assert (_u == G_FILE_ATTRIBUTE_ID_ ## name); \
200 REGISTER_ATTRIBUTE (STANDARD_TYPE);
201 REGISTER_ATTRIBUTE (STANDARD_IS_HIDDEN);
202 REGISTER_ATTRIBUTE (STANDARD_IS_BACKUP);
203 REGISTER_ATTRIBUTE (STANDARD_IS_SYMLINK);
204 REGISTER_ATTRIBUTE (STANDARD_IS_VIRTUAL);
205 REGISTER_ATTRIBUTE (STANDARD_NAME);
206 REGISTER_ATTRIBUTE (STANDARD_DISPLAY_NAME);
207 REGISTER_ATTRIBUTE (STANDARD_EDIT_NAME);
208 REGISTER_ATTRIBUTE (STANDARD_COPY_NAME);
209 REGISTER_ATTRIBUTE (STANDARD_DESCRIPTION);
210 REGISTER_ATTRIBUTE (STANDARD_ICON);
211 REGISTER_ATTRIBUTE (STANDARD_CONTENT_TYPE);
212 REGISTER_ATTRIBUTE (STANDARD_FAST_CONTENT_TYPE);
213 REGISTER_ATTRIBUTE (STANDARD_SIZE);
214 REGISTER_ATTRIBUTE (STANDARD_ALLOCATED_SIZE);
215 REGISTER_ATTRIBUTE (STANDARD_SYMLINK_TARGET);
216 REGISTER_ATTRIBUTE (STANDARD_TARGET_URI);
217 REGISTER_ATTRIBUTE (STANDARD_SORT_ORDER);
218 REGISTER_ATTRIBUTE (STANDARD_SYMBOLIC_ICON);
219 REGISTER_ATTRIBUTE (STANDARD_IS_VOLATILE);
220 REGISTER_ATTRIBUTE (ETAG_VALUE);
221 REGISTER_ATTRIBUTE (ID_FILE);
222 REGISTER_ATTRIBUTE (ID_FILESYSTEM);
223 REGISTER_ATTRIBUTE (ACCESS_CAN_READ);
224 REGISTER_ATTRIBUTE (ACCESS_CAN_WRITE);
225 REGISTER_ATTRIBUTE (ACCESS_CAN_EXECUTE);
226 REGISTER_ATTRIBUTE (ACCESS_CAN_DELETE);
227 REGISTER_ATTRIBUTE (ACCESS_CAN_TRASH);
228 REGISTER_ATTRIBUTE (ACCESS_CAN_RENAME);
229 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_MOUNT);
230 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_UNMOUNT);
231 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_EJECT);
232 REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE);
233 REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE_FILE);
234 REGISTER_ATTRIBUTE (MOUNTABLE_HAL_UDI);
235 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START);
236 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START_DEGRADED);
237 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_STOP);
238 REGISTER_ATTRIBUTE (MOUNTABLE_START_STOP_TYPE);
239 REGISTER_ATTRIBUTE (MOUNTABLE_CAN_POLL);
240 REGISTER_ATTRIBUTE (MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC);
241 REGISTER_ATTRIBUTE (TIME_MODIFIED);
242 REGISTER_ATTRIBUTE (TIME_MODIFIED_USEC);
243 REGISTER_ATTRIBUTE (TIME_ACCESS);
244 REGISTER_ATTRIBUTE (TIME_ACCESS_USEC);
245 REGISTER_ATTRIBUTE (TIME_CHANGED);
246 REGISTER_ATTRIBUTE (TIME_CHANGED_USEC);
247 REGISTER_ATTRIBUTE (TIME_CREATED);
248 REGISTER_ATTRIBUTE (TIME_CREATED_USEC);
249 REGISTER_ATTRIBUTE (TIME_MODIFIED_NSEC);
250 REGISTER_ATTRIBUTE (TIME_ACCESS_NSEC);
251 REGISTER_ATTRIBUTE (TIME_CREATED_NSEC);
252 REGISTER_ATTRIBUTE (TIME_CHANGED_NSEC);
253 REGISTER_ATTRIBUTE (UNIX_DEVICE);
254 REGISTER_ATTRIBUTE (UNIX_INODE);
255 REGISTER_ATTRIBUTE (UNIX_MODE);
256 REGISTER_ATTRIBUTE (UNIX_NLINK);
257 REGISTER_ATTRIBUTE (UNIX_UID);
258 REGISTER_ATTRIBUTE (UNIX_GID);
259 REGISTER_ATTRIBUTE (UNIX_RDEV);
260 REGISTER_ATTRIBUTE (UNIX_BLOCK_SIZE);
261 REGISTER_ATTRIBUTE (UNIX_BLOCKS);
262 REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT);
263 REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE);
264 REGISTER_ATTRIBUTE (DOS_IS_SYSTEM);
265 REGISTER_ATTRIBUTE (DOS_IS_MOUNTPOINT);
266 REGISTER_ATTRIBUTE (DOS_REPARSE_POINT_TAG);
267 REGISTER_ATTRIBUTE (OWNER_USER);
268 REGISTER_ATTRIBUTE (OWNER_USER_REAL);
269 REGISTER_ATTRIBUTE (OWNER_GROUP);
270 REGISTER_ATTRIBUTE (THUMBNAIL_PATH);
271 REGISTER_ATTRIBUTE (THUMBNAILING_FAILED);
272 REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID);
273 REGISTER_ATTRIBUTE (THUMBNAIL_PATH_NORMAL);
274 REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_NORMAL);
275 REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_NORMAL);
276 REGISTER_ATTRIBUTE (THUMBNAIL_PATH_LARGE);
277 REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_LARGE);
278 REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_LARGE);
279 REGISTER_ATTRIBUTE (THUMBNAIL_PATH_XLARGE);
280 REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_XLARGE);
281 REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_XLARGE);
282 REGISTER_ATTRIBUTE (THUMBNAIL_PATH_XXLARGE);
283 REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_XXLARGE);
284 REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_XXLARGE);
285 REGISTER_ATTRIBUTE (PREVIEW_ICON);
286 REGISTER_ATTRIBUTE (FILESYSTEM_SIZE);
287 REGISTER_ATTRIBUTE (FILESYSTEM_FREE);
288 REGISTER_ATTRIBUTE (FILESYSTEM_TYPE);
289 REGISTER_ATTRIBUTE (FILESYSTEM_READONLY);
290 REGISTER_ATTRIBUTE (FILESYSTEM_USE_PREVIEW);
291 REGISTER_ATTRIBUTE (GVFS_BACKEND);
292 REGISTER_ATTRIBUTE (SELINUX_CONTEXT);
293 REGISTER_ATTRIBUTE (TRASH_ITEM_COUNT);
294 REGISTER_ATTRIBUTE (TRASH_ORIG_PATH);
295 REGISTER_ATTRIBUTE (TRASH_DELETION_DATE);
297 #undef REGISTER_ATTRIBUTE
301 lookup_namespace (const char *namespace)
306 G_LOCK (attribute_hash);
308 ensure_attribute_hash ();
310 ns_info = _lookup_namespace (namespace);
315 G_UNLOCK (attribute_hash);
321 get_attribute_for_id (int attribute)
324 G_LOCK (attribute_hash);
325 s = global_attributes[GET_NS (attribute)][GET_ID (attribute)];
326 G_UNLOCK (attribute_hash);
331 lookup_attribute (const char *attribute)
335 G_LOCK (attribute_hash);
336 ensure_attribute_hash ();
338 attr_id = _lookup_attribute (attribute);
340 G_UNLOCK (attribute_hash);
346 g_file_info_finalize (GObject *object)
350 GFileAttribute *attrs;
352 info = G_FILE_INFO (object);
354 attrs = (GFileAttribute *)info->attributes->data;
355 for (i = 0; i < info->attributes->len; i++)
356 _g_file_attribute_value_clear (&attrs[i].value);
357 g_array_free (info->attributes, TRUE);
359 if (info->mask != NO_ATTRIBUTE_MASK)
360 g_file_attribute_matcher_unref (info->mask);
362 G_OBJECT_CLASS (g_file_info_parent_class)->finalize (object);
366 g_file_info_class_init (GFileInfoClass *klass)
368 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
370 gobject_class->finalize = g_file_info_finalize;
374 g_file_info_init (GFileInfo *info)
376 info->mask = NO_ATTRIBUTE_MASK;
377 info->attributes = g_array_new (FALSE, FALSE,
378 sizeof (GFileAttribute));
384 * Creates a new file info structure.
386 * Returns: a #GFileInfo.
389 g_file_info_new (void)
391 return g_object_new (G_TYPE_FILE_INFO, NULL);
395 * g_file_info_copy_into:
396 * @src_info: source to copy attributes from.
397 * @dest_info: destination to copy attributes to.
399 * First clears all of the [GFileAttribute][gio-GFileAttribute] of @dest_info,
400 * and then copies all of the file attributes from @src_info to @dest_info.
403 g_file_info_copy_into (GFileInfo *src_info,
404 GFileInfo *dest_info)
406 GFileAttribute *source, *dest;
409 g_return_if_fail (G_IS_FILE_INFO (src_info));
410 g_return_if_fail (G_IS_FILE_INFO (dest_info));
412 dest = (GFileAttribute *)dest_info->attributes->data;
413 for (i = 0; i < dest_info->attributes->len; i++)
414 _g_file_attribute_value_clear (&dest[i].value);
416 g_array_set_size (dest_info->attributes,
417 src_info->attributes->len);
419 source = (GFileAttribute *)src_info->attributes->data;
420 dest = (GFileAttribute *)dest_info->attributes->data;
422 for (i = 0; i < src_info->attributes->len; i++)
424 dest[i].attribute = source[i].attribute;
425 dest[i].value.type = G_FILE_ATTRIBUTE_TYPE_INVALID;
426 _g_file_attribute_value_set (&dest[i].value, &source[i].value);
429 if (dest_info->mask != NO_ATTRIBUTE_MASK)
430 g_file_attribute_matcher_unref (dest_info->mask);
432 if (src_info->mask == NO_ATTRIBUTE_MASK)
433 dest_info->mask = NO_ATTRIBUTE_MASK;
435 dest_info->mask = g_file_attribute_matcher_ref (src_info->mask);
440 * @other: a #GFileInfo.
442 * Duplicates a file info structure.
444 * Returns: (transfer full): a duplicate #GFileInfo of @other.
447 g_file_info_dup (GFileInfo *other)
451 g_return_val_if_fail (G_IS_FILE_INFO (other), NULL);
453 new = g_file_info_new ();
454 g_file_info_copy_into (other, new);
459 * g_file_info_set_attribute_mask:
460 * @info: a #GFileInfo.
461 * @mask: a #GFileAttributeMatcher.
463 * Sets @mask on @info to match specific attribute types.
466 g_file_info_set_attribute_mask (GFileInfo *info,
467 GFileAttributeMatcher *mask)
469 GFileAttribute *attr;
472 g_return_if_fail (G_IS_FILE_INFO (info));
474 if (mask != info->mask)
476 if (info->mask != NO_ATTRIBUTE_MASK)
477 g_file_attribute_matcher_unref (info->mask);
478 info->mask = g_file_attribute_matcher_ref (mask);
480 /* Remove non-matching attributes */
481 for (i = 0; i < info->attributes->len; i++)
483 attr = &g_array_index (info->attributes, GFileAttribute, i);
484 if (!_g_file_attribute_matcher_matches_id (mask,
487 _g_file_attribute_value_clear (&attr->value);
488 g_array_remove_index (info->attributes, i);
496 * g_file_info_unset_attribute_mask:
499 * Unsets a mask set by g_file_info_set_attribute_mask(), if one
503 g_file_info_unset_attribute_mask (GFileInfo *info)
505 g_return_if_fail (G_IS_FILE_INFO (info));
507 if (info->mask != NO_ATTRIBUTE_MASK)
508 g_file_attribute_matcher_unref (info->mask);
509 info->mask = NO_ATTRIBUTE_MASK;
513 * g_file_info_clear_status:
514 * @info: a #GFileInfo.
516 * Clears the status information from @info.
519 g_file_info_clear_status (GFileInfo *info)
521 GFileAttribute *attrs;
524 g_return_if_fail (G_IS_FILE_INFO (info));
526 attrs = (GFileAttribute *)info->attributes->data;
527 for (i = 0; i < info->attributes->len; i++)
528 attrs[i].value.status = G_FILE_ATTRIBUTE_STATUS_UNSET;
532 g_file_info_find_place (GFileInfo *info,
536 GFileAttribute *attrs;
537 /* Binary search for the place where attribute would be, if it's
541 max = info->attributes->len;
543 attrs = (GFileAttribute *)info->attributes->data;
547 med = min + (max - min) / 2;
548 if (attrs[med].attribute == attribute)
553 else if (attrs[med].attribute < attribute)
555 else /* attrs[med].attribute > attribute */
562 static GFileAttributeValue *
563 g_file_info_find_value (GFileInfo *info,
566 GFileAttribute *attrs;
569 i = g_file_info_find_place (info, attr_id);
570 attrs = (GFileAttribute *)info->attributes->data;
571 if (i < info->attributes->len &&
572 attrs[i].attribute == attr_id)
573 return &attrs[i].value;
578 static GFileAttributeValue *
579 g_file_info_find_value_by_name (GFileInfo *info,
580 const char *attribute)
584 attr_id = lookup_attribute (attribute);
585 return g_file_info_find_value (info, attr_id);
589 * g_file_info_has_attribute:
590 * @info: a #GFileInfo.
591 * @attribute: a file attribute key.
593 * Checks if a file info structure has an attribute named @attribute.
595 * Returns: %TRUE if @info has an attribute named @attribute,
599 g_file_info_has_attribute (GFileInfo *info,
600 const char *attribute)
602 GFileAttributeValue *value;
604 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
605 g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
607 value = g_file_info_find_value_by_name (info, attribute);
608 return value != NULL;
612 * g_file_info_has_namespace:
613 * @info: a #GFileInfo.
614 * @name_space: a file attribute namespace.
616 * Checks if a file info structure has an attribute in the
617 * specified @name_space.
619 * Returns: %TRUE if @info has an attribute in @name_space,
625 g_file_info_has_namespace (GFileInfo *info,
626 const char *name_space)
628 GFileAttribute *attrs;
632 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
633 g_return_val_if_fail (name_space != NULL, FALSE);
635 ns_id = lookup_namespace (name_space);
637 attrs = (GFileAttribute *)info->attributes->data;
638 for (i = 0; i < info->attributes->len; i++)
640 if (GET_NS (attrs[i].attribute) == ns_id)
648 * g_file_info_list_attributes:
649 * @info: a #GFileInfo.
650 * @name_space: (nullable): a file attribute key's namespace, or %NULL to list
653 * Lists the file info structure's attributes.
655 * Returns: (nullable) (array zero-terminated=1) (transfer full): a
656 * null-terminated array of strings of all of the possible attribute
657 * types for the given @name_space, or %NULL on error.
660 g_file_info_list_attributes (GFileInfo *info,
661 const char *name_space)
664 GFileAttribute *attrs;
666 guint32 ns_id = (name_space) ? lookup_namespace (name_space) : 0;
669 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
671 names = g_ptr_array_new ();
672 attrs = (GFileAttribute *)info->attributes->data;
673 for (i = 0; i < info->attributes->len; i++)
675 attribute = attrs[i].attribute;
676 if (ns_id == 0 || GET_NS (attribute) == ns_id)
677 g_ptr_array_add (names, g_strdup (get_attribute_for_id (attribute)));
681 g_ptr_array_add (names, NULL);
683 return (char **)g_ptr_array_free (names, FALSE);
687 * g_file_info_get_attribute_type:
688 * @info: a #GFileInfo.
689 * @attribute: a file attribute key.
691 * Gets the attribute type for an attribute key.
693 * Returns: a #GFileAttributeType for the given @attribute, or
694 * %G_FILE_ATTRIBUTE_TYPE_INVALID if the key is not set.
697 g_file_info_get_attribute_type (GFileInfo *info,
698 const char *attribute)
700 GFileAttributeValue *value;
702 g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_ATTRIBUTE_TYPE_INVALID);
703 g_return_val_if_fail (attribute != NULL && *attribute != '\0', G_FILE_ATTRIBUTE_TYPE_INVALID);
705 value = g_file_info_find_value_by_name (info, attribute);
709 return G_FILE_ATTRIBUTE_TYPE_INVALID;
713 g_file_info_remove_value (GFileInfo *info,
716 GFileAttribute *attrs;
719 if (info->mask != NO_ATTRIBUTE_MASK &&
720 !_g_file_attribute_matcher_matches_id (info->mask, attr_id))
723 i = g_file_info_find_place (info, attr_id);
725 attrs = (GFileAttribute *)info->attributes->data;
726 if (i < info->attributes->len &&
727 attrs[i].attribute == attr_id)
729 _g_file_attribute_value_clear (&attrs[i].value);
730 g_array_remove_index (info->attributes, i);
735 * g_file_info_remove_attribute:
736 * @info: a #GFileInfo.
737 * @attribute: a file attribute key.
739 * Removes all cases of @attribute from @info if it exists.
742 g_file_info_remove_attribute (GFileInfo *info,
743 const char *attribute)
747 g_return_if_fail (G_IS_FILE_INFO (info));
748 g_return_if_fail (attribute != NULL && *attribute != '\0');
750 attr_id = lookup_attribute (attribute);
752 g_file_info_remove_value (info, attr_id);
756 * g_file_info_get_attribute_data:
757 * @info: a #GFileInfo
758 * @attribute: a file attribute key
759 * @type: (out) (optional): return location for the attribute type, or %NULL
760 * @value_pp: (out) (optional) (not nullable): return location for the
761 * attribute value, or %NULL; the attribute value will not be %NULL
762 * @status: (out) (optional): return location for the attribute status, or %NULL
764 * Gets the attribute type, value and status for an attribute key.
766 * Returns: (transfer none): %TRUE if @info has an attribute named @attribute,
770 g_file_info_get_attribute_data (GFileInfo *info,
771 const char *attribute,
772 GFileAttributeType *type,
774 GFileAttributeStatus *status)
776 GFileAttributeValue *value;
778 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
779 g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
781 value = g_file_info_find_value_by_name (info, attribute);
786 *status = value->status;
792 *value_pp = _g_file_attribute_value_peek_as_pointer (value);
798 * g_file_info_get_attribute_status:
799 * @info: a #GFileInfo
800 * @attribute: a file attribute key
802 * Gets the attribute status for an attribute key.
804 * Returns: a #GFileAttributeStatus for the given @attribute, or
805 * %G_FILE_ATTRIBUTE_STATUS_UNSET if the key is invalid.
809 g_file_info_get_attribute_status (GFileInfo *info,
810 const char *attribute)
812 GFileAttributeValue *val;
814 g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
815 g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
817 val = g_file_info_find_value_by_name (info, attribute);
821 return G_FILE_ATTRIBUTE_STATUS_UNSET;
825 * g_file_info_set_attribute_status:
826 * @info: a #GFileInfo
827 * @attribute: a file attribute key
828 * @status: a #GFileAttributeStatus
830 * Sets the attribute status for an attribute key. This is only
831 * needed by external code that implement g_file_set_attributes_from_info()
832 * or similar functions.
834 * The attribute must exist in @info for this to work. Otherwise %FALSE
835 * is returned and @info is unchanged.
837 * Returns: %TRUE if the status was changed, %FALSE if the key was not set.
842 g_file_info_set_attribute_status (GFileInfo *info,
843 const char *attribute,
844 GFileAttributeStatus status)
846 GFileAttributeValue *val;
848 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
849 g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
851 val = g_file_info_find_value_by_name (info, attribute);
854 val->status = status;
861 GFileAttributeValue *
862 _g_file_info_get_attribute_value (GFileInfo *info,
863 const char *attribute)
866 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
867 g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
869 return g_file_info_find_value_by_name (info, attribute);
873 * g_file_info_get_attribute_as_string:
874 * @info: a #GFileInfo.
875 * @attribute: a file attribute key.
877 * Gets the value of an attribute, formatted as a string.
878 * This escapes things as needed to make the string valid
881 * Returns: (nullable): a UTF-8 string associated with the given @attribute, or
882 * %NULL if the attribute wasn’t set.
883 * When you're done with the string it must be freed with g_free().
886 g_file_info_get_attribute_as_string (GFileInfo *info,
887 const char *attribute)
889 GFileAttributeValue *val;
890 val = _g_file_info_get_attribute_value (info, attribute);
892 return _g_file_attribute_value_as_string (val);
898 * g_file_info_get_attribute_object:
899 * @info: a #GFileInfo.
900 * @attribute: a file attribute key.
902 * Gets the value of a #GObject attribute. If the attribute does
903 * not contain a #GObject, %NULL will be returned.
905 * Returns: (transfer none) (nullable): a #GObject associated with the given @attribute,
906 * or %NULL otherwise.
909 g_file_info_get_attribute_object (GFileInfo *info,
910 const char *attribute)
912 GFileAttributeValue *value;
914 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
915 g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
917 value = g_file_info_find_value_by_name (info, attribute);
918 return _g_file_attribute_value_get_object (value);
922 * g_file_info_get_attribute_string:
923 * @info: a #GFileInfo.
924 * @attribute: a file attribute key.
926 * Gets the value of a string attribute. If the attribute does
927 * not contain a string, %NULL will be returned.
929 * Returns: (nullable): the contents of the @attribute value as a UTF-8 string,
930 * or %NULL otherwise.
933 g_file_info_get_attribute_string (GFileInfo *info,
934 const char *attribute)
936 GFileAttributeValue *value;
938 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
939 g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
941 value = g_file_info_find_value_by_name (info, attribute);
942 return _g_file_attribute_value_get_string (value);
946 * g_file_info_get_attribute_byte_string:
947 * @info: a #GFileInfo.
948 * @attribute: a file attribute key.
950 * Gets the value of a byte string attribute. If the attribute does
951 * not contain a byte string, %NULL will be returned.
953 * Returns: (nullable): the contents of the @attribute value as a byte string, or
957 g_file_info_get_attribute_byte_string (GFileInfo *info,
958 const char *attribute)
960 GFileAttributeValue *value;
962 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
963 g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
965 value = g_file_info_find_value_by_name (info, attribute);
966 return _g_file_attribute_value_get_byte_string (value);
970 * g_file_info_get_attribute_file_path:
971 * @info: a #GFileInfo.
972 * @attribute: a file attribute key.
974 * Gets the value of a byte string attribute as a file path.
976 * If the attribute does not contain a byte string, `NULL` will be returned.
978 * This function is meant to be used by language bindings that have specific
979 * handling for Unix paths.
981 * Returns: (type filename) (nullable): the contents of the @attribute value as
982 * a file path, or %NULL otherwise.
987 g_file_info_get_attribute_file_path (GFileInfo *info,
988 const char *attribute)
990 return g_file_info_get_attribute_byte_string (info, attribute);
994 * g_file_info_get_attribute_stringv:
995 * @info: a #GFileInfo.
996 * @attribute: a file attribute key.
998 * Gets the value of a stringv attribute. If the attribute does
999 * not contain a stringv, %NULL will be returned.
1001 * Returns: (transfer none) (nullable): the contents of the @attribute value as a stringv,
1002 * or %NULL otherwise. Do not free. These returned strings are UTF-8.
1007 g_file_info_get_attribute_stringv (GFileInfo *info,
1008 const char *attribute)
1010 GFileAttributeValue *value;
1012 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1013 g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
1015 value = g_file_info_find_value_by_name (info, attribute);
1016 return _g_file_attribute_value_get_stringv (value);
1020 * g_file_info_get_attribute_boolean:
1021 * @info: a #GFileInfo.
1022 * @attribute: a file attribute key.
1024 * Gets the value of a boolean attribute. If the attribute does not
1025 * contain a boolean value, %FALSE will be returned.
1027 * Returns: the boolean value contained within the attribute.
1030 g_file_info_get_attribute_boolean (GFileInfo *info,
1031 const char *attribute)
1033 GFileAttributeValue *value;
1035 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
1036 g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
1038 value = g_file_info_find_value_by_name (info, attribute);
1039 return _g_file_attribute_value_get_boolean (value);
1043 * g_file_info_get_attribute_uint32:
1044 * @info: a #GFileInfo.
1045 * @attribute: a file attribute key.
1047 * Gets an unsigned 32-bit integer contained within the attribute. If the
1048 * attribute does not contain an unsigned 32-bit integer, or is invalid,
1049 * 0 will be returned.
1051 * Returns: an unsigned 32-bit integer from the attribute.
1054 g_file_info_get_attribute_uint32 (GFileInfo *info,
1055 const char *attribute)
1057 GFileAttributeValue *value;
1059 g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
1060 g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
1062 value = g_file_info_find_value_by_name (info, attribute);
1063 return _g_file_attribute_value_get_uint32 (value);
1067 * g_file_info_get_attribute_int32:
1068 * @info: a #GFileInfo.
1069 * @attribute: a file attribute key.
1071 * Gets a signed 32-bit integer contained within the attribute. If the
1072 * attribute does not contain a signed 32-bit integer, or is invalid,
1073 * 0 will be returned.
1075 * Returns: a signed 32-bit integer from the attribute.
1078 g_file_info_get_attribute_int32 (GFileInfo *info,
1079 const char *attribute)
1081 GFileAttributeValue *value;
1083 g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
1084 g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
1086 value = g_file_info_find_value_by_name (info, attribute);
1087 return _g_file_attribute_value_get_int32 (value);
1091 * g_file_info_get_attribute_uint64:
1092 * @info: a #GFileInfo.
1093 * @attribute: a file attribute key.
1095 * Gets a unsigned 64-bit integer contained within the attribute. If the
1096 * attribute does not contain an unsigned 64-bit integer, or is invalid,
1097 * 0 will be returned.
1099 * Returns: a unsigned 64-bit integer from the attribute.
1102 g_file_info_get_attribute_uint64 (GFileInfo *info,
1103 const char *attribute)
1105 GFileAttributeValue *value;
1107 g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
1108 g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
1110 value = g_file_info_find_value_by_name (info, attribute);
1111 return _g_file_attribute_value_get_uint64 (value);
1115 * g_file_info_get_attribute_int64:
1116 * @info: a #GFileInfo.
1117 * @attribute: a file attribute key.
1119 * Gets a signed 64-bit integer contained within the attribute. If the
1120 * attribute does not contain a signed 64-bit integer, or is invalid,
1121 * 0 will be returned.
1123 * Returns: a signed 64-bit integer from the attribute.
1126 g_file_info_get_attribute_int64 (GFileInfo *info,
1127 const char *attribute)
1129 GFileAttributeValue *value;
1131 g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
1132 g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
1134 value = g_file_info_find_value_by_name (info, attribute);
1135 return _g_file_attribute_value_get_int64 (value);
1138 static GFileAttributeValue *
1139 g_file_info_create_value (GFileInfo *info,
1142 GFileAttribute *attrs;
1145 if (info->mask != NO_ATTRIBUTE_MASK &&
1146 !_g_file_attribute_matcher_matches_id (info->mask, attr_id))
1149 i = g_file_info_find_place (info, attr_id);
1151 attrs = (GFileAttribute *)info->attributes->data;
1152 if (i < info->attributes->len &&
1153 attrs[i].attribute == attr_id)
1154 return &attrs[i].value;
1157 GFileAttribute attr = { 0 };
1158 attr.attribute = attr_id;
1159 g_array_insert_val (info->attributes, i, attr);
1161 attrs = (GFileAttribute *)info->attributes->data;
1162 return &attrs[i].value;
1167 _g_file_info_set_attribute_by_id (GFileInfo *info,
1169 GFileAttributeType type,
1172 GFileAttributeValue *value;
1174 value = g_file_info_create_value (info, attribute);
1177 _g_file_attribute_value_set_from_pointer (value, type, value_p, TRUE);
1181 * g_file_info_set_attribute:
1182 * @info: a #GFileInfo.
1183 * @attribute: a file attribute key.
1184 * @type: a #GFileAttributeType
1185 * @value_p: (not nullable): pointer to the value
1187 * Sets the @attribute to contain the given value, if possible. To unset the
1188 * attribute, use %G_FILE_ATTRIBUTE_TYPE_INVALID for @type.
1191 g_file_info_set_attribute (GFileInfo *info,
1192 const char *attribute,
1193 GFileAttributeType type,
1196 g_return_if_fail (G_IS_FILE_INFO (info));
1197 g_return_if_fail (attribute != NULL && *attribute != '\0');
1199 _g_file_info_set_attribute_by_id (info, lookup_attribute (attribute), type, value_p);
1203 _g_file_info_set_attribute_object_by_id (GFileInfo *info,
1205 GObject *attr_value)
1207 GFileAttributeValue *value;
1209 value = g_file_info_create_value (info, attribute);
1211 _g_file_attribute_value_set_object (value, attr_value);
1215 * g_file_info_set_attribute_object:
1216 * @info: a #GFileInfo.
1217 * @attribute: a file attribute key.
1218 * @attr_value: a #GObject.
1220 * Sets the @attribute to contain the given @attr_value,
1224 g_file_info_set_attribute_object (GFileInfo *info,
1225 const char *attribute,
1226 GObject *attr_value)
1228 g_return_if_fail (G_IS_FILE_INFO (info));
1229 g_return_if_fail (attribute != NULL && *attribute != '\0');
1230 g_return_if_fail (G_IS_OBJECT (attr_value));
1232 _g_file_info_set_attribute_object_by_id (info,
1233 lookup_attribute (attribute),
1238 _g_file_info_set_attribute_stringv_by_id (GFileInfo *info,
1242 GFileAttributeValue *value;
1244 value = g_file_info_create_value (info, attribute);
1246 _g_file_attribute_value_set_stringv (value, attr_value);
1250 * g_file_info_set_attribute_stringv:
1251 * @info: a #GFileInfo.
1252 * @attribute: a file attribute key
1253 * @attr_value: (array zero-terminated=1) (element-type utf8): a %NULL
1254 * terminated array of UTF-8 strings.
1256 * Sets the @attribute to contain the given @attr_value,
1262 g_file_info_set_attribute_stringv (GFileInfo *info,
1263 const char *attribute,
1266 g_return_if_fail (G_IS_FILE_INFO (info));
1267 g_return_if_fail (attribute != NULL && *attribute != '\0');
1268 g_return_if_fail (attr_value != NULL);
1270 _g_file_info_set_attribute_stringv_by_id (info,
1271 lookup_attribute (attribute),
1276 _g_file_info_set_attribute_string_by_id (GFileInfo *info,
1278 const char *attr_value)
1280 GFileAttributeValue *value;
1282 value = g_file_info_create_value (info, attribute);
1284 _g_file_attribute_value_set_string (value, attr_value);
1288 * g_file_info_set_attribute_string:
1289 * @info: a #GFileInfo.
1290 * @attribute: a file attribute key.
1291 * @attr_value: a UTF-8 string.
1293 * Sets the @attribute to contain the given @attr_value,
1297 g_file_info_set_attribute_string (GFileInfo *info,
1298 const char *attribute,
1299 const char *attr_value)
1301 g_return_if_fail (G_IS_FILE_INFO (info));
1302 g_return_if_fail (attribute != NULL && *attribute != '\0');
1303 g_return_if_fail (attr_value != NULL);
1305 _g_file_info_set_attribute_string_by_id (info,
1306 lookup_attribute (attribute),
1311 _g_file_info_set_attribute_byte_string_by_id (GFileInfo *info,
1313 const char *attr_value)
1315 GFileAttributeValue *value;
1317 value = g_file_info_create_value (info, attribute);
1319 _g_file_attribute_value_set_byte_string (value, attr_value);
1323 * g_file_info_set_attribute_byte_string:
1324 * @info: a #GFileInfo.
1325 * @attribute: a file attribute key.
1326 * @attr_value: a byte string.
1328 * Sets the @attribute to contain the given @attr_value,
1332 g_file_info_set_attribute_byte_string (GFileInfo *info,
1333 const char *attribute,
1334 const char *attr_value)
1336 g_return_if_fail (G_IS_FILE_INFO (info));
1337 g_return_if_fail (attribute != NULL && *attribute != '\0');
1338 g_return_if_fail (attr_value != NULL);
1340 _g_file_info_set_attribute_byte_string_by_id (info,
1341 lookup_attribute (attribute),
1346 * g_file_info_set_attribute_file_path:
1347 * @info: a #GFileInfo.
1348 * @attribute: a file attribute key.
1349 * @attr_value: (type filename): a file path.
1351 * Sets the @attribute to contain the given @attr_value,
1354 * This function is meant to be used by language bindings that have specific
1355 * handling for Unix paths.
1360 g_file_info_set_attribute_file_path (GFileInfo *info,
1361 const char *attribute,
1362 const char *attr_value)
1364 g_file_info_set_attribute_byte_string (info, attribute, attr_value);
1368 _g_file_info_set_attribute_boolean_by_id (GFileInfo *info,
1370 gboolean attr_value)
1372 GFileAttributeValue *value;
1374 value = g_file_info_create_value (info, attribute);
1376 _g_file_attribute_value_set_boolean (value, attr_value);
1380 * g_file_info_set_attribute_boolean:
1381 * @info: a #GFileInfo.
1382 * @attribute: a file attribute key.
1383 * @attr_value: a boolean value.
1385 * Sets the @attribute to contain the given @attr_value,
1389 g_file_info_set_attribute_boolean (GFileInfo *info,
1390 const char *attribute,
1391 gboolean attr_value)
1393 g_return_if_fail (G_IS_FILE_INFO (info));
1394 g_return_if_fail (attribute != NULL && *attribute != '\0');
1396 _g_file_info_set_attribute_boolean_by_id (info,
1397 lookup_attribute (attribute),
1402 _g_file_info_set_attribute_uint32_by_id (GFileInfo *info,
1406 GFileAttributeValue *value;
1408 value = g_file_info_create_value (info, attribute);
1410 _g_file_attribute_value_set_uint32 (value, attr_value);
1414 * g_file_info_set_attribute_uint32:
1415 * @info: a #GFileInfo.
1416 * @attribute: a file attribute key.
1417 * @attr_value: an unsigned 32-bit integer.
1419 * Sets the @attribute to contain the given @attr_value,
1423 g_file_info_set_attribute_uint32 (GFileInfo *info,
1424 const char *attribute,
1427 g_return_if_fail (G_IS_FILE_INFO (info));
1428 g_return_if_fail (attribute != NULL && *attribute != '\0');
1430 _g_file_info_set_attribute_uint32_by_id (info,
1431 lookup_attribute (attribute),
1436 _g_file_info_set_attribute_int32_by_id (GFileInfo *info,
1440 GFileAttributeValue *value;
1442 value = g_file_info_create_value (info, attribute);
1444 _g_file_attribute_value_set_int32 (value, attr_value);
1448 * g_file_info_set_attribute_int32:
1449 * @info: a #GFileInfo.
1450 * @attribute: a file attribute key.
1451 * @attr_value: a signed 32-bit integer
1453 * Sets the @attribute to contain the given @attr_value,
1457 g_file_info_set_attribute_int32 (GFileInfo *info,
1458 const char *attribute,
1461 g_return_if_fail (G_IS_FILE_INFO (info));
1462 g_return_if_fail (attribute != NULL && *attribute != '\0');
1464 _g_file_info_set_attribute_int32_by_id (info,
1465 lookup_attribute (attribute),
1470 _g_file_info_set_attribute_uint64_by_id (GFileInfo *info,
1474 GFileAttributeValue *value;
1476 value = g_file_info_create_value (info, attribute);
1478 _g_file_attribute_value_set_uint64 (value, attr_value);
1482 * g_file_info_set_attribute_uint64:
1483 * @info: a #GFileInfo.
1484 * @attribute: a file attribute key.
1485 * @attr_value: an unsigned 64-bit integer.
1487 * Sets the @attribute to contain the given @attr_value,
1491 g_file_info_set_attribute_uint64 (GFileInfo *info,
1492 const char *attribute,
1495 g_return_if_fail (G_IS_FILE_INFO (info));
1496 g_return_if_fail (attribute != NULL && *attribute != '\0');
1498 _g_file_info_set_attribute_uint64_by_id (info,
1499 lookup_attribute (attribute),
1504 _g_file_info_set_attribute_int64_by_id (GFileInfo *info,
1508 GFileAttributeValue *value;
1510 value = g_file_info_create_value (info, attribute);
1512 _g_file_attribute_value_set_int64 (value, attr_value);
1516 * g_file_info_set_attribute_int64:
1517 * @info: a #GFileInfo.
1518 * @attribute: attribute name to set.
1519 * @attr_value: int64 value to set attribute to.
1521 * Sets the @attribute to contain the given @attr_value,
1526 g_file_info_set_attribute_int64 (GFileInfo *info,
1527 const char *attribute,
1530 g_return_if_fail (G_IS_FILE_INFO (info));
1531 g_return_if_fail (attribute != NULL && *attribute != '\0');
1533 _g_file_info_set_attribute_int64_by_id (info,
1534 lookup_attribute (attribute),
1538 /* Helper getters */
1539 #define get_required_attribute(value_ptr, info, attribute_name, error_value) \
1541 static guint32 attr = 0; \
1544 attr = lookup_attribute (attribute_name); \
1546 *value_ptr = g_file_info_find_value (info, attr); \
1547 if (G_UNLIKELY (*value_ptr == NULL)) \
1549 g_critical ("GFileInfo created without " attribute_name); \
1550 g_return_val_if_reached (error_value); \
1555 * g_file_info_get_deletion_date:
1556 * @info: a #GFileInfo.
1558 * Returns the #GDateTime representing the deletion date of the file, as
1559 * available in %G_FILE_ATTRIBUTE_TRASH_DELETION_DATE. If the
1560 * %G_FILE_ATTRIBUTE_TRASH_DELETION_DATE attribute is unset, %NULL is returned.
1562 * Returns: (nullable): a #GDateTime, or %NULL.
1567 g_file_info_get_deletion_date (GFileInfo *info)
1569 static guint32 attr = 0;
1570 GFileAttributeValue *value;
1571 const char *date_str;
1572 GTimeZone *local_tz = NULL;
1573 GDateTime *dt = NULL;
1575 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
1578 attr = lookup_attribute (G_FILE_ATTRIBUTE_TRASH_DELETION_DATE);
1580 value = g_file_info_find_value (info, attr);
1581 date_str = _g_file_attribute_value_get_string (value);
1585 local_tz = g_time_zone_new_local ();
1586 dt = g_date_time_new_from_iso8601 (date_str, local_tz);
1587 g_time_zone_unref (local_tz);
1589 return g_steal_pointer (&dt);
1593 * g_file_info_get_file_type:
1594 * @info: a #GFileInfo.
1596 * Gets a file's type (whether it is a regular file, symlink, etc).
1597 * This is different from the file's content type, see g_file_info_get_content_type().
1599 * It is an error to call this if the #GFileInfo does not contain
1600 * %G_FILE_ATTRIBUTE_STANDARD_TYPE.
1602 * Returns: a #GFileType for the given file.
1605 g_file_info_get_file_type (GFileInfo *info)
1607 GFileAttributeValue *value;
1609 g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_TYPE_UNKNOWN);
1611 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_TYPE_UNKNOWN);
1612 return (GFileType)_g_file_attribute_value_get_uint32 (value);
1616 * g_file_info_get_is_hidden:
1617 * @info: a #GFileInfo.
1619 * Checks if a file is hidden.
1621 * It is an error to call this if the #GFileInfo does not contain
1622 * %G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN.
1624 * Returns: %TRUE if the file is a hidden file, %FALSE otherwise.
1627 g_file_info_get_is_hidden (GFileInfo *info)
1629 GFileAttributeValue *value;
1631 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
1633 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, FALSE);
1634 return _g_file_attribute_value_get_boolean (value);
1638 * g_file_info_get_is_backup:
1639 * @info: a #GFileInfo.
1641 * Checks if a file is a backup file.
1643 * It is an error to call this if the #GFileInfo does not contain
1644 * %G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP.
1646 * Returns: %TRUE if file is a backup file, %FALSE otherwise.
1649 g_file_info_get_is_backup (GFileInfo *info)
1651 GFileAttributeValue *value;
1653 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
1655 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, FALSE);
1656 return _g_file_attribute_value_get_boolean (value);
1660 * g_file_info_get_is_symlink:
1661 * @info: a #GFileInfo.
1663 * Checks if a file is a symlink.
1665 * It is an error to call this if the #GFileInfo does not contain
1666 * %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK.
1668 * Returns: %TRUE if the given @info is a symlink.
1671 g_file_info_get_is_symlink (GFileInfo *info)
1673 GFileAttributeValue *value;
1675 g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
1677 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, FALSE);
1678 return _g_file_attribute_value_get_boolean (value);
1682 * g_file_info_get_name:
1683 * @info: a #GFileInfo.
1685 * Gets the name for a file. This is guaranteed to always be set.
1687 * It is an error to call this if the #GFileInfo does not contain
1688 * %G_FILE_ATTRIBUTE_STANDARD_NAME.
1690 * Returns: (type filename) (not nullable): a string containing the file name.
1693 g_file_info_get_name (GFileInfo *info)
1695 GFileAttributeValue *value;
1697 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1699 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_NAME, NULL);
1700 return _g_file_attribute_value_get_byte_string (value);
1704 * g_file_info_get_display_name:
1705 * @info: a #GFileInfo.
1707 * Gets a display name for a file. This is guaranteed to always be set.
1709 * It is an error to call this if the #GFileInfo does not contain
1710 * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME.
1712 * Returns: (not nullable): a string containing the display name.
1715 g_file_info_get_display_name (GFileInfo *info)
1717 GFileAttributeValue *value;
1719 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1721 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, NULL);
1722 return _g_file_attribute_value_get_string (value);
1726 * g_file_info_get_edit_name:
1727 * @info: a #GFileInfo.
1729 * Gets the edit name for a file.
1731 * It is an error to call this if the #GFileInfo does not contain
1732 * %G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME.
1734 * Returns: a string containing the edit name.
1737 g_file_info_get_edit_name (GFileInfo *info)
1739 GFileAttributeValue *value;
1741 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1743 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, NULL);
1744 return _g_file_attribute_value_get_string (value);
1748 * g_file_info_get_icon:
1749 * @info: a #GFileInfo.
1751 * Gets the icon for a file.
1753 * It is an error to call this if the #GFileInfo does not contain
1754 * %G_FILE_ATTRIBUTE_STANDARD_ICON.
1756 * Returns: (nullable) (transfer none): #GIcon for the given @info.
1759 g_file_info_get_icon (GFileInfo *info)
1761 GFileAttributeValue *value;
1764 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1766 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_ICON, NULL);
1768 obj = _g_file_attribute_value_get_object (value);
1769 if (G_IS_ICON (obj))
1770 return G_ICON (obj);
1775 * g_file_info_get_symbolic_icon:
1776 * @info: a #GFileInfo.
1778 * Gets the symbolic icon for a file.
1780 * It is an error to call this if the #GFileInfo does not contain
1781 * %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON.
1783 * Returns: (nullable) (transfer none): #GIcon for the given @info.
1788 g_file_info_get_symbolic_icon (GFileInfo *info)
1790 GFileAttributeValue *value;
1793 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1795 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON, NULL);
1797 obj = _g_file_attribute_value_get_object (value);
1798 if (G_IS_ICON (obj))
1799 return G_ICON (obj);
1804 * g_file_info_get_content_type:
1805 * @info: a #GFileInfo.
1807 * Gets the file's content type.
1809 * It is an error to call this if the #GFileInfo does not contain
1810 * %G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE.
1812 * Returns: (nullable): a string containing the file's content type,
1813 * or %NULL if unknown.
1816 g_file_info_get_content_type (GFileInfo *info)
1818 GFileAttributeValue *value;
1820 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1822 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, NULL);
1823 return _g_file_attribute_value_get_string (value);
1827 * g_file_info_get_size:
1828 * @info: a #GFileInfo.
1830 * Gets the file's size (in bytes). The size is retrieved through the value of
1831 * the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute and is converted
1832 * from #guint64 to #goffset before returning the result.
1834 * It is an error to call this if the #GFileInfo does not contain
1835 * %G_FILE_ATTRIBUTE_STANDARD_SIZE.
1837 * Returns: a #goffset containing the file's size (in bytes).
1840 g_file_info_get_size (GFileInfo *info)
1842 GFileAttributeValue *value;
1844 g_return_val_if_fail (G_IS_FILE_INFO (info), (goffset) 0);
1846 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SIZE, (goffset) 0);
1847 return (goffset) _g_file_attribute_value_get_uint64 (value);
1851 * g_file_info_get_modification_time:
1852 * @info: a #GFileInfo.
1853 * @result: (out caller-allocates): a #GTimeVal.
1855 * Gets the modification time of the current @info and sets it
1858 * It is an error to call this if the #GFileInfo does not contain
1859 * %G_FILE_ATTRIBUTE_TIME_MODIFIED. If %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is
1860 * provided it will be used too.
1862 * Deprecated: 2.62: Use g_file_info_get_modification_date_time() instead, as
1863 * #GTimeVal is deprecated due to the year 2038 problem.
1865 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
1867 g_file_info_get_modification_time (GFileInfo *info,
1870 static guint32 attr_mtime = 0, attr_mtime_usec;
1871 GFileAttributeValue *value;
1873 g_return_if_fail (G_IS_FILE_INFO (info));
1874 g_return_if_fail (result != NULL);
1876 if (attr_mtime == 0)
1878 attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
1879 attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
1882 value = g_file_info_find_value (info, attr_mtime);
1884 if (G_UNLIKELY (value == NULL))
1886 g_critical ("GFileInfo created without " G_FILE_ATTRIBUTE_TIME_MODIFIED);
1887 result->tv_sec = result->tv_usec = 0;
1888 g_return_if_reached ();
1891 result->tv_sec = _g_file_attribute_value_get_uint64 (value);
1892 value = g_file_info_find_value (info, attr_mtime_usec);
1893 result->tv_usec = _g_file_attribute_value_get_uint32 (value);
1895 G_GNUC_END_IGNORE_DEPRECATIONS
1898 * g_file_info_get_modification_date_time:
1899 * @info: a #GFileInfo.
1901 * Gets the modification time of the current @info and returns it as a
1904 * It is an error to call this if the #GFileInfo does not contain
1905 * %G_FILE_ATTRIBUTE_TIME_MODIFIED. If %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is
1906 * provided, the resulting #GDateTime will additionally have microsecond
1909 * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC must
1910 * be queried separately using g_file_info_get_attribute_uint32().
1912 * Returns: (transfer full) (nullable): modification time, or %NULL if unknown
1916 g_file_info_get_modification_date_time (GFileInfo *info)
1918 static guint32 attr_mtime = 0, attr_mtime_usec;
1919 GFileAttributeValue *value, *value_usec;
1920 GDateTime *dt = NULL, *dt2 = NULL;
1922 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1924 if (attr_mtime == 0)
1926 attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
1927 attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
1930 value = g_file_info_find_value (info, attr_mtime);
1934 dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
1936 value_usec = g_file_info_find_value (info, attr_mtime_usec);
1937 if (value_usec == NULL)
1938 return g_steal_pointer (&dt);
1940 dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
1941 g_date_time_unref (dt);
1943 return g_steal_pointer (&dt2);
1947 * g_file_info_get_access_date_time:
1948 * @info: a #GFileInfo.
1950 * Gets the access time of the current @info and returns it as a
1953 * It is an error to call this if the #GFileInfo does not contain
1954 * %G_FILE_ATTRIBUTE_TIME_ACCESS. If %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC is
1955 * provided, the resulting #GDateTime will additionally have microsecond
1958 * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC must
1959 * be queried separately using g_file_info_get_attribute_uint32().
1961 * Returns: (transfer full) (nullable): access time, or %NULL if unknown
1965 g_file_info_get_access_date_time (GFileInfo *info)
1967 static guint32 attr_atime = 0, attr_atime_usec;
1968 GFileAttributeValue *value, *value_usec;
1969 GDateTime *dt = NULL, *dt2 = NULL;
1971 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
1973 if (attr_atime == 0)
1975 attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS);
1976 attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
1979 value = g_file_info_find_value (info, attr_atime);
1983 dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
1985 value_usec = g_file_info_find_value (info, attr_atime_usec);
1986 if (value_usec == NULL)
1987 return g_steal_pointer (&dt);
1989 dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
1990 g_date_time_unref (dt);
1992 return g_steal_pointer (&dt2);
1996 * g_file_info_get_creation_date_time:
1997 * @info: a #GFileInfo.
1999 * Gets the creation time of the current @info and returns it as a
2002 * It is an error to call this if the #GFileInfo does not contain
2003 * %G_FILE_ATTRIBUTE_TIME_CREATED. If %G_FILE_ATTRIBUTE_TIME_CREATED_USEC is
2004 * provided, the resulting #GDateTime will additionally have microsecond
2007 * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_CREATED_NSEC must
2008 * be queried separately using g_file_info_get_attribute_uint32().
2010 * Returns: (transfer full) (nullable): creation time, or %NULL if unknown
2014 g_file_info_get_creation_date_time (GFileInfo *info)
2016 static guint32 attr_ctime = 0, attr_ctime_usec;
2017 GFileAttributeValue *value, *value_usec;
2018 GDateTime *dt = NULL, *dt2 = NULL;
2020 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
2022 if (attr_ctime == 0)
2024 attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED);
2025 attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
2028 value = g_file_info_find_value (info, attr_ctime);
2032 dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
2034 value_usec = g_file_info_find_value (info, attr_ctime_usec);
2035 if (value_usec == NULL)
2036 return g_steal_pointer (&dt);
2038 dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
2039 g_date_time_unref (dt);
2041 return g_steal_pointer (&dt2);
2045 * g_file_info_get_symlink_target:
2046 * @info: a #GFileInfo.
2048 * Gets the symlink target for a given #GFileInfo.
2050 * It is an error to call this if the #GFileInfo does not contain
2051 * %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET.
2053 * Returns: (type filename) (nullable): a string containing the symlink target.
2056 g_file_info_get_symlink_target (GFileInfo *info)
2058 GFileAttributeValue *value;
2060 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
2062 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, NULL);
2063 return _g_file_attribute_value_get_byte_string (value);
2067 * g_file_info_get_etag:
2068 * @info: a #GFileInfo.
2070 * Gets the [entity tag][gfile-etag] for a given
2071 * #GFileInfo. See %G_FILE_ATTRIBUTE_ETAG_VALUE.
2073 * It is an error to call this if the #GFileInfo does not contain
2074 * %G_FILE_ATTRIBUTE_ETAG_VALUE.
2076 * Returns: (nullable): a string containing the value of the "etag:value" attribute.
2079 g_file_info_get_etag (GFileInfo *info)
2081 GFileAttributeValue *value;
2083 g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
2085 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_ETAG_VALUE, NULL);
2086 return _g_file_attribute_value_get_string (value);
2090 * g_file_info_get_sort_order:
2091 * @info: a #GFileInfo.
2093 * Gets the value of the sort_order attribute from the #GFileInfo.
2094 * See %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER.
2096 * It is an error to call this if the #GFileInfo does not contain
2097 * %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER.
2099 * Returns: a #gint32 containing the value of the "standard::sort_order" attribute.
2102 g_file_info_get_sort_order (GFileInfo *info)
2104 GFileAttributeValue *value;
2106 g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
2108 get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 0);
2109 return _g_file_attribute_value_get_int32 (value);
2112 /* Helper setters: */
2114 * g_file_info_set_file_type:
2115 * @info: a #GFileInfo.
2116 * @type: a #GFileType.
2118 * Sets the file type in a #GFileInfo to @type.
2119 * See %G_FILE_ATTRIBUTE_STANDARD_TYPE.
2122 g_file_info_set_file_type (GFileInfo *info,
2125 static guint32 attr = 0;
2126 GFileAttributeValue *value;
2128 g_return_if_fail (G_IS_FILE_INFO (info));
2131 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_TYPE);
2133 value = g_file_info_create_value (info, attr);
2135 _g_file_attribute_value_set_uint32 (value, type);
2139 * g_file_info_set_is_hidden:
2140 * @info: a #GFileInfo.
2141 * @is_hidden: a #gboolean.
2143 * Sets the "is_hidden" attribute in a #GFileInfo according to @is_hidden.
2144 * See %G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN.
2147 g_file_info_set_is_hidden (GFileInfo *info,
2150 static guint32 attr = 0;
2151 GFileAttributeValue *value;
2153 g_return_if_fail (G_IS_FILE_INFO (info));
2156 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
2158 value = g_file_info_create_value (info, attr);
2160 _g_file_attribute_value_set_boolean (value, is_hidden);
2164 * g_file_info_set_is_symlink:
2165 * @info: a #GFileInfo.
2166 * @is_symlink: a #gboolean.
2168 * Sets the "is_symlink" attribute in a #GFileInfo according to @is_symlink.
2169 * See %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK.
2172 g_file_info_set_is_symlink (GFileInfo *info,
2173 gboolean is_symlink)
2175 static guint32 attr = 0;
2176 GFileAttributeValue *value;
2178 g_return_if_fail (G_IS_FILE_INFO (info));
2181 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
2183 value = g_file_info_create_value (info, attr);
2185 _g_file_attribute_value_set_boolean (value, is_symlink);
2189 * g_file_info_set_name:
2190 * @info: a #GFileInfo.
2191 * @name: (type filename): a string containing a name.
2193 * Sets the name attribute for the current #GFileInfo.
2194 * See %G_FILE_ATTRIBUTE_STANDARD_NAME.
2197 g_file_info_set_name (GFileInfo *info,
2200 static guint32 attr = 0;
2201 GFileAttributeValue *value;
2203 g_return_if_fail (G_IS_FILE_INFO (info));
2204 g_return_if_fail (name != NULL);
2207 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_NAME);
2209 value = g_file_info_create_value (info, attr);
2211 _g_file_attribute_value_set_byte_string (value, name);
2215 * g_file_info_set_display_name:
2216 * @info: a #GFileInfo.
2217 * @display_name: a string containing a display name.
2219 * Sets the display name for the current #GFileInfo.
2220 * See %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME.
2223 g_file_info_set_display_name (GFileInfo *info,
2224 const char *display_name)
2226 static guint32 attr = 0;
2227 GFileAttributeValue *value;
2229 g_return_if_fail (G_IS_FILE_INFO (info));
2230 g_return_if_fail (display_name != NULL);
2233 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
2235 value = g_file_info_create_value (info, attr);
2237 _g_file_attribute_value_set_string (value, display_name);
2241 * g_file_info_set_edit_name:
2242 * @info: a #GFileInfo.
2243 * @edit_name: a string containing an edit name.
2245 * Sets the edit name for the current file.
2246 * See %G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME.
2249 g_file_info_set_edit_name (GFileInfo *info,
2250 const char *edit_name)
2252 static guint32 attr = 0;
2253 GFileAttributeValue *value;
2255 g_return_if_fail (G_IS_FILE_INFO (info));
2256 g_return_if_fail (edit_name != NULL);
2259 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME);
2261 value = g_file_info_create_value (info, attr);
2263 _g_file_attribute_value_set_string (value, edit_name);
2267 * g_file_info_set_icon:
2268 * @info: a #GFileInfo.
2271 * Sets the icon for a given #GFileInfo.
2272 * See %G_FILE_ATTRIBUTE_STANDARD_ICON.
2275 g_file_info_set_icon (GFileInfo *info,
2278 static guint32 attr = 0;
2279 GFileAttributeValue *value;
2281 g_return_if_fail (G_IS_FILE_INFO (info));
2282 g_return_if_fail (G_IS_ICON (icon));
2285 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_ICON);
2287 value = g_file_info_create_value (info, attr);
2289 _g_file_attribute_value_set_object (value, G_OBJECT (icon));
2293 * g_file_info_set_symbolic_icon:
2294 * @info: a #GFileInfo.
2297 * Sets the symbolic icon for a given #GFileInfo.
2298 * See %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON.
2303 g_file_info_set_symbolic_icon (GFileInfo *info,
2306 static guint32 attr = 0;
2307 GFileAttributeValue *value;
2309 g_return_if_fail (G_IS_FILE_INFO (info));
2310 g_return_if_fail (G_IS_ICON (icon));
2313 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON);
2315 value = g_file_info_create_value (info, attr);
2317 _g_file_attribute_value_set_object (value, G_OBJECT (icon));
2321 * g_file_info_set_content_type:
2322 * @info: a #GFileInfo.
2323 * @content_type: a content type. See [GContentType][gio-GContentType]
2325 * Sets the content type attribute for a given #GFileInfo.
2326 * See %G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE.
2329 g_file_info_set_content_type (GFileInfo *info,
2330 const char *content_type)
2332 static guint32 attr = 0;
2333 GFileAttributeValue *value;
2335 g_return_if_fail (G_IS_FILE_INFO (info));
2336 g_return_if_fail (content_type != NULL);
2339 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
2341 value = g_file_info_create_value (info, attr);
2343 _g_file_attribute_value_set_string (value, content_type);
2347 * g_file_info_set_size:
2348 * @info: a #GFileInfo.
2349 * @size: a #goffset containing the file's size.
2351 * Sets the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute in the file info
2352 * to the given size.
2355 g_file_info_set_size (GFileInfo *info,
2358 static guint32 attr = 0;
2359 GFileAttributeValue *value;
2361 g_return_if_fail (G_IS_FILE_INFO (info));
2364 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SIZE);
2366 value = g_file_info_create_value (info, attr);
2368 _g_file_attribute_value_set_uint64 (value, size);
2372 * g_file_info_set_modification_time:
2373 * @info: a #GFileInfo.
2374 * @mtime: a #GTimeVal.
2376 * Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and
2377 * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the
2380 * %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC will be cleared.
2382 * Deprecated: 2.62: Use g_file_info_set_modification_date_time() instead, as
2383 * #GTimeVal is deprecated due to the year 2038 problem.
2385 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
2387 g_file_info_set_modification_time (GFileInfo *info,
2390 static guint32 attr_mtime = 0, attr_mtime_usec = 0, attr_mtime_nsec = 0;
2391 GFileAttributeValue *value;
2393 g_return_if_fail (G_IS_FILE_INFO (info));
2394 g_return_if_fail (mtime != NULL);
2396 if (attr_mtime == 0)
2398 attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
2399 attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
2400 attr_mtime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
2403 value = g_file_info_create_value (info, attr_mtime);
2405 _g_file_attribute_value_set_uint64 (value, mtime->tv_sec);
2406 value = g_file_info_create_value (info, attr_mtime_usec);
2408 _g_file_attribute_value_set_uint32 (value, mtime->tv_usec);
2410 /* nsecs can’t be known from a #GTimeVal, so remove them */
2411 g_file_info_remove_value (info, attr_mtime_nsec);
2413 G_GNUC_END_IGNORE_DEPRECATIONS
2416 * g_file_info_set_modification_date_time:
2417 * @info: a #GFileInfo.
2418 * @mtime: (not nullable): a #GDateTime.
2420 * Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and
2421 * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the
2422 * given date/time value.
2424 * %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC will be cleared.
2429 g_file_info_set_modification_date_time (GFileInfo *info,
2432 static guint32 attr_mtime = 0, attr_mtime_usec = 0, attr_mtime_nsec = 0;
2433 GFileAttributeValue *value;
2435 g_return_if_fail (G_IS_FILE_INFO (info));
2436 g_return_if_fail (mtime != NULL);
2438 if (attr_mtime == 0)
2440 attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
2441 attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
2442 attr_mtime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
2445 value = g_file_info_create_value (info, attr_mtime);
2447 _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (mtime));
2448 value = g_file_info_create_value (info, attr_mtime_usec);
2450 _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (mtime));
2452 /* nsecs can’t be known from a #GDateTime, so remove them */
2453 g_file_info_remove_value (info, attr_mtime_nsec);
2457 * g_file_info_set_access_date_time:
2458 * @info: a #GFileInfo.
2459 * @atime: (not nullable): a #GDateTime.
2461 * Sets the %G_FILE_ATTRIBUTE_TIME_ACCESS and
2462 * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC attributes in the file info to the
2463 * given date/time value.
2465 * %G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC will be cleared.
2470 g_file_info_set_access_date_time (GFileInfo *info,
2473 static guint32 attr_atime = 0, attr_atime_usec = 0, attr_atime_nsec = 0;
2474 GFileAttributeValue *value;
2476 g_return_if_fail (G_IS_FILE_INFO (info));
2477 g_return_if_fail (atime != NULL);
2479 if (attr_atime == 0)
2481 attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS);
2482 attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
2483 attr_atime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC);
2486 value = g_file_info_create_value (info, attr_atime);
2488 _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (atime));
2489 value = g_file_info_create_value (info, attr_atime_usec);
2491 _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (atime));
2493 /* nsecs can’t be known from a #GDateTime, so remove them */
2494 g_file_info_remove_value (info, attr_atime_nsec);
2498 * g_file_info_set_creation_date_time:
2499 * @info: a #GFileInfo.
2500 * @creation_time: (not nullable): a #GDateTime.
2502 * Sets the %G_FILE_ATTRIBUTE_TIME_CREATED and
2503 * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC attributes in the file info to the
2504 * given date/time value.
2506 * %G_FILE_ATTRIBUTE_TIME_CREATED_NSEC will be cleared.
2511 g_file_info_set_creation_date_time (GFileInfo *info,
2512 GDateTime *creation_time)
2514 static guint32 attr_ctime = 0, attr_ctime_usec = 0, attr_ctime_nsec = 0;
2515 GFileAttributeValue *value;
2517 g_return_if_fail (G_IS_FILE_INFO (info));
2518 g_return_if_fail (creation_time != NULL);
2520 if (attr_ctime == 0)
2522 attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED);
2523 attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
2524 attr_ctime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_NSEC);
2527 value = g_file_info_create_value (info, attr_ctime);
2529 _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (creation_time));
2530 value = g_file_info_create_value (info, attr_ctime_usec);
2532 _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (creation_time));
2534 /* nsecs can’t be known from a #GDateTime, so remove them */
2535 g_file_info_remove_value (info, attr_ctime_nsec);
2539 * g_file_info_set_symlink_target:
2540 * @info: a #GFileInfo.
2541 * @symlink_target: (type filename): a static string containing a path to a symlink target.
2543 * Sets the %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET attribute in the file info
2544 * to the given symlink target.
2547 g_file_info_set_symlink_target (GFileInfo *info,
2548 const char *symlink_target)
2550 static guint32 attr = 0;
2551 GFileAttributeValue *value;
2553 g_return_if_fail (G_IS_FILE_INFO (info));
2554 g_return_if_fail (symlink_target != NULL);
2557 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET);
2559 value = g_file_info_create_value (info, attr);
2561 _g_file_attribute_value_set_byte_string (value, symlink_target);
2565 * g_file_info_set_sort_order:
2566 * @info: a #GFileInfo.
2567 * @sort_order: a sort order integer.
2569 * Sets the sort order attribute in the file info structure. See
2570 * %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER.
2573 g_file_info_set_sort_order (GFileInfo *info,
2576 static guint32 attr = 0;
2577 GFileAttributeValue *value;
2579 g_return_if_fail (G_IS_FILE_INFO (info));
2582 attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER);
2584 value = g_file_info_create_value (info, attr);
2586 _g_file_attribute_value_set_int32 (value, sort_order);
2595 struct _GFileAttributeMatcher {
2599 GArray *sub_matchers;
2602 guint32 iterator_ns;
2606 G_DEFINE_BOXED_TYPE (GFileAttributeMatcher, g_file_attribute_matcher,
2607 g_file_attribute_matcher_ref,
2608 g_file_attribute_matcher_unref)
2611 compare_sub_matchers (gconstpointer a,
2614 const SubMatcher *suba = a;
2615 const SubMatcher *subb = b;
2618 diff = suba->id - subb->id;
2623 return suba->mask - subb->mask;
2627 sub_matcher_matches (SubMatcher *matcher,
2628 SubMatcher *submatcher)
2630 if ((matcher->mask & submatcher->mask) != matcher->mask)
2633 return matcher->id == (submatcher->id & matcher->mask);
2636 /* Call this function after modifying a matcher.
2637 * It will ensure all the invariants other functions rely on.
2639 static GFileAttributeMatcher *
2640 matcher_optimize (GFileAttributeMatcher *matcher)
2642 SubMatcher *submatcher, *compare;
2645 /* remove sub_matchers if we match everything anyway */
2648 if (matcher->sub_matchers)
2650 g_array_free (matcher->sub_matchers, TRUE);
2651 matcher->sub_matchers = NULL;
2656 if (matcher->sub_matchers->len == 0)
2658 g_file_attribute_matcher_unref (matcher);
2662 /* sort sub_matchers by id (and then mask), so we can bsearch
2663 * and compare matchers in O(N) instead of O(N²) */
2664 g_array_sort (matcher->sub_matchers, compare_sub_matchers);
2666 /* remove duplicates and specific matches when we match the whole namespace */
2668 compare = &g_array_index (matcher->sub_matchers, SubMatcher, j);
2670 for (i = 1; i < matcher->sub_matchers->len; i++)
2672 submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
2673 if (sub_matcher_matches (compare, submatcher))
2680 *compare = *submatcher;
2683 g_array_set_size (matcher->sub_matchers, j + 1);
2689 * g_file_attribute_matcher_new:
2690 * @attributes: an attribute string to match.
2692 * Creates a new file attribute matcher, which matches attributes
2693 * against a given string. #GFileAttributeMatchers are reference
2694 * counted structures, and are created with a reference count of 1. If
2695 * the number of references falls to 0, the #GFileAttributeMatcher is
2696 * automatically destroyed.
2698 * The @attributes string should be formatted with specific keys separated
2699 * from namespaces with a double colon. Several "namespace::key" strings may be
2700 * concatenated with a single comma (e.g. "standard::type,standard::is-hidden").
2701 * The wildcard "*" may be used to match all keys and namespaces, or
2702 * "namespace::*" will match all keys in a given namespace.
2704 * ## Examples of file attribute matcher strings and results
2706 * - `"*"`: matches all attributes.
2707 * - `"standard::is-hidden"`: matches only the key is-hidden in the
2708 * standard namespace.
2709 * - `"standard::type,unix::*"`: matches the type key in the standard
2710 * namespace and all keys in the unix namespace.
2712 * Returns: a #GFileAttributeMatcher
2714 GFileAttributeMatcher *
2715 g_file_attribute_matcher_new (const char *attributes)
2720 GFileAttributeMatcher *matcher;
2722 if (attributes == NULL || *attributes == '\0')
2725 matcher = g_malloc0 (sizeof (GFileAttributeMatcher));
2727 matcher->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
2729 split = g_strsplit (attributes, ",", -1);
2731 for (i = 0; split[i] != NULL; i++)
2733 if (strcmp (split[i], "*") == 0)
2734 matcher->all = TRUE;
2739 colon = strstr (split[i], "::");
2740 if (colon != NULL &&
2745 s.id = lookup_attribute (split[i]);
2746 s.mask = 0xffffffff;
2753 s.id = lookup_namespace (split[i]) << NS_POS;
2754 s.mask = NS_MASK << NS_POS;
2757 g_array_append_val (matcher->sub_matchers, s);
2763 matcher = matcher_optimize (matcher);
2769 * g_file_attribute_matcher_subtract:
2770 * @matcher: (nullable): Matcher to subtract from
2771 * @subtract: (nullable): The matcher to subtract
2773 * Subtracts all attributes of @subtract from @matcher and returns
2774 * a matcher that supports those attributes.
2776 * Note that currently it is not possible to remove a single
2777 * attribute when the @matcher matches the whole namespace - or remove
2778 * a namespace or attribute when the matcher matches everything. This
2779 * is a limitation of the current implementation, but may be fixed
2782 * Returns: (nullable): A file attribute matcher matching all attributes of
2783 * @matcher that are not matched by @subtract
2785 GFileAttributeMatcher *
2786 g_file_attribute_matcher_subtract (GFileAttributeMatcher *matcher,
2787 GFileAttributeMatcher *subtract)
2789 GFileAttributeMatcher *result;
2791 SubMatcher *msub, *ssub;
2793 if (matcher == NULL)
2795 if (subtract == NULL)
2796 return g_file_attribute_matcher_ref (matcher);
2800 return g_file_attribute_matcher_ref (matcher);
2802 result = g_malloc0 (sizeof (GFileAttributeMatcher));
2804 result->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
2807 g_assert (subtract->sub_matchers->len > 0);
2808 ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si);
2810 for (mi = 0; mi < matcher->sub_matchers->len; mi++)
2812 msub = &g_array_index (matcher->sub_matchers, SubMatcher, mi);
2815 if (sub_matcher_matches (ssub, msub))
2819 if (si >= subtract->sub_matchers->len)
2822 ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si);
2823 if (ssub->id <= msub->id)
2826 g_array_append_val (result->sub_matchers, *msub);
2829 if (mi < matcher->sub_matchers->len)
2830 g_array_append_vals (result->sub_matchers,
2831 &g_array_index (matcher->sub_matchers, SubMatcher, mi),
2832 matcher->sub_matchers->len - mi);
2834 result = matcher_optimize (result);
2840 * g_file_attribute_matcher_ref:
2841 * @matcher: a #GFileAttributeMatcher.
2843 * References a file attribute matcher.
2845 * Returns: a #GFileAttributeMatcher.
2847 GFileAttributeMatcher *
2848 g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher)
2852 g_return_val_if_fail (matcher->ref > 0, NULL);
2853 g_atomic_int_inc (&matcher->ref);
2859 * g_file_attribute_matcher_unref:
2860 * @matcher: a #GFileAttributeMatcher.
2862 * Unreferences @matcher. If the reference count falls below 1,
2863 * the @matcher is automatically freed.
2867 g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher)
2871 g_return_if_fail (matcher->ref > 0);
2873 if (g_atomic_int_dec_and_test (&matcher->ref))
2875 if (matcher->sub_matchers)
2876 g_array_free (matcher->sub_matchers, TRUE);
2884 * g_file_attribute_matcher_matches_only:
2885 * @matcher: a #GFileAttributeMatcher.
2886 * @attribute: a file attribute key.
2888 * Checks if an attribute matcher only matches a given attribute. Always
2889 * returns %FALSE if "*" was used when creating the matcher.
2891 * Returns: %TRUE if the matcher only matches @attribute. %FALSE otherwise.
2894 g_file_attribute_matcher_matches_only (GFileAttributeMatcher *matcher,
2895 const char *attribute)
2897 SubMatcher *sub_matcher;
2900 g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
2902 if (matcher == NULL ||
2906 if (matcher->sub_matchers->len != 1)
2909 id = lookup_attribute (attribute);
2911 sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, 0);
2913 return sub_matcher->id == id &&
2914 sub_matcher->mask == 0xffffffff;
2918 matcher_matches_id (GFileAttributeMatcher *matcher,
2921 SubMatcher *sub_matchers;
2924 if (matcher->sub_matchers)
2926 sub_matchers = (SubMatcher *)matcher->sub_matchers->data;
2927 for (i = 0; i < matcher->sub_matchers->len; i++)
2929 if (sub_matchers[i].id == (id & sub_matchers[i].mask))
2938 _g_file_attribute_matcher_matches_id (GFileAttributeMatcher *matcher,
2941 /* We return a NULL matcher for an empty match string, so handle this */
2942 if (matcher == NULL)
2948 return matcher_matches_id (matcher, id);
2952 * g_file_attribute_matcher_matches:
2953 * @matcher: a #GFileAttributeMatcher.
2954 * @attribute: a file attribute key.
2956 * Checks if an attribute will be matched by an attribute matcher. If
2957 * the matcher was created with the "*" matching string, this function
2958 * will always return %TRUE.
2960 * Returns: %TRUE if @attribute matches @matcher. %FALSE otherwise.
2963 g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
2964 const char *attribute)
2966 g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
2968 /* We return a NULL matcher for an empty match string, so handle this */
2969 if (matcher == NULL)
2975 return matcher_matches_id (matcher, lookup_attribute (attribute));
2978 /* return TRUE -> all */
2980 * g_file_attribute_matcher_enumerate_namespace:
2981 * @matcher: a #GFileAttributeMatcher.
2982 * @ns: a string containing a file attribute namespace.
2984 * Checks if the matcher will match all of the keys in a given namespace.
2985 * This will always return %TRUE if a wildcard character is in use (e.g. if
2986 * matcher was created with "standard::*" and @ns is "standard", or if matcher was created
2987 * using "*" and namespace is anything.)
2989 * TODO: this is awkwardly worded.
2991 * Returns: %TRUE if the matcher matches all of the entries
2992 * in the given @ns, %FALSE otherwise.
2995 g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher,
2998 SubMatcher *sub_matchers;
3002 g_return_val_if_fail (ns != NULL && *ns != '\0', FALSE);
3004 /* We return a NULL matcher for an empty match string, so handle this */
3005 if (matcher == NULL)
3011 ns_id = lookup_namespace (ns) << NS_POS;
3013 if (matcher->sub_matchers)
3015 sub_matchers = (SubMatcher *)matcher->sub_matchers->data;
3016 for (i = 0; i < matcher->sub_matchers->len; i++)
3018 if (sub_matchers[i].id == ns_id)
3023 matcher->iterator_ns = ns_id;
3024 matcher->iterator_pos = 0;
3030 * g_file_attribute_matcher_enumerate_next:
3031 * @matcher: a #GFileAttributeMatcher.
3033 * Gets the next matched attribute from a #GFileAttributeMatcher.
3035 * Returns: (nullable): a string containing the next attribute or, %NULL if
3036 * no more attribute exist.
3039 g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher)
3042 SubMatcher *sub_matcher;
3044 /* We return a NULL matcher for an empty match string, so handle this */
3045 if (matcher == NULL)
3050 i = matcher->iterator_pos++;
3052 if (matcher->sub_matchers == NULL)
3055 if (i < matcher->sub_matchers->len)
3056 sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
3060 if (sub_matcher->mask == 0xffffffff &&
3061 (sub_matcher->id & (NS_MASK << NS_POS)) == matcher->iterator_ns)
3062 return get_attribute_for_id (sub_matcher->id);
3067 * g_file_attribute_matcher_to_string:
3068 * @matcher: (nullable): a #GFileAttributeMatcher.
3070 * Prints what the matcher is matching against. The format will be
3071 * equal to the format passed to g_file_attribute_matcher_new().
3072 * The output however, might not be identical, as the matcher may
3073 * decide to use a different order or omit needless parts.
3075 * Returns: a string describing the attributes the matcher matches
3076 * against or %NULL if @matcher was %NULL.
3081 g_file_attribute_matcher_to_string (GFileAttributeMatcher *matcher)
3086 if (matcher == NULL)
3090 return g_strdup ("*");
3092 string = g_string_new ("");
3093 for (i = 0; i < matcher->sub_matchers->len; i++)
3095 SubMatcher *submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
3098 g_string_append_c (string, ',');
3100 g_string_append (string, get_attribute_for_id (submatcher->id));
3103 return g_string_free (string, FALSE);