LCOV - code coverage report
Current view: top level - glib/gio - gfileinfo.c (source / functions) Hit Total Coverage
Test: unnamed Lines: 760 936 81.2 %
Date: 2024-04-16 05:15:53 Functions: 92 115 80.0 %
Branches: 356 594 59.9 %

           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 [file-attributes.html](file attributes) for more information on how GIO
      33                 :            :  * 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   [ +  +  +  -  :      12448 : 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                 :       2699 : _lookup_namespace (const char *namespace)
     134                 :            : {
     135                 :            :   NSInfo *ns_info;
     136                 :            : 
     137                 :       2699 :   ns_info = g_hash_table_lookup (ns_hash, namespace);
     138         [ +  + ]:       2699 :   if (ns_info == NULL)
     139                 :            :     {
     140                 :        182 :       ns_info = g_new0 (NSInfo, 1);
     141                 :        182 :       ns_info->id = ++namespace_id_counter;
     142                 :        182 :       g_hash_table_insert (ns_hash, g_strdup (namespace), ns_info);
     143                 :        182 :       global_attributes = g_realloc (global_attributes, (ns_info->id + 1) * sizeof (char **));
     144                 :        182 :       global_attributes[ns_info->id] = g_new (char *, 1);
     145                 :        182 :       global_attributes[ns_info->id][0] = g_strconcat (namespace, "::*", NULL);
     146                 :            :     }
     147                 :       2699 :   return ns_info;
     148                 :            : }
     149                 :            : 
     150                 :            : static guint32
     151                 :       5937 : _lookup_attribute (const char *attribute)
     152                 :            : {
     153                 :            :   guint32 attr_id, id;
     154                 :            :   char *ns;
     155                 :            :   const char *colon;
     156                 :            :   NSInfo *ns_info;
     157                 :            : 
     158                 :       5937 :   attr_id = GPOINTER_TO_UINT (g_hash_table_lookup (attribute_hash, attribute));
     159                 :            : 
     160         [ +  + ]:       5937 :   if (attr_id != 0)
     161                 :       4869 :     return attr_id;
     162                 :            : 
     163                 :       1068 :   colon = strstr (attribute, "::");
     164         [ +  - ]:       1068 :   if (colon)
     165                 :       1068 :     ns = g_strndup (attribute, colon - attribute);
     166                 :            :   else
     167                 :          0 :     ns = g_strdup ("");
     168                 :            : 
     169                 :       1068 :   ns_info = _lookup_namespace (ns);
     170                 :       1068 :   g_free (ns);
     171                 :            : 
     172                 :       1068 :   id = ++ns_info->attribute_id_counter;
     173                 :       1068 :   global_attributes[ns_info->id] = g_realloc (global_attributes[ns_info->id], (id + 1) * sizeof (char *));
     174                 :       1068 :   global_attributes[ns_info->id][id] = g_strdup (attribute);
     175                 :            : 
     176                 :       1068 :   attr_id = MAKE_ATTR_ID (ns_info->id, id);
     177                 :            : 
     178                 :       1068 :   g_hash_table_insert (attribute_hash, global_attributes[ns_info->id][id], GUINT_TO_POINTER (attr_id));
     179                 :            : 
     180                 :       1068 :   return attr_id;
     181                 :            : }
     182                 :            : 
     183                 :            : static void
     184                 :       6512 : ensure_attribute_hash (void)
     185                 :            : {
     186         [ +  + ]:       6512 :   if (attribute_hash != NULL)
     187                 :       6501 :     return;
     188                 :            : 
     189                 :         11 :   ns_hash = g_hash_table_new (g_str_hash, g_str_equal);
     190                 :         11 :   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         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_TYPE);
     200         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_IS_HIDDEN);
     201         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_IS_BACKUP);
     202         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_IS_SYMLINK);
     203         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_IS_VIRTUAL);
     204         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_NAME);
     205         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_DISPLAY_NAME);
     206         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_EDIT_NAME);
     207         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_COPY_NAME);
     208         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_DESCRIPTION);
     209         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_ICON);
     210         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_CONTENT_TYPE);
     211         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_FAST_CONTENT_TYPE);
     212         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_SIZE);
     213         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_ALLOCATED_SIZE);
     214         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_SYMLINK_TARGET);
     215         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_TARGET_URI);
     216         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_SORT_ORDER);
     217         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_SYMBOLIC_ICON);
     218         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (STANDARD_IS_VOLATILE);
     219         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ETAG_VALUE);
     220         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ID_FILE);
     221         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ID_FILESYSTEM);
     222         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ACCESS_CAN_READ);
     223         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ACCESS_CAN_WRITE);
     224         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ACCESS_CAN_EXECUTE);
     225         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ACCESS_CAN_DELETE);
     226         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ACCESS_CAN_TRASH);
     227         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (ACCESS_CAN_RENAME);
     228         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_MOUNT);
     229         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_UNMOUNT);
     230         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_EJECT);
     231         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE);
     232         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE_FILE);
     233         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_HAL_UDI);
     234         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START);
     235         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START_DEGRADED);
     236         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_STOP);
     237         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_START_STOP_TYPE);
     238         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_CAN_POLL);
     239         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC);
     240         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_MODIFIED);
     241         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_MODIFIED_USEC);
     242         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_ACCESS);
     243         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_ACCESS_USEC);
     244         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_CHANGED);
     245         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_CHANGED_USEC);
     246         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_CREATED);
     247         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_CREATED_USEC);
     248         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_MODIFIED_NSEC);
     249         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_ACCESS_NSEC);
     250         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_CREATED_NSEC);
     251         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TIME_CHANGED_NSEC);
     252         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_DEVICE);
     253         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_INODE);
     254         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_MODE);
     255         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_NLINK);
     256         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_UID);
     257         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_GID);
     258         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_RDEV);
     259         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_BLOCK_SIZE);
     260         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_BLOCKS);
     261         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT);
     262         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE);
     263         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (DOS_IS_SYSTEM);
     264         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (DOS_IS_MOUNTPOINT);
     265         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (DOS_REPARSE_POINT_TAG);
     266         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (OWNER_USER);
     267         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (OWNER_USER_REAL);
     268         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (OWNER_GROUP);
     269         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH);
     270         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED);
     271         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID);
     272         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_NORMAL);
     273         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_NORMAL);
     274         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_NORMAL);
     275         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_LARGE);
     276         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_LARGE);
     277         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_LARGE);
     278         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_XLARGE);
     279         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_XLARGE);
     280         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_XLARGE);
     281         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_PATH_XXLARGE);
     282         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAILING_FAILED_XXLARGE);
     283         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID_XXLARGE);
     284         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (PREVIEW_ICON);
     285         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (FILESYSTEM_SIZE);
     286         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (FILESYSTEM_FREE);
     287         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (FILESYSTEM_TYPE);
     288         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (FILESYSTEM_READONLY);
     289         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (FILESYSTEM_USE_PREVIEW);
     290         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (GVFS_BACKEND);
     291         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (SELINUX_CONTEXT);
     292         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TRASH_ITEM_COUNT);
     293         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TRASH_ORIG_PATH);
     294         [ -  + ]:         11 :   REGISTER_ATTRIBUTE (TRASH_DELETION_DATE);
     295                 :            : 
     296                 :            : #undef REGISTER_ATTRIBUTE
     297                 :            : }
     298                 :            : 
     299                 :            : static guint32
     300                 :       1631 : lookup_namespace (const char *namespace)
     301                 :            : {
     302                 :            :   NSInfo *ns_info;
     303                 :            :   guint32 id;
     304                 :            : 
     305                 :       1631 :   G_LOCK (attribute_hash);
     306                 :            : 
     307                 :       1631 :   ensure_attribute_hash ();
     308                 :            : 
     309                 :       1631 :   ns_info = _lookup_namespace (namespace);
     310                 :       1631 :   id = 0;
     311         [ +  - ]:       1631 :   if (ns_info)
     312                 :       1631 :     id = ns_info->id;
     313                 :            : 
     314                 :       1631 :   G_UNLOCK (attribute_hash);
     315                 :            : 
     316                 :       1631 :   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                 :       4881 : lookup_attribute (const char *attribute)
     331                 :            : {
     332                 :            :   guint32 attr_id;
     333                 :            : 
     334                 :       4881 :   G_LOCK (attribute_hash);
     335                 :       4881 :   ensure_attribute_hash ();
     336                 :            : 
     337                 :       4881 :   attr_id = _lookup_attribute (attribute);
     338                 :            : 
     339                 :       4881 :   G_UNLOCK (attribute_hash);
     340                 :            : 
     341                 :       4881 :   return attr_id;
     342                 :            : }
     343                 :            : 
     344                 :            : static void
     345                 :       1218 : g_file_info_finalize (GObject *object)
     346                 :            : {
     347                 :            :   GFileInfo *info;
     348                 :            :   guint i;
     349                 :            :   GFileAttribute *attrs;
     350                 :            : 
     351                 :       1218 :   info = G_FILE_INFO (object);
     352                 :            : 
     353                 :       1218 :   attrs = (GFileAttribute *)info->attributes->data;
     354         [ +  + ]:       7162 :   for (i = 0; i < info->attributes->len; i++)
     355                 :       5944 :     _g_file_attribute_value_clear (&attrs[i].value);
     356                 :       1218 :   g_array_free (info->attributes, TRUE);
     357                 :            : 
     358         [ +  + ]:       1218 :   if (info->mask != NO_ATTRIBUTE_MASK)
     359                 :        109 :     g_file_attribute_matcher_unref (info->mask);
     360                 :            : 
     361                 :       1218 :   G_OBJECT_CLASS (g_file_info_parent_class)->finalize (object);
     362                 :       1218 : }
     363                 :            : 
     364                 :            : static void
     365                 :         12 : g_file_info_class_init (GFileInfoClass *klass)
     366                 :            : {
     367                 :         12 :   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
     368                 :            : 
     369                 :         12 :   gobject_class->finalize = g_file_info_finalize;
     370                 :         12 : }
     371                 :            : 
     372                 :            : static void
     373                 :       1218 : g_file_info_init (GFileInfo *info)
     374                 :            : {
     375                 :       1218 :   info->mask = NO_ATTRIBUTE_MASK;
     376                 :       1218 :   info->attributes = g_array_new (FALSE, FALSE,
     377                 :            :                                   sizeof (GFileAttribute));
     378                 :       1218 : }
     379                 :            : 
     380                 :            : /**
     381                 :            :  * g_file_info_new:
     382                 :            :  *
     383                 :            :  * Creates a new file info structure.
     384                 :            :  *
     385                 :            :  * Returns: a #GFileInfo.
     386                 :            :  **/
     387                 :            : GFileInfo *
     388                 :       1217 : g_file_info_new (void)
     389                 :            : {
     390                 :       1217 :   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                 :       1200 : g_file_info_set_attribute_mask (GFileInfo             *info,
     466                 :            :                                 GFileAttributeMatcher *mask)
     467                 :            : {
     468                 :            :   GFileAttribute *attr;
     469                 :            :   guint i;
     470                 :            : 
     471                 :       1200 :   g_return_if_fail (G_IS_FILE_INFO (info));
     472                 :            : 
     473         [ +  - ]:       1200 :   if (mask != info->mask)
     474                 :            :     {
     475         [ -  + ]:       1200 :       if (info->mask != NO_ATTRIBUTE_MASK)
     476                 :          0 :         g_file_attribute_matcher_unref (info->mask);
     477                 :       1200 :       info->mask = g_file_attribute_matcher_ref (mask);
     478                 :            : 
     479                 :            :       /* Remove non-matching attributes */
     480         [ +  + ]:       1204 :       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                 :       1091 : g_file_info_unset_attribute_mask (GFileInfo *info)
     503                 :            : {
     504                 :       1091 :   g_return_if_fail (G_IS_FILE_INFO (info));
     505                 :            : 
     506         [ +  - ]:       1091 :   if (info->mask != NO_ATTRIBUTE_MASK)
     507                 :       1091 :     g_file_attribute_matcher_unref (info->mask);
     508                 :       1091 :   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                 :       8868 : 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                 :       8868 :   min = 0;
     540                 :       8868 :   max = info->attributes->len;
     541                 :            : 
     542                 :       8868 :   attrs = (GFileAttribute *)info->attributes->data;
     543                 :            : 
     544         [ +  + ]:      32150 :   while (min < max)
     545                 :            :     {
     546                 :      25907 :       med = min + (max - min) / 2;
     547         [ +  + ]:      25907 :       if (attrs[med].attribute == attribute)
     548                 :            :         {
     549                 :       2625 :           min = med;
     550                 :       2625 :           break;
     551                 :            :         }
     552         [ +  + ]:      23282 :       else if (attrs[med].attribute < attribute)
     553                 :      11382 :         min = med + 1;
     554                 :            :       else /* attrs[med].attribute > attribute */
     555                 :      11900 :         max = med;
     556                 :            :     }
     557                 :            : 
     558                 :       8868 :   return min;
     559                 :            : }
     560                 :            : 
     561                 :            : static GFileAttributeValue *
     562                 :       2624 : g_file_info_find_value (GFileInfo *info,
     563                 :            :                         guint32    attr_id)
     564                 :            : {
     565                 :            :   GFileAttribute *attrs;
     566                 :            :   guint i;
     567                 :            : 
     568                 :       2624 :   i = g_file_info_find_place (info, attr_id);
     569                 :       2624 :   attrs = (GFileAttribute *)info->attributes->data;
     570         [ +  + ]:       2624 :   if (i < info->attributes->len &&
     571         [ +  + ]:       2501 :       attrs[i].attribute == attr_id)
     572                 :       2326 :     return &attrs[i].value;
     573                 :            : 
     574                 :        298 :   return NULL;
     575                 :            : }
     576                 :            : 
     577                 :            : static GFileAttributeValue *
     578                 :       1545 : g_file_info_find_value_by_name (GFileInfo  *info,
     579                 :            :                                 const char *attribute)
     580                 :            : {
     581                 :            :   guint32 attr_id;
     582                 :            : 
     583                 :       1545 :   attr_id = lookup_attribute (attribute);
     584                 :       1545 :   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                 :         55 : g_file_info_get_attribute_string (GFileInfo  *info,
     933                 :            :                                   const char *attribute)
     934                 :            : {
     935                 :            :   GFileAttributeValue *value;
     936                 :            : 
     937                 :         55 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
     938                 :         55 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', NULL);
     939                 :            : 
     940                 :         55 :   value = g_file_info_find_value_by_name (info, attribute);
     941                 :         55 :   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                 :        189 : g_file_info_get_attribute_boolean (GFileInfo  *info,
    1030                 :            :                                    const char *attribute)
    1031                 :            : {
    1032                 :            :   GFileAttributeValue *value;
    1033                 :            : 
    1034                 :        189 :   g_return_val_if_fail (G_IS_FILE_INFO (info), FALSE);
    1035                 :        189 :   g_return_val_if_fail (attribute != NULL && *attribute != '\0', FALSE);
    1036                 :            : 
    1037                 :        189 :   value = g_file_info_find_value_by_name (info, attribute);
    1038                 :        189 :   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                 :      24616 : g_file_info_create_value (GFileInfo *info,
    1139                 :            :                           guint32 attr_id)
    1140                 :            : {
    1141                 :            :   GFileAttribute *attrs;
    1142                 :            :   guint i;
    1143                 :            : 
    1144   [ +  +  +  + ]:      48253 :   if (info->mask != NO_ATTRIBUTE_MASK &&
    1145                 :      23637 :       !_g_file_attribute_matcher_matches_id (info->mask, attr_id))
    1146                 :      18379 :     return NULL;
    1147                 :            : 
    1148                 :       6237 :   i = g_file_info_find_place (info, attr_id);
    1149                 :            : 
    1150                 :       6237 :   attrs = (GFileAttribute *)info->attributes->data;
    1151         [ +  + ]:       6237 :   if (i < info->attributes->len &&
    1152         [ +  + ]:       3421 :       attrs[i].attribute == attr_id)
    1153                 :        294 :     return &attrs[i].value;
    1154                 :            :   else
    1155                 :            :     {
    1156                 :       5943 :       GFileAttribute attr = { 0 };
    1157                 :       5943 :       attr.attribute = attr_id;
    1158                 :       5943 :       g_array_insert_val (info->attributes, i, attr);
    1159                 :            : 
    1160                 :       5943 :       attrs = (GFileAttribute *)info->attributes->data;
    1161                 :       5943 :       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                 :        766 : _g_file_info_set_attribute_string_by_id (GFileInfo  *info,
    1276                 :            :                                          guint32     attribute,
    1277                 :            :                                          const char *attr_value)
    1278                 :            : {
    1279                 :            :   GFileAttributeValue *value;
    1280                 :            : 
    1281                 :        766 :   value = g_file_info_create_value (info, attribute);
    1282         [ +  - ]:        766 :   if (value)
    1283                 :        766 :     _g_file_attribute_value_set_string (value, attr_value);
    1284                 :        766 : }
    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                 :         93 : g_file_info_set_attribute_string (GFileInfo  *info,
    1297                 :            :                                   const char *attribute,
    1298                 :            :                                   const char *attr_value)
    1299                 :            : {
    1300                 :         93 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1301                 :         93 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1302                 :         93 :   g_return_if_fail (attr_value != NULL);
    1303                 :            : 
    1304                 :         93 :   _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                 :       1653 : _g_file_info_set_attribute_boolean_by_id (GFileInfo *info,
    1368                 :            :                                           guint32    attribute,
    1369                 :            :                                           gboolean   attr_value)
    1370                 :            : {
    1371                 :            :   GFileAttributeValue *value;
    1372                 :            : 
    1373                 :       1653 :   value = g_file_info_create_value (info, attribute);
    1374         [ +  + ]:       1653 :   if (value)
    1375                 :       1007 :     _g_file_attribute_value_set_boolean (value, attr_value);
    1376                 :       1653 : }
    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                 :      11824 : _g_file_info_set_attribute_uint32_by_id (GFileInfo *info,
    1402                 :            :                                          guint32    attribute,
    1403                 :            :                                          guint32    attr_value)
    1404                 :            : {
    1405                 :            :   GFileAttributeValue *value;
    1406                 :            : 
    1407                 :      11824 :   value = g_file_info_create_value (info, attribute);
    1408         [ +  + ]:      11824 :   if (value)
    1409                 :       1542 :     _g_file_attribute_value_set_uint32 (value, attr_value);
    1410                 :      11824 : }
    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                 :          6 : g_file_info_set_attribute_uint32 (GFileInfo  *info,
    1423                 :            :                                   const char *attribute,
    1424                 :            :                                   guint32     attr_value)
    1425                 :            : {
    1426                 :          6 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1427                 :          6 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1428                 :            : 
    1429                 :          6 :   _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                 :       5519 : _g_file_info_set_attribute_uint64_by_id (GFileInfo *info,
    1470                 :            :                                          guint32    attribute,
    1471                 :            :                                          guint64    attr_value)
    1472                 :            : {
    1473                 :            :   GFileAttributeValue *value;
    1474                 :            : 
    1475                 :       5519 :   value = g_file_info_create_value (info, attribute);
    1476         [ +  + ]:       5519 :   if (value)
    1477                 :        616 :     _g_file_attribute_value_set_uint64 (value, attr_value);
    1478                 :       5519 : }
    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                 :          4 : g_file_info_set_attribute_uint64 (GFileInfo  *info,
    1491                 :            :                                   const char *attribute,
    1492                 :            :                                   guint64     attr_value)
    1493                 :            : {
    1494                 :          4 :   g_return_if_fail (G_IS_FILE_INFO (info));
    1495                 :          4 :   g_return_if_fail (attribute != NULL && *attribute != '\0');
    1496                 :            : 
    1497                 :          4 :   _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                 :          6 : g_file_info_get_content_type (GFileInfo *info)
    1816                 :            : {
    1817                 :            :   GFileAttributeValue *value;
    1818                 :            : 
    1819                 :          6 :   g_return_val_if_fail (G_IS_FILE_INFO (info), NULL);
    1820                 :            : 
    1821   [ +  +  -  + ]:          6 :   get_required_attribute (&value, info, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, NULL);
    1822                 :          6 :   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                 :       1149 : g_file_info_set_file_type (GFileInfo *info,
    2122                 :            :                            GFileType  type)
    2123                 :            : {
    2124                 :            :   static guint32 attr = 0;
    2125                 :            :   GFileAttributeValue *value;
    2126                 :            : 
    2127                 :       1149 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2128                 :            : 
    2129         [ +  + ]:       1149 :   if (attr == 0)
    2130                 :          8 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_TYPE);
    2131                 :            : 
    2132                 :       1149 :   value = g_file_info_create_value (info, attr);
    2133         [ +  + ]:       1149 :   if (value)
    2134                 :        803 :     _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                 :        739 : g_file_info_set_is_symlink (GFileInfo *info,
    2172                 :            :                             gboolean   is_symlink)
    2173                 :            : {
    2174                 :            :   static guint32 attr = 0;
    2175                 :            :   GFileAttributeValue *value;
    2176                 :            : 
    2177                 :        739 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2178                 :            : 
    2179         [ +  + ]:        739 :   if (attr == 0)
    2180                 :          7 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK);
    2181                 :            : 
    2182                 :        739 :   value = g_file_info_create_value (info, attr);
    2183         [ +  + ]:        739 :   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                 :       1497 : g_file_info_set_name (GFileInfo  *info,
    2197                 :            :                       const char *name)
    2198                 :            : {
    2199                 :            :   static guint32 attr = 0;
    2200                 :            :   GFileAttributeValue *value;
    2201                 :            : 
    2202                 :       1497 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2203                 :       1497 :   g_return_if_fail (name != NULL);
    2204                 :            : 
    2205         [ +  + ]:       1497 :   if (attr == 0)
    2206                 :          9 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_NAME);
    2207                 :            : 
    2208                 :       1497 :   value = g_file_info_create_value (info, attr);
    2209         [ +  + ]:       1497 :   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                 :         82 : g_file_info_set_content_type (GFileInfo  *info,
    2329                 :            :                               const char *content_type)
    2330                 :            : {
    2331                 :            :   static guint32 attr = 0;
    2332                 :            :   GFileAttributeValue *value;
    2333                 :            : 
    2334                 :         82 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2335                 :         82 :   g_return_if_fail (content_type != NULL);
    2336                 :            : 
    2337         [ +  + ]:         82 :   if (attr == 0)
    2338                 :          3 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE);
    2339                 :            : 
    2340                 :         82 :   value = g_file_info_create_value (info, attr);
    2341         [ +  - ]:         82 :   if (value)
    2342                 :         82 :     _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                 :        792 : g_file_info_set_size (GFileInfo *info,
    2355                 :            :                       goffset    size)
    2356                 :            : {
    2357                 :            :   static guint32 attr = 0;
    2358                 :            :   GFileAttributeValue *value;
    2359                 :            : 
    2360                 :        792 :   g_return_if_fail (G_IS_FILE_INFO (info));
    2361                 :            : 
    2362         [ +  + ]:        792 :   if (attr == 0)
    2363                 :          8 :     attr = lookup_attribute (G_FILE_ATTRIBUTE_STANDARD_SIZE);
    2364                 :            : 
    2365                 :        792 :   value = g_file_info_create_value (info, attr);
    2366         [ +  + ]:        792 :   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                 :       3348 : compare_sub_matchers (gconstpointer a,
    2611                 :            :                       gconstpointer b)
    2612                 :            : {
    2613                 :       3348 :   const SubMatcher *suba = a;
    2614                 :       3348 :   const SubMatcher *subb = b;
    2615                 :            :   int diff;
    2616                 :            : 
    2617                 :       3348 :   diff = suba->id - subb->id;
    2618                 :            : 
    2619         [ +  + ]:       3348 :   if (diff)
    2620                 :       3345 :     return diff;
    2621                 :            : 
    2622                 :          3 :   return suba->mask - subb->mask;
    2623                 :            : }
    2624                 :            : 
    2625                 :            : static gboolean
    2626                 :       2462 : sub_matcher_matches (SubMatcher *matcher,
    2627                 :            :                      SubMatcher *submatcher)
    2628                 :            : {
    2629         [ +  + ]:       2462 :   if ((matcher->mask & submatcher->mask) != matcher->mask)
    2630                 :        128 :     return FALSE;
    2631                 :            :   
    2632                 :       2334 :   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                 :       1648 : matcher_optimize (GFileAttributeMatcher *matcher)
    2640                 :            : {
    2641                 :            :   SubMatcher *submatcher, *compare;
    2642                 :            :   guint i, j;
    2643                 :            : 
    2644                 :            :   /* remove sub_matchers if we match everything anyway */
    2645         [ +  + ]:       1648 :   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         [ +  + ]:       1584 :   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                 :       1374 :   g_array_sort (matcher->sub_matchers, compare_sub_matchers);
    2664                 :            : 
    2665                 :            :   /* remove duplicates and specific matches when we match the whole namespace */
    2666                 :       1374 :   j = 0;
    2667                 :       1374 :   compare = &g_array_index (matcher->sub_matchers, SubMatcher, j);
    2668                 :            : 
    2669         [ +  + ]:       3362 :   for (i = 1; i < matcher->sub_matchers->len; i++)
    2670                 :            :     {
    2671                 :       1988 :       submatcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
    2672         [ +  + ]:       1988 :       if (sub_matcher_matches (compare, submatcher))
    2673                 :          7 :         continue;
    2674                 :            : 
    2675                 :       1981 :       j++;
    2676                 :       1981 :       compare++;
    2677                 :            : 
    2678         [ +  + ]:       1981 :       if (j < i)
    2679                 :          1 :         *compare = *submatcher;
    2680                 :            :     }
    2681                 :            : 
    2682                 :       1374 :   g_array_set_size (matcher->sub_matchers, j + 1);
    2683                 :            : 
    2684                 :       1374 :   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                 :       1413 : g_file_attribute_matcher_new (const char *attributes)
    2715                 :            : {
    2716                 :            :   char **split;
    2717                 :            :   char *colon;
    2718                 :            :   int i;
    2719                 :            :   GFileAttributeMatcher *matcher;
    2720                 :            : 
    2721   [ +  +  -  + ]:       1413 :   if (attributes == NULL || *attributes == '\0')
    2722                 :          2 :     return NULL;
    2723                 :            : 
    2724                 :       1411 :   matcher = g_malloc0 (sizeof (GFileAttributeMatcher));
    2725                 :       1411 :   matcher->ref = 1;
    2726                 :       1411 :   matcher->sub_matchers = g_array_new (FALSE, FALSE, sizeof (SubMatcher));
    2727                 :            : 
    2728                 :       1411 :   split = g_strsplit (attributes, ",", -1);
    2729                 :            : 
    2730         [ +  + ]:       4811 :   for (i = 0; split[i] != NULL; i++)
    2731                 :            :     {
    2732         [ +  + ]:       3400 :       if (strcmp (split[i], "*") == 0)
    2733                 :         65 :         matcher->all = TRUE;
    2734                 :            :       else
    2735                 :            :         {
    2736                 :            :           SubMatcher s;
    2737                 :            : 
    2738                 :       3335 :           colon = strstr (split[i], "::");
    2739         [ +  + ]:       3335 :           if (colon != NULL &&
    2740         [ +  - ]:       3308 :               !(colon[2] == 0 ||
    2741         [ +  + ]:       3308 :                 (colon[2] == '*' &&
    2742         [ -  + ]:        175 :                  colon[3] == 0)))
    2743                 :            :             {
    2744                 :       3133 :               s.id = lookup_attribute (split[i]);
    2745                 :       3133 :               s.mask = 0xffffffff;
    2746                 :            :             }
    2747                 :            :           else
    2748                 :            :             {
    2749         [ +  + ]:        202 :               if (colon)
    2750                 :        175 :                 *colon = 0;
    2751                 :            : 
    2752                 :        202 :               s.id = lookup_namespace (split[i]) << NS_POS;
    2753                 :        202 :               s.mask = NS_MASK << NS_POS;
    2754                 :            :             }
    2755                 :            : 
    2756                 :       3335 :           g_array_append_val (matcher->sub_matchers, s);
    2757                 :            :         }
    2758                 :            :     }
    2759                 :            : 
    2760                 :       1411 :   g_strfreev (split);
    2761                 :            : 
    2762                 :       1411 :   matcher = matcher_optimize (matcher);
    2763                 :            : 
    2764                 :       1411 :   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                 :       1223 : g_file_attribute_matcher_ref (GFileAttributeMatcher *matcher)
    2848                 :            : {
    2849         [ +  + ]:       1223 :   if (matcher)
    2850                 :            :     {
    2851                 :        922 :       g_return_val_if_fail (matcher->ref > 0, NULL);
    2852                 :        922 :       g_atomic_int_inc (&matcher->ref);
    2853                 :            :     }
    2854                 :       1223 :   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                 :       3095 : g_file_attribute_matcher_unref (GFileAttributeMatcher *matcher)
    2867                 :            : {
    2868         [ +  + ]:       3095 :   if (matcher)
    2869                 :            :     {
    2870                 :       2570 :       g_return_if_fail (matcher->ref > 0);
    2871                 :            : 
    2872         [ +  + ]:       2570 :       if (g_atomic_int_dec_and_test (&matcher->ref))
    2873                 :            :         {
    2874         [ +  + ]:       1648 :           if (matcher->sub_matchers)
    2875                 :       1584 :             g_array_free (matcher->sub_matchers, TRUE);
    2876                 :            : 
    2877                 :       1648 :           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                 :      47913 : matcher_matches_id (GFileAttributeMatcher *matcher,
    2918                 :            :                     guint32                id)
    2919                 :            : {
    2920                 :            :   SubMatcher *sub_matchers;
    2921                 :            :   guint i;
    2922                 :            : 
    2923         [ +  - ]:      47913 :   if (matcher->sub_matchers)
    2924                 :            :     {
    2925                 :      47913 :       sub_matchers = (SubMatcher *)matcher->sub_matchers->data;
    2926         [ +  + ]:     142634 :       for (i = 0; i < matcher->sub_matchers->len; i++)
    2927                 :            :         {
    2928         [ +  + ]:      96745 :           if (sub_matchers[i].id == (id & sub_matchers[i].mask))
    2929                 :       2024 :             return TRUE;
    2930                 :            :         }
    2931                 :            :     }
    2932                 :            : 
    2933                 :      45889 :   return FALSE;
    2934                 :            : }
    2935                 :            : 
    2936                 :            : gboolean
    2937                 :      55086 : _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         [ +  + ]:      55086 :   if (matcher == NULL)
    2942                 :       1224 :     return FALSE;
    2943                 :            : 
    2944         [ +  + ]:      53862 :   if (matcher->all)
    2945                 :       5957 :     return TRUE;
    2946                 :            : 
    2947                 :      47905 :   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                 :         10 : g_file_attribute_matcher_matches (GFileAttributeMatcher *matcher,
    2963                 :            :                                   const char            *attribute)
    2964                 :            : {
    2965                 :         10 :   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         [ -  + ]:         10 :   if (matcher == NULL)
    2969                 :          0 :     return FALSE;
    2970                 :            : 
    2971         [ +  + ]:         10 :   if (matcher->all)
    2972                 :          2 :     return TRUE;
    2973                 :            : 
    2974                 :          8 :   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                 :       1580 : 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                 :       1580 :   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         [ -  + ]:       1580 :   if (matcher == NULL)
    3005                 :          0 :     return FALSE;
    3006                 :            : 
    3007         [ +  + ]:       1580 :   if (matcher->all)
    3008                 :        152 :     return TRUE;
    3009                 :            : 
    3010                 :       1428 :   ns_id = lookup_namespace (ns) << NS_POS;
    3011                 :            : 
    3012         [ +  - ]:       1428 :   if (matcher->sub_matchers)
    3013                 :            :     {
    3014                 :       1428 :       sub_matchers = (SubMatcher *)matcher->sub_matchers->data;
    3015         [ +  + ]:       4788 :       for (i = 0; i < matcher->sub_matchers->len; i++)
    3016                 :            :         {
    3017         [ +  + ]:       3432 :           if (sub_matchers[i].id == ns_id)
    3018                 :         72 :             return TRUE;
    3019                 :            :         }
    3020                 :            :     }
    3021                 :            : 
    3022                 :       1356 :   matcher->iterator_ns = ns_id;
    3023                 :       1356 :   matcher->iterator_pos = 0;
    3024                 :            : 
    3025                 :       1356 :   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                 :       1357 : 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         [ +  - ]:       1357 :   if (matcher == NULL)
    3045                 :          0 :     return NULL;
    3046                 :            : 
    3047                 :            :   while (1)
    3048                 :            :     {
    3049                 :       4324 :       i = matcher->iterator_pos++;
    3050                 :            : 
    3051         [ -  + ]:       4324 :       if (matcher->sub_matchers == NULL)
    3052                 :          0 :         return NULL;
    3053                 :            : 
    3054         [ +  + ]:       4324 :       if (i < matcher->sub_matchers->len)
    3055                 :       2968 :         sub_matcher = &g_array_index (matcher->sub_matchers, SubMatcher, i);
    3056                 :            :       else
    3057                 :       1356 :         return NULL;
    3058                 :            : 
    3059         [ +  + ]:       2968 :       if (sub_matcher->mask == 0xffffffff &&
    3060         [ +  + ]:       2776 :           (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 1.14