Remove redundant header inclusions
[glib.git] / glib / gdataset.c
blob86970c91f12bcccf74efdd676e300ce7ae328e54
1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * gdataset.c: Generic dataset mechanism, similar to GtkObject data.
5 * Copyright (C) 1998 Tim Janik
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 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
23 * Modified by the GLib Team and others 1997-2000. See the AUTHORS
24 * file for a list of people on the GLib Team. See the ChangeLog
25 * files for a list of changes. These files are distributed with
26 * GLib at ftp://ftp.gtk.org/pub/gtk/.
29 /*
30 * MT safe ; except for g_data*_foreach()
33 #include "config.h"
35 #include <string.h>
37 #include "glib.h"
38 #include "gdatasetprivate.h"
39 #include "glib_trace.h"
41 /**
42 * SECTION: datasets
43 * @title: Datasets
44 * @short_description: associate groups of data elements with
45 * particular memory locations
47 * Datasets associate groups of data elements with particular memory
48 * locations. These are useful if you need to associate data with a
49 * structure returned from an external library. Since you cannot modify
50 * the structure, you use its location in memory as the key into a
51 * dataset, where you can associate any number of data elements with it.
53 * There are two forms of most of the dataset functions. The first form
54 * uses strings to identify the data elements associated with a
55 * location. The second form uses #GQuark identifiers, which are
56 * created with a call to g_quark_from_string() or
57 * g_quark_from_static_string(). The second form is quicker, since it
58 * does not require looking up the string in the hash table of #GQuark
59 * identifiers.
61 * There is no function to create a dataset. It is automatically
62 * created as soon as you add elements to it.
64 * To add data elements to a dataset use g_dataset_id_set_data(),
65 * g_dataset_id_set_data_full(), g_dataset_set_data() and
66 * g_dataset_set_data_full().
68 * To get data elements from a dataset use g_dataset_id_get_data() and
69 * g_dataset_get_data().
71 * To iterate over all data elements in a dataset use
72 * g_dataset_foreach() (not thread-safe).
74 * To remove data elements from a dataset use
75 * g_dataset_id_remove_data() and g_dataset_remove_data().
77 * To destroy a dataset, use g_dataset_destroy().
78 **/
80 /**
81 * SECTION: datalist
82 * @title: Keyed Data Lists
83 * @short_description: lists of data elements which are accessible by a
84 * string or GQuark identifier
86 * Keyed data lists provide lists of arbitrary data elements which can
87 * be accessed either with a string or with a #GQuark corresponding to
88 * the string.
90 * The #GQuark methods are quicker, since the strings have to be
91 * converted to #GQuarks anyway.
93 * Data lists are used for associating arbitrary data with #GObjects,
94 * using g_object_set_data() and related functions.
96 * To create a datalist, use g_datalist_init().
98 * To add data elements to a datalist use g_datalist_id_set_data(),
99 * g_datalist_id_set_data_full(), g_datalist_set_data() and
100 * g_datalist_set_data_full().
102 * To get data elements from a datalist use g_datalist_id_get_data()
103 * and g_datalist_get_data().
105 * To iterate over all data elements in a datalist use
106 * g_datalist_foreach() (not thread-safe).
108 * To remove data elements from a datalist use
109 * g_datalist_id_remove_data() and g_datalist_remove_data().
111 * To remove all data elements from a datalist, use g_datalist_clear().
115 * GData:
117 * The #GData struct is an opaque data structure to represent a <link
118 * linkend="glib-Keyed-Data-Lists">Keyed Data List</link>. It should
119 * only be accessed via the following functions.
123 * GDestroyNotify:
124 * @data: the data element.
126 * Specifies the type of function which is called when a data element
127 * is destroyed. It is passed the pointer to the data element and
128 * should free any memory and resources allocated for it.
131 /* --- defines --- */
132 #define G_QUARK_BLOCK_SIZE (512)
134 /* datalist pointer accesses have to be carried out atomically */
135 #define G_DATALIST_GET_POINTER(datalist) \
136 ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK))
138 #define G_DATALIST_SET_POINTER(datalist, pointer) G_STMT_START { \
139 gpointer _oldv, _newv; \
140 do { \
141 _oldv = g_atomic_pointer_get (datalist); \
142 _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK) | (gsize) pointer); \
143 } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv)); \
144 } G_STMT_END
146 /* --- structures --- */
147 typedef struct _GDataset GDataset;
148 struct _GData
150 GData *next;
151 GQuark id;
152 gpointer data;
153 GDestroyNotify destroy_func;
156 struct _GDataset
158 gconstpointer location;
159 GData *datalist;
163 /* --- prototypes --- */
164 static inline GDataset* g_dataset_lookup (gconstpointer dataset_location);
165 static inline void g_datalist_clear_i (GData **datalist);
166 static void g_dataset_destroy_internal (GDataset *dataset);
167 static inline gpointer g_data_set_internal (GData **datalist,
168 GQuark key_id,
169 gpointer data,
170 GDestroyNotify destroy_func,
171 GDataset *dataset);
172 static void g_data_initialize (void);
173 static inline GQuark g_quark_new (gchar *string);
176 /* --- variables --- */
177 G_LOCK_DEFINE_STATIC (g_dataset_global);
178 static GHashTable *g_dataset_location_ht = NULL;
179 static GDataset *g_dataset_cached = NULL; /* should this be
180 threadspecific? */
181 G_LOCK_DEFINE_STATIC (g_quark_global);
182 static GHashTable *g_quark_ht = NULL;
183 static gchar **g_quarks = NULL;
184 static GQuark g_quark_seq_id = 0;
186 /* --- functions --- */
188 /* HOLDS: g_dataset_global_lock */
189 static inline void
190 g_datalist_clear_i (GData **datalist)
192 register GData *list;
194 /* unlink *all* items before walking their destructors
196 list = G_DATALIST_GET_POINTER (datalist);
197 G_DATALIST_SET_POINTER (datalist, NULL);
199 while (list)
201 register GData *prev;
203 prev = list;
204 list = prev->next;
206 if (prev->destroy_func)
208 G_UNLOCK (g_dataset_global);
209 prev->destroy_func (prev->data);
210 G_LOCK (g_dataset_global);
213 g_slice_free (GData, prev);
218 * g_datalist_clear:
219 * @datalist: a datalist.
221 * Frees all the data elements of the datalist. The data elements'
222 * destroy functions are called if they have been set.
224 void
225 g_datalist_clear (GData **datalist)
227 g_return_if_fail (datalist != NULL);
229 G_LOCK (g_dataset_global);
230 if (!g_dataset_location_ht)
231 g_data_initialize ();
233 while (G_DATALIST_GET_POINTER (datalist))
234 g_datalist_clear_i (datalist);
235 G_UNLOCK (g_dataset_global);
238 /* HOLDS: g_dataset_global_lock */
239 static inline GDataset*
240 g_dataset_lookup (gconstpointer dataset_location)
242 register GDataset *dataset;
244 if (g_dataset_cached && g_dataset_cached->location == dataset_location)
245 return g_dataset_cached;
247 dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
248 if (dataset)
249 g_dataset_cached = dataset;
251 return dataset;
254 /* HOLDS: g_dataset_global_lock */
255 static void
256 g_dataset_destroy_internal (GDataset *dataset)
258 register gconstpointer dataset_location;
260 dataset_location = dataset->location;
261 while (dataset)
263 if (!dataset->datalist)
265 if (dataset == g_dataset_cached)
266 g_dataset_cached = NULL;
267 g_hash_table_remove (g_dataset_location_ht, dataset_location);
268 g_slice_free (GDataset, dataset);
269 break;
272 g_datalist_clear_i (&dataset->datalist);
273 dataset = g_dataset_lookup (dataset_location);
278 * g_dataset_destroy:
279 * @dataset_location: the location identifying the dataset.
281 * Destroys the dataset, freeing all memory allocated, and calling any
282 * destroy functions set for data elements.
284 void
285 g_dataset_destroy (gconstpointer dataset_location)
287 g_return_if_fail (dataset_location != NULL);
289 G_LOCK (g_dataset_global);
290 if (g_dataset_location_ht)
292 register GDataset *dataset;
294 dataset = g_dataset_lookup (dataset_location);
295 if (dataset)
296 g_dataset_destroy_internal (dataset);
298 G_UNLOCK (g_dataset_global);
301 /* HOLDS: g_dataset_global_lock */
302 static inline gpointer
303 g_data_set_internal (GData **datalist,
304 GQuark key_id,
305 gpointer data,
306 GDestroyNotify destroy_func,
307 GDataset *dataset)
309 register GData *list;
311 list = G_DATALIST_GET_POINTER (datalist);
312 if (!data)
314 register GData *prev;
316 prev = NULL;
317 while (list)
319 if (list->id == key_id)
321 gpointer ret_data = NULL;
323 if (prev)
324 prev->next = list->next;
325 else
327 G_DATALIST_SET_POINTER (datalist, list->next);
329 /* the dataset destruction *must* be done
330 * prior to invocation of the data destroy function
332 if (!list->next && dataset)
333 g_dataset_destroy_internal (dataset);
336 /* the GData struct *must* already be unlinked
337 * when invoking the destroy function.
338 * we use (data==NULL && destroy_func!=NULL) as
339 * a special hint combination to "steal"
340 * data without destroy notification
342 if (list->destroy_func && !destroy_func)
344 G_UNLOCK (g_dataset_global);
345 list->destroy_func (list->data);
346 G_LOCK (g_dataset_global);
348 else
349 ret_data = list->data;
351 g_slice_free (GData, list);
353 return ret_data;
356 prev = list;
357 list = list->next;
360 else
362 while (list)
364 if (list->id == key_id)
366 if (!list->destroy_func)
368 list->data = data;
369 list->destroy_func = destroy_func;
371 else
373 register GDestroyNotify dfunc;
374 register gpointer ddata;
376 dfunc = list->destroy_func;
377 ddata = list->data;
378 list->data = data;
379 list->destroy_func = destroy_func;
381 /* we need to have updated all structures prior to
382 * invocation of the destroy function
384 G_UNLOCK (g_dataset_global);
385 dfunc (ddata);
386 G_LOCK (g_dataset_global);
389 return NULL;
392 list = list->next;
395 list = g_slice_new (GData);
396 list->next = G_DATALIST_GET_POINTER (datalist);
397 list->id = key_id;
398 list->data = data;
399 list->destroy_func = destroy_func;
400 G_DATALIST_SET_POINTER (datalist, list);
403 return NULL;
407 * g_dataset_id_set_data_full:
408 * @dataset_location: the location identifying the dataset.
409 * @key_id: the #GQuark id to identify the data element.
410 * @data: the data element.
411 * @destroy_func: the function to call when the data element is
412 * removed. This function will be called with the data
413 * element and can be used to free any memory allocated
414 * for it.
416 * Sets the data element associated with the given #GQuark id, and also
417 * the function to call when the data element is destroyed. Any
418 * previous data with the same key is removed, and its destroy function
419 * is called.
422 * g_dataset_set_data_full:
423 * @l: the location identifying the dataset.
424 * @k: the string to identify the data element.
425 * @d: the data element.
426 * @f: the function to call when the data element is removed. This
427 * function will be called with the data element and can be used to
428 * free any memory allocated for it.
430 * Sets the data corresponding to the given string identifier, and the
431 * function to call when the data element is destroyed.
434 * g_dataset_id_set_data:
435 * @l: the location identifying the dataset.
436 * @k: the #GQuark id to identify the data element.
437 * @d: the data element.
439 * Sets the data element associated with the given #GQuark id. Any
440 * previous data with the same key is removed, and its destroy function
441 * is called.
444 * g_dataset_set_data:
445 * @l: the location identifying the dataset.
446 * @k: the string to identify the data element.
447 * @d: the data element.
449 * Sets the data corresponding to the given string identifier.
452 * g_dataset_id_remove_data:
453 * @l: the location identifying the dataset.
454 * @k: the #GQuark id identifying the data element.
456 * Removes a data element from a dataset. The data element's destroy
457 * function is called if it has been set.
460 * g_dataset_remove_data:
461 * @l: the location identifying the dataset.
462 * @k: the string identifying the data element.
464 * Removes a data element corresponding to a string. Its destroy
465 * function is called if it has been set.
467 void
468 g_dataset_id_set_data_full (gconstpointer dataset_location,
469 GQuark key_id,
470 gpointer data,
471 GDestroyNotify destroy_func)
473 register GDataset *dataset;
475 g_return_if_fail (dataset_location != NULL);
476 if (!data)
477 g_return_if_fail (destroy_func == NULL);
478 if (!key_id)
480 if (data)
481 g_return_if_fail (key_id > 0);
482 else
483 return;
486 G_LOCK (g_dataset_global);
487 if (!g_dataset_location_ht)
488 g_data_initialize ();
490 dataset = g_dataset_lookup (dataset_location);
491 if (!dataset)
493 dataset = g_slice_new (GDataset);
494 dataset->location = dataset_location;
495 g_datalist_init (&dataset->datalist);
496 g_hash_table_insert (g_dataset_location_ht,
497 (gpointer) dataset->location,
498 dataset);
501 g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
502 G_UNLOCK (g_dataset_global);
506 * g_datalist_id_set_data_full:
507 * @datalist: a datalist.
508 * @key_id: the #GQuark to identify the data element.
509 * @data: the data element or %NULL to remove any previous element
510 * corresponding to @key_id.
511 * @destroy_func: the function to call when the data element is
512 * removed. This function will be called with the data
513 * element and can be used to free any memory allocated
514 * for it. If @data is %NULL, then @destroy_func must
515 * also be %NULL.
517 * Sets the data corresponding to the given #GQuark id, and the
518 * function to be called when the element is removed from the datalist.
519 * Any previous data with the same key is removed, and its destroy
520 * function is called.
523 * g_datalist_set_data_full:
524 * @dl: a datalist.
525 * @k: the string to identify the data element.
526 * @d: the data element, or %NULL to remove any previous element
527 * corresponding to @k.
528 * @f: the function to call when the data element is removed. This
529 * function will be called with the data element and can be used to
530 * free any memory allocated for it. If @d is %NULL, then @f must
531 * also be %NULL.
533 * Sets the data element corresponding to the given string identifier,
534 * and the function to be called when the data element is removed.
537 * g_datalist_id_set_data:
538 * @dl: a datalist.
539 * @q: the #GQuark to identify the data element.
540 * @d: the data element, or %NULL to remove any previous element
541 * corresponding to @q.
543 * Sets the data corresponding to the given #GQuark id. Any previous
544 * data with the same key is removed, and its destroy function is
545 * called.
548 * g_datalist_set_data:
549 * @dl: a datalist.
550 * @k: the string to identify the data element.
551 * @d: the data element, or %NULL to remove any previous element
552 * corresponding to @k.
554 * Sets the data element corresponding to the given string identifier.
557 * g_datalist_id_remove_data:
558 * @dl: a datalist.
559 * @q: the #GQuark identifying the data element.
561 * Removes an element, using its #GQuark identifier.
564 * g_datalist_remove_data:
565 * @dl: a datalist.
566 * @k: the string identifying the data element.
568 * Removes an element using its string identifier. The data element's
569 * destroy function is called if it has been set.
571 void
572 g_datalist_id_set_data_full (GData **datalist,
573 GQuark key_id,
574 gpointer data,
575 GDestroyNotify destroy_func)
577 g_return_if_fail (datalist != NULL);
578 if (!data)
579 g_return_if_fail (destroy_func == NULL);
580 if (!key_id)
582 if (data)
583 g_return_if_fail (key_id > 0);
584 else
585 return;
588 G_LOCK (g_dataset_global);
589 if (!g_dataset_location_ht)
590 g_data_initialize ();
592 g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
593 G_UNLOCK (g_dataset_global);
597 * g_dataset_id_remove_no_notify:
598 * @dataset_location: the location identifying the dataset.
599 * @key_id: the #GQuark ID identifying the data element.
600 * @Returns: the data previously stored at @key_id, or %NULL if none.
602 * Removes an element, without calling its destroy notification
603 * function.
606 * g_dataset_remove_no_notify:
607 * @l: the location identifying the dataset.
608 * @k: the string identifying the data element.
610 * Removes an element, without calling its destroy notifier.
612 gpointer
613 g_dataset_id_remove_no_notify (gconstpointer dataset_location,
614 GQuark key_id)
616 gpointer ret_data = NULL;
618 g_return_val_if_fail (dataset_location != NULL, NULL);
620 G_LOCK (g_dataset_global);
621 if (key_id && g_dataset_location_ht)
623 GDataset *dataset;
625 dataset = g_dataset_lookup (dataset_location);
626 if (dataset)
627 ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
629 G_UNLOCK (g_dataset_global);
631 return ret_data;
635 * g_datalist_id_remove_no_notify:
636 * @datalist: a datalist.
637 * @key_id: the #GQuark identifying a data element.
638 * @Returns: the data previously stored at @key_id, or %NULL if none.
640 * Removes an element, without calling its destroy notification
641 * function.
644 * g_datalist_remove_no_notify:
645 * @dl: a datalist.
646 * @k: the string identifying the data element.
648 * Removes an element, without calling its destroy notifier.
650 gpointer
651 g_datalist_id_remove_no_notify (GData **datalist,
652 GQuark key_id)
654 gpointer ret_data = NULL;
656 g_return_val_if_fail (datalist != NULL, NULL);
658 G_LOCK (g_dataset_global);
659 if (key_id && g_dataset_location_ht)
660 ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
661 G_UNLOCK (g_dataset_global);
663 return ret_data;
667 * g_dataset_id_get_data:
668 * @dataset_location: the location identifying the dataset.
669 * @key_id: the #GQuark id to identify the data element.
670 * @Returns: the data element corresponding to the #GQuark, or %NULL if
671 * it is not found.
673 * Gets the data element corresponding to a #GQuark.
676 * g_dataset_get_data:
677 * @l: the location identifying the dataset.
678 * @k: the string identifying the data element.
679 * @Returns: the data element corresponding to the string, or %NULL if
680 * it is not found.
682 * Gets the data element corresponding to a string.
684 gpointer
685 g_dataset_id_get_data (gconstpointer dataset_location,
686 GQuark key_id)
688 g_return_val_if_fail (dataset_location != NULL, NULL);
690 G_LOCK (g_dataset_global);
691 if (key_id && g_dataset_location_ht)
693 register GDataset *dataset;
695 dataset = g_dataset_lookup (dataset_location);
696 if (dataset)
698 register GData *list;
700 for (list = dataset->datalist; list; list = list->next)
701 if (list->id == key_id)
703 G_UNLOCK (g_dataset_global);
704 return list->data;
708 G_UNLOCK (g_dataset_global);
710 return NULL;
714 * g_datalist_id_get_data:
715 * @datalist: a datalist.
716 * @key_id: the #GQuark identifying a data element.
717 * @Returns: the data element, or %NULL if it is not found.
719 * Retrieves the data element corresponding to @key_id.
722 * g_datalist_get_data:
723 * @dl: a datalist.
724 * @k: the string identifying a data element.
725 * @Returns: the data element, or %NULL if it is not found.
727 * Gets a data element, using its string identifer. This is slower than
728 * g_datalist_id_get_data() because the string is first converted to a
729 * #GQuark.
731 gpointer
732 g_datalist_id_get_data (GData **datalist,
733 GQuark key_id)
735 gpointer data = NULL;
736 g_return_val_if_fail (datalist != NULL, NULL);
737 if (key_id)
739 register GData *list;
740 G_LOCK (g_dataset_global);
741 for (list = G_DATALIST_GET_POINTER (datalist); list; list = list->next)
742 if (list->id == key_id)
744 data = list->data;
745 break;
747 G_UNLOCK (g_dataset_global);
749 return data;
753 * GDataForeachFunc:
754 * @key_id: the #GQuark id to identifying the data element.
755 * @data: the data element.
756 * @user_data: user data passed to g_dataset_foreach().
758 * Specifies the type of function passed to g_dataset_foreach(). It is
759 * called with each #GQuark id and associated data element, together
760 * with the @user_data parameter supplied to g_dataset_foreach().
764 * g_dataset_foreach:
765 * @dataset_location: the location identifying the dataset.
766 * @func: the function to call for each data element.
767 * @user_data: user data to pass to the function.
769 * Calls the given function for each data element which is associated
770 * with the given location. Note that this function is NOT thread-safe.
771 * So unless @datalist can be protected from any modifications during
772 * invocation of this function, it should not be called.
774 void
775 g_dataset_foreach (gconstpointer dataset_location,
776 GDataForeachFunc func,
777 gpointer user_data)
779 register GDataset *dataset;
781 g_return_if_fail (dataset_location != NULL);
782 g_return_if_fail (func != NULL);
784 G_LOCK (g_dataset_global);
785 if (g_dataset_location_ht)
787 dataset = g_dataset_lookup (dataset_location);
788 G_UNLOCK (g_dataset_global);
789 if (dataset)
791 register GData *list, *next;
793 for (list = dataset->datalist; list; list = next)
795 next = list->next;
796 func (list->id, list->data, user_data);
800 else
802 G_UNLOCK (g_dataset_global);
807 * g_datalist_foreach:
808 * @datalist: a datalist.
809 * @func: the function to call for each data element.
810 * @user_data: user data to pass to the function.
812 * Calls the given function for each data element of the datalist. The
813 * function is called with each data element's #GQuark id and data,
814 * together with the given @user_data parameter. Note that this
815 * function is NOT thread-safe. So unless @datalist can be protected
816 * from any modifications during invocation of this function, it should
817 * not be called.
819 void
820 g_datalist_foreach (GData **datalist,
821 GDataForeachFunc func,
822 gpointer user_data)
824 register GData *list, *next;
826 g_return_if_fail (datalist != NULL);
827 g_return_if_fail (func != NULL);
829 for (list = G_DATALIST_GET_POINTER (datalist); list; list = next)
831 next = list->next;
832 func (list->id, list->data, user_data);
837 * g_datalist_init:
838 * @datalist: a pointer to a pointer to a datalist.
840 * Resets the datalist to %NULL. It does not free any memory or call
841 * any destroy functions.
843 void
844 g_datalist_init (GData **datalist)
846 g_return_if_fail (datalist != NULL);
848 g_atomic_pointer_set (datalist, NULL);
852 * g_datalist_set_flags:
853 * @datalist: pointer to the location that holds a list
854 * @flags: the flags to turn on. The values of the flags are
855 * restricted by %G_DATALIST_FLAGS_MASK (currently
856 * 3; giving two possible boolean flags).
857 * A value for @flags that doesn't fit within the mask is
858 * an error.
860 * Turns on flag values for a data list. This function is used
861 * to keep a small number of boolean flags in an object with
862 * a data list without using any additional space. It is
863 * not generally useful except in circumstances where space
864 * is very tight. (It is used in the base #GObject type, for
865 * example.)
867 * Since: 2.8
869 void
870 g_datalist_set_flags (GData **datalist,
871 guint flags)
873 gpointer oldvalue;
874 g_return_if_fail (datalist != NULL);
875 g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
879 oldvalue = g_atomic_pointer_get (datalist);
881 while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, oldvalue,
882 (gpointer) ((gsize) oldvalue | flags)));
886 * g_datalist_unset_flags:
887 * @datalist: pointer to the location that holds a list
888 * @flags: the flags to turn off. The values of the flags are
889 * restricted by %G_DATALIST_FLAGS_MASK (currently
890 * 3: giving two possible boolean flags).
891 * A value for @flags that doesn't fit within the mask is
892 * an error.
894 * Turns off flag values for a data list. See g_datalist_unset_flags()
896 * Since: 2.8
898 void
899 g_datalist_unset_flags (GData **datalist,
900 guint flags)
902 gpointer oldvalue;
903 g_return_if_fail (datalist != NULL);
904 g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
908 oldvalue = g_atomic_pointer_get (datalist);
910 while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, oldvalue,
911 (gpointer) ((gsize) oldvalue & ~(gsize) flags)));
915 * g_datalist_get_flags:
916 * @datalist: pointer to the location that holds a list
918 * Gets flags values packed in together with the datalist.
919 * See g_datalist_set_flags().
921 * Return value: the flags of the datalist
923 * Since: 2.8
925 guint
926 g_datalist_get_flags (GData **datalist)
928 g_return_val_if_fail (datalist != NULL, 0);
930 return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */
933 /* HOLDS: g_dataset_global_lock */
934 static void
935 g_data_initialize (void)
937 g_return_if_fail (g_dataset_location_ht == NULL);
939 g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
940 g_dataset_cached = NULL;
944 * SECTION: quarks
945 * @title: Quarks
946 * @short_description: a 2-way association between a string and a
947 * unique integer identifier
949 * Quarks are associations between strings and integer identifiers.
950 * Given either the string or the #GQuark identifier it is possible to
951 * retrieve the other.
953 * Quarks are used for both <link
954 * linkend="glib-datasets">Datasets</link> and <link
955 * linkend="glib-keyed-data-lists">Keyed Data Lists</link>.
957 * To create a new quark from a string, use g_quark_from_string() or
958 * g_quark_from_static_string().
960 * To find the string corresponding to a given #GQuark, use
961 * g_quark_to_string().
963 * To find the #GQuark corresponding to a given string, use
964 * g_quark_try_string().
966 * Another use for the string pool maintained for the quark functions
967 * is string interning, using g_intern_string() or
968 * g_intern_static_string(). An interned string is a canonical
969 * representation for a string. One important advantage of interned
970 * strings is that they can be compared for equality by a simple
971 * pointer comparision, rather than using strcmp().
975 * GQuark:
977 * A GQuark is a non-zero integer which uniquely identifies a
978 * particular string. A GQuark value of zero is associated to %NULL.
982 * g_quark_try_string:
983 * @string: a string.
984 * @Returns: the #GQuark associated with the string, or 0 if @string is
985 * %NULL or there is no #GQuark associated with it.
987 * Gets the #GQuark associated with the given string, or 0 if string is
988 * %NULL or it has no associated #GQuark.
990 * If you want the GQuark to be created if it doesn't already exist,
991 * use g_quark_from_string() or g_quark_from_static_string().
993 GQuark
994 g_quark_try_string (const gchar *string)
996 GQuark quark = 0;
997 g_return_val_if_fail (string != NULL, 0);
999 G_LOCK (g_quark_global);
1000 if (g_quark_ht)
1001 quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
1002 G_UNLOCK (g_quark_global);
1004 return quark;
1007 #define QUARK_STRING_BLOCK_SIZE (4096 - sizeof (gsize))
1008 static char *quark_block = NULL;
1009 static int quark_block_offset = 0;
1011 /* HOLDS: g_quark_global_lock */
1012 static char *
1013 quark_strdup(const gchar *string)
1015 gchar *copy;
1016 gsize len;
1018 len = strlen (string) + 1;
1020 /* For strings longer than half the block size, fall back
1021 to strdup so that we fill our blocks at least 50%. */
1022 if (len > QUARK_STRING_BLOCK_SIZE / 2)
1023 return g_strdup (string);
1025 if (quark_block == NULL ||
1026 QUARK_STRING_BLOCK_SIZE - quark_block_offset < len)
1028 quark_block = g_malloc (QUARK_STRING_BLOCK_SIZE);
1029 quark_block_offset = 0;
1032 copy = quark_block + quark_block_offset;
1033 memcpy (copy, string, len);
1034 quark_block_offset += len;
1036 return copy;
1039 /* HOLDS: g_quark_global_lock */
1040 static inline GQuark
1041 g_quark_from_string_internal (const gchar *string,
1042 gboolean duplicate)
1044 GQuark quark = 0;
1046 if (g_quark_ht)
1047 quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
1049 if (!quark)
1051 quark = g_quark_new (duplicate ? quark_strdup (string) : (gchar *)string);
1052 TRACE(GLIB_QUARK_NEW(string, quark));
1055 return quark;
1059 * g_quark_from_string:
1060 * @string: a string.
1061 * @Returns: the #GQuark identifying the string, or 0 if @string is
1062 * %NULL.
1064 * Gets the #GQuark identifying the given string. If the string does
1065 * not currently have an associated #GQuark, a new #GQuark is created,
1066 * using a copy of the string.
1068 GQuark
1069 g_quark_from_string (const gchar *string)
1071 GQuark quark;
1073 if (!string)
1074 return 0;
1076 G_LOCK (g_quark_global);
1077 quark = g_quark_from_string_internal (string, TRUE);
1078 G_UNLOCK (g_quark_global);
1080 return quark;
1084 * g_quark_from_static_string:
1085 * @string: a string.
1086 * @Returns: the #GQuark identifying the string, or 0 if @string is
1087 * %NULL.
1089 * Gets the #GQuark identifying the given (static) string. If the
1090 * string does not currently have an associated #GQuark, a new #GQuark
1091 * is created, linked to the given string.
1093 * Note that this function is identical to g_quark_from_string() except
1094 * that if a new #GQuark is created the string itself is used rather
1095 * than a copy. This saves memory, but can only be used if the string
1096 * will <emphasis>always</emphasis> exist. It can be used with
1097 * statically allocated strings in the main program, but not with
1098 * statically allocated memory in dynamically loaded modules, if you
1099 * expect to ever unload the module again (e.g. do not use this
1100 * function in GTK+ theme engines).
1102 GQuark
1103 g_quark_from_static_string (const gchar *string)
1105 GQuark quark;
1107 if (!string)
1108 return 0;
1110 G_LOCK (g_quark_global);
1111 quark = g_quark_from_string_internal (string, FALSE);
1112 G_UNLOCK (g_quark_global);
1114 return quark;
1118 * g_quark_to_string:
1119 * @quark: a #GQuark.
1120 * @Returns: the string associated with the #GQuark.
1122 * Gets the string associated with the given #GQuark.
1124 G_CONST_RETURN gchar*
1125 g_quark_to_string (GQuark quark)
1127 gchar* result = NULL;
1129 G_LOCK (g_quark_global);
1130 if (quark < g_quark_seq_id)
1131 result = g_quarks[quark];
1132 G_UNLOCK (g_quark_global);
1134 return result;
1137 /* HOLDS: g_quark_global_lock */
1138 static inline GQuark
1139 g_quark_new (gchar *string)
1141 GQuark quark;
1143 if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
1144 g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
1145 if (!g_quark_ht)
1147 g_assert (g_quark_seq_id == 0);
1148 g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
1149 g_quarks[g_quark_seq_id++] = NULL;
1152 quark = g_quark_seq_id++;
1153 g_quarks[quark] = string;
1154 g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
1156 return quark;
1160 * g_intern_string:
1161 * @string: a string
1163 * Returns a canonical representation for @string. Interned strings can
1164 * be compared for equality by comparing the pointers, instead of using strcmp().
1166 * Returns: a canonical representation for the string
1168 * Since: 2.10
1170 G_CONST_RETURN gchar*
1171 g_intern_string (const gchar *string)
1173 const gchar *result;
1174 GQuark quark;
1176 if (!string)
1177 return NULL;
1179 G_LOCK (g_quark_global);
1180 quark = g_quark_from_string_internal (string, TRUE);
1181 result = g_quarks[quark];
1182 G_UNLOCK (g_quark_global);
1184 return result;
1188 * g_intern_static_string:
1189 * @string: a static string
1191 * Returns a canonical representation for @string. Interned strings can
1192 * be compared for equality by comparing the pointers, instead of using strcmp().
1193 * g_intern_static_string() does not copy the string, therefore @string must
1194 * not be freed or modified.
1196 * Returns: a canonical representation for the string
1198 * Since: 2.10
1200 G_CONST_RETURN gchar*
1201 g_intern_static_string (const gchar *string)
1203 GQuark quark;
1204 const gchar *result;
1206 if (!string)
1207 return NULL;
1209 G_LOCK (g_quark_global);
1210 quark = g_quark_from_string_internal (string, FALSE);
1211 result = g_quarks[quark];
1212 G_UNLOCK (g_quark_global);
1214 return result;