+_lookup_attribute (const char *attribute)
+{
+ guint32 attr_id, id;
+ char *ns;
+ const char *colon;
+ NSInfo *ns_info;
+
+ attr_id = GPOINTER_TO_UINT (g_hash_table_lookup (attribute_hash, attribute));
+
+ if (attr_id != 0)
+ return attr_id;
+
+ colon = strstr (attribute, "::");
+ if (colon)
+ ns = g_strndup (attribute, colon - attribute);
+ else
+ ns = g_strdup ("");
+
+ ns_info = _lookup_namespace (ns);
+ g_free (ns);
+
+ id = ++ns_info->attribute_id_counter;
+ attributes[ns_info->id] = g_realloc (attributes[ns_info->id], (id + 1) * sizeof (char *));
+ attributes[ns_info->id][id] = g_strdup (attribute);
+
+ attr_id = MAKE_ATTR_ID (ns_info->id, id);
+
+ g_hash_table_insert (attribute_hash, attributes[ns_info->id][id], GUINT_TO_POINTER (attr_id));
+
+ return attr_id;
+}
+
+static void
+ensure_attribute_hash (void)
+{
+ if (attribute_hash != NULL)
+ return;
+
+ ns_hash = g_hash_table_new (g_str_hash, g_str_equal);
+ attribute_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+#define REGISTER_ATTRIBUTE(name) G_STMT_START{\
+ guint _u = _lookup_attribute (G_FILE_ATTRIBUTE_ ## name); \
+ /* use for generating the ID: g_print ("#define G_FILE_ATTRIBUTE_ID_%s (%u + %u)\n", #name + 17, _u & ~ID_MASK, _u & ID_MASK); */ \
+ g_assert (_u == G_FILE_ATTRIBUTE_ID_ ## name); \
+}G_STMT_END
+
+ REGISTER_ATTRIBUTE (STANDARD_TYPE);
+ REGISTER_ATTRIBUTE (STANDARD_IS_HIDDEN);
+ REGISTER_ATTRIBUTE (STANDARD_IS_BACKUP);
+ REGISTER_ATTRIBUTE (STANDARD_IS_SYMLINK);
+ REGISTER_ATTRIBUTE (STANDARD_IS_VIRTUAL);
+ REGISTER_ATTRIBUTE (STANDARD_NAME);
+ REGISTER_ATTRIBUTE (STANDARD_DISPLAY_NAME);
+ REGISTER_ATTRIBUTE (STANDARD_EDIT_NAME);
+ REGISTER_ATTRIBUTE (STANDARD_COPY_NAME);
+ REGISTER_ATTRIBUTE (STANDARD_DESCRIPTION);
+ REGISTER_ATTRIBUTE (STANDARD_ICON);
+ REGISTER_ATTRIBUTE (STANDARD_CONTENT_TYPE);
+ REGISTER_ATTRIBUTE (STANDARD_FAST_CONTENT_TYPE);
+ REGISTER_ATTRIBUTE (STANDARD_SIZE);
+ REGISTER_ATTRIBUTE (STANDARD_ALLOCATED_SIZE);
+ REGISTER_ATTRIBUTE (STANDARD_SYMLINK_TARGET);
+ REGISTER_ATTRIBUTE (STANDARD_TARGET_URI);
+ REGISTER_ATTRIBUTE (STANDARD_SORT_ORDER);
+ REGISTER_ATTRIBUTE (STANDARD_SYMBOLIC_ICON);
+ REGISTER_ATTRIBUTE (ETAG_VALUE);
+ REGISTER_ATTRIBUTE (ID_FILE);
+ REGISTER_ATTRIBUTE (ID_FILESYSTEM);
+ REGISTER_ATTRIBUTE (ACCESS_CAN_READ);
+ REGISTER_ATTRIBUTE (ACCESS_CAN_WRITE);
+ REGISTER_ATTRIBUTE (ACCESS_CAN_EXECUTE);
+ REGISTER_ATTRIBUTE (ACCESS_CAN_DELETE);
+ REGISTER_ATTRIBUTE (ACCESS_CAN_TRASH);
+ REGISTER_ATTRIBUTE (ACCESS_CAN_RENAME);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_MOUNT);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_UNMOUNT);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_EJECT);
+ REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE);
+ REGISTER_ATTRIBUTE (MOUNTABLE_UNIX_DEVICE_FILE);
+ REGISTER_ATTRIBUTE (MOUNTABLE_HAL_UDI);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_START_DEGRADED);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_STOP);
+ REGISTER_ATTRIBUTE (MOUNTABLE_START_STOP_TYPE);
+ REGISTER_ATTRIBUTE (MOUNTABLE_CAN_POLL);
+ REGISTER_ATTRIBUTE (MOUNTABLE_IS_MEDIA_CHECK_AUTOMATIC);
+ REGISTER_ATTRIBUTE (TIME_MODIFIED);
+ REGISTER_ATTRIBUTE (TIME_MODIFIED_USEC);
+ REGISTER_ATTRIBUTE (TIME_ACCESS);
+ REGISTER_ATTRIBUTE (TIME_ACCESS_USEC);
+ REGISTER_ATTRIBUTE (TIME_CHANGED);
+ REGISTER_ATTRIBUTE (TIME_CHANGED_USEC);
+ REGISTER_ATTRIBUTE (TIME_CREATED);
+ REGISTER_ATTRIBUTE (TIME_CREATED_USEC);
+ REGISTER_ATTRIBUTE (UNIX_DEVICE);
+ REGISTER_ATTRIBUTE (UNIX_INODE);
+ REGISTER_ATTRIBUTE (UNIX_MODE);
+ REGISTER_ATTRIBUTE (UNIX_NLINK);
+ REGISTER_ATTRIBUTE (UNIX_UID);
+ REGISTER_ATTRIBUTE (UNIX_GID);
+ REGISTER_ATTRIBUTE (UNIX_RDEV);
+ REGISTER_ATTRIBUTE (UNIX_BLOCK_SIZE);
+ REGISTER_ATTRIBUTE (UNIX_BLOCKS);
+ REGISTER_ATTRIBUTE (UNIX_IS_MOUNTPOINT);
+ REGISTER_ATTRIBUTE (DOS_IS_ARCHIVE);
+ REGISTER_ATTRIBUTE (DOS_IS_SYSTEM);
+ REGISTER_ATTRIBUTE (OWNER_USER);
+ REGISTER_ATTRIBUTE (OWNER_USER_REAL);
+ REGISTER_ATTRIBUTE (OWNER_GROUP);
+ REGISTER_ATTRIBUTE (THUMBNAIL_PATH);
+ REGISTER_ATTRIBUTE (THUMBNAILING_FAILED);
+ REGISTER_ATTRIBUTE (THUMBNAIL_IS_VALID);
+ REGISTER_ATTRIBUTE (PREVIEW_ICON);
+ REGISTER_ATTRIBUTE (FILESYSTEM_SIZE);
+ REGISTER_ATTRIBUTE (FILESYSTEM_FREE);
+ REGISTER_ATTRIBUTE (FILESYSTEM_TYPE);
+ REGISTER_ATTRIBUTE (FILESYSTEM_READONLY);
+ REGISTER_ATTRIBUTE (FILESYSTEM_USE_PREVIEW);
+ REGISTER_ATTRIBUTE (GVFS_BACKEND);
+ REGISTER_ATTRIBUTE (SELINUX_CONTEXT);
+ REGISTER_ATTRIBUTE (TRASH_ITEM_COUNT);
+ REGISTER_ATTRIBUTE (TRASH_ORIG_PATH);
+ REGISTER_ATTRIBUTE (TRASH_DELETION_DATE);
+
+#undef REGISTER_ATTRIBUTE
+}
+
+static guint32