LCOV - code coverage report
Current view: top level - gio - gfileinfo.c (source / functions) Coverage Total Hit
Test: unnamed Lines: 81.2 % 936 760
Test Date: 2024-11-26 05:23:01 Functions: 80.0 % 115 92
Branches: - 0 0

             Branch data     Line data    Source code
       1                 :             : /* GIO - GLib Input, Output and Streaming Library
       2                 :             :  *
       3                 :             :  * Copyright (C) 2006-2007 Red Hat, Inc.
       4                 :             :  *
       5                 :             :  * SPDX-License-Identifier: LGPL-2.1-or-later
       6                 :             :  *
       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.
      11                 :             :  *
      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.
      16                 :             :  *
      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/>.
      19                 :             :  *
      20                 :             :  * Author: Alexander Larsson <alexl@redhat.com>
      21                 :             :  */
      22                 :             : 
      23                 :             : /**
      24                 :             :  * GFileInfo:
      25                 :             :  *
      26                 :             :  * Stores information about a file system object referenced by a [iface@Gio.File].
      27                 :             :  *
      28                 :             :  * Functionality for manipulating basic metadata for files. `GFileInfo`
      29                 :             :  * implements methods for getting information that all files should
      30                 :             :  * contain, and allows for manipulation of extended attributes.
      31                 :             :  *
      32                 :             :  * See the [file attributes](file-attributes.html) document for more
      33                 :             :  * information on how GIO handles file attributes.
      34                 :             :  *
      35                 :             :  * To obtain a `GFileInfo` for a [iface@Gio.File], use
      36                 :             :  * [method@Gio.File.query_info] (or its async variant). To obtain a `GFileInfo`
      37                 :             :  * for a file input or output stream, use [method@Gio.FileInputStream.query_info]
      38                 :             :  * or [method@Gio.FileOutputStream.query_info] (or their async variants).
      39                 :             :  *
      40                 :             :  * To change the actual attributes of a file, you should then set the
      41                 :             :  * attribute in the `GFileInfo` and call [method@Gio.File.set_attributes_from_info]
      42                 :             :  * or [method@Gio.File.set_attributes_async] on a `GFile`.
      43                 :             :  *
      44                 :             :  * However, not all attributes can be changed in the file. For instance,
      45                 :             :  * the actual size of a file cannot be changed via [method@Gio.FileInfo.set_size].
      46                 :             :  * You may call [method@Gio.File.query_settable_attributes] and
      47                 :             :  * [method@Gio.File.query_writable_namespaces] to discover the settable attributes
      48                 :             :  * of a particular file at runtime.
      49                 :             :  *
      50                 :             :  * The direct accessors, such as [method@Gio.FileInfo.get_name], are slightly more
      51                 :             :  * optimized than the generic attribute accessors, such as
      52                 :             :  * [method@Gio.FileInfo.get_attribute_byte_string].This optimization will matter
      53                 :             :  * only if calling the API in a tight loop.
      54                 :             :  *
      55                 :             :  * It is an error to call these accessors without specifying their required file
      56                 :             :  * attributes when creating the `GFileInfo`. Use
      57                 :             :  * [method@Gio.FileInfo.has_attribute] or [method@Gio.FileInfo.list_attributes]
      58                 :             :  * to check what attributes are specified for a `GFileInfo`.
      59                 :             :  *
      60                 :             :  * [struct@Gio.FileAttributeMatcher] allows for searching through a `GFileInfo`
      61                 :             :  * for attributes.
      62                 :             :  **/
      63                 :             : 
      64                 :             : #include "config.h"
      65                 :             : 
      66                 :             : #include <string.h>
      67                 :             : 
      68                 :             : #include "gfileinfo.h"
      69                 :             : #include "gfileinfo-priv.h"
      70                 :             : #include "gfileattribute-priv.h"
      71                 :             : #include "gicon.h"
      72                 :             : #include "glibintl.h"
      73                 :             : 
      74                 :             : 
      75                 :             : /* We use this nasty thing, because NULL is a valid attribute matcher (matches nothing) */
      76                 :             : #define NO_ATTRIBUTE_MASK ((GFileAttributeMatcher *)1)
      77                 :             : 
      78                 :             : typedef struct  {
      79                 :             :   guint32 attribute;
      80                 :             :   GFileAttributeValue value;
      81                 :             : } GFileAttribute;
      82                 :             : 
      83                 :             : struct _GFileInfo
      84                 :             : {
      85                 :             :   GObject parent_instance;
      86                 :             : 
      87                 :             :   GArray *attributes;
      88                 :             :   GFileAttributeMatcher *mask;
      89                 :             : };
      90                 :             : 
      91                 :             : struct _GFileInfoClass
      92                 :             : {
      93                 :             :   GObjectClass parent_class;
      94                 :             : };
      95                 :             : 
      96                 :             : 
      97                 :       11549 : G_DEFINE_TYPE (GFileInfo, g_file_info, G_TYPE_OBJECT)
      98                 :             : 
      99                 :             : typedef struct {
     100                 :             :   guint32 id;
     101                 :             :   guint32 attribute_id_counter;
     102                 :             : } NSInfo;
     103                 :             : 
     104                 :             : G_LOCK_DEFINE_STATIC (attribute_hash);
     105                 :             : static int namespace_id_counter = 0;
     106                 :             : static GHashTable *ns_hash = NULL;
     107                 :             : static GHashTable *attribute_hash = NULL;
     108                 :             : static char ***global_attributes = NULL;
     109                 :             : 
     110                 :             : /* Attribute ids are 32bit, we split it up like this:
     111                 :             :  * |------------|--------------------|
     112                 :             :  *   12 bit          20 bit
     113                 :             :  *   namespace      attribute id
     114                 :             :  *
     115                 :             :  * This way the attributes gets sorted in namespace order
     116                 :             :  */
     117                 :             : 
     118                 :             : #define NS_POS 20
     119                 :             : #define NS_MASK ((guint32)((1<<12) - 1))
     120                 :             : #define ID_POS 0
     121                 :             : #define ID_MASK ((guint32)((1<<20) - 1))
     122                 :             : 
     123                 :             : #define GET_NS(_attr_id) \
     124                 :             :     (((guint32) (_attr_id) >> NS_POS) & NS_MASK)
     125                 :             : #define GET_ID(_attr_id) \
     126                 :             :     (((guint32)(_attr_id) >> ID_POS) & ID_MASK)
     127                 :             : 
     128                 :             : #define MAKE_ATTR_ID(_ns, _id)                          \
     129                 :             :     ( ((((guint32) _ns) & NS_MASK) << NS_POS) |               \
     130                 :             :       ((((guint32) _id) & ID_MASK) << ID_POS) )
     131                 :             : 
     132                 :             : static NSInfo *
     133                 :        2634 : _lookup_namespace (const char *namespace)
     134                 :             : {
     135                 :             :   NSInfo *ns_info;
     136                 :             : 
     137                 :        2634 :   ns_info = g_hash_table_lookup (ns_hash, namespace);
     138                 :        2634 :   if (ns_info == NULL)
     139                 :             :     {
     140                 :         199 :       ns_info = g_new0 (NSInfo, 1);
     141                 :         199 :       ns_info->id = ++namespace_id_counter;
     142                 :         199 :       g_hash_table_insert (ns_hash, g_strdup (namespace), ns_info);
     143                 :         199 :       global_attributes = g_realloc (global_attributes, (ns_info->id + 1) * sizeof (char **));
     144                 :         199 :       global_attributes[ns_info->id] = g_new (char *, 1);
     145                 :         199 :       global_attributes[ns_info->id][0] = g_strconcat (namespace, "::*", NULL);
     146                 :             :     }
     147                 :        2634 :   return ns_info;
     148                 :             : }
     149                 :             : 
     150                 :             : static guint32
     151                 :        5888 : _lookup_attribute (const char *attribute)
     152                 :             : {
     153                 :             :   guint32 attr_id, id;
     154                 :             :   char *ns;
     155                 :             :   const char *colon;
     156                 :             :   NSInfo *ns_info;
     157                 :             : 
     158                 :        5888 :   attr_id = GPOINTER_TO_UINT (g_hash_table_lookup (attribute_hash, attribute));
     159                 :             : 
     160                 :        5888 :   if (attr_id != 0)
     161                 :        4726 :     return attr_id;
     162                 :             : 
     163                 :        1162 :   colon = strstr (attribute, "::");
     164                 :        1162 :   if (colon)
     165                 :        1162 :     ns = g_strndup (attribute, colon - attribute);
     166                 :             :   else
     167                 :           0 :     ns = g_strdup ("");
     168                 :             : 
     169                 :        1162 :   ns_info = _lookup_namespace (ns);
     170                 :        1162 :   g_free (ns);
     171                 :             : 
     172                 :        1162 :   id = ++ns_info->attribute_id_counter;
     173                 :        1162 :   global_attributes[ns_info->id] = g_realloc (global_attributes[ns_info->id], (id + 1) * sizeof (char *));
     174                 :        1162 :   global_attributes[ns_info->id][id] = g_strdup (attribute);
     175                 :             : 
     176                 :        1162 :   attr_id = MAKE_ATTR_ID (ns_info->id, id);
     177                 :             : 
     178                 :        1162 :   g_hash_table_insert (attribute_hash, global_attributes[ns_info->id][id], GUINT_TO_POINTER (attr_id));
     179                 :             : 
     180                 :        1162 :   return attr_id;
     181                 :             : }
     182                 :             : 
     183                 :             : static void
     184                 :        6208 : ensure_attribute_hash (void)
     185                 :             : {
     186                 :        6208 :   if (attribute_hash != NULL)
     187                 :        6196 :     return;
     188                 :             : 
     189                 :          12 :   ns_hash = g_hash_table_new (g_str_hash, g_str_equal);
     190                 :          12 :   attribute_hash = g_hash_table_new (g_str_hash, g_str_equal);
     191                 :             : 
     192                 :             : #define REGISTER_ATTRIBUTE(name) G_STMT_START{\
     193                 :             :   guint _u G_GNUC_UNUSED  /* when compiling with G_DISABLE_ASSERT */; \
     194                 :             :   _u = _lookup_attribute (G_FILE_ATTRIBUTE_ ## name); \
     195                 :             :   /* use for generating the ID: g_print ("#define G_FILE_ATTRIBUTE_ID_%s (%u + %u)\n", #name + 17, _u & ~ID_MASK, _u & ID_MASK); */ \
     196                 :             :   g_assert (_u == G_FILE_ATTRIBUTE_ID_ ## name); \
     197                 :             : }G_STMT_END
     198                 :             : 
     199                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_TYPE);
     200                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_IS_HIDDEN);
     201                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_IS_BACKUP);
     202                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_IS_SYMLINK);
     203                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_IS_VIRTUAL);
     204                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_NAME);
     205                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_DISPLAY_NAME);
     206                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_EDIT_NAME);
     207                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_COPY_NAME);
     208                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_DESCRIPTION);
     209                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_ICON);
     210                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_CONTENT_TYPE);
     211                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_FAST_CONTENT_TYPE);
     212                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_SIZE);
     213                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_ALLOCATED_SIZE);
     214                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_SYMLINK_TARGET);
     215                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_TARGET_URI);
     216                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_SORT_ORDER);
     217                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_SYMBOLIC_ICON);
     218                 :          12 :   REGISTER_ATTRIBUTE (STANDARD_IS_VOLATILE);
     219                 :          12 :   REGISTER_ATTRIBUTE (ETAG_VALUE);
     220                 :          12 :   REGISTER_ATTRIBUTE (ID_FILE);
     221                 :          12 :   REGISTER_ATTRIBUTE (ID_FILESYSTEM);
     222                 :          12 :   REGISTER_ATTRIBUTE (ACCESS_CAN_READ);
     223                 :          12 :   REGISTER_ATTRIBUTE (ACCESS_CAN_WRITE);
     224                 :          12 :   REGISTER_ATTRIBUTE (ACCESS_CAN_EXECUTE);
     225                 :          12 :   REGISTER_ATTRIBUTE (ACCESS_CAN_DELETE);
     226                 :          12 :   REGISTER_ATTRIBUTE (ACCESS_CAN_TRASH);
     227                 :          12 :   REGISTER_ATTRIBUTE (ACCESS_CAN_RENAME);
     228                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_MOUNT);
     229                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_UNMOUNT);
     230                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_EJECT);
     231                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE);
     232                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE_FILE);
     233                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_HAL_UDI);
     234                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START);
     235                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START_DEGRADED);
     236                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_STOP);
     237                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_START_STOP_TYPE);
     238                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_POLL);
     239                 :          12 :   REGISTER_ATTRIBUTE (MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC);
     240                 :          12 :   REGISTER_ATTRIBUTE (TIME_MODIFIED);
     241                 :          12 :   REGISTER_ATTRIBUTE (TIME_MODIFIED_USEC);
     242                 :          12 :   REGISTER_ATTRIBUTE (TIME_ACCESS);
     243                 :          12 :   REGISTER_ATTRIBUTE (TIME_ACCESS_USEC);
     244                 :          12 :   REGISTER_ATTRIBUTE (TIME_CHANGED);
     245                 :          12 :   REGISTER_ATTRIBUTE (TIME_CHANGED_USEC);
     246                 :          12 :   REGISTER_ATTRIBUTE (TIME_CREATED);
     247                 :          12 :   REGISTER_ATTRIBUTE (TIME_CREATED_USEC);
     248                 :          12 :   REGISTER_ATTRIBUTE (TIME_MODIFIED_NSEC);
     249                 :          12 :   REGISTER_ATTRIBUTE (TIME_ACCESS_NSEC);
     250                 :          12 :   REGISTER_ATTRIBUTE (TIME_CREATED_NSEC);
     251                 :          12 :   REGISTER_ATTRIBUTE (TIME_CHANGED_NSEC);
     252                 :          12 :   REGISTER_ATTRIBUTE (UNIX_DEVICE);
     253                 :          12 :   REGISTER_ATTRIBUTE (UNIX_INODE);
     254                 :          12 :   REGISTER_ATTRIBUTE (UNIX_MODE);
     255                 :          12 :   REGISTER_ATTRIBUTE (UNIX_NLINK);
     256                 :          12 :   REGISTER_ATTRIBUTE (UNIX_UID);
     257                 :          12 :   REGISTER_ATTRIBUTE (UNIX_GID);
     258                 :          12 :   REGISTER_ATTRIBUTE (UNIX_RDEV);
     259                 :          12 :   REGISTER_ATTRIBUTE (UNIX_BLOCK_SIZE);
     260                 :          12 :   REGISTER_ATTRIBUTE (UNIX_BLOCKS);
     261                 :          12 :   REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT);
     262                 :          12 :   REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE);
     263                 :          12 :   REGISTER_ATTRIBUTE (DOS_IS_SYSTEM);
     264                 :          12 :   REGISTER_ATTRIBUTE (DOS_IS_MOUNTPOINT);
     265                 :          12 :   REGISTER_ATTRIBUTE (DOS_REPARSE_POINT_TAG);
     266                 :          12 :   REGISTER_ATTRIBUTE (OWNER_USER);
     267                 :          12 :   REGISTER_ATTRIBUTE (OWNER_USER_REAL);
     268                 :          12 :   REGISTER_ATTRIBUTE (OWNER_GROUP);
     269                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH);
     270                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED);
     271                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID);
     272                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_NORMAL);
     273                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_NORMAL);
     274                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_NORMAL);
     275                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_LARGE);
     276                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_LARGE);
     277                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_LARGE);
     278                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_XLARGE);
     279                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_XLARGE);
     280                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_XLARGE);
     281                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_XXLARGE);
     282                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_XXLARGE);
     283                 :          12 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_XXLARGE);
     284                 :          12 :   REGISTER_ATTRIBUTE (PREVIEW_ICON);
     285                 :          12 :   REGISTER_ATTRIBUTE (FILESYSTEM_SIZE);
     286                 :          12 :   REGISTER_ATTRIBUTE (FILESYSTEM_FREE);
     287                 :          12 :   REGISTER_ATTRIBUTE (FILESYSTEM_TYPE);
     288                 :          12 :   REGISTER_ATTRIBUTE (FILESYSTEM_READONLY);
     289                 :          12 :   REGISTER_ATTRIBUTE (FILESYSTEM_USE_PREVIEW);
     290                 :          12 :   REGISTER_ATTRIBUTE (GVFS_BACKEND);
     291                 :          12 :   REGISTER_ATTRIBUTE (SELINUX_CONTEXT);
     292                 :          12 :   REGISTER_ATTRIBUTE (TRASH_ITEM_COUNT);
     293                 :          12 :   REGISTER_ATTRIBUTE (TRASH_ORIG_PATH);
     294                 :          12 :   REGISTER_ATTRIBUTE (TRASH_DELETION_DATE);
     295                 :             : 
     296                 :             : #undef REGISTER_ATTRIBUTE
     297                 :             : }
     298                 :             : 
     299                 :             : static guint32
     300                 :        1472 : lookup_namespace (const char *namespace)
     301                 :             : {
     302                 :             :   NSInfo *ns_info;
     303                 :             :   guint32 id;
     304                 :             : 
     305                 :        1472 :   G_LOCK (attribute_hash);
     306                 :             : 
     307                 :        1472 :   ensure_attribute_hash ();
     308                 :             : 
     309                 :        1472 :   ns_info = _lookup_namespace (namespace);
     310                 :        1472 :   id = 0;
     311                 :        1472 :   if (ns_info)
     312                 :        1472 :     id = ns_info->id;
     313                 :             : 
     314                 :        1472 :   G_UNLOCK (attribute_hash);
     315                 :             : 
     316                 :        1472 :   return id;
     317                 :             : }
     318                 :             : 
     319                 :             : static char *
     320                 :         255 : get_attribute_for_id (int attribute)
     321                 :             : {
     322                 :             :   char *s;
     323                 :         255 :   G_LOCK (attribute_hash);
     324                 :         255 :   s = global_attributes[GET_NS (attribute)][GET_ID (attribute)];
     325                 :         255 :   G_UNLOCK (attribute_hash);
     326                 :         255 :   return s;
     327                 :             : }
     328                 :             : 
     329                 :             : static guint32
     330                 :        4736 : lookup_attribute (const char *attribute)
     331                 :             : {
     332                 :             :   guint32 attr_id;
     333                 :             : 
     334                 :        4736 :   G_LOCK (attribute_hash);
     335                 :        4736 :   ensure_attribute_hash ();
     336                 :             : 
     337                 :        4736 :   attr_id = _lookup_attribute (attribute);
     338                 :             : 
     339                 :        4736 :   G_UNLOCK (attribute_hash);
     340                 :             : 
     341                 :        4736 :   return attr_id;
     342                 :             : }
     343                 :             : 
     344                 :             : static void
     345                 :        1070 : g_file_info_finalize (GObject *object)
     346                 :             : {
     347                 :             :   GFileInfo *info;
     348                 :             :   guint i;
     349                 :             :   GFileAttribute *attrs;
     350                 :             : 
     351                 :        1070 :   info = G_FILE_INFO (object);
     352                 :             : 
     353                 :        1070 :   attrs = (GFileAttribute *)info->attributes->data;
     354                 :        6943 :   for (i = 0; i < info->attributes->len; i++)
     355                 :        5873 :     _g_file_attribute_value_clear (&attrs[i].value);
     356                 :        1070 :   g_array_free (info->attributes, TRUE);
     357                 :             : 
     358                 :        1070 :   if (info->mask != NO_ATTRIBUTE_MASK)
     359                 :          41 :     g_file_attribute_matcher_unref (info->mask);
     360                 :             : 
     361                 :        1070 :   G_OBJECT_CLASS (g_file_info_parent_class)->finalize (object);
     362                 :        1070 : }
     363                 :             : 
     364                 :             : static void
     365                 :          13 : g_file_info_class_init (GFileInfoClass *klass)
     366                 :             : {
     367                 :          13 :   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     368                 :             : 
     369                 :          13 :   gobject_class->finalize = g_file_info_finalize;
     370                 :          13 : }
     371                 :             : 
     372                 :             : static void
     373                 :        1070 : g_file_info_init (GFileInfo *info)
     374                 :             : {
     375                 :        1070 :   info->mask = NO_ATTRIBUTE_MASK;
     376                 :        1070 :   info->attributes = g_array_new (FALSE, FALSE,
     377                 :             :                                   sizeof (GFileAttribute));
     378                 :        1070 : }
     379                 :             : 
     380                 :             : /**
     381                 :             :  * g_file_info_new:
     382                 :             :  *
     383                 :             :  * Creates a new file info structure.
     384                 :             :  *
     385                 :             :  * Returns: a #GFileInfo.
     386                 :             :  **/
     387                 :             : GFileInfo *
     388                 :        1069 : g_file_info_new (void)
     389                 :             : {
     390                 :        1069 :   return g_object_new (G_TYPE_FILE_INFO, NULL);
     391                 :             : }
     392                 :             : 
     393                 :             : /**
     394                 :             :  * g_file_info_copy_into:
     395                 :             :  * @src_info: source to copy attributes from.
     396                 :             :  * @dest_info: destination to copy attributes to.
     397                 :             :  *
     398                 :             :  * First clears all of the [GFileAttribute][gio-GFileAttribute] of @dest_info,
     399                 :             :  * and then copies all of the file attributes from @src_info to @dest_info.
     400                 :             :  **/
     401                 :             : void
     402                 :           2 : g_file_info_copy_into (GFileInfo *src_info,
     403                 :             :                        GFileInfo *dest_info)
     404                 :             : {
     405                 :             :   GFileAttribute *source, *dest;
     406                 :             :   guint i;
     407                 :             : 
     408                 :           2 :   g_return_if_fail (G_IS_FILE_INFO (src_info));
     409                 :           2 :   g_return_if_fail (G_IS_FILE_INFO (dest_info));
     410                 :             : 
     411                 :           2 :   dest = (GFileAttribute *)dest_info->attributes->data;
     412                 :           2 :   for (i = 0; i < dest_info->attributes->len; i++)
     413                 :           0 :     _g_file_attribute_value_clear (&dest[i].value);
     414                 :             : 
     415                 :           2 :   g_array_set_size (dest_info->attributes,
     416                 :           2 :                     src_info->attributes->len);
     417                 :             : 
     418                 :           2 :   source = (GFileAttribute *)src_info->attributes->data;
     419                 :           2 :   dest = (GFileAttribute *)dest_info->attributes->data;
     420                 :             : 
     421                 :          10 :   for (i = 0; i < src_info->attributes->len; i++)
     422                 :             :     {
     423                 :           8 :       dest[i].attribute = source[i].attribute;
     424                 :           8 :       dest[i].value.type = G_FILE_ATTRIBUTE_TYPE_INVALID;
     425                 :           8 :       _g_file_attribute_value_set (&dest[i].value, &source[i].value);
     426                 :             :     }
     427                 :             : 
     428                 :           2 :   if (dest_info->mask != NO_ATTRIBUTE_MASK)
     429                 :           0 :     g_file_attribute_matcher_unref (dest_info->mask);
     430                 :             : 
     431                 :           2 :   if (src_info->mask == NO_ATTRIBUTE_MASK)
     432                 :           2 :     dest_info->mask = NO_ATTRIBUTE_MASK;
     433                 :             :   else
     434                 :           0 :     dest_info->mask = g_file_attribute_matcher_ref (src_info->mask);
     435                 :             : }
     436                 :             : 
     437                 :             : /**
     438                 :             :  * g_file_info_dup:
     439                 :             :  * @other: a #GFileInfo.
     440                 :             :  *
     441                 :             :  * Duplicates a file info structure.
     442                 :             :  *
     443                 :             :  * Returns: (transfer full): a duplicate #GFileInfo of @other.
     444                 :             :  **/
     445                 :             : GFileInfo *
     446                 :           1 : g_file_info_dup (GFileInfo *other)
     447                 :             : {
     448                 :             :   GFileInfo *new;
     449                 :             : 
     450                 :           1 :   g_return_val_if_fail (G_IS_FILE_INFO (other), NULL);
     451                 :             : 
     452                 :           1 :   new = g_file_info_new ();
     453                 :           1 :   g_file_info_copy_into (other, new);
     454                 :           1 :   return new;
     455                 :             : }
     456                 :             : 
     457                 :             : /**
     458                 :             :  * g_file_info_set_attribute_mask:
     459                 :             :  * @info: a #GFileInfo.
     460                 :             :  * @mask: a #GFileAttributeMatcher.
     461                 :             :  *
     462                 :             :  * Sets @mask on @info to match specific attribute types.
     463                 :             :  **/
     464                 :             : void
     465                 :        1052 : g_file_info_set_attribute_mask (GFileInfo             *info,
     466                 :             :                                 GFileAttributeMatcher *mask)
     467                 :             : {
     468                 :             :   GFileAttribute *attr;
     469                 :             :   guint i;
     470                 :             : 
     471                 :        1052 :   g_return_if_fail (G_IS_FILE_INFO (info));
     472                 :             : 
     473                 :        1052 :   if (mask != info->mask)
     474                 :             :     {
     475                 :        1052 :       if (info->mask != NO_ATTRIBUTE_MASK)
     476                 :           0 :         g_file_attribute_matcher_unref (info->mask);
     477                 :        1052 :       info->mask = g_file_attribute_matcher_ref (mask);
     478                 :             : 
     479                 :             :       /* Remove non-matching attributes */
     480                 :        1056 :       for (i = 0; i < info->attributes->len; i++)
     481                 :             :         {
     482                 :           4 :           attr = &g_array_index (info->attributes, GFileAttribute, i);
     483                 :           4 :           if (!_g_file_attribute_matcher_matches_id (mask,
     484                 :             :                                                     attr->attribute))
     485                 :             :             {
     486                 :           2 :               _g_file_attribute_value_clear (&attr->value);
     487                 :           2 :               g_array_remove_index (info->attributes, i);
     488                 :           2 :               i--;
     489                 :             :             }
     490                 :             :         }
     491                 :             :     }
     492                 :             : }
     493                 :             : 
     494                 :             : /**
     495                 :             :  * g_file_info_unset_attribute_mask:
     496                 :             :  * @info: #GFileInfo.
     497                 :             :  *
     498                 :             :  * Unsets a mask set by g_file_info_set_attribute_mask(), if one
     499                 :             :  * is set.
     500                 :             :  **/
     501                 :             : void
     502                 :        1011 : g_file_info_unset_attribute_mask (GFileInfo *info)
     503                 :             : {
     504                 :        1011 :   g_return_if_fail (G_IS_FILE_INFO (info));
     505                 :             : 
     506                 :        1011 :   if (info->mask != NO_ATTRIBUTE_MASK)
     507                 :        1011 :     g_file_attribute_matcher_unref (info->mask);
     508                 :        1011 :   info->mask = NO_ATTRIBUTE_MASK;
     509                 :             : }
     510                 :             : 
     511                 :             : /**
     512                 :             :  * g_file_info_clear_status:
     513                 :             :  * @info: a #GFileInfo.
     514                 :             :  *
     515                 :             :  * Clears the status information from @info.
     516                 :             :  **/
     517                 :             : void
     518                 :          36 : g_file_info_clear_status (GFileInfo  *info)
     519                 :             : {
     520                 :             :   GFileAttribute *attrs;
     521                 :             :   guint i;
     522                 :             : 
     523                 :          36 :   g_return_if_fail (G_IS_FILE_INFO (info));
     524                 :             : 
     525                 :          36 :   attrs = (GFileAttribute *)info->attributes->data;
     526                 :         233 :   for (i = 0; i < info->attributes->len; i++)
     527                 :         197 :     attrs[i].value.status = G_FILE_ATTRIBUTE_STATUS_UNSET;
     528                 :             : }
     529                 :             : 
     530                 :             : static int
     531                 :        8800 : g_file_info_find_place (GFileInfo  *info,
     532                 :             :                         guint32     attribute)
     533                 :             : {
     534                 :             :   int min, max, med;
     535                 :             :   GFileAttribute *attrs;
     536                 :             :   /* Binary search for the place where attribute would be, if it's
     537                 :             :      in the array */
     538                 :             : 
     539                 :        8800 :   min = 0;
     540                 :        8800 :   max = info->attributes->len;
     541                 :             : 
     542                 :        8800 :   attrs = (GFileAttribute *)info->attributes->data;
     543                 :             : 
     544                 :       32100 :   while (min < max)
     545                 :             :     {
     546                 :       25928 :       med = min + (max - min) / 2;
     547                 :       25928 :       if (attrs[med].attribute == attribute)
     548                 :             :         {
     549                 :        2628 :           min = med;
     550                 :        2628 :           break;
     551                 :             :         }
     552                 :       23300 :       else if (attrs[med].attribute < attribute)
     553                 :       11395 :         min = med + 1;
     554                 :             :       else /* attrs[med].attribute > attribute */
     555                 :       11905 :         max = med;
     556                 :             :     }
     557                 :             : 
     558                 :        8800 :   return min;
     559                 :             : }
     560                 :             : 
     561                 :             : static GFileAttributeValue *
     562                 :        2627 : g_file_info_find_value (GFileInfo *info,
     563                 :             :                         guint32    attr_id)
     564                 :             : {
     565                 :             :   GFileAttribute *attrs;
     566                 :             :   guint i;
     567                 :             : 
     568                 :        2627 :   i = g_file_info_find_place (info, attr_id);
     569                 :        2627 :   attrs = (GFileAttribute *)info->attributes->data;
     570                 :        2627 :   if (i < info->attributes->len &&
     571                 :        2504 :       attrs[i].attribute == attr_id)
     572                 :        2329 :     return &attrs[i].value;
     573                 :             : 
     574                 :         298 :   return NULL;
     575                 :             : }
     576                 :             : 
     577                 :             : static GFileAttributeValue *
     578                 :        1546 : g_file_info_find_value_by_name (GFileInfo  *info,
     579                 :             :                                 const char *attribute)
     580                 :             : {
     581                 :             :   guint32 attr_id;
     582                 :             : 
     583                 :        1546 :   attr_id = lookup_attribute (attribute);
     584                 :        1546 :   return g_file_info_find_value (info, attr_id);
     585                 :             : }
     586                 :             : 
     587                 :             : /**
     588                 :             :  * g_file_info_has_attribute:
     589                 :             :  * @info: a #GFileInfo.
     590                 :             :  * @attribute: a file attribute key.
     591                 :             :  *
     592                 :             :  * Checks if a file info structure has an attribute named @attribute.
     593                 :             :  *
     594                 :             :  * Returns: %TRUE if @info has an attribute named @attribute,
     595                 :             :  *     %FALSE otherwise.
     596                 :             :  **/
     597                 :             : gboolean
     598                 :         439 : g_file_info_has_attribute (GFileInfo  *info,
     599                 :             :                            const char *attribute)
     600                 :             : {
     601                 :             :   GFileAttributeValue *value;
     602                 :             : 
     603                 :         439 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
     604                 :         439 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
     605                 :             : 
     606                 :         439 :   value = g_file_info_find_value_by_name (info, attribute);
     607                 :         439 :   return value != NULL;
     608                 :             : }
     609                 :             : 
     610                 :             : /**
     611                 :             :  * g_file_info_has_namespace:
     612                 :             :  * @info: a #GFileInfo.
     613                 :             :  * @name_space: a file attribute namespace.
     614                 :             :  *
     615                 :             :  * Checks if a file info structure has an attribute in the
     616                 :             :  * specified @name_space.
     617                 :             :  *
     618                 :             :  * Returns: %TRUE if @info has an attribute in @name_space,
     619                 :             :  *     %FALSE otherwise.
     620                 :             :  *
     621                 :             :  * Since: 2.22
     622                 :             :  **/
     623                 :             : gboolean
     624                 :           1 : g_file_info_has_namespace (GFileInfo  *info,
     625                 :             :                            const char *name_space)
     626                 :             : {
     627                 :             :   GFileAttribute *attrs;
     628                 :             :   guint32 ns_id;
     629                 :             :   guint i;
     630                 :             : 
     631                 :           1 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
     632                 :           1 :   g_return_val_if_fail (name_space != NULL, FALSE);
     633                 :             : 
     634                 :           1 :   ns_id = lookup_namespace (name_space);
     635                 :             : 
     636                 :           1 :   attrs = (GFileAttribute *)info->attributes->data;
     637                 :           1 :   for (i = 0; i < info->attributes->len; i++)
     638                 :             :     {
     639                 :           1 :       if (GET_NS (attrs[i].attribute) == ns_id)
     640                 :           1 :         return TRUE;
     641                 :             :     }
     642                 :             : 
     643                 :           0 :   return FALSE;
     644                 :             : }
     645                 :             : 
     646                 :             : /**
     647                 :             :  * g_file_info_list_attributes:
     648                 :             :  * @info: a #GFileInfo.
     649                 :             :  * @name_space: (nullable): a file attribute key's namespace, or %NULL to list
     650                 :             :  *   all attributes.
     651                 :             :  *
     652                 :             :  * Lists the file info structure's attributes.
     653                 :             :  *
     654                 :             :  * Returns: (nullable) (array zero-terminated=1) (transfer full): a
     655                 :             :  * null-terminated array of strings of all of the possible attribute
     656                 :             :  * types for the given @name_space, or %NULL on error.
     657                 :             :  **/
     658                 :             : char **
     659                 :          39 : g_file_info_list_attributes (GFileInfo  *info,
     660                 :             :                              const char *name_space)
     661                 :             : {
     662                 :             :   GPtrArray *names;
     663                 :             :   GFileAttribute *attrs;
     664                 :             :   guint32 attribute;
     665                 :          39 :   guint32 ns_id = (name_space) ? lookup_namespace (name_space) : 0;
     666                 :             :   guint i;
     667                 :             : 
     668                 :          39 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
     669                 :             : 
     670                 :          39 :   names = g_ptr_array_new ();
     671                 :          39 :   attrs = (GFileAttribute *)info->attributes->data;
     672                 :         241 :   for (i = 0; i < info->attributes->len; i++)
     673                 :             :     {
     674                 :         202 :       attribute = attrs[i].attribute;
     675                 :         202 :       if (ns_id == 0 || GET_NS (attribute) == ns_id)
     676                 :         404 :         g_ptr_array_add (names, g_strdup (get_attribute_for_id (attribute)));
     677                 :             :     }
     678                 :             : 
     679                 :             :   /* NULL terminate */
     680                 :          39 :   g_ptr_array_add (names, NULL);
     681                 :             : 
     682                 :          39 :   return (char **)g_ptr_array_free (names, FALSE);
     683                 :             : }
     684                 :             : 
     685                 :             : /**
     686                 :             :  * g_file_info_get_attribute_type:
     687                 :             :  * @info: a #GFileInfo.
     688                 :             :  * @attribute: a file attribute key.
     689                 :             :  *
     690                 :             :  * Gets the attribute type for an attribute key.
     691                 :             :  *
     692                 :             :  * Returns: a #GFileAttributeType for the given @attribute, or
     693                 :             :  * %G_FILE_ATTRIBUTE_TYPE_INVALID if the key is not set.
     694                 :             :  **/
     695                 :             : GFileAttributeType
     696                 :           2 : g_file_info_get_attribute_type (GFileInfo  *info,
     697                 :             :                                 const char *attribute)
     698                 :             : {
     699                 :             :   GFileAttributeValue *value;
     700                 :             : 
     701                 :           2 :   g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_ATTRIBUTE_TYPE_INVALID);
     702                 :           2 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', G_FILE_ATTRIBUTE_TYPE_INVALID);
     703                 :             : 
     704                 :           2 :   value = g_file_info_find_value_by_name (info, attribute);
     705                 :           2 :   if (value)
     706                 :           1 :     return value->type;
     707                 :             :   else
     708                 :           1 :     return G_FILE_ATTRIBUTE_TYPE_INVALID;
     709                 :             : }
     710                 :             : 
     711                 :             : static void
     712                 :           7 : g_file_info_remove_value (GFileInfo *info,
     713                 :             :                           guint32 attr_id)
     714                 :             : {
     715                 :             :   GFileAttribute *attrs;
     716                 :             :   guint i;
     717                 :             : 
     718                 :           7 :   if (info->mask != NO_ATTRIBUTE_MASK &&
     719                 :           0 :       !_g_file_attribute_matcher_matches_id (info->mask, attr_id))
     720                 :           0 :     return;
     721                 :             : 
     722                 :           7 :   i = g_file_info_find_place (info, attr_id);
     723                 :             : 
     724                 :           7 :   attrs = (GFileAttribute *)info->attributes->data;
     725                 :           7 :   if (i < info->attributes->len &&
     726                 :           5 :       attrs[i].attribute == attr_id)
     727                 :             :     {
     728                 :           5 :       _g_file_attribute_value_clear (&attrs[i].value);
     729                 :           5 :       g_array_remove_index (info->attributes, i);
     730                 :             :     }
     731                 :             : }
     732                 :             : 
     733                 :             : /**
     734                 :             :  * g_file_info_remove_attribute:
     735                 :             :  * @info: a #GFileInfo.
     736                 :             :  * @attribute: a file attribute key.
     737                 :             :  *
     738                 :             :  * Removes all cases of @attribute from @info if it exists.
     739                 :             :  **/
     740                 :             : void
     741                 :           1 : g_file_info_remove_attribute (GFileInfo  *info,
     742                 :             :                               const char *attribute)
     743                 :             : {
     744                 :             :   guint32 attr_id;
     745                 :             : 
     746                 :           1 :   g_return_if_fail (G_IS_FILE_INFO (info));
     747                 :           1 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
     748                 :             : 
     749                 :           1 :   attr_id = lookup_attribute (attribute);
     750                 :             : 
     751                 :           1 :   g_file_info_remove_value (info, attr_id);
     752                 :             : }
     753                 :             : 
     754                 :             : /**
     755                 :             :  * g_file_info_get_attribute_data:
     756                 :             :  * @info: a #GFileInfo
     757                 :             :  * @attribute: a file attribute key
     758                 :             :  * @type: (out) (optional): return location for the attribute type, or %NULL
     759                 :             :  * @value_pp: (out) (optional) (not nullable): return location for the
     760                 :             :  *    attribute value, or %NULL; the attribute value will not be %NULL
     761                 :             :  * @status: (out) (optional): return location for the attribute status, or %NULL
     762                 :             :  *
     763                 :             :  * Gets the attribute type, value and status for an attribute key.
     764                 :             :  *
     765                 :             :  * Returns: %TRUE if @info has an attribute named @attribute,
     766                 :             :  *      %FALSE otherwise.
     767                 :             :  */
     768                 :             : gboolean
     769                 :           0 : g_file_info_get_attribute_data (GFileInfo            *info,
     770                 :             :                                 const char           *attribute,
     771                 :             :                                 GFileAttributeType   *type,
     772                 :             :                                 gpointer             *value_pp,
     773                 :             :                                 GFileAttributeStatus *status)
     774                 :             : {
     775                 :             :   GFileAttributeValue *value;
     776                 :             : 
     777                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
     778                 :           0 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
     779                 :             : 
     780                 :           0 :   value = g_file_info_find_value_by_name (info, attribute);
     781                 :           0 :   if (value == NULL)
     782                 :           0 :     return FALSE;
     783                 :             : 
     784                 :           0 :   if (status)
     785                 :           0 :     *status = value->status;
     786                 :             : 
     787                 :           0 :   if (type)
     788                 :           0 :     *type = value->type;
     789                 :             : 
     790                 :           0 :   if (value_pp)
     791                 :           0 :     *value_pp = _g_file_attribute_value_peek_as_pointer (value);
     792                 :             : 
     793                 :           0 :   return TRUE;
     794                 :             : }
     795                 :             : 
     796                 :             : /**
     797                 :             :  * g_file_info_get_attribute_status:
     798                 :             :  * @info: a #GFileInfo
     799                 :             :  * @attribute: a file attribute key
     800                 :             :  *
     801                 :             :  * Gets the attribute status for an attribute key.
     802                 :             :  *
     803                 :             :  * Returns: a #GFileAttributeStatus for the given @attribute, or
     804                 :             :  *    %G_FILE_ATTRIBUTE_STATUS_UNSET if the key is invalid.
     805                 :             :  *
     806                 :             :  */
     807                 :             : GFileAttributeStatus
     808                 :           1 : g_file_info_get_attribute_status (GFileInfo  *info,
     809                 :             :                                   const char *attribute)
     810                 :             : {
     811                 :             :   GFileAttributeValue *val;
     812                 :             : 
     813                 :           1 :   g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
     814                 :           1 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
     815                 :             : 
     816                 :           1 :   val = g_file_info_find_value_by_name (info, attribute);
     817                 :           1 :   if (val)
     818                 :           1 :     return val->status;
     819                 :             : 
     820                 :           0 :   return G_FILE_ATTRIBUTE_STATUS_UNSET;
     821                 :             : }
     822                 :             : 
     823                 :             : /**
     824                 :             :  * g_file_info_set_attribute_status:
     825                 :             :  * @info: a #GFileInfo
     826                 :             :  * @attribute: a file attribute key
     827                 :             :  * @status: a #GFileAttributeStatus
     828                 :             :  *
     829                 :             :  * Sets the attribute status for an attribute key. This is only
     830                 :             :  * needed by external code that implement g_file_set_attributes_from_info()
     831                 :             :  * or similar functions.
     832                 :             :  *
     833                 :             :  * The attribute must exist in @info for this to work. Otherwise %FALSE
     834                 :             :  * is returned and @info is unchanged.
     835                 :             :  *
     836                 :             :  * Returns: %TRUE if the status was changed, %FALSE if the key was not set.
     837                 :             :  *
     838                 :             :  * Since: 2.22
     839                 :             :  */
     840                 :             : gboolean
     841                 :           0 : g_file_info_set_attribute_status (GFileInfo  *info,
     842                 :             :                                   const char *attribute,
     843                 :             :                                   GFileAttributeStatus status)
     844                 :             : {
     845                 :             :   GFileAttributeValue *val;
     846                 :             : 
     847                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
     848                 :           0 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
     849                 :             : 
     850                 :           0 :   val = g_file_info_find_value_by_name (info, attribute);
     851                 :           0 :   if (val)
     852                 :             :     {
     853                 :           0 :       val->status = status;
     854                 :           0 :       return TRUE;
     855                 :             :     }
     856                 :             : 
     857                 :           0 :   return FALSE;
     858                 :             : }
     859                 :             : 
     860                 :             : GFileAttributeValue *
     861                 :         558 : _g_file_info_get_attribute_value (GFileInfo  *info,
     862                 :             :                                   const char *attribute)
     863                 :             : 
     864                 :             : {
     865                 :         558 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
     866                 :         558 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
     867                 :             : 
     868                 :         558 :   return g_file_info_find_value_by_name (info, attribute);
     869                 :             : }
     870                 :             : 
     871                 :             : /**
     872                 :             :  * g_file_info_get_attribute_as_string:
     873                 :             :  * @info: a #GFileInfo.
     874                 :             :  * @attribute: a file attribute key.
     875                 :             :  *
     876                 :             :  * Gets the value of an attribute, formatted as a string.
     877                 :             :  * This escapes things as needed to make the string valid
     878                 :             :  * UTF-8.
     879                 :             :  *
     880                 :             :  * Returns: (nullable): a UTF-8 string associated with the given @attribute, or
     881                 :             :  *    %NULL if the attribute wasn’t set.
     882                 :             :  *    When you're done with the string it must be freed with g_free().
     883                 :             :  **/
     884                 :             : char *
     885                 :           1 : g_file_info_get_attribute_as_string (GFileInfo  *info,
     886                 :             :                                      const char *attribute)
     887                 :             : {
     888                 :             :   GFileAttributeValue *val;
     889                 :           1 :   val = _g_file_info_get_attribute_value (info, attribute);
     890                 :           1 :   if (val)
     891                 :           1 :     return _g_file_attribute_value_as_string (val);
     892                 :           0 :   return NULL;
     893                 :             : }
     894                 :             : 
     895                 :             : 
     896                 :             : /**
     897                 :             :  * g_file_info_get_attribute_object:
     898                 :             :  * @info: a #GFileInfo.
     899                 :             :  * @attribute: a file attribute key.
     900                 :             :  *
     901                 :             :  * Gets the value of a #GObject attribute. If the attribute does
     902                 :             :  * not contain a #GObject, %NULL will be returned.
     903                 :             :  *
     904                 :             :  * Returns: (transfer none) (nullable): a #GObject associated with the given @attribute,
     905                 :             :  * or %NULL otherwise.
     906                 :             :  **/
     907                 :             : GObject *
     908                 :           0 : g_file_info_get_attribute_object (GFileInfo  *info,
     909                 :             :                                   const char *attribute)
     910                 :             : {
     911                 :             :   GFileAttributeValue *value;
     912                 :             : 
     913                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
     914                 :           0 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
     915                 :             : 
     916                 :           0 :   value = g_file_info_find_value_by_name (info, attribute);
     917                 :           0 :   return _g_file_attribute_value_get_object (value);
     918                 :             : }
     919                 :             : 
     920                 :             : /**
     921                 :             :  * g_file_info_get_attribute_string:
     922                 :             :  * @info: a #GFileInfo.
     923                 :             :  * @attribute: a file attribute key.
     924                 :             :  *
     925                 :             :  * Gets the value of a string attribute. If the attribute does
     926                 :             :  * not contain a string, %NULL will be returned.
     927                 :             :  *
     928                 :             :  * Returns: (nullable): the contents of the @attribute value as a UTF-8 string,
     929                 :             :  * or %NULL otherwise.
     930                 :             :  **/
     931                 :             : const char *
     932                 :          54 : g_file_info_get_attribute_string (GFileInfo  *info,
     933                 :             :                                   const char *attribute)
     934                 :             : {
     935                 :             :   GFileAttributeValue *value;
     936                 :             : 
     937                 :          54 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
     938                 :          54 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
     939                 :             : 
     940                 :          54 :   value = g_file_info_find_value_by_name (info, attribute);
     941                 :          54 :   return _g_file_attribute_value_get_string (value);
     942                 :             : }
     943                 :             : 
     944                 :             : /**
     945                 :             :  * g_file_info_get_attribute_byte_string:
     946                 :             :  * @info: a #GFileInfo.
     947                 :             :  * @attribute: a file attribute key.
     948                 :             :  *
     949                 :             :  * Gets the value of a byte string attribute. If the attribute does
     950                 :             :  * not contain a byte string, %NULL will be returned.
     951                 :             :  *
     952                 :             :  * Returns: (nullable): the contents of the @attribute value as a byte string, or
     953                 :             :  * %NULL otherwise.
     954                 :             :  **/
     955                 :             : const char *
     956                 :          37 : g_file_info_get_attribute_byte_string (GFileInfo  *info,
     957                 :             :                                        const char *attribute)
     958                 :             : {
     959                 :             :   GFileAttributeValue *value;
     960                 :             : 
     961                 :          37 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
     962                 :          37 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
     963                 :             : 
     964                 :          37 :   value = g_file_info_find_value_by_name (info, attribute);
     965                 :          37 :   return _g_file_attribute_value_get_byte_string (value);
     966                 :             : }
     967                 :             : 
     968                 :             : /**
     969                 :             :  * g_file_info_get_attribute_file_path:
     970                 :             :  * @info: a #GFileInfo.
     971                 :             :  * @attribute: a file attribute key.
     972                 :             :  *
     973                 :             :  * Gets the value of a byte string attribute as a file path.
     974                 :             :  *
     975                 :             :  * If the attribute does not contain a byte string, `NULL` will be returned.
     976                 :             :  *
     977                 :             :  * This function is meant to be used by language bindings that have specific
     978                 :             :  * handling for Unix paths.
     979                 :             :  *
     980                 :             :  * Returns: (type filename) (nullable): the contents of the @attribute value as
     981                 :             :  * a file path, or %NULL otherwise.
     982                 :             :  *
     983                 :             :  * Since: 2.78
     984                 :             :  **/
     985                 :             : const char *
     986                 :           4 : g_file_info_get_attribute_file_path (GFileInfo  *info,
     987                 :             :                                      const char *attribute)
     988                 :             : {
     989                 :           4 :   return g_file_info_get_attribute_byte_string (info, attribute);
     990                 :             : }
     991                 :             : 
     992                 :             : /**
     993                 :             :  * g_file_info_get_attribute_stringv:
     994                 :             :  * @info: a #GFileInfo.
     995                 :             :  * @attribute: a file attribute key.
     996                 :             :  *
     997                 :             :  * Gets the value of a stringv attribute. If the attribute does
     998                 :             :  * not contain a stringv, %NULL will be returned.
     999                 :             :  *
    1000                 :             :  * Returns: (transfer none) (nullable): the contents of the @attribute value as a stringv,
    1001                 :             :  * or %NULL otherwise. Do not free. These returned strings are UTF-8.
    1002                 :             :  *
    1003                 :             :  * Since: 2.22
    1004                 :             :  **/
    1005                 :             : char **
    1006                 :           0 : g_file_info_get_attribute_stringv (GFileInfo  *info,
    1007                 :             :                                    const char *attribute)
    1008                 :             : {
    1009                 :             :   GFileAttributeValue *value;
    1010                 :             : 
    1011                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1012                 :           0 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
    1013                 :             : 
    1014                 :           0 :   value = g_file_info_find_value_by_name (info, attribute);
    1015                 :           0 :   return _g_file_attribute_value_get_stringv (value);
    1016                 :             : }
    1017                 :             : 
    1018                 :             : /**
    1019                 :             :  * g_file_info_get_attribute_boolean:
    1020                 :             :  * @info: a #GFileInfo.
    1021                 :             :  * @attribute: a file attribute key.
    1022                 :             :  *
    1023                 :             :  * Gets the value of a boolean attribute. If the attribute does not
    1024                 :             :  * contain a boolean value, %FALSE will be returned.
    1025                 :             :  *
    1026                 :             :  * Returns: the boolean value contained within the attribute.
    1027                 :             :  **/
    1028                 :             : gboolean
    1029                 :         191 : g_file_info_get_attribute_boolean (GFileInfo  *info,
    1030                 :             :                                    const char *attribute)
    1031                 :             : {
    1032                 :             :   GFileAttributeValue *value;
    1033                 :             : 
    1034                 :         191 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
    1035                 :         191 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
    1036                 :             : 
    1037                 :         191 :   value = g_file_info_find_value_by_name (info, attribute);
    1038                 :         191 :   return _g_file_attribute_value_get_boolean (value);
    1039                 :             : }
    1040                 :             : 
    1041                 :             : /**
    1042                 :             :  * g_file_info_get_attribute_uint32:
    1043                 :             :  * @info: a #GFileInfo.
    1044                 :             :  * @attribute: a file attribute key.
    1045                 :             :  *
    1046                 :             :  * Gets an unsigned 32-bit integer contained within the attribute. If the
    1047                 :             :  * attribute does not contain an unsigned 32-bit integer, or is invalid,
    1048                 :             :  * 0 will be returned.
    1049                 :             :  *
    1050                 :             :  * Returns: an unsigned 32-bit integer from the attribute.
    1051                 :             :  **/
    1052                 :             : guint32
    1053                 :         257 : g_file_info_get_attribute_uint32 (GFileInfo  *info,
    1054                 :             :                                   const char *attribute)
    1055                 :             : {
    1056                 :             :   GFileAttributeValue *value;
    1057                 :             : 
    1058                 :         257 :   g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
    1059                 :         257 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
    1060                 :             : 
    1061                 :         257 :   value = g_file_info_find_value_by_name (info, attribute);
    1062                 :         257 :   return _g_file_attribute_value_get_uint32 (value);
    1063                 :             : }
    1064                 :             : 
    1065                 :             : /**
    1066                 :             :  * g_file_info_get_attribute_int32:
    1067                 :             :  * @info: a #GFileInfo.
    1068                 :             :  * @attribute: a file attribute key.
    1069                 :             :  *
    1070                 :             :  * Gets a signed 32-bit integer contained within the attribute. If the
    1071                 :             :  * attribute does not contain a signed 32-bit integer, or is invalid,
    1072                 :             :  * 0 will be returned.
    1073                 :             :  *
    1074                 :             :  * Returns: a signed 32-bit integer from the attribute.
    1075                 :             :  **/
    1076                 :             : gint32
    1077                 :           0 : g_file_info_get_attribute_int32 (GFileInfo  *info,
    1078                 :             :                                  const char *attribute)
    1079                 :             : {
    1080                 :             :   GFileAttributeValue *value;
    1081                 :             : 
    1082                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
    1083                 :           0 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
    1084                 :             : 
    1085                 :           0 :   value = g_file_info_find_value_by_name (info, attribute);
    1086                 :           0 :   return _g_file_attribute_value_get_int32 (value);
    1087                 :             : }
    1088                 :             : 
    1089                 :             : /**
    1090                 :             :  * g_file_info_get_attribute_uint64:
    1091                 :             :  * @info: a #GFileInfo.
    1092                 :             :  * @attribute: a file attribute key.
    1093                 :             :  *
    1094                 :             :  * Gets a unsigned 64-bit integer contained within the attribute. If the
    1095                 :             :  * attribute does not contain an unsigned 64-bit integer, or is invalid,
    1096                 :             :  * 0 will be returned.
    1097                 :             :  *
    1098                 :             :  * Returns: a unsigned 64-bit integer from the attribute.
    1099                 :             :  **/
    1100                 :             : guint64
    1101                 :           7 : g_file_info_get_attribute_uint64 (GFileInfo  *info,
    1102                 :             :                                   const char *attribute)
    1103                 :             : {
    1104                 :             :   GFileAttributeValue *value;
    1105                 :             : 
    1106                 :           7 :   g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
    1107                 :           7 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
    1108                 :             : 
    1109                 :           7 :   value = g_file_info_find_value_by_name (info, attribute);
    1110                 :           7 :   return _g_file_attribute_value_get_uint64 (value);
    1111                 :             : }
    1112                 :             : 
    1113                 :             : /**
    1114                 :             :  * g_file_info_get_attribute_int64:
    1115                 :             :  * @info: a #GFileInfo.
    1116                 :             :  * @attribute: a file attribute key.
    1117                 :             :  *
    1118                 :             :  * Gets a signed 64-bit integer contained within the attribute. If the
    1119                 :             :  * attribute does not contain a signed 64-bit integer, or is invalid,
    1120                 :             :  * 0 will be returned.
    1121                 :             :  *
    1122                 :             :  * Returns: a signed 64-bit integer from the attribute.
    1123                 :             :  **/
    1124                 :             : gint64
    1125                 :           0 : g_file_info_get_attribute_int64  (GFileInfo  *info,
    1126                 :             :                                   const char *attribute)
    1127                 :             : {
    1128                 :             :   GFileAttributeValue *value;
    1129                 :             : 
    1130                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
    1131                 :           0 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', 0);
    1132                 :             : 
    1133                 :           0 :   value = g_file_info_find_value_by_name (info, attribute);
    1134                 :           0 :   return _g_file_attribute_value_get_int64 (value);
    1135                 :             : }
    1136                 :             : 
    1137                 :             : static GFileAttributeValue *
    1138                 :       22400 : g_file_info_create_value (GFileInfo *info,
    1139                 :             :                           guint32 attr_id)
    1140                 :             : {
    1141                 :             :   GFileAttribute *attrs;
    1142                 :             :   guint i;
    1143                 :             : 
    1144                 :       43819 :   if (info->mask != NO_ATTRIBUTE_MASK &&
    1145                 :       21419 :       !_g_file_attribute_matcher_matches_id (info->mask, attr_id))
    1146                 :       16234 :     return NULL;
    1147                 :             : 
    1148                 :        6166 :   i = g_file_info_find_place (info, attr_id);
    1149                 :             : 
    1150                 :        6166 :   attrs = (GFileAttribute *)info->attributes->data;
    1151                 :        6166 :   if (i < info->attributes->len &&
    1152                 :        3423 :       attrs[i].attribute == attr_id)
    1153                 :         294 :     return &attrs[i].value;
    1154                 :             :   else
    1155                 :             :     {
    1156                 :        5872 :       GFileAttribute attr = { 0 };
    1157                 :        5872 :       attr.attribute = attr_id;
    1158                 :        5872 :       g_array_insert_val (info->attributes, i, attr);
    1159                 :             : 
    1160                 :        5872 :       attrs = (GFileAttribute *)info->attributes->data;
    1161                 :        5872 :       return &attrs[i].value;
    1162                 :             :     }
    1163                 :             : }
    1164                 :             : 
    1165                 :             : void
    1166                 :           0 : _g_file_info_set_attribute_by_id (GFileInfo                 *info,
    1167                 :             :                                   guint32                    attribute,
    1168                 :             :                                   GFileAttributeType         type,
    1169                 :             :                                   gpointer                   value_p)
    1170                 :             : {
    1171                 :             :   GFileAttributeValue *value;
    1172                 :             : 
    1173                 :           0 :   value = g_file_info_create_value (info, attribute);
    1174                 :             : 
    1175                 :           0 :   if (value)
    1176                 :           0 :     _g_file_attribute_value_set_from_pointer (value, type, value_p, TRUE);
    1177                 :           0 : }
    1178                 :             : 
    1179                 :             : /**
    1180                 :             :  * g_file_info_set_attribute:
    1181                 :             :  * @info: a #GFileInfo.
    1182                 :             :  * @attribute: a file attribute key.
    1183                 :             :  * @type: a #GFileAttributeType
    1184                 :             :  * @value_p: (not nullable): pointer to the value
    1185                 :             :  *
    1186                 :             :  * Sets the @attribute to contain the given value, if possible. To unset the
    1187                 :             :  * attribute, use %G_FILE_ATTRIBUTE_TYPE_INVALID for @type.
    1188                 :             :  **/
    1189                 :             : void
    1190                 :           0 : g_file_info_set_attribute (GFileInfo                 *info,
    1191                 :             :                            const char                *attribute,
    1192                 :             :                            GFileAttributeType         type,
    1193                 :             :                            gpointer                   value_p)
    1194                 :             : {
    1195                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1196                 :           0 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1197                 :             : 
    1198                 :           0 :   _g_file_info_set_attribute_by_id (info, lookup_attribute (attribute), type, value_p);
    1199                 :             : }
    1200                 :             : 
    1201                 :             : void
    1202                 :           0 : _g_file_info_set_attribute_object_by_id (GFileInfo *info,
    1203                 :             :                                          guint32    attribute,
    1204                 :             :                                          GObject   *attr_value)
    1205                 :             : {
    1206                 :             :   GFileAttributeValue *value;
    1207                 :             : 
    1208                 :           0 :   value = g_file_info_create_value (info, attribute);
    1209                 :           0 :   if (value)
    1210                 :           0 :     _g_file_attribute_value_set_object (value, attr_value);
    1211                 :           0 : }
    1212                 :             : 
    1213                 :             : /**
    1214                 :             :  * g_file_info_set_attribute_object:
    1215                 :             :  * @info: a #GFileInfo.
    1216                 :             :  * @attribute: a file attribute key.
    1217                 :             :  * @attr_value: a #GObject.
    1218                 :             :  *
    1219                 :             :  * Sets the @attribute to contain the given @attr_value,
    1220                 :             :  * if possible.
    1221                 :             :  **/
    1222                 :             : void
    1223                 :           0 : g_file_info_set_attribute_object (GFileInfo  *info,
    1224                 :             :                                   const char *attribute,
    1225                 :             :                                   GObject    *attr_value)
    1226                 :             : {
    1227                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1228                 :           0 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1229                 :           0 :   g_return_if_fail (G_IS_OBJECT (attr_value));
    1230                 :             : 
    1231                 :           0 :   _g_file_info_set_attribute_object_by_id (info,
    1232                 :             :                                            lookup_attribute (attribute),
    1233                 :             :                                            attr_value);
    1234                 :             : }
    1235                 :             : 
    1236                 :             : void
    1237                 :           0 : _g_file_info_set_attribute_stringv_by_id (GFileInfo *info,
    1238                 :             :                                           guint32    attribute,
    1239                 :             :                                           char     **attr_value)
    1240                 :             : {
    1241                 :             :   GFileAttributeValue *value;
    1242                 :             : 
    1243                 :           0 :   value = g_file_info_create_value (info, attribute);
    1244                 :           0 :   if (value)
    1245                 :           0 :     _g_file_attribute_value_set_stringv (value, attr_value);
    1246                 :           0 : }
    1247                 :             : 
    1248                 :             : /**
    1249                 :             :  * g_file_info_set_attribute_stringv:
    1250                 :             :  * @info: a #GFileInfo.
    1251                 :             :  * @attribute: a file attribute key
    1252                 :             :  * @attr_value: (array zero-terminated=1) (element-type utf8): a %NULL
    1253                 :             :  *   terminated array of UTF-8 strings.
    1254                 :             :  *
    1255                 :             :  * Sets the @attribute to contain the given @attr_value,
    1256                 :             :  * if possible.
    1257                 :             :  *
    1258                 :             :  * Sinze: 2.22
    1259                 :             :  **/
    1260                 :             : void
    1261                 :           0 : g_file_info_set_attribute_stringv (GFileInfo  *info,
    1262                 :             :                                    const char *attribute,
    1263                 :             :                                    char      **attr_value)
    1264                 :             : {
    1265                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1266                 :           0 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1267                 :           0 :   g_return_if_fail (attr_value != NULL);
    1268                 :             : 
    1269                 :           0 :   _g_file_info_set_attribute_stringv_by_id (info,
    1270                 :             :                                             lookup_attribute (attribute),
    1271                 :             :                                             attr_value);
    1272                 :             : }
    1273                 :             : 
    1274                 :             : void
    1275                 :         767 : _g_file_info_set_attribute_string_by_id (GFileInfo  *info,
    1276                 :             :                                          guint32     attribute,
    1277                 :             :                                          const char *attr_value)
    1278                 :             : {
    1279                 :             :   GFileAttributeValue *value;
    1280                 :             : 
    1281                 :         767 :   value = g_file_info_create_value (info, attribute);
    1282                 :         767 :   if (value)
    1283                 :         767 :     _g_file_attribute_value_set_string (value, attr_value);
    1284                 :         767 : }
    1285                 :             : 
    1286                 :             : /**
    1287                 :             :  * g_file_info_set_attribute_string:
    1288                 :             :  * @info: a #GFileInfo.
    1289                 :             :  * @attribute: a file attribute key.
    1290                 :             :  * @attr_value: a UTF-8 string.
    1291                 :             :  *
    1292                 :             :  * Sets the @attribute to contain the given @attr_value,
    1293                 :             :  * if possible.
    1294                 :             :  **/
    1295                 :             : void
    1296                 :          92 : g_file_info_set_attribute_string (GFileInfo  *info,
    1297                 :             :                                   const char *attribute,
    1298                 :             :                                   const char *attr_value)
    1299                 :             : {
    1300                 :          92 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1301                 :          92 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1302                 :          92 :   g_return_if_fail (attr_value != NULL);
    1303                 :             : 
    1304                 :          92 :   _g_file_info_set_attribute_string_by_id (info,
    1305                 :             :                                            lookup_attribute (attribute),
    1306                 :             :                                            attr_value);
    1307                 :             : }
    1308                 :             : 
    1309                 :             : void
    1310                 :          56 : _g_file_info_set_attribute_byte_string_by_id (GFileInfo  *info,
    1311                 :             :                                               guint32     attribute,
    1312                 :             :                                               const char *attr_value)
    1313                 :             : {
    1314                 :             :   GFileAttributeValue *value;
    1315                 :             : 
    1316                 :          56 :   value = g_file_info_create_value (info, attribute);
    1317                 :          56 :   if (value)
    1318                 :          56 :     _g_file_attribute_value_set_byte_string (value, attr_value);
    1319                 :          56 : }
    1320                 :             : 
    1321                 :             : /**
    1322                 :             :  * g_file_info_set_attribute_byte_string:
    1323                 :             :  * @info: a #GFileInfo.
    1324                 :             :  * @attribute: a file attribute key.
    1325                 :             :  * @attr_value: a byte string.
    1326                 :             :  *
    1327                 :             :  * Sets the @attribute to contain the given @attr_value,
    1328                 :             :  * if possible.
    1329                 :             :  **/
    1330                 :             : void
    1331                 :           5 : g_file_info_set_attribute_byte_string (GFileInfo  *info,
    1332                 :             :                                        const char *attribute,
    1333                 :             :                                        const char *attr_value)
    1334                 :             : {
    1335                 :           5 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1336                 :           5 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1337                 :           5 :   g_return_if_fail (attr_value != NULL);
    1338                 :             : 
    1339                 :           5 :   _g_file_info_set_attribute_byte_string_by_id (info,
    1340                 :             :                                                 lookup_attribute (attribute),
    1341                 :             :                                                 attr_value);
    1342                 :             : }
    1343                 :             : 
    1344                 :             : /**
    1345                 :             :  * g_file_info_set_attribute_file_path:
    1346                 :             :  * @info: a #GFileInfo.
    1347                 :             :  * @attribute: a file attribute key.
    1348                 :             :  * @attr_value: (type filename): a file path.
    1349                 :             :  *
    1350                 :             :  * Sets the @attribute to contain the given @attr_value,
    1351                 :             :  * if possible.
    1352                 :             :  *
    1353                 :             :  * This function is meant to be used by language bindings that have specific
    1354                 :             :  * handling for Unix paths.
    1355                 :             :  *
    1356                 :             :  * Since: 2.78
    1357                 :             :  **/
    1358                 :             : void
    1359                 :           2 : g_file_info_set_attribute_file_path (GFileInfo  *info,
    1360                 :             :                                      const char *attribute,
    1361                 :             :                                      const char *attr_value)
    1362                 :             : {
    1363                 :           2 :   g_file_info_set_attribute_byte_string (info, attribute, attr_value);
    1364                 :           2 : }
    1365                 :             : 
    1366                 :             : void
    1367                 :        1579 : _g_file_info_set_attribute_boolean_by_id (GFileInfo *info,
    1368                 :             :                                           guint32    attribute,
    1369                 :             :                                           gboolean   attr_value)
    1370                 :             : {
    1371                 :             :   GFileAttributeValue *value;
    1372                 :             : 
    1373                 :        1579 :   value = g_file_info_create_value (info, attribute);
    1374                 :        1579 :   if (value)
    1375                 :        1013 :     _g_file_attribute_value_set_boolean (value, attr_value);
    1376                 :        1579 : }
    1377                 :             : 
    1378                 :             : /**
    1379                 :             :  * g_file_info_set_attribute_boolean:
    1380                 :             :  * @info: a #GFileInfo.
    1381                 :             :  * @attribute: a file attribute key.
    1382                 :             :  * @attr_value: a boolean value.
    1383                 :             :  *
    1384                 :             :  * Sets the @attribute to contain the given @attr_value,
    1385                 :             :  * if possible.
    1386                 :             :  **/
    1387                 :             : void
    1388                 :           1 : g_file_info_set_attribute_boolean (GFileInfo  *info,
    1389                 :             :                                    const char *attribute,
    1390                 :             :                                    gboolean    attr_value)
    1391                 :             : {
    1392                 :           1 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1393                 :           1 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1394                 :             : 
    1395                 :           1 :   _g_file_info_set_attribute_boolean_by_id (info,
    1396                 :             :                                             lookup_attribute (attribute),
    1397                 :             :                                             attr_value);
    1398                 :             : }
    1399                 :             : 
    1400                 :             : void
    1401                 :       10626 : _g_file_info_set_attribute_uint32_by_id (GFileInfo *info,
    1402                 :             :                                          guint32    attribute,
    1403                 :             :                                          guint32    attr_value)
    1404                 :             : {
    1405                 :             :   GFileAttributeValue *value;
    1406                 :             : 
    1407                 :       10626 :   value = g_file_info_create_value (info, attribute);
    1408                 :       10626 :   if (value)
    1409                 :        1544 :     _g_file_attribute_value_set_uint32 (value, attr_value);
    1410                 :       10626 : }
    1411                 :             : 
    1412                 :             : /**
    1413                 :             :  * g_file_info_set_attribute_uint32:
    1414                 :             :  * @info: a #GFileInfo.
    1415                 :             :  * @attribute: a file attribute key.
    1416                 :             :  * @attr_value: an unsigned 32-bit integer.
    1417                 :             :  *
    1418                 :             :  * Sets the @attribute to contain the given @attr_value,
    1419                 :             :  * if possible.
    1420                 :             :  **/
    1421                 :             : void
    1422                 :           8 : g_file_info_set_attribute_uint32 (GFileInfo  *info,
    1423                 :             :                                   const char *attribute,
    1424                 :             :                                   guint32     attr_value)
    1425                 :             : {
    1426                 :           8 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1427                 :           8 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1428                 :             : 
    1429                 :           8 :   _g_file_info_set_attribute_uint32_by_id (info,
    1430                 :             :                                            lookup_attribute (attribute),
    1431                 :             :                                            attr_value);
    1432                 :             : }
    1433                 :             : 
    1434                 :             : void
    1435                 :           1 : _g_file_info_set_attribute_int32_by_id (GFileInfo *info,
    1436                 :             :                                         guint32    attribute,
    1437                 :             :                                         gint32     attr_value)
    1438                 :             : {
    1439                 :             :   GFileAttributeValue *value;
    1440                 :             : 
    1441                 :           1 :   value = g_file_info_create_value (info, attribute);
    1442                 :           1 :   if (value)
    1443                 :           1 :     _g_file_attribute_value_set_int32 (value, attr_value);
    1444                 :           1 : }
    1445                 :             : 
    1446                 :             : /**
    1447                 :             :  * g_file_info_set_attribute_int32:
    1448                 :             :  * @info: a #GFileInfo.
    1449                 :             :  * @attribute: a file attribute key.
    1450                 :             :  * @attr_value: a signed 32-bit integer
    1451                 :             :  *
    1452                 :             :  * Sets the @attribute to contain the given @attr_value,
    1453                 :             :  * if possible.
    1454                 :             :  **/
    1455                 :             : void
    1456                 :           1 : g_file_info_set_attribute_int32 (GFileInfo  *info,
    1457                 :             :                                  const char *attribute,
    1458                 :             :                                  gint32      attr_value)
    1459                 :             : {
    1460                 :           1 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1461                 :           1 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1462                 :             : 
    1463                 :           1 :   _g_file_info_set_attribute_int32_by_id (info,
    1464                 :             :                                           lookup_attribute (attribute),
    1465                 :             :                                           attr_value);
    1466                 :             : }
    1467                 :             : 
    1468                 :             : void
    1469                 :        4960 : _g_file_info_set_attribute_uint64_by_id (GFileInfo *info,
    1470                 :             :                                          guint32    attribute,
    1471                 :             :                                          guint64    attr_value)
    1472                 :             : {
    1473                 :             :   GFileAttributeValue *value;
    1474                 :             : 
    1475                 :        4960 :   value = g_file_info_create_value (info, attribute);
    1476                 :        4960 :   if (value)
    1477                 :         617 :     _g_file_attribute_value_set_uint64 (value, attr_value);
    1478                 :        4960 : }
    1479                 :             : 
    1480                 :             : /**
    1481                 :             :  * g_file_info_set_attribute_uint64:
    1482                 :             :  * @info: a #GFileInfo.
    1483                 :             :  * @attribute: a file attribute key.
    1484                 :             :  * @attr_value: an unsigned 64-bit integer.
    1485                 :             :  *
    1486                 :             :  * Sets the @attribute to contain the given @attr_value,
    1487                 :             :  * if possible.
    1488                 :             :  **/
    1489                 :             : void
    1490                 :           5 : g_file_info_set_attribute_uint64 (GFileInfo  *info,
    1491                 :             :                                   const char *attribute,
    1492                 :             :                                   guint64     attr_value)
    1493                 :             : {
    1494                 :           5 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1495                 :           5 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1496                 :             : 
    1497                 :           5 :   _g_file_info_set_attribute_uint64_by_id (info,
    1498                 :             :                                            lookup_attribute (attribute),
    1499                 :             :                                            attr_value);
    1500                 :             : }
    1501                 :             : 
    1502                 :             : void
    1503                 :           0 : _g_file_info_set_attribute_int64_by_id (GFileInfo *info,
    1504                 :             :                                         guint32    attribute,
    1505                 :             :                                         gint64     attr_value)
    1506                 :             : {
    1507                 :             :   GFileAttributeValue *value;
    1508                 :             : 
    1509                 :           0 :   value = g_file_info_create_value (info, attribute);
    1510                 :           0 :   if (value)
    1511                 :           0 :     _g_file_attribute_value_set_int64 (value, attr_value);
    1512                 :           0 : }
    1513                 :             : 
    1514                 :             : /**
    1515                 :             :  * g_file_info_set_attribute_int64:
    1516                 :             :  * @info: a #GFileInfo.
    1517                 :             :  * @attribute: attribute name to set.
    1518                 :             :  * @attr_value: int64 value to set attribute to.
    1519                 :             :  *
    1520                 :             :  * Sets the @attribute to contain the given @attr_value,
    1521                 :             :  * if possible.
    1522                 :             :  *
    1523                 :             :  **/
    1524                 :             : void
    1525                 :           0 : g_file_info_set_attribute_int64  (GFileInfo  *info,
    1526                 :             :                                   const char *attribute,
    1527                 :             :                                   gint64      attr_value)
    1528                 :             : {
    1529                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1530                 :           0 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1531                 :             : 
    1532                 :           0 :   _g_file_info_set_attribute_int64_by_id (info,
    1533                 :             :                                           lookup_attribute (attribute),
    1534                 :             :                                           attr_value);
    1535                 :             : }
    1536                 :             : 
    1537                 :             : /* Helper getters */
    1538                 :             : #define get_required_attribute(value_ptr, info, attribute_name, error_value) \
    1539                 :             :   G_STMT_START { \
    1540                 :             :     static guint32 attr = 0; \
    1541                 :             : \
    1542                 :             :     if (attr == 0) \
    1543                 :             :       attr = lookup_attribute (attribute_name); \
    1544                 :             : \
    1545                 :             :     *value_ptr = g_file_info_find_value (info, attr); \
    1546                 :             :     if (G_UNLIKELY (*value_ptr == NULL)) \
    1547                 :             :       { \
    1548                 :             :         g_critical ("GFileInfo created without " attribute_name); \
    1549                 :             :         g_return_val_if_reached (error_value); \
    1550                 :             :       } \
    1551                 :             :   } G_STMT_END
    1552                 :             : 
    1553                 :             : /**
    1554                 :             :  * g_file_info_get_deletion_date:
    1555                 :             :  * @info: a #GFileInfo.
    1556                 :             :  *
    1557                 :             :  * Returns the #GDateTime representing the deletion date of the file, as
    1558                 :             :  * available in %G_FILE_ATTRIBUTE_TRASH_DELETION_DATE. If the
    1559                 :             :  * %G_FILE_ATTRIBUTE_TRASH_DELETION_DATE attribute is unset, %NULL is returned.
    1560                 :             :  *
    1561                 :             :  * Returns: (nullable): a #GDateTime, or %NULL.
    1562                 :             :  *
    1563                 :             :  * Since: 2.36
    1564                 :             :  **/
    1565                 :             : GDateTime *
    1566                 :           0 : g_file_info_get_deletion_date (GFileInfo *info)
    1567                 :             : {
    1568                 :             :   static guint32 attr = 0;
    1569                 :             :   GFileAttributeValue *value;
    1570                 :             :   const char *date_str;
    1571                 :           0 :   GTimeZone *local_tz = NULL;
    1572                 :           0 :   GDateTime *dt = NULL;
    1573                 :             : 
    1574                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
    1575                 :             : 
    1576                 :           0 :   if (attr == 0)
    1577                 :           0 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_TRASH_DELETION_DATE);
    1578                 :             : 
    1579                 :           0 :   value = g_file_info_find_value (info, attr);
    1580                 :           0 :   date_str = _g_file_attribute_value_get_string (value);
    1581                 :           0 :   if (!date_str)
    1582                 :           0 :     return NULL;
    1583                 :             : 
    1584                 :           0 :   local_tz = g_time_zone_new_local ();
    1585                 :           0 :   dt = g_date_time_new_from_iso8601 (date_str, local_tz);
    1586                 :           0 :   g_time_zone_unref (local_tz);
    1587                 :             : 
    1588                 :           0 :   return g_steal_pointer (&dt);
    1589                 :             : }
    1590                 :             : 
    1591                 :             : /**
    1592                 :             :  * g_file_info_get_file_type:
    1593                 :             :  * @info: a #GFileInfo.
    1594                 :             :  *
    1595                 :             :  * Gets a file's type (whether it is a regular file, symlink, etc).
    1596                 :             :  * This is different from the file's content type, see g_file_info_get_content_type().
    1597                 :             :  *
    1598                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1599                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_TYPE.
    1600                 :             :  *
    1601                 :             :  * Returns: a #GFileType for the given file.
    1602                 :             :  **/
    1603                 :             : GFileType
    1604                 :         447 : g_file_info_get_file_type (GFileInfo *info)
    1605                 :             : {
    1606                 :             :   GFileAttributeValue *value;
    1607                 :             : 
    1608                 :         447 :   g_return_val_if_fail (G_IS_FILE_INFO (info), G_FILE_TYPE_UNKNOWN);
    1609                 :             : 
    1610                 :         447 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_TYPE, G_FILE_TYPE_UNKNOWN);
    1611                 :         447 :   return (GFileType)_g_file_attribute_value_get_uint32 (value);
    1612                 :             : }
    1613                 :             : 
    1614                 :             : /**
    1615                 :             :  * g_file_info_get_is_hidden:
    1616                 :             :  * @info: a #GFileInfo.
    1617                 :             :  *
    1618                 :             :  * Checks if a file is hidden.
    1619                 :             :  *
    1620                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1621                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN.
    1622                 :             :  *
    1623                 :             :  * Returns: %TRUE if the file is a hidden file, %FALSE otherwise.
    1624                 :             :  **/
    1625                 :             : gboolean
    1626                 :           0 : g_file_info_get_is_hidden (GFileInfo *info)
    1627                 :             : {
    1628                 :             :   GFileAttributeValue *value;
    1629                 :             : 
    1630                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
    1631                 :             : 
    1632                 :           0 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN, FALSE);
    1633                 :           0 :   return _g_file_attribute_value_get_boolean (value);
    1634                 :             : }
    1635                 :             : 
    1636                 :             : /**
    1637                 :             :  * g_file_info_get_is_backup:
    1638                 :             :  * @info: a #GFileInfo.
    1639                 :             :  *
    1640                 :             :  * Checks if a file is a backup file.
    1641                 :             :  *
    1642                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1643                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP.
    1644                 :             :  *
    1645                 :             :  * Returns: %TRUE if file is a backup file, %FALSE otherwise.
    1646                 :             :  **/
    1647                 :             : gboolean
    1648                 :           0 : g_file_info_get_is_backup (GFileInfo *info)
    1649                 :             : {
    1650                 :             :   GFileAttributeValue *value;
    1651                 :             : 
    1652                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
    1653                 :             : 
    1654                 :           0 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, FALSE);
    1655                 :           0 :   return _g_file_attribute_value_get_boolean (value);
    1656                 :             : }
    1657                 :             : 
    1658                 :             : /**
    1659                 :             :  * g_file_info_get_is_symlink:
    1660                 :             :  * @info: a #GFileInfo.
    1661                 :             :  *
    1662                 :             :  * Checks if a file is a symlink.
    1663                 :             :  *
    1664                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1665                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK.
    1666                 :             :  *
    1667                 :             :  * Returns: %TRUE if the given @info is a symlink.
    1668                 :             :  **/
    1669                 :             : gboolean
    1670                 :          43 : g_file_info_get_is_symlink (GFileInfo *info)
    1671                 :             : {
    1672                 :             :   GFileAttributeValue *value;
    1673                 :             : 
    1674                 :          43 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
    1675                 :             : 
    1676                 :          43 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK, FALSE);
    1677                 :          43 :   return _g_file_attribute_value_get_boolean (value);
    1678                 :             : }
    1679                 :             : 
    1680                 :             : /**
    1681                 :             :  * g_file_info_get_name:
    1682                 :             :  * @info: a #GFileInfo.
    1683                 :             :  *
    1684                 :             :  * Gets the name for a file. This is guaranteed to always be set.
    1685                 :             :  *
    1686                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1687                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_NAME.
    1688                 :             :  *
    1689                 :             :  * Returns: (type filename) (not nullable): a string containing the file name.
    1690                 :             :  **/
    1691                 :             : const char *
    1692                 :         206 : g_file_info_get_name (GFileInfo *info)
    1693                 :             : {
    1694                 :             :   GFileAttributeValue *value;
    1695                 :             : 
    1696                 :         206 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1697                 :             : 
    1698                 :         206 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_NAME, NULL);
    1699                 :         206 :   return _g_file_attribute_value_get_byte_string (value);
    1700                 :             : }
    1701                 :             : 
    1702                 :             : /**
    1703                 :             :  * g_file_info_get_display_name:
    1704                 :             :  * @info: a #GFileInfo.
    1705                 :             :  *
    1706                 :             :  * Gets a display name for a file. This is guaranteed to always be set.
    1707                 :             :  *
    1708                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1709                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME.
    1710                 :             :  *
    1711                 :             :  * Returns: (not nullable): a string containing the display name.
    1712                 :             :  **/
    1713                 :             : const char *
    1714                 :         100 : g_file_info_get_display_name (GFileInfo *info)
    1715                 :             : {
    1716                 :             :   GFileAttributeValue *value;
    1717                 :             : 
    1718                 :         100 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1719                 :             : 
    1720                 :         100 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME, NULL);
    1721                 :         100 :   return _g_file_attribute_value_get_string (value);
    1722                 :             : }
    1723                 :             : 
    1724                 :             : /**
    1725                 :             :  * g_file_info_get_edit_name:
    1726                 :             :  * @info: a #GFileInfo.
    1727                 :             :  *
    1728                 :             :  * Gets the edit name for a file.
    1729                 :             :  *
    1730                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1731                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME.
    1732                 :             :  *
    1733                 :             :  * Returns: a string containing the edit name.
    1734                 :             :  **/
    1735                 :             : const char *
    1736                 :          42 : g_file_info_get_edit_name (GFileInfo *info)
    1737                 :             : {
    1738                 :             :   GFileAttributeValue *value;
    1739                 :             : 
    1740                 :          42 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1741                 :             : 
    1742                 :          42 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME, NULL);
    1743                 :          42 :   return _g_file_attribute_value_get_string (value);
    1744                 :             : }
    1745                 :             : 
    1746                 :             : /**
    1747                 :             :  * g_file_info_get_icon:
    1748                 :             :  * @info: a #GFileInfo.
    1749                 :             :  *
    1750                 :             :  * Gets the icon for a file.
    1751                 :             :  *
    1752                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1753                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_ICON.
    1754                 :             :  *
    1755                 :             :  * Returns: (nullable) (transfer none): #GIcon for the given @info.
    1756                 :             :  **/
    1757                 :             : GIcon *
    1758                 :           0 : g_file_info_get_icon (GFileInfo *info)
    1759                 :             : {
    1760                 :             :   GFileAttributeValue *value;
    1761                 :             :   GObject *obj;
    1762                 :             : 
    1763                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1764                 :             : 
    1765                 :           0 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_ICON, NULL);
    1766                 :             : 
    1767                 :           0 :   obj = _g_file_attribute_value_get_object (value);
    1768                 :           0 :   if (G_IS_ICON (obj))
    1769                 :           0 :     return G_ICON (obj);
    1770                 :           0 :   return NULL;
    1771                 :             : }
    1772                 :             : 
    1773                 :             : /**
    1774                 :             :  * g_file_info_get_symbolic_icon:
    1775                 :             :  * @info: a #GFileInfo.
    1776                 :             :  *
    1777                 :             :  * Gets the symbolic icon for a file.
    1778                 :             :  *
    1779                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1780                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON.
    1781                 :             :  *
    1782                 :             :  * Returns: (nullable) (transfer none): #GIcon for the given @info.
    1783                 :             :  *
    1784                 :             :  * Since: 2.34
    1785                 :             :  **/
    1786                 :             : GIcon *
    1787                 :           0 : g_file_info_get_symbolic_icon (GFileInfo *info)
    1788                 :             : {
    1789                 :             :   GFileAttributeValue *value;
    1790                 :             :   GObject *obj;
    1791                 :             : 
    1792                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1793                 :             : 
    1794                 :           0 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON, NULL);
    1795                 :             : 
    1796                 :           0 :   obj = _g_file_attribute_value_get_object (value);
    1797                 :           0 :   if (G_IS_ICON (obj))
    1798                 :           0 :     return G_ICON (obj);
    1799                 :           0 :   return NULL;
    1800                 :             : }
    1801                 :             : 
    1802                 :             : /**
    1803                 :             :  * g_file_info_get_content_type:
    1804                 :             :  * @info: a #GFileInfo.
    1805                 :             :  *
    1806                 :             :  * Gets the file's content type.
    1807                 :             :  *
    1808                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1809                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE.
    1810                 :             :  *
    1811                 :             :  * Returns: (nullable): a string containing the file's content type,
    1812                 :             :  * or %NULL if unknown.
    1813                 :             :  **/
    1814                 :             : const char *
    1815                 :           8 : g_file_info_get_content_type (GFileInfo *info)
    1816                 :             : {
    1817                 :             :   GFileAttributeValue *value;
    1818                 :             : 
    1819                 :           8 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1820                 :             : 
    1821                 :           8 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, NULL);
    1822                 :           8 :   return _g_file_attribute_value_get_string (value);
    1823                 :             : }
    1824                 :             : 
    1825                 :             : /**
    1826                 :             :  * g_file_info_get_size:
    1827                 :             :  * @info: a #GFileInfo.
    1828                 :             :  *
    1829                 :             :  * Gets the file's size (in bytes). The size is retrieved through the value of
    1830                 :             :  * the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute and is converted
    1831                 :             :  * from #guint64 to #goffset before returning the result.
    1832                 :             :  *
    1833                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1834                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_SIZE.
    1835                 :             :  *
    1836                 :             :  * Returns: a #goffset containing the file's size (in bytes).
    1837                 :             :  **/
    1838                 :             : goffset
    1839                 :         164 : g_file_info_get_size (GFileInfo *info)
    1840                 :             : {
    1841                 :             :   GFileAttributeValue *value;
    1842                 :             : 
    1843                 :         164 :   g_return_val_if_fail (G_IS_FILE_INFO (info), (goffset) 0);
    1844                 :             : 
    1845                 :         164 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SIZE, (goffset) 0);
    1846                 :         164 :   return (goffset) _g_file_attribute_value_get_uint64 (value);
    1847                 :             : }
    1848                 :             : 
    1849                 :             : /**
    1850                 :             :  * g_file_info_get_modification_time:
    1851                 :             :  * @info: a #GFileInfo.
    1852                 :             :  * @result: (out caller-allocates): a #GTimeVal.
    1853                 :             :  *
    1854                 :             :  * Gets the modification time of the current @info and sets it
    1855                 :             :  * in @result.
    1856                 :             :  *
    1857                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1858                 :             :  * %G_FILE_ATTRIBUTE_TIME_MODIFIED. If %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is
    1859                 :             :  * provided it will be used too.
    1860                 :             :  *
    1861                 :             :  * Deprecated: 2.62: Use g_file_info_get_modification_date_time() instead, as
    1862                 :             :  *    #GTimeVal is deprecated due to the year 2038 problem.
    1863                 :             :  **/
    1864                 :             : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    1865                 :             : void
    1866                 :           0 : g_file_info_get_modification_time (GFileInfo *info,
    1867                 :             :                                    GTimeVal  *result)
    1868                 :             : {
    1869                 :             :   static guint32 attr_mtime = 0, attr_mtime_usec;
    1870                 :             :   GFileAttributeValue *value;
    1871                 :             : 
    1872                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1873                 :           0 :   g_return_if_fail (result != NULL);
    1874                 :             : 
    1875                 :           0 :   if (attr_mtime == 0)
    1876                 :             :     {
    1877                 :           0 :       attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
    1878                 :           0 :       attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
    1879                 :             :     }
    1880                 :             : 
    1881                 :           0 :   value = g_file_info_find_value (info, attr_mtime);
    1882                 :             : 
    1883                 :           0 :   if (G_UNLIKELY (value == NULL))
    1884                 :             :     {
    1885                 :           0 :       g_critical ("GFileInfo created without " G_FILE_ATTRIBUTE_TIME_MODIFIED);
    1886                 :           0 :       result->tv_sec = result->tv_usec = 0;
    1887                 :             :       g_return_if_reached ();
    1888                 :             :     }
    1889                 :             : 
    1890                 :           0 :   result->tv_sec = _g_file_attribute_value_get_uint64 (value);
    1891                 :           0 :   value = g_file_info_find_value (info, attr_mtime_usec);
    1892                 :           0 :   result->tv_usec = _g_file_attribute_value_get_uint32 (value);
    1893                 :             : }
    1894                 :             : G_GNUC_END_IGNORE_DEPRECATIONS
    1895                 :             : 
    1896                 :             : /**
    1897                 :             :  * g_file_info_get_modification_date_time:
    1898                 :             :  * @info: a #GFileInfo.
    1899                 :             :  *
    1900                 :             :  * Gets the modification time of the current @info and returns it as a
    1901                 :             :  * #GDateTime.
    1902                 :             :  *
    1903                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1904                 :             :  * %G_FILE_ATTRIBUTE_TIME_MODIFIED. If %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC is
    1905                 :             :  * provided, the resulting #GDateTime will additionally have microsecond
    1906                 :             :  * precision.
    1907                 :             :  *
    1908                 :             :  * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC must
    1909                 :             :  * be queried separately using g_file_info_get_attribute_uint32().
    1910                 :             :  *
    1911                 :             :  * Returns: (transfer full) (nullable): modification time, or %NULL if unknown
    1912                 :             :  * Since: 2.62
    1913                 :             :  */
    1914                 :             : GDateTime *
    1915                 :           4 : g_file_info_get_modification_date_time (GFileInfo *info)
    1916                 :             : {
    1917                 :             :   static guint32 attr_mtime = 0, attr_mtime_usec;
    1918                 :             :   GFileAttributeValue *value, *value_usec;
    1919                 :           4 :   GDateTime *dt = NULL, *dt2 = NULL;
    1920                 :             : 
    1921                 :           4 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1922                 :             : 
    1923                 :           4 :   if (attr_mtime == 0)
    1924                 :             :     {
    1925                 :           1 :       attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
    1926                 :           1 :       attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
    1927                 :             :     }
    1928                 :             : 
    1929                 :           4 :   value = g_file_info_find_value (info, attr_mtime);
    1930                 :           4 :   if (value == NULL)
    1931                 :           0 :     return NULL;
    1932                 :             : 
    1933                 :           4 :   dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
    1934                 :             : 
    1935                 :           4 :   value_usec = g_file_info_find_value (info, attr_mtime_usec);
    1936                 :           4 :   if (value_usec == NULL)
    1937                 :           1 :     return g_steal_pointer (&dt);
    1938                 :             : 
    1939                 :           3 :   dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
    1940                 :           3 :   g_date_time_unref (dt);
    1941                 :             : 
    1942                 :           3 :   return g_steal_pointer (&dt2);
    1943                 :             : }
    1944                 :             : 
    1945                 :             : /**
    1946                 :             :  * g_file_info_get_access_date_time:
    1947                 :             :  * @info: a #GFileInfo.
    1948                 :             :  *
    1949                 :             :  * Gets the access time of the current @info and returns it as a
    1950                 :             :  * #GDateTime.
    1951                 :             :  *
    1952                 :             :  * It is an error to call this if the #GFileInfo does not contain
    1953                 :             :  * %G_FILE_ATTRIBUTE_TIME_ACCESS. If %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC is
    1954                 :             :  * provided, the resulting #GDateTime will additionally have microsecond
    1955                 :             :  * precision.
    1956                 :             :  *
    1957                 :             :  * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC must
    1958                 :             :  * be queried separately using g_file_info_get_attribute_uint32().
    1959                 :             :  *
    1960                 :             :  * Returns: (transfer full) (nullable): access time, or %NULL if unknown
    1961                 :             :  * Since: 2.70
    1962                 :             :  */
    1963                 :             : GDateTime *
    1964                 :           5 : g_file_info_get_access_date_time (GFileInfo *info)
    1965                 :             : {
    1966                 :             :   static guint32 attr_atime = 0, attr_atime_usec;
    1967                 :             :   GFileAttributeValue *value, *value_usec;
    1968                 :           5 :   GDateTime *dt = NULL, *dt2 = NULL;
    1969                 :             : 
    1970                 :           5 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1971                 :             : 
    1972                 :           5 :   if (attr_atime == 0)
    1973                 :             :     {
    1974                 :           1 :       attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS);
    1975                 :           1 :       attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
    1976                 :             :     }
    1977                 :             : 
    1978                 :           5 :   value = g_file_info_find_value (info, attr_atime);
    1979                 :           5 :   if (value == NULL)
    1980                 :           0 :     return NULL;
    1981                 :             : 
    1982                 :           5 :   dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
    1983                 :             : 
    1984                 :           5 :   value_usec = g_file_info_find_value (info, attr_atime_usec);
    1985                 :           5 :   if (value_usec == NULL)
    1986                 :           1 :     return g_steal_pointer (&dt);
    1987                 :             : 
    1988                 :           4 :   dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
    1989                 :           4 :   g_date_time_unref (dt);
    1990                 :             : 
    1991                 :           4 :   return g_steal_pointer (&dt2);
    1992                 :             : }
    1993                 :             : 
    1994                 :             : /**
    1995                 :             :  * g_file_info_get_creation_date_time:
    1996                 :             :  * @info: a #GFileInfo.
    1997                 :             :  *
    1998                 :             :  * Gets the creation time of the current @info and returns it as a
    1999                 :             :  * #GDateTime.
    2000                 :             :  *
    2001                 :             :  * It is an error to call this if the #GFileInfo does not contain
    2002                 :             :  * %G_FILE_ATTRIBUTE_TIME_CREATED. If %G_FILE_ATTRIBUTE_TIME_CREATED_USEC is
    2003                 :             :  * provided, the resulting #GDateTime will additionally have microsecond
    2004                 :             :  * precision.
    2005                 :             :  *
    2006                 :             :  * If nanosecond precision is needed, %G_FILE_ATTRIBUTE_TIME_CREATED_NSEC must
    2007                 :             :  * be queried separately using g_file_info_get_attribute_uint32().
    2008                 :             :  *
    2009                 :             :  * Returns: (transfer full) (nullable): creation time, or %NULL if unknown
    2010                 :             :  * Since: 2.70
    2011                 :             :  */
    2012                 :             : GDateTime *
    2013                 :           4 : g_file_info_get_creation_date_time (GFileInfo *info)
    2014                 :             : {
    2015                 :             :   static guint32 attr_ctime = 0, attr_ctime_usec;
    2016                 :             :   GFileAttributeValue *value, *value_usec;
    2017                 :           4 :   GDateTime *dt = NULL, *dt2 = NULL;
    2018                 :             : 
    2019                 :           4 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    2020                 :             : 
    2021                 :           4 :   if (attr_ctime == 0)
    2022                 :             :     {
    2023                 :           1 :       attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED);
    2024                 :           1 :       attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
    2025                 :             :     }
    2026                 :             : 
    2027                 :           4 :   value = g_file_info_find_value (info, attr_ctime);
    2028                 :           4 :   if (value == NULL)
    2029                 :           0 :     return NULL;
    2030                 :             : 
    2031                 :           4 :   dt = g_date_time_new_from_unix_utc (_g_file_attribute_value_get_uint64 (value));
    2032                 :             : 
    2033                 :           4 :   value_usec = g_file_info_find_value (info, attr_ctime_usec);
    2034                 :           4 :   if (value_usec == NULL)
    2035                 :           1 :     return g_steal_pointer (&dt);
    2036                 :             : 
    2037                 :           3 :   dt2 = g_date_time_add (dt, _g_file_attribute_value_get_uint32 (value_usec));
    2038                 :           3 :   g_date_time_unref (dt);
    2039                 :             : 
    2040                 :           3 :   return g_steal_pointer (&dt2);
    2041                 :             : }
    2042                 :             : 
    2043                 :             : /**
    2044                 :             :  * g_file_info_get_symlink_target:
    2045                 :             :  * @info: a #GFileInfo.
    2046                 :             :  *
    2047                 :             :  * Gets the symlink target for a given #GFileInfo.
    2048                 :             :  *
    2049                 :             :  * It is an error to call this if the #GFileInfo does not contain
    2050                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET.
    2051                 :             :  *
    2052                 :             :  * Returns: (type filename) (nullable): a string containing the symlink target.
    2053                 :             :  **/
    2054                 :             : const char *
    2055                 :          41 : g_file_info_get_symlink_target (GFileInfo *info)
    2056                 :             : {
    2057                 :             :   GFileAttributeValue *value;
    2058                 :             : 
    2059                 :          41 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    2060                 :             : 
    2061                 :          41 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET, NULL);
    2062                 :          41 :   return _g_file_attribute_value_get_byte_string (value);
    2063                 :             : }
    2064                 :             : 
    2065                 :             : /**
    2066                 :             :  * g_file_info_get_etag:
    2067                 :             :  * @info: a #GFileInfo.
    2068                 :             :  *
    2069                 :             :  * Gets the [entity tag](iface.File.html#entity-tags) for a given
    2070                 :             :  * #GFileInfo. See %G_FILE_ATTRIBUTE_ETAG_VALUE.
    2071                 :             :  *
    2072                 :             :  * It is an error to call this if the #GFileInfo does not contain
    2073                 :             :  * %G_FILE_ATTRIBUTE_ETAG_VALUE.
    2074                 :             :  *
    2075                 :             :  * Returns: (nullable): a string containing the value of the "etag:value" attribute.
    2076                 :             :  **/
    2077                 :             : const char *
    2078                 :           4 : g_file_info_get_etag (GFileInfo *info)
    2079                 :             : {
    2080                 :             :   GFileAttributeValue *value;
    2081                 :             : 
    2082                 :           4 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    2083                 :             : 
    2084                 :           4 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_ETAG_VALUE, NULL);
    2085                 :           4 :   return _g_file_attribute_value_get_string (value);
    2086                 :             : }
    2087                 :             : 
    2088                 :             : /**
    2089                 :             :  * g_file_info_get_sort_order:
    2090                 :             :  * @info: a #GFileInfo.
    2091                 :             :  *
    2092                 :             :  * Gets the value of the sort_order attribute from the #GFileInfo.
    2093                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER.
    2094                 :             :  *
    2095                 :             :  * It is an error to call this if the #GFileInfo does not contain
    2096                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER.
    2097                 :             :  *
    2098                 :             :  * Returns: a #gint32 containing the value of the "standard::sort_order" attribute.
    2099                 :             :  **/
    2100                 :             : gint32
    2101                 :           0 : g_file_info_get_sort_order (GFileInfo *info)
    2102                 :             : {
    2103                 :             :   GFileAttributeValue *value;
    2104                 :             : 
    2105                 :           0 :   g_return_val_if_fail (G_IS_FILE_INFO (info), 0);
    2106                 :             : 
    2107                 :           0 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER, 0);
    2108                 :           0 :   return _g_file_attribute_value_get_int32 (value);
    2109                 :             : }
    2110                 :             : 
    2111                 :             : /* Helper setters: */
    2112                 :             : /**
    2113                 :             :  * g_file_info_set_file_type:
    2114                 :             :  * @info: a #GFileInfo.
    2115                 :             :  * @type: a #GFileType.
    2116                 :             :  *
    2117                 :             :  * Sets the file type in a #GFileInfo to @type.
    2118                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_TYPE.
    2119                 :             :  **/
    2120                 :             : void
    2121                 :        1069 : g_file_info_set_file_type (GFileInfo *info,
    2122                 :             :                            GFileType  type)
    2123                 :             : {
    2124                 :             :   static guint32 attr = 0;
    2125                 :             :   GFileAttributeValue *value;
    2126                 :             : 
    2127                 :        1069 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2128                 :             : 
    2129                 :        1069 :   if (attr == 0)
    2130                 :           9 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_TYPE);
    2131                 :             : 
    2132                 :        1069 :   value = g_file_info_create_value (info, attr);
    2133                 :        1069 :   if (value)
    2134                 :         720 :     _g_file_attribute_value_set_uint32 (value, type);
    2135                 :             : }
    2136                 :             : 
    2137                 :             : /**
    2138                 :             :  * g_file_info_set_is_hidden:
    2139                 :             :  * @info: a #GFileInfo.
    2140                 :             :  * @is_hidden: a #gboolean.
    2141                 :             :  *
    2142                 :             :  * Sets the "is_hidden" attribute in a #GFileInfo according to @is_hidden.
    2143                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN.
    2144                 :             :  **/
    2145                 :             : void
    2146                 :          76 : g_file_info_set_is_hidden (GFileInfo *info,
    2147                 :             :                            gboolean   is_hidden)
    2148                 :             : {
    2149                 :             :   static guint32 attr = 0;
    2150                 :             :   GFileAttributeValue *value;
    2151                 :             : 
    2152                 :          76 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2153                 :             : 
    2154                 :          76 :   if (attr == 0)
    2155                 :           1 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN);
    2156                 :             : 
    2157                 :          76 :   value = g_file_info_create_value (info, attr);
    2158                 :          76 :   if (value)
    2159                 :          76 :     _g_file_attribute_value_set_boolean (value, is_hidden);
    2160                 :             : }
    2161                 :             : 
    2162                 :             : /**
    2163                 :             :  * g_file_info_set_is_symlink:
    2164                 :             :  * @info: a #GFileInfo.
    2165                 :             :  * @is_symlink: a #gboolean.
    2166                 :             :  *
    2167                 :             :  * Sets the "is_symlink" attribute in a #GFileInfo according to @is_symlink.
    2168                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK.
    2169                 :             :  **/
    2170                 :             : void
    2171                 :         659 : g_file_info_set_is_symlink (GFileInfo *info,
    2172                 :             :                             gboolean   is_symlink)
    2173                 :             : {
    2174                 :             :   static guint32 attr = 0;
    2175                 :             :   GFileAttributeValue *value;
    2176                 :             : 
    2177                 :         659 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2178                 :             : 
    2179                 :         659 :   if (attr == 0)
    2180                 :           8 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
    2181                 :             : 
    2182                 :         659 :   value = g_file_info_create_value (info, attr);
    2183                 :         659 :   if (value)
    2184                 :          94 :     _g_file_attribute_value_set_boolean (value, is_symlink);
    2185                 :             : }
    2186                 :             : 
    2187                 :             : /**
    2188                 :             :  * g_file_info_set_name:
    2189                 :             :  * @info: a #GFileInfo.
    2190                 :             :  * @name: (type filename): a string containing a name.
    2191                 :             :  *
    2192                 :             :  * Sets the name attribute for the current #GFileInfo.
    2193                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_NAME.
    2194                 :             :  **/
    2195                 :             : void
    2196                 :        1349 : g_file_info_set_name (GFileInfo  *info,
    2197                 :             :                       const char *name)
    2198                 :             : {
    2199                 :             :   static guint32 attr = 0;
    2200                 :             :   GFileAttributeValue *value;
    2201                 :             : 
    2202                 :        1349 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2203                 :        1349 :   g_return_if_fail (name != NULL);
    2204                 :             : 
    2205                 :        1349 :   if (attr == 0)
    2206                 :          10 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_NAME);
    2207                 :             : 
    2208                 :        1349 :   value = g_file_info_create_value (info, attr);
    2209                 :        1349 :   if (value)
    2210                 :         442 :     _g_file_attribute_value_set_byte_string (value, name);
    2211                 :             : }
    2212                 :             : 
    2213                 :             : /**
    2214                 :             :  * g_file_info_set_display_name:
    2215                 :             :  * @info: a #GFileInfo.
    2216                 :             :  * @display_name: a string containing a display name.
    2217                 :             :  *
    2218                 :             :  * Sets the display name for the current #GFileInfo.
    2219                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME.
    2220                 :             :  **/
    2221                 :             : void
    2222                 :         135 : g_file_info_set_display_name (GFileInfo  *info,
    2223                 :             :                               const char *display_name)
    2224                 :             : {
    2225                 :             :   static guint32 attr = 0;
    2226                 :             :   GFileAttributeValue *value;
    2227                 :             : 
    2228                 :         135 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2229                 :         135 :   g_return_if_fail (display_name != NULL);
    2230                 :             : 
    2231                 :         135 :   if (attr == 0)
    2232                 :           2 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
    2233                 :             : 
    2234                 :         135 :   value = g_file_info_create_value (info, attr);
    2235                 :         135 :   if (value)
    2236                 :         135 :     _g_file_attribute_value_set_string (value, display_name);
    2237                 :             : }
    2238                 :             : 
    2239                 :             : /**
    2240                 :             :  * g_file_info_set_edit_name:
    2241                 :             :  * @info: a #GFileInfo.
    2242                 :             :  * @edit_name: a string containing an edit name.
    2243                 :             :  *
    2244                 :             :  * Sets the edit name for the current file.
    2245                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME.
    2246                 :             :  **/
    2247                 :             : void
    2248                 :         131 : g_file_info_set_edit_name (GFileInfo  *info,
    2249                 :             :                            const char *edit_name)
    2250                 :             : {
    2251                 :             :   static guint32 attr = 0;
    2252                 :             :   GFileAttributeValue *value;
    2253                 :             : 
    2254                 :         131 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2255                 :         131 :   g_return_if_fail (edit_name != NULL);
    2256                 :             : 
    2257                 :         131 :   if (attr == 0)
    2258                 :           1 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME);
    2259                 :             : 
    2260                 :         131 :   value = g_file_info_create_value (info, attr);
    2261                 :         131 :   if (value)
    2262                 :         131 :     _g_file_attribute_value_set_string (value, edit_name);
    2263                 :             : }
    2264                 :             : 
    2265                 :             : /**
    2266                 :             :  * g_file_info_set_icon:
    2267                 :             :  * @info: a #GFileInfo.
    2268                 :             :  * @icon: a #GIcon.
    2269                 :             :  *
    2270                 :             :  * Sets the icon for a given #GFileInfo.
    2271                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_ICON.
    2272                 :             :  **/
    2273                 :             : void
    2274                 :          76 : g_file_info_set_icon (GFileInfo *info,
    2275                 :             :                       GIcon     *icon)
    2276                 :             : {
    2277                 :             :   static guint32 attr = 0;
    2278                 :             :   GFileAttributeValue *value;
    2279                 :             : 
    2280                 :          76 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2281                 :          76 :   g_return_if_fail (G_IS_ICON (icon));
    2282                 :             : 
    2283                 :          76 :   if (attr == 0)
    2284                 :           1 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_ICON);
    2285                 :             : 
    2286                 :          76 :   value = g_file_info_create_value (info, attr);
    2287                 :          76 :   if (value)
    2288                 :          76 :     _g_file_attribute_value_set_object (value, G_OBJECT (icon));
    2289                 :             : }
    2290                 :             : 
    2291                 :             : /**
    2292                 :             :  * g_file_info_set_symbolic_icon:
    2293                 :             :  * @info: a #GFileInfo.
    2294                 :             :  * @icon: a #GIcon.
    2295                 :             :  *
    2296                 :             :  * Sets the symbolic icon for a given #GFileInfo.
    2297                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON.
    2298                 :             :  *
    2299                 :             :  * Since: 2.34
    2300                 :             :  **/
    2301                 :             : void
    2302                 :          76 : g_file_info_set_symbolic_icon (GFileInfo *info,
    2303                 :             :                                GIcon     *icon)
    2304                 :             : {
    2305                 :             :   static guint32 attr = 0;
    2306                 :             :   GFileAttributeValue *value;
    2307                 :             : 
    2308                 :          76 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2309                 :          76 :   g_return_if_fail (G_IS_ICON (icon));
    2310                 :             : 
    2311                 :          76 :   if (attr == 0)
    2312                 :           1 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMBOLIC_ICON);
    2313                 :             : 
    2314                 :          76 :   value = g_file_info_create_value (info, attr);
    2315                 :          76 :   if (value)
    2316                 :          76 :     _g_file_attribute_value_set_object (value, G_OBJECT (icon));
    2317                 :             : }
    2318                 :             : 
    2319                 :             : /**
    2320                 :             :  * g_file_info_set_content_type:
    2321                 :             :  * @info: a #GFileInfo.
    2322                 :             :  * @content_type: a content type. See [GContentType][gio-GContentType]
    2323                 :             :  *
    2324                 :             :  * Sets the content type attribute for a given #GFileInfo.
    2325                 :             :  * See %G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE.
    2326                 :             :  **/
    2327                 :             : void
    2328                 :          84 : g_file_info_set_content_type (GFileInfo  *info,
    2329                 :             :                               const char *content_type)
    2330                 :             : {
    2331                 :             :   static guint32 attr = 0;
    2332                 :             :   GFileAttributeValue *value;
    2333                 :             : 
    2334                 :          84 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2335                 :          84 :   g_return_if_fail (content_type != NULL);
    2336                 :             : 
    2337                 :          84 :   if (attr == 0)
    2338                 :           4 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
    2339                 :             : 
    2340                 :          84 :   value = g_file_info_create_value (info, attr);
    2341                 :          84 :   if (value)
    2342                 :          84 :     _g_file_attribute_value_set_string (value, content_type);
    2343                 :             : }
    2344                 :             : 
    2345                 :             : /**
    2346                 :             :  * g_file_info_set_size:
    2347                 :             :  * @info: a #GFileInfo.
    2348                 :             :  * @size: a #goffset containing the file's size.
    2349                 :             :  *
    2350                 :             :  * Sets the %G_FILE_ATTRIBUTE_STANDARD_SIZE attribute in the file info
    2351                 :             :  * to the given size.
    2352                 :             :  **/
    2353                 :             : void
    2354                 :         712 : g_file_info_set_size (GFileInfo *info,
    2355                 :             :                       goffset    size)
    2356                 :             : {
    2357                 :             :   static guint32 attr = 0;
    2358                 :             :   GFileAttributeValue *value;
    2359                 :             : 
    2360                 :         712 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2361                 :             : 
    2362                 :         712 :   if (attr == 0)
    2363                 :           9 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SIZE);
    2364                 :             : 
    2365                 :         712 :   value = g_file_info_create_value (info, attr);
    2366                 :         712 :   if (value)
    2367                 :         290 :     _g_file_attribute_value_set_uint64 (value, size);
    2368                 :             : }
    2369                 :             : 
    2370                 :             : /**
    2371                 :             :  * g_file_info_set_modification_time:
    2372                 :             :  * @info: a #GFileInfo.
    2373                 :             :  * @mtime: a #GTimeVal.
    2374                 :             :  *
    2375                 :             :  * Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and
    2376                 :             :  * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the
    2377                 :             :  * given time value.
    2378                 :             :  *
    2379                 :             :  * %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC will be cleared.
    2380                 :             :  *
    2381                 :             :  * Deprecated: 2.62: Use g_file_info_set_modification_date_time() instead, as
    2382                 :             :  *    #GTimeVal is deprecated due to the year 2038 problem.
    2383                 :             :  **/
    2384                 :             : G_GNUC_BEGIN_IGNORE_DEPRECATIONS
    2385                 :             : void
    2386                 :           0 : g_file_info_set_modification_time (GFileInfo *info,
    2387                 :             :                                    GTimeVal  *mtime)
    2388                 :             : {
    2389                 :             :   static guint32 attr_mtime = 0, attr_mtime_usec = 0, attr_mtime_nsec = 0;
    2390                 :             :   GFileAttributeValue *value;
    2391                 :             : 
    2392                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2393                 :           0 :   g_return_if_fail (mtime != NULL);
    2394                 :             : 
    2395                 :           0 :   if (attr_mtime == 0)
    2396                 :             :     {
    2397                 :           0 :       attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
    2398                 :           0 :       attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
    2399                 :           0 :       attr_mtime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
    2400                 :             :     }
    2401                 :             : 
    2402                 :           0 :   value = g_file_info_create_value (info, attr_mtime);
    2403                 :           0 :   if (value)
    2404                 :           0 :     _g_file_attribute_value_set_uint64 (value, mtime->tv_sec);
    2405                 :           0 :   value = g_file_info_create_value (info, attr_mtime_usec);
    2406                 :           0 :   if (value)
    2407                 :           0 :     _g_file_attribute_value_set_uint32 (value, mtime->tv_usec);
    2408                 :             : 
    2409                 :             :   /* nsecs can’t be known from a #GTimeVal, so remove them */
    2410                 :           0 :   g_file_info_remove_value (info, attr_mtime_nsec);
    2411                 :             : }
    2412                 :             : G_GNUC_END_IGNORE_DEPRECATIONS
    2413                 :             : 
    2414                 :             : /**
    2415                 :             :  * g_file_info_set_modification_date_time:
    2416                 :             :  * @info: a #GFileInfo.
    2417                 :             :  * @mtime: (not nullable): a #GDateTime.
    2418                 :             :  *
    2419                 :             :  * Sets the %G_FILE_ATTRIBUTE_TIME_MODIFIED and
    2420                 :             :  * %G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC attributes in the file info to the
    2421                 :             :  * given date/time value.
    2422                 :             :  *
    2423                 :             :  * %G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC will be cleared.
    2424                 :             :  *
    2425                 :             :  * Since: 2.62
    2426                 :             :  */
    2427                 :             : void
    2428                 :           2 : g_file_info_set_modification_date_time (GFileInfo *info,
    2429                 :             :                                         GDateTime *mtime)
    2430                 :             : {
    2431                 :             :   static guint32 attr_mtime = 0, attr_mtime_usec = 0, attr_mtime_nsec = 0;
    2432                 :             :   GFileAttributeValue *value;
    2433                 :             : 
    2434                 :           2 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2435                 :           2 :   g_return_if_fail (mtime != NULL);
    2436                 :             : 
    2437                 :           2 :   if (attr_mtime == 0)
    2438                 :             :     {
    2439                 :           1 :       attr_mtime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED);
    2440                 :           1 :       attr_mtime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
    2441                 :           1 :       attr_mtime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_MODIFIED_NSEC);
    2442                 :             :     }
    2443                 :             : 
    2444                 :           2 :   value = g_file_info_create_value (info, attr_mtime);
    2445                 :           2 :   if (value)
    2446                 :           2 :     _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (mtime));
    2447                 :           2 :   value = g_file_info_create_value (info, attr_mtime_usec);
    2448                 :           2 :   if (value)
    2449                 :           2 :     _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (mtime));
    2450                 :             : 
    2451                 :             :   /* nsecs can’t be known from a #GDateTime, so remove them */
    2452                 :           2 :   g_file_info_remove_value (info, attr_mtime_nsec);
    2453                 :             : }
    2454                 :             : 
    2455                 :             : /**
    2456                 :             :  * g_file_info_set_access_date_time:
    2457                 :             :  * @info: a #GFileInfo.
    2458                 :             :  * @atime: (not nullable): a #GDateTime.
    2459                 :             :  *
    2460                 :             :  * Sets the %G_FILE_ATTRIBUTE_TIME_ACCESS and
    2461                 :             :  * %G_FILE_ATTRIBUTE_TIME_ACCESS_USEC attributes in the file info to the
    2462                 :             :  * given date/time value.
    2463                 :             :  *
    2464                 :             :  * %G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC will be cleared.
    2465                 :             :  *
    2466                 :             :  * Since: 2.70
    2467                 :             :  */
    2468                 :             : void
    2469                 :           2 : g_file_info_set_access_date_time (GFileInfo *info,
    2470                 :             :                                   GDateTime *atime)
    2471                 :             : {
    2472                 :             :   static guint32 attr_atime = 0, attr_atime_usec = 0, attr_atime_nsec = 0;
    2473                 :             :   GFileAttributeValue *value;
    2474                 :             : 
    2475                 :           2 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2476                 :           2 :   g_return_if_fail (atime != NULL);
    2477                 :             : 
    2478                 :           2 :   if (attr_atime == 0)
    2479                 :             :     {
    2480                 :           1 :       attr_atime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS);
    2481                 :           1 :       attr_atime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
    2482                 :           1 :       attr_atime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_ACCESS_NSEC);
    2483                 :             :     }
    2484                 :             : 
    2485                 :           2 :   value = g_file_info_create_value (info, attr_atime);
    2486                 :           2 :   if (value)
    2487                 :           2 :     _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (atime));
    2488                 :           2 :   value = g_file_info_create_value (info, attr_atime_usec);
    2489                 :           2 :   if (value)
    2490                 :           2 :     _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (atime));
    2491                 :             : 
    2492                 :             :   /* nsecs can’t be known from a #GDateTime, so remove them */
    2493                 :           2 :   g_file_info_remove_value (info, attr_atime_nsec);
    2494                 :             : }
    2495                 :             : 
    2496                 :             : /**
    2497                 :             :  * g_file_info_set_creation_date_time:
    2498                 :             :  * @info: a #GFileInfo.
    2499                 :             :  * @creation_time: (not nullable): a #GDateTime.
    2500                 :             :  *
    2501                 :             :  * Sets the %G_FILE_ATTRIBUTE_TIME_CREATED and
    2502                 :             :  * %G_FILE_ATTRIBUTE_TIME_CREATED_USEC attributes in the file info to the
    2503                 :             :  * given date/time value.
    2504                 :             :  *
    2505                 :             :  * %G_FILE_ATTRIBUTE_TIME_CREATED_NSEC will be cleared.
    2506                 :             :  *
    2507                 :             :  * Since: 2.70
    2508                 :             :  */
    2509                 :             : void
    2510                 :           2 : g_file_info_set_creation_date_time (GFileInfo *info,
    2511                 :             :                                     GDateTime *creation_time)
    2512                 :             : {
    2513                 :             :   static guint32 attr_ctime = 0, attr_ctime_usec = 0, attr_ctime_nsec = 0;
    2514                 :             :   GFileAttributeValue *value;
    2515                 :             : 
    2516                 :           2 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2517                 :           2 :   g_return_if_fail (creation_time != NULL);
    2518                 :             : 
    2519                 :           2 :   if (attr_ctime == 0)
    2520                 :             :     {
    2521                 :           1 :       attr_ctime = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED);
    2522                 :           1 :       attr_ctime_usec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_USEC);
    2523                 :           1 :       attr_ctime_nsec = lookup_attribute (G_FILE_ATTRIBUTE_TIME_CREATED_NSEC);
    2524                 :             :     }
    2525                 :             : 
    2526                 :           2 :   value = g_file_info_create_value (info, attr_ctime);
    2527                 :           2 :   if (value)
    2528                 :           2 :     _g_file_attribute_value_set_uint64 (value, g_date_time_to_unix (creation_time));
    2529                 :           2 :   value = g_file_info_create_value (info, attr_ctime_usec);
    2530                 :           2 :   if (value)
    2531                 :           2 :     _g_file_attribute_value_set_uint32 (value, g_date_time_get_microsecond (creation_time));
    2532                 :             : 
    2533                 :             :   /* nsecs can’t be known from a #GDateTime, so remove them */
    2534                 :           2 :   g_file_info_remove_value (info, attr_ctime_nsec);
    2535                 :             : }
    2536                 :             : 
    2537                 :             : /**
    2538                 :             :  * g_file_info_set_symlink_target:
    2539                 :             :  * @info: a #GFileInfo.
    2540                 :             :  * @symlink_target: (type filename): a static string containing a path to a symlink target.
    2541                 :             :  *
    2542                 :             :  * Sets the %G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET attribute in the file info
    2543                 :             :  * to the given symlink target.
    2544                 :             :  **/
    2545                 :             : void
    2546                 :          32 : g_file_info_set_symlink_target (GFileInfo  *info,
    2547                 :             :                                 const char *symlink_target)
    2548                 :             : {
    2549                 :             :   static guint32 attr = 0;
    2550                 :             :   GFileAttributeValue *value;
    2551                 :             : 
    2552                 :          32 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2553                 :          32 :   g_return_if_fail (symlink_target != NULL);
    2554                 :             : 
    2555                 :          32 :   if (attr == 0)
    2556                 :           2 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET);
    2557                 :             : 
    2558                 :          32 :   value = g_file_info_create_value (info, attr);
    2559                 :          32 :   if (value)
    2560                 :          32 :     _g_file_attribute_value_set_byte_string (value, symlink_target);
    2561                 :             : }
    2562                 :             : 
    2563                 :             : /**
    2564                 :             :  * g_file_info_set_sort_order:
    2565                 :             :  * @info: a #GFileInfo.
    2566                 :             :  * @sort_order: a sort order integer.
    2567                 :             :  *
    2568                 :             :  * Sets the sort order attribute in the file info structure. See
    2569                 :             :  * %G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER.
    2570                 :             :  **/
    2571                 :             : void
    2572                 :           0 : g_file_info_set_sort_order (GFileInfo *info,
    2573                 :             :                             gint32     sort_order)
    2574                 :             : {
    2575                 :             :   static guint32 attr = 0;
    2576                 :             :   GFileAttributeValue *value;
    2577                 :             : 
    2578                 :           0 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2579                 :             : 
    2580                 :           0 :   if (attr == 0)
    2581                 :           0 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SORT_ORDER);
    2582                 :             : 
    2583                 :           0 :   value = g_file_info_create_value (info, attr);
    2584                 :           0 :   if (value)
    2585                 :           0 :     _g_file_attribute_value_set_int32 (value, sort_order);
    2586                 :             : }
    2587                 :             : 
    2588                 :             : 
    2589                 :             : typedef struct {
    2590                 :             :   guint32 id;
    2591                 :             :   guint32 mask;
    2592                 :             : } SubMatcher;
    2593                 :             : 
    2594                 :             : struct _GFileAttributeMatcher {
    2595                 :             :   gboolean all;
    2596                 :             :   gint ref;
    2597                 :             : 
    2598                 :             :   GArray *sub_matchers;
    2599                 :             : 
    2600                 :             :   /* Iterator */
    2601                 :             :   guint32 iterator_ns;
    2602                 :             :   gint iterator_pos;
    2603                 :             : };
    2604                 :             : 
    2605                 :           4 : G_DEFINE_BOXED_TYPE (GFileAttributeMatcher, g_file_attribute_matcher,
    2606                 :             :                      g_file_attribute_matcher_ref,
    2607                 :             :                      g_file_attribute_matcher_unref)
    2608                 :             : 
    2609                 :             : static gint
    2610                 :        3350 : compare_sub_matchers (gconstpointer a,
    2611                 :             :                       gconstpointer b)
    2612                 :             : {
    2613                 :        3350 :   const SubMatcher *suba = a;
    2614                 :        3350 :   const SubMatcher *subb = b;
    2615                 :             :   int diff;
    2616                 :             : 
    2617                 :        3350 :   diff = suba->id - subb->id;
    2618                 :             : 
    2619                 :        3350 :   if (diff)
    2620                 :        3347 :     return diff;
    2621                 :             : 
    2622                 :           3 :   return suba->mask - subb->mask;
    2623                 :             : }
    2624                 :             : 
    2625                 :             : static gboolean
    2626                 :        2464 : sub_matcher_matches (SubMatcher *matcher,
    2627                 :             :                      SubMatcher *submatcher)
    2628                 :             : {
    2629                 :        2464 :   if ((matcher->mask & submatcher->mask) != matcher->mask)
    2630                 :         128 :     return FALSE;
    2631                 :             :   
    2632                 :        2336 :   return matcher->id == (submatcher->id & matcher->mask);
    2633                 :             : }
    2634                 :             : 
    2635                 :             : /* Call this function after modifying a matcher.
    2636                 :             :  * It will ensure all the invariants other functions rely on.
    2637                 :             :  */
    2638                 :             : static GFileAttributeMatcher *
    2639                 :        1499 : matcher_optimize (GFileAttributeMatcher *matcher)
    2640                 :             : {
    2641                 :             :   SubMatcher *submatcher, *compare;
    2642                 :             :   guint i, j;
    2643                 :             : 
    2644                 :             :   /* remove sub_matchers if we match everything anyway */
    2645                 :        1499 :   if (matcher->all)
    2646                 :             :     {
    2647                 :          64 :       if (matcher->sub_matchers)
    2648                 :             :         {
    2649                 :          64 :           g_array_free (matcher->sub_matchers, TRUE);
    2650                 :          64 :           matcher->sub_matchers = NULL;
    2651                 :             :         }
    2652                 :          64 :       return matcher;
    2653                 :             :     }
    2654                 :             : 
    2655                 :        1435 :   if (matcher->sub_matchers->len == 0)
    2656                 :             :     {
    2657                 :         210 :       g_file_attribute_matcher_unref (matcher);
    2658                 :         210 :       return NULL;
    2659                 :             :     }
    2660                 :             : 
    2661                 :             :   /* sort sub_matchers by id (and then mask), so we can bsearch
    2662                 :             :    * and compare matchers in O(N) instead of O(N²) */
    2663                 :        1225 :   g_array_sort (matcher->sub_matchers, compare_sub_matchers);
    2664                 :             : 
    2665                 :             :   /* remove duplicates and specific matches when we match the whole namespace */
    2666                 :        1225 :   j = 0;
    2667                 :        1225 :   compare = &g_array_index (matcher->sub_matchers, SubMatcher, j);
    2668                 :             : 
    2669                 :        3215 :   for (i = 1; i < matcher->sub_matchers->len; i++)
    2670                 :             :     {
    2671                 :        1990 :       submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
    2672                 :        1990 :       if (sub_matcher_matches (compare, submatcher))
    2673                 :           7 :         continue;
    2674                 :             : 
    2675                 :        1983 :       j++;
    2676                 :        1983 :       compare++;
    2677                 :             : 
    2678                 :        1983 :       if (j < i)
    2679                 :           1 :         *compare = *submatcher;
    2680                 :             :     }
    2681                 :             : 
    2682                 :        1225 :   g_array_set_size (matcher->sub_matchers, j + 1);
    2683                 :             : 
    2684                 :        1225 :   return matcher;
    2685                 :             : }
    2686                 :             : 
    2687                 :             : /**
    2688                 :             :  * g_file_attribute_matcher_new:
    2689                 :             :  * @attributes: an attribute string to match.
    2690                 :             :  *
    2691                 :             :  * Creates a new file attribute matcher, which matches attributes
    2692                 :             :  * against a given string. #GFileAttributeMatchers are reference
    2693                 :             :  * counted structures, and are created with a reference count of 1. If
    2694                 :             :  * the number of references falls to 0, the #GFileAttributeMatcher is
    2695                 :             :  * automatically destroyed.
    2696                 :             :  *
    2697                 :             :  * The @attributes string should be formatted with specific keys separated
    2698                 :             :  * from namespaces with a double colon. Several "namespace::key" strings may be
    2699                 :             :  * concatenated with a single comma (e.g. "standard::type,standard::is-hidden").
    2700                 :             :  * The wildcard "*" may be used to match all keys and namespaces, or
    2701                 :             :  * "namespace::*" will match all keys in a given namespace.
    2702                 :             :  *
    2703                 :             :  * ## Examples of file attribute matcher strings and results
    2704                 :             :  *
    2705                 :             :  * - `"*"`: matches all attributes.
    2706                 :             :  * - `"standard::is-hidden"`: matches only the key is-hidden in the
    2707                 :             :  *   standard namespace.
    2708                 :             :  * - `"standard::type,unix::*"`: matches the type key in the standard
    2709                 :             :  *   namespace and all keys in the unix namespace.
    2710                 :             :  *
    2711                 :             :  * Returns: a #GFileAttributeMatcher
    2712                 :             :  */
    2713                 :             : GFileAttributeMatcher *
    2714                 :        1264 : g_file_attribute_matcher_new (const char *attributes)
    2715                 :             : {
    2716                 :             :   char **split;
    2717                 :             :   char *colon;
    2718                 :             :   int i;
    2719                 :             :   GFileAttributeMatcher *matcher;
    2720                 :             : 
    2721                 :        1264 :   if (attributes == NULL || *attributes == '\0')
    2722                 :           2 :     return NULL;
    2723                 :             : 
    2724                 :        1262 :   matcher = g_malloc0 (sizeof (GFileAttributeMatcher));
    2725                 :        1262 :   matcher->ref = 1;
    2726                 :        1262 :   matcher->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
    2727                 :             : 
    2728                 :        1262 :   split = g_strsplit (attributes, ",", -1);
    2729                 :             : 
    2730                 :        4515 :   for (i = 0; split[i] != NULL; i++)
    2731                 :             :     {
    2732                 :        3253 :       if (strcmp (split[i], "*") == 0)
    2733                 :          65 :         matcher->all = TRUE;
    2734                 :             :       else
    2735                 :             :         {
    2736                 :             :           SubMatcher s;
    2737                 :             : 
    2738                 :        3188 :           colon = strstr (split[i], "::");
    2739                 :        3188 :           if (colon != NULL &&
    2740                 :        3161 :               !(colon[2] == 0 ||
    2741                 :        3161 :                 (colon[2] == '*' &&
    2742                 :         176 :                  colon[3] == 0)))
    2743                 :             :             {
    2744                 :        2985 :               s.id = lookup_attribute (split[i]);
    2745                 :        2985 :               s.mask = 0xffffffff;
    2746                 :             :             }
    2747                 :             :           else
    2748                 :             :             {
    2749                 :         203 :               if (colon)
    2750                 :         176 :                 *colon = 0;
    2751                 :             : 
    2752                 :         203 :               s.id = lookup_namespace (split[i]) << NS_POS;
    2753                 :         203 :               s.mask = NS_MASK << NS_POS;
    2754                 :             :             }
    2755                 :             : 
    2756                 :        3188 :           g_array_append_val (matcher->sub_matchers, s);
    2757                 :             :         }
    2758                 :             :     }
    2759                 :             : 
    2760                 :        1262 :   g_strfreev (split);
    2761                 :             : 
    2762                 :        1262 :   matcher = matcher_optimize (matcher);
    2763                 :             : 
    2764                 :        1262 :   return matcher;
    2765                 :             : }
    2766                 :             : 
    2767                 :             : /**
    2768                 :             :  * g_file_attribute_matcher_subtract:
    2769                 :             :  * @matcher: (nullable): Matcher to subtract from 
    2770                 :             :  * @subtract: (nullable): The matcher to subtract
    2771                 :             :  *
    2772                 :             :  * Subtracts all attributes of @subtract from @matcher and returns
    2773                 :             :  * a matcher that supports those attributes.
    2774                 :             :  *
    2775                 :             :  * Note that currently it is not possible to remove a single
    2776                 :             :  * attribute when the @matcher matches the whole namespace - or remove
    2777                 :             :  * a namespace or attribute when the matcher matches everything. This
    2778                 :             :  * is a limitation of the current implementation, but may be fixed
    2779                 :             :  * in the future.
    2780                 :             :  *
    2781                 :             :  * Returns: (nullable): A file attribute matcher matching all attributes of
    2782                 :             :  *     @matcher that are not matched by @subtract
    2783                 :             :  **/
    2784                 :             : GFileAttributeMatcher *
    2785                 :         272 : g_file_attribute_matcher_subtract (GFileAttributeMatcher *matcher,
    2786                 :             :                                    GFileAttributeMatcher *subtract)
    2787                 :             : {
    2788                 :             :   GFileAttributeMatcher *result;
    2789                 :             :   guint mi, si;
    2790                 :             :   SubMatcher *msub, *ssub;
    2791                 :             : 
    2792                 :         272 :   if (matcher == NULL)
    2793                 :           2 :     return NULL;
    2794                 :         270 :   if (subtract == NULL)
    2795                 :           0 :     return g_file_attribute_matcher_ref (matcher);
    2796                 :         270 :   if (subtract->all)
    2797                 :          10 :     return NULL;
    2798                 :         260 :   if (matcher->all)
    2799                 :          23 :     return g_file_attribute_matcher_ref (matcher);
    2800                 :             : 
    2801                 :         237 :   result = g_malloc0 (sizeof (GFileAttributeMatcher));
    2802                 :         237 :   result->ref = 1;
    2803                 :         237 :   result->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
    2804                 :             : 
    2805                 :         237 :   si = 0;
    2806                 :         237 :   g_assert (subtract->sub_matchers->len > 0);
    2807                 :         237 :   ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si);
    2808                 :             : 
    2809                 :         491 :   for (mi = 0; mi < matcher->sub_matchers->len; mi++)
    2810                 :             :     {
    2811                 :         270 :       msub = &g_array_index (matcher->sub_matchers, SubMatcher, mi);
    2812                 :             : 
    2813                 :         474 : retry:
    2814                 :         474 :       if (sub_matcher_matches (ssub, msub))
    2815                 :         241 :         continue;
    2816                 :             : 
    2817                 :         233 :       si++;
    2818                 :         233 :       if (si >= subtract->sub_matchers->len)
    2819                 :          16 :         break;
    2820                 :             : 
    2821                 :         217 :       ssub = &g_array_index (subtract->sub_matchers, SubMatcher, si);
    2822                 :         217 :       if (ssub->id <= msub->id)
    2823                 :         204 :         goto retry;
    2824                 :             : 
    2825                 :          13 :       g_array_append_val (result->sub_matchers, *msub);
    2826                 :             :     }
    2827                 :             : 
    2828                 :         237 :   if (mi < matcher->sub_matchers->len)
    2829                 :          16 :     g_array_append_vals (result->sub_matchers,
    2830                 :          16 :                          &g_array_index (matcher->sub_matchers, SubMatcher, mi),
    2831                 :          16 :                          matcher->sub_matchers->len - mi);
    2832                 :             : 
    2833                 :         237 :   result = matcher_optimize (result);
    2834                 :             : 
    2835                 :         237 :   return result;
    2836                 :             : }
    2837                 :             : 
    2838                 :             : /**
    2839                 :             :  * g_file_attribute_matcher_ref:
    2840                 :             :  * @matcher: a #GFileAttributeMatcher.
    2841                 :             :  *
    2842                 :             :  * References a file attribute matcher.
    2843                 :             :  *
    2844                 :             :  * Returns: a #GFileAttributeMatcher.
    2845                 :             :  **/
    2846                 :             : GFileAttributeMatcher *
    2847                 :        1075 : g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher)
    2848                 :             : {
    2849                 :        1075 :   if (matcher)
    2850                 :             :     {
    2851                 :         774 :       g_return_val_if_fail (matcher->ref > 0, NULL);
    2852                 :         774 :       g_atomic_int_inc (&matcher->ref);
    2853                 :             :     }
    2854                 :        1075 :   return matcher;
    2855                 :             : }
    2856                 :             : 
    2857                 :             : /**
    2858                 :             :  * g_file_attribute_matcher_unref:
    2859                 :             :  * @matcher: a #GFileAttributeMatcher.
    2860                 :             :  *
    2861                 :             :  * Unreferences @matcher. If the reference count falls below 1,
    2862                 :             :  * the @matcher is automatically freed.
    2863                 :             :  *
    2864                 :             :  **/
    2865                 :             : void
    2866                 :        2798 : g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher)
    2867                 :             : {
    2868                 :        2798 :   if (matcher)
    2869                 :             :     {
    2870                 :        2273 :       g_return_if_fail (matcher->ref > 0);
    2871                 :             : 
    2872                 :        2273 :       if (g_atomic_int_dec_and_test (&matcher->ref))
    2873                 :             :         {
    2874                 :        1499 :           if (matcher->sub_matchers)
    2875                 :        1435 :             g_array_free (matcher->sub_matchers, TRUE);
    2876                 :             : 
    2877                 :        1499 :           g_free (matcher);
    2878                 :             :         }
    2879                 :             :     }
    2880                 :             : }
    2881                 :             : 
    2882                 :             : /**
    2883                 :             :  * g_file_attribute_matcher_matches_only:
    2884                 :             :  * @matcher: a #GFileAttributeMatcher.
    2885                 :             :  * @attribute: a file attribute key.
    2886                 :             :  *
    2887                 :             :  * Checks if an attribute matcher only matches a given attribute. Always
    2888                 :             :  * returns %FALSE if "*" was used when creating the matcher.
    2889                 :             :  *
    2890                 :             :  * Returns: %TRUE if the matcher only matches @attribute. %FALSE otherwise.
    2891                 :             :  **/
    2892                 :             : gboolean
    2893                 :           1 : g_file_attribute_matcher_matches_only (GFileAttributeMatcher *matcher,
    2894                 :             :                                        const char            *attribute)
    2895                 :             : {
    2896                 :             :   SubMatcher *sub_matcher;
    2897                 :             :   guint32 id;
    2898                 :             : 
    2899                 :           1 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
    2900                 :             : 
    2901                 :           1 :   if (matcher == NULL ||
    2902                 :           1 :       matcher->all)
    2903                 :           0 :     return FALSE;
    2904                 :             : 
    2905                 :           1 :   if (matcher->sub_matchers->len != 1)
    2906                 :           1 :     return FALSE;
    2907                 :             :   
    2908                 :           0 :   id = lookup_attribute (attribute);
    2909                 :             :   
    2910                 :           0 :   sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, 0);
    2911                 :             :   
    2912                 :           0 :   return sub_matcher->id == id &&
    2913                 :           0 :          sub_matcher->mask == 0xffffffff;
    2914                 :             : }
    2915                 :             : 
    2916                 :             : static gboolean
    2917                 :       42008 : matcher_matches_id (GFileAttributeMatcher *matcher,
    2918                 :             :                     guint32                id)
    2919                 :             : {
    2920                 :             :   SubMatcher *sub_matchers;
    2921                 :             :   guint i;
    2922                 :             : 
    2923                 :       42008 :   if (matcher->sub_matchers)
    2924                 :             :     {
    2925                 :       42008 :       sub_matchers = (SubMatcher *)matcher->sub_matchers->data;
    2926                 :      131020 :       for (i = 0; i < matcher->sub_matchers->len; i++)
    2927                 :             :         {
    2928                 :       90974 :           if (sub_matchers[i].id == (id & sub_matchers[i].mask))
    2929                 :        1962 :             return TRUE;
    2930                 :             :         }
    2931                 :             :     }
    2932                 :             : 
    2933                 :       40046 :   return FALSE;
    2934                 :             : }
    2935                 :             : 
    2936                 :             : gboolean
    2937                 :       49187 : _g_file_attribute_matcher_matches_id (GFileAttributeMatcher *matcher,
    2938                 :             :                                       guint32                id)
    2939                 :             : {
    2940                 :             :   /* We return a NULL matcher for an empty match string, so handle this */
    2941                 :       49187 :   if (matcher == NULL)
    2942                 :        1224 :     return FALSE;
    2943                 :             : 
    2944                 :       47963 :   if (matcher->all)
    2945                 :        5957 :     return TRUE;
    2946                 :             : 
    2947                 :       42006 :   return matcher_matches_id (matcher, id);
    2948                 :             : }
    2949                 :             : 
    2950                 :             : /**
    2951                 :             :  * g_file_attribute_matcher_matches:
    2952                 :             :  * @matcher: a #GFileAttributeMatcher.
    2953                 :             :  * @attribute: a file attribute key.
    2954                 :             :  *
    2955                 :             :  * Checks if an attribute will be matched by an attribute matcher. If
    2956                 :             :  * the matcher was created with the "*" matching string, this function
    2957                 :             :  * will always return %TRUE.
    2958                 :             :  *
    2959                 :             :  * Returns: %TRUE if @attribute matches @matcher. %FALSE otherwise.
    2960                 :             :  **/
    2961                 :             : gboolean
    2962                 :           4 : g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
    2963                 :             :                                   const char            *attribute)
    2964                 :             : {
    2965                 :           4 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
    2966                 :             : 
    2967                 :             :   /* We return a NULL matcher for an empty match string, so handle this */
    2968                 :           4 :   if (matcher == NULL)
    2969                 :           0 :     return FALSE;
    2970                 :             : 
    2971                 :           4 :   if (matcher->all)
    2972                 :           2 :     return TRUE;
    2973                 :             : 
    2974                 :           2 :   return matcher_matches_id (matcher, lookup_attribute (attribute));
    2975                 :             : }
    2976                 :             : 
    2977                 :             : /* return TRUE -> all */
    2978                 :             : /**
    2979                 :             :  * g_file_attribute_matcher_enumerate_namespace:
    2980                 :             :  * @matcher: a #GFileAttributeMatcher.
    2981                 :             :  * @ns: a string containing a file attribute namespace.
    2982                 :             :  *
    2983                 :             :  * Checks if the matcher will match all of the keys in a given namespace.
    2984                 :             :  * This will always return %TRUE if a wildcard character is in use (e.g. if
    2985                 :             :  * matcher was created with "standard::*" and @ns is "standard", or if matcher was created
    2986                 :             :  * using "*" and namespace is anything.)
    2987                 :             :  *
    2988                 :             :  * TODO: this is awkwardly worded.
    2989                 :             :  *
    2990                 :             :  * Returns: %TRUE if the matcher matches all of the entries
    2991                 :             :  * in the given @ns, %FALSE otherwise.
    2992                 :             :  **/
    2993                 :             : gboolean
    2994                 :        1420 : g_file_attribute_matcher_enumerate_namespace (GFileAttributeMatcher *matcher,
    2995                 :             :                                               const char            *ns)
    2996                 :             : {
    2997                 :             :   SubMatcher *sub_matchers;
    2998                 :             :   guint ns_id;
    2999                 :             :   guint i;
    3000                 :             : 
    3001                 :        1420 :   g_return_val_if_fail (ns != NULL && *ns != '\0', FALSE);
    3002                 :             : 
    3003                 :             :   /* We return a NULL matcher for an empty match string, so handle this */
    3004                 :        1420 :   if (matcher == NULL)
    3005                 :           0 :     return FALSE;
    3006                 :             : 
    3007                 :        1420 :   if (matcher->all)
    3008                 :         152 :     return TRUE;
    3009                 :             : 
    3010                 :        1268 :   ns_id = lookup_namespace (ns) << NS_POS;
    3011                 :             : 
    3012                 :        1268 :   if (matcher->sub_matchers)
    3013                 :             :     {
    3014                 :        1268 :       sub_matchers = (SubMatcher *)matcher->sub_matchers->data;
    3015                 :        4472 :       for (i = 0; i < matcher->sub_matchers->len; i++)
    3016                 :             :         {
    3017                 :        3276 :           if (sub_matchers[i].id == ns_id)
    3018                 :          72 :             return TRUE;
    3019                 :             :         }
    3020                 :             :     }
    3021                 :             : 
    3022                 :        1196 :   matcher->iterator_ns = ns_id;
    3023                 :        1196 :   matcher->iterator_pos = 0;
    3024                 :             : 
    3025                 :        1196 :   return FALSE;
    3026                 :             : }
    3027                 :             : 
    3028                 :             : /**
    3029                 :             :  * g_file_attribute_matcher_enumerate_next:
    3030                 :             :  * @matcher: a #GFileAttributeMatcher.
    3031                 :             :  *
    3032                 :             :  * Gets the next matched attribute from a #GFileAttributeMatcher.
    3033                 :             :  *
    3034                 :             :  * Returns: (nullable): a string containing the next attribute or, %NULL if
    3035                 :             :  * no more attribute exist.
    3036                 :             :  **/
    3037                 :             : const char *
    3038                 :        1197 : g_file_attribute_matcher_enumerate_next (GFileAttributeMatcher *matcher)
    3039                 :             : {
    3040                 :             :   guint i;
    3041                 :             :   SubMatcher *sub_matcher;
    3042                 :             : 
    3043                 :             :   /* We return a NULL matcher for an empty match string, so handle this */
    3044                 :        1197 :   if (matcher == NULL)
    3045                 :           0 :     return NULL;
    3046                 :             : 
    3047                 :             :   while (1)
    3048                 :             :     {
    3049                 :        4008 :       i = matcher->iterator_pos++;
    3050                 :             : 
    3051                 :        4008 :       if (matcher->sub_matchers == NULL)
    3052                 :           0 :         return NULL;
    3053                 :             : 
    3054                 :        4008 :       if (i < matcher->sub_matchers->len)
    3055                 :        2812 :         sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
    3056                 :             :       else
    3057                 :        1196 :         return NULL;
    3058                 :             : 
    3059                 :        2812 :       if (sub_matcher->mask == 0xffffffff &&
    3060                 :        2618 :           (sub_matcher->id & (NS_MASK << NS_POS)) == matcher->iterator_ns)
    3061                 :           1 :         return get_attribute_for_id (sub_matcher->id);
    3062                 :             :     }
    3063                 :             : }
    3064                 :             : 
    3065                 :             : /**
    3066                 :             :  * g_file_attribute_matcher_to_string:
    3067                 :             :  * @matcher: (nullable): a #GFileAttributeMatcher.
    3068                 :             :  *
    3069                 :             :  * Prints what the matcher is matching against. The format will be 
    3070                 :             :  * equal to the format passed to g_file_attribute_matcher_new().
    3071                 :             :  * The output however, might not be identical, as the matcher may
    3072                 :             :  * decide to use a different order or omit needless parts.
    3073                 :             :  *
    3074                 :             :  * Returns: a string describing the attributes the matcher matches
    3075                 :             :  *   against or %NULL if @matcher was %NULL.
    3076                 :             :  *
    3077                 :             :  * Since: 2.32
    3078                 :             :  **/
    3079                 :             : char *
    3080                 :          69 : g_file_attribute_matcher_to_string (GFileAttributeMatcher *matcher)
    3081                 :             : {
    3082                 :             :   GString *string;
    3083                 :             :   guint i;
    3084                 :             : 
    3085                 :          69 :   if (matcher == NULL)
    3086                 :          19 :     return NULL;
    3087                 :             : 
    3088                 :          50 :   if (matcher->all)
    3089                 :          11 :     return g_strdup ("*");
    3090                 :             : 
    3091                 :          39 :   string = g_string_new ("");
    3092                 :          91 :   for (i = 0; i < matcher->sub_matchers->len; i++)
    3093                 :             :     {
    3094                 :          52 :       SubMatcher *submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
    3095                 :             : 
    3096                 :          52 :       if (i > 0)
    3097                 :             :         g_string_append_c (string, ',');
    3098                 :             : 
    3099                 :          52 :       g_string_append (string, get_attribute_for_id (submatcher->id));
    3100                 :             :     }
    3101                 :             : 
    3102                 :          39 :   return g_string_free (string, FALSE);
    3103                 :             : }
        

Generated by: LCOV version 2.0-1