1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Alexander Larsson <alexl@redhat.com>
27 #include "gfileattribute.h"
28 #include <glib-object.h>
32 * g_file_attribute_value_free:
33 * @attr: a #GFileAttributeValue.
35 * Frees the memory used by @attr.
39 g_file_attribute_value_free (GFileAttributeValue *attr)
41 g_return_if_fail (attr != NULL);
43 g_file_attribute_value_clear (attr);
48 * g_file_attribute_value_clear:
49 * @attr: a #GFileAttributeValue.
51 * Clears the value of @attr and sets its type to
52 * %G_FILE_ATTRIBUTE_TYPE_INVALID.
56 g_file_attribute_value_clear (GFileAttributeValue *attr)
58 g_return_if_fail (attr != NULL);
60 if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING ||
61 attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
62 g_free (attr->u.string);
64 if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT &&
66 g_object_unref (attr->u.obj);
68 attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
72 * g_file_attribute_value_set:
73 * @attr: a #GFileAttributeValue.
78 g_file_attribute_value_set (GFileAttributeValue *attr,
79 const GFileAttributeValue *new_value)
81 g_return_if_fail (attr != NULL);
82 g_return_if_fail (new_value != NULL);
84 g_file_attribute_value_clear (attr);
87 if (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING ||
88 attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING)
89 attr->u.string = g_strdup (attr->u.string);
91 if (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT &&
93 g_object_ref (attr->u.obj);
97 * g_file_attribute_value_new:
99 * Returns: a new #GFileAttributeValue.
101 GFileAttributeValue *
102 g_file_attribute_value_new (void)
104 GFileAttributeValue *attr;
106 attr = g_new (GFileAttributeValue, 1);
107 attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
113 * g_file_attribute_value_dup:
114 * @other: a #GFileAttributeValue to duplicate.
116 * Returns: a duplicate of the @other.
118 GFileAttributeValue *
119 g_file_attribute_value_dup (const GFileAttributeValue *other)
121 GFileAttributeValue *attr;
123 g_return_val_if_fail (other != NULL, NULL);
125 attr = g_new (GFileAttributeValue, 1);
126 attr->type = G_FILE_ATTRIBUTE_TYPE_INVALID;
127 g_file_attribute_value_set (attr, other);
134 return c >= 32 && c <= 126 && c != '\\';
138 escape_byte_string (const char *str)
142 char *escaped_val, *p;
144 char *hex_digits = "0123456789abcdef";
149 for (i = 0; i < len; i++)
151 if (!valid_char (str[i]))
155 if (num_invalid == 0)
156 return g_strdup (str);
159 escaped_val = g_malloc (len + num_invalid*3 + 1);
162 for (i = 0; i < len; i++)
171 *p++ = hex_digits[(c >> 8) & 0xf];
172 *p++ = hex_digits[c & 0xf];
181 * g_file_attribute_value_as_string:
182 * @attr: a #GFileAttributeValue.
184 * Converts a #GFileAttributeValue to a string for display.
185 * The returned string should be freed when no longer needed
187 * Returns: a string from the @attr, %NULL on error, or "<invalid>" if
188 * @attr is of type %G_FILE_ATTRIBUTE_TYPE_INVALID.
191 g_file_attribute_value_as_string (const GFileAttributeValue *attr)
195 g_return_val_if_fail (attr != NULL, NULL);
199 case G_FILE_ATTRIBUTE_TYPE_STRING:
200 str = g_strdup (attr->u.string);
202 case G_FILE_ATTRIBUTE_TYPE_BYTE_STRING:
203 str = escape_byte_string (attr->u.string);
205 case G_FILE_ATTRIBUTE_TYPE_BOOLEAN:
206 str = g_strdup_printf ("%s", attr->u.boolean?"TRUE":"FALSE");
208 case G_FILE_ATTRIBUTE_TYPE_UINT32:
209 str = g_strdup_printf ("%u", (unsigned int)attr->u.uint32);
211 case G_FILE_ATTRIBUTE_TYPE_INT32:
212 str = g_strdup_printf ("%i", (int)attr->u.int32);
214 case G_FILE_ATTRIBUTE_TYPE_UINT64:
215 str = g_strdup_printf ("%"G_GUINT64_FORMAT, attr->u.uint64);
217 case G_FILE_ATTRIBUTE_TYPE_INT64:
218 str = g_strdup_printf ("%"G_GINT64_FORMAT, attr->u.int64);
220 case G_FILE_ATTRIBUTE_TYPE_OBJECT:
221 str = g_strdup_printf ("%s:%p", g_type_name_from_instance
222 ((GTypeInstance *) attr->u.obj),
226 g_warning ("Invalid type in GFileInfo attribute");
227 str = g_strdup ("<invalid>");
235 * g_file_attribute_value_get_string:
236 * @attr: a #GFileAttributeValue.
241 g_file_attribute_value_get_string (const GFileAttributeValue *attr)
246 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_STRING, NULL);
248 return attr->u.string;
252 * g_file_attribute_value_get_byte_string:
253 * @attr: a #GFileAttributeValue.
258 g_file_attribute_value_get_byte_string (const GFileAttributeValue *attr)
263 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BYTE_STRING, NULL);
265 return attr->u.string;
269 * g_file_attribute_value_get_boolean:
270 * @attr: a #GFileAttributeValue.
275 g_file_attribute_value_get_boolean (const GFileAttributeValue *attr)
280 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_BOOLEAN, FALSE);
282 return attr->u.boolean;
286 * g_file_attribute_value_get_uint32:
287 * @attr: a #GFileAttributeValue.
292 g_file_attribute_value_get_uint32 (const GFileAttributeValue *attr)
297 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT32, 0);
299 return attr->u.uint32;
303 * g_file_attribute_value_get_int32:
304 * @attr: a #GFileAttributeValue.
309 g_file_attribute_value_get_int32 (const GFileAttributeValue *attr)
314 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT32, 0);
316 return attr->u.int32;
320 * g_file_attribute_value_get_uint64:
321 * @attr: a #GFileAttributeValue.
326 g_file_attribute_value_get_uint64 (const GFileAttributeValue *attr)
331 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_UINT64, 0);
333 return attr->u.uint64;
337 * g_file_attribute_value_get_int64:
338 * @attr: a #GFileAttributeValue.
343 g_file_attribute_value_get_int64 (const GFileAttributeValue *attr)
348 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_INT64, 0);
350 return attr->u.int64;
354 * g_file_attribute_value_get_object:
355 * @attr: a #GFileAttributeValue.
360 g_file_attribute_value_get_object (const GFileAttributeValue *attr)
365 g_return_val_if_fail (attr->type == G_FILE_ATTRIBUTE_TYPE_OBJECT, NULL);
371 * g_file_attribute_value_set_string:
372 * @attr: a #GFileAttributeValue.
377 g_file_attribute_value_set_string (GFileAttributeValue *attr,
380 g_return_if_fail (attr != NULL);
381 g_return_if_fail (string != NULL);
383 g_file_attribute_value_clear (attr);
384 attr->type = G_FILE_ATTRIBUTE_TYPE_STRING;
385 attr->u.string = g_strdup (string);
389 * g_file_attribute_value_set_byte_string:
390 * @attr: a #GFileAttributeValue.
395 g_file_attribute_value_set_byte_string (GFileAttributeValue *attr,
398 g_return_if_fail (attr != NULL);
399 g_return_if_fail (string != NULL);
401 g_file_attribute_value_clear (attr);
402 attr->type = G_FILE_ATTRIBUTE_TYPE_BYTE_STRING;
403 attr->u.string = g_strdup (string);
407 * g_file_attribute_value_set_boolean:
408 * @attr: a #GFileAttributeValue.
413 g_file_attribute_value_set_boolean (GFileAttributeValue *attr,
416 g_return_if_fail (attr != NULL);
418 g_file_attribute_value_clear (attr);
419 attr->type = G_FILE_ATTRIBUTE_TYPE_BOOLEAN;
420 attr->u.boolean = !!value;
424 * g_file_attribute_value_set_uint32:
425 * @attr: a #GFileAttributeValue.
430 g_file_attribute_value_set_uint32 (GFileAttributeValue *attr,
433 g_return_if_fail (attr != NULL);
435 g_file_attribute_value_clear (attr);
436 attr->type = G_FILE_ATTRIBUTE_TYPE_UINT32;
437 attr->u.uint32 = value;
441 * g_file_attribute_value_set_int32:
442 * @attr: a #GFileAttributeValue.
447 g_file_attribute_value_set_int32 (GFileAttributeValue *attr,
450 g_return_if_fail (attr != NULL);
452 g_file_attribute_value_clear (attr);
453 attr->type = G_FILE_ATTRIBUTE_TYPE_INT32;
454 attr->u.int32 = value;
458 * g_file_attribute_value_set_uint64:
459 * @attr: a #GFileAttributeValue.
464 g_file_attribute_value_set_uint64 (GFileAttributeValue *attr,
467 g_return_if_fail (attr != NULL);
469 g_file_attribute_value_clear (attr);
470 attr->type = G_FILE_ATTRIBUTE_TYPE_UINT64;
471 attr->u.uint64 = value;
475 * g_file_attribute_value_set_int64:
476 * @attr: a #GFileAttributeValue.
477 * @value: a #gint64 to set the value to.
481 g_file_attribute_value_set_int64 (GFileAttributeValue *attr,
484 g_return_if_fail (attr != NULL);
486 g_file_attribute_value_clear (attr);
487 attr->type = G_FILE_ATTRIBUTE_TYPE_INT64;
488 attr->u.int64 = value;
492 * g_file_attribute_value_set_object:
493 * @attr: a #GFileAttributeValue.
496 * Sets the file attribute @attr to contain the value @obj.
497 * The @attr references the object internally.
501 g_file_attribute_value_set_object (GFileAttributeValue *attr,
504 g_return_if_fail (attr != NULL);
505 g_return_if_fail (obj != NULL);
507 g_file_attribute_value_clear (attr);
508 attr->type = G_FILE_ATTRIBUTE_TYPE_OBJECT;
509 attr->u.obj = g_object_ref (obj);
513 GFileAttributeInfoList public;
516 } GFileAttributeInfoListPriv;
519 list_update_public (GFileAttributeInfoListPriv *priv)
521 priv->public.infos = (GFileAttributeInfo *)priv->array->data;
522 priv->public.n_infos = priv->array->len;
526 * g_file_attribute_info_list_new:
528 * Returns a new #GFileAttributeInfoList.
530 GFileAttributeInfoList *
531 g_file_attribute_info_list_new (void)
533 GFileAttributeInfoListPriv *priv;
535 priv = g_new0 (GFileAttributeInfoListPriv, 1);
538 priv->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo));
540 list_update_public (priv);
542 return (GFileAttributeInfoList *)priv;
546 * g_file_attribute_info_list_dup:
547 * @list: a #GFileAttributeInfoList to duplicate.
549 * Returns a duplicate of the given @list.
551 GFileAttributeInfoList *
552 g_file_attribute_info_list_dup (GFileAttributeInfoList *list)
554 GFileAttributeInfoListPriv *new;
557 g_return_val_if_fail (list != NULL, NULL);
559 new = g_new0 (GFileAttributeInfoListPriv, 1);
561 new->array = g_array_new (TRUE, FALSE, sizeof (GFileAttributeInfo));
563 g_array_set_size (new->array, list->n_infos);
564 list_update_public (new);
565 for (i = 0; i < list->n_infos; i++)
567 new->public.infos[i].name = g_strdup (list->infos[i].name);
568 new->public.infos[i].type = list->infos[i].type;
569 new->public.infos[i].flags = list->infos[i].flags;
572 return (GFileAttributeInfoList *)new;
576 * g_file_attribute_info_list_ref:
577 * @list: a #GFileAttributeInfoList to reference.
579 * Returns: #GFileAttributeInfoList or %NULL on error.
581 GFileAttributeInfoList *
582 g_file_attribute_info_list_ref (GFileAttributeInfoList *list)
584 GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
586 g_return_val_if_fail (list != NULL, NULL);
587 g_return_val_if_fail (priv->ref_count > 0, NULL);
589 g_atomic_int_inc (&priv->ref_count);
595 * g_file_attribute_info_list_unref:
596 * @list: The #GFileAttributeInfoList to unreference.
598 * Removes a reference from the given @list. If the reference count
599 * falls to zero, the @list is deleted.
602 g_file_attribute_info_list_unref (GFileAttributeInfoList *list)
604 GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
607 g_return_if_fail (list != NULL);
608 g_return_if_fail (priv->ref_count > 0);
610 if (g_atomic_int_dec_and_test (&priv->ref_count))
612 for (i = 0; i < list->n_infos; i++)
613 g_free (list->infos[i].name);
614 g_array_free (priv->array, TRUE);
619 g_file_attribute_info_list_bsearch (GFileAttributeInfoList *list,
629 mid = start + (end - start) / 2;
631 if (strcmp (name, list->infos[mid].name) < 0)
633 else if (strcmp (name, list->infos[mid].name) > 0)
642 * g_file_attribute_info_list_lookup:
643 * @list: a #GFileAttributeInfoList.
644 * @name: the name of the attribute to lookup.
646 * Returns: a #GFileAttributeInfo for the @name, or %NULL if an
647 * attribute isn't found.
649 const GFileAttributeInfo *
650 g_file_attribute_info_list_lookup (GFileAttributeInfoList *list,
655 g_return_val_if_fail (list != NULL, NULL);
656 g_return_val_if_fail (name != NULL, NULL);
658 i = g_file_attribute_info_list_bsearch (list, name);
660 if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0)
661 return &list->infos[i];
667 * g_file_attribute_info_list_add:
668 * @list: a #GFileAttributeInfoList.
669 * @name: the name of the attribute to add.
670 * @type: the #GFileAttributeType for the attribute.
671 * @flags: #GFileAttributeFlags for the attribute.
673 * Adds a new attribute with @name to the @list, setting
674 * its @type and @flags.
678 g_file_attribute_info_list_add (GFileAttributeInfoList *list,
680 GFileAttributeType type,
681 GFileAttributeFlags flags)
683 GFileAttributeInfoListPriv *priv = (GFileAttributeInfoListPriv *)list;
684 GFileAttributeInfo info;
687 g_return_if_fail (list != NULL);
688 g_return_if_fail (name != NULL);
690 i = g_file_attribute_info_list_bsearch (list, name);
692 if (i < list->n_infos && strcmp (list->infos[i].name, name) == 0)
694 list->infos[i].type = type;
698 info.name = g_strdup (name);
701 g_array_insert_vals (priv->array, i, &info, 1);
703 list_update_public (priv);