2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include "gtktreedatalist.h"
21 #include "gobject/gvalue.h"
22 #include "gobject/gvaluetypes.h"
26 struct _GAllocator /* from gmem.c */
34 GtkTreeDataList *free_nodes;
38 G_LOCK_DEFINE_STATIC (current_allocator);
39 static GAllocator *current_allocator = NULL;
41 /* HOLDS: current_allocator_lock */
43 gtk_tree_data_list_validate_allocator (GAllocator *allocator)
45 g_return_if_fail (allocator != NULL);
46 g_return_if_fail (allocator->is_unused == TRUE);
48 if (allocator->type != G_ALLOCATOR_NODE)
50 allocator->type = G_ALLOCATOR_NODE;
51 if (allocator->mem_chunk)
53 g_mem_chunk_destroy (allocator->mem_chunk);
54 allocator->mem_chunk = NULL;
58 if (!allocator->mem_chunk)
60 allocator->mem_chunk = g_mem_chunk_new (allocator->name,
61 sizeof (GtkTreeDataList),
62 sizeof (GtkTreeDataList) * allocator->n_preallocs,
64 allocator->free_nodes = NULL;
67 allocator->is_unused = FALSE;
71 _gtk_tree_data_list_push_allocator (GAllocator *allocator)
73 G_LOCK (current_allocator);
74 gtk_tree_data_list_validate_allocator ( allocator );
75 allocator->last = current_allocator;
76 current_allocator = allocator;
77 G_UNLOCK (current_allocator);
81 _gtk_tree_data_list_pop_allocator (void)
83 G_LOCK (current_allocator);
84 if (current_allocator)
86 GAllocator *allocator;
88 allocator = current_allocator;
89 current_allocator = allocator->last;
90 allocator->last = NULL;
91 allocator->is_unused = TRUE;
93 G_UNLOCK (current_allocator);
97 _gtk_tree_data_list_alloc (void)
99 GtkTreeDataList *list;
101 G_LOCK (current_allocator);
102 if (!current_allocator)
104 GAllocator *allocator = g_allocator_new ("GTK+ default GtkTreeDataList allocator",
106 gtk_tree_data_list_validate_allocator (allocator);
107 allocator->last = NULL;
108 current_allocator = allocator;
110 if (!current_allocator->free_nodes)
111 list = g_chunk_new (GtkTreeDataList, current_allocator->mem_chunk);
114 list = current_allocator->free_nodes;
115 current_allocator->free_nodes = list->next;
117 G_UNLOCK (current_allocator);
123 _gtk_tree_data_list_free (GtkTreeDataList *list,
124 GType *column_headers)
126 GtkTreeDataList *tmp;
129 for (tmp = list; tmp; tmp = tmp->next)
131 switch (column_headers [i])
134 g_free ((gchar *) tmp->data.v_pointer);
137 g_object_unref (G_OBJECT (tmp->data.v_pointer));
145 G_LOCK (current_allocator);
146 list->next = current_allocator->free_nodes;
147 current_allocator->free_nodes = list;
148 G_UNLOCK (current_allocator);
152 _gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
156 g_value_init (value, type);
161 g_value_set_boolean (value, (gboolean) list->data.v_int);
164 g_value_set_char (value, list->data.v_char);
167 g_value_set_uchar (value, list->data.v_uchar);
170 g_value_set_int (value, list->data.v_int);
173 g_value_set_uint (value, list->data.v_uint);
176 g_value_set_pointer (value, (gpointer) list->data.v_pointer);
179 g_value_set_float (value, list->data.v_float);
182 g_value_set_string (value, (gchar *) list->data.v_pointer);
186 if (g_type_is_a (type, G_TYPE_OBJECT))
187 g_value_set_object (value, (GObject *) list->data.v_pointer);
188 else if (g_type_is_a (type, G_TYPE_BOXED))
189 g_value_set_boxed (value, (GObject *) list->data.v_pointer);
191 g_warning ("Unsupported type (%s) retrieved.", g_type_name (value->g_type));
197 _gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
200 switch (value->g_type)
203 list->data.v_int = g_value_get_boolean (value);
206 list->data.v_char = g_value_get_char (value);
209 list->data.v_uchar = g_value_get_uchar (value);
212 list->data.v_int = g_value_get_int (value);
215 list->data.v_uint = g_value_get_uint (value);
218 list->data.v_pointer = g_value_get_pointer (value);
221 list->data.v_float = g_value_get_float (value);
224 list->data.v_pointer = g_value_dup_string (value);
227 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT))
228 list->data.v_pointer = g_value_dup_object (value);
229 else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_BOXED))
230 list->data.v_pointer = g_value_dup_boxed (value);
232 g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
238 _gtk_tree_data_list_node_copy (GtkTreeDataList *list,
241 GtkTreeDataList *new_list;
243 g_return_val_if_fail (list != NULL, NULL);
245 new_list = _gtk_tree_data_list_alloc ();
246 new_list->next = NULL;
257 new_list->data = list->data;
261 new_list->data.v_pointer = g_strdup (list->data.v_pointer);
265 if (g_type_is_a (type, G_TYPE_OBJECT))
267 new_list->data.v_pointer = list->data.v_pointer;
268 if (new_list->data.v_pointer)
269 g_object_ref (G_OBJECT (new_list->data.v_pointer));
271 else if (g_type_is_a (type, G_TYPE_BOXED))
273 if (list->data.v_pointer)
274 new_list->data.v_pointer = g_boxed_copy (type, list->data.v_pointer);
276 new_list->data.v_pointer = NULL;
279 g_warning ("Unsupported node type (%s) copied.", g_type_name (type));