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/gboxed.h"
22 #include "gobject/gvalue.h"
23 #include "gobject/gvaluetypes.h"
27 struct _GAllocator /* from gmem.c */
35 GtkTreeDataList *free_nodes;
39 G_LOCK_DEFINE_STATIC (current_allocator);
40 static GAllocator *current_allocator = NULL;
42 /* HOLDS: current_allocator_lock */
44 gtk_tree_data_list_validate_allocator (GAllocator *allocator)
46 g_return_if_fail (allocator != NULL);
47 g_return_if_fail (allocator->is_unused == TRUE);
49 if (allocator->type != G_ALLOCATOR_NODE)
51 allocator->type = G_ALLOCATOR_NODE;
52 if (allocator->mem_chunk)
54 g_mem_chunk_destroy (allocator->mem_chunk);
55 allocator->mem_chunk = NULL;
59 if (!allocator->mem_chunk)
61 allocator->mem_chunk = g_mem_chunk_new (allocator->name,
62 sizeof (GtkTreeDataList),
63 sizeof (GtkTreeDataList) * allocator->n_preallocs,
65 allocator->free_nodes = NULL;
68 allocator->is_unused = FALSE;
72 _gtk_tree_data_list_push_allocator (GAllocator *allocator)
74 G_LOCK (current_allocator);
75 gtk_tree_data_list_validate_allocator ( allocator );
76 allocator->last = current_allocator;
77 current_allocator = allocator;
78 G_UNLOCK (current_allocator);
82 _gtk_tree_data_list_pop_allocator (void)
84 G_LOCK (current_allocator);
85 if (current_allocator)
87 GAllocator *allocator;
89 allocator = current_allocator;
90 current_allocator = allocator->last;
91 allocator->last = NULL;
92 allocator->is_unused = TRUE;
94 G_UNLOCK (current_allocator);
98 _gtk_tree_data_list_alloc (void)
100 GtkTreeDataList *list;
102 G_LOCK (current_allocator);
103 if (!current_allocator)
105 GAllocator *allocator = g_allocator_new ("GTK+ default GtkTreeDataList allocator",
107 gtk_tree_data_list_validate_allocator (allocator);
108 allocator->last = NULL;
109 current_allocator = allocator;
111 if (!current_allocator->free_nodes)
112 list = g_chunk_new (GtkTreeDataList, current_allocator->mem_chunk);
115 list = current_allocator->free_nodes;
116 current_allocator->free_nodes = list->next;
118 G_UNLOCK (current_allocator);
124 _gtk_tree_data_list_free (GtkTreeDataList *list,
125 GType *column_headers)
127 GtkTreeDataList *tmp;
130 for (tmp = list; tmp; tmp = tmp->next)
132 switch (column_headers [i])
135 g_free ((gchar *) tmp->data.v_pointer);
138 g_object_unref (G_OBJECT (tmp->data.v_pointer));
146 G_LOCK (current_allocator);
147 list->next = current_allocator->free_nodes;
148 current_allocator->free_nodes = list;
149 G_UNLOCK (current_allocator);
153 _gtk_tree_data_list_node_to_value (GtkTreeDataList *list,
157 g_value_init (value, type);
162 g_value_set_boolean (value, (gboolean) list->data.v_int);
165 g_value_set_char (value, list->data.v_char);
168 g_value_set_uchar (value, list->data.v_uchar);
171 g_value_set_int (value, list->data.v_int);
174 g_value_set_uint (value, list->data.v_uint);
177 g_value_set_pointer (value, (gpointer) list->data.v_pointer);
180 g_value_set_float (value, list->data.v_float);
183 g_value_set_string (value, (gchar *) list->data.v_pointer);
187 if (g_type_is_a (type, G_TYPE_OBJECT))
188 g_value_set_object (value, (GObject *) list->data.v_pointer);
189 else if (g_type_is_a (type, G_TYPE_BOXED))
190 g_value_set_boxed (value, (GObject *) list->data.v_pointer);
192 g_warning ("Unsupported type (%s) retrieved.", g_type_name (value->g_type));
198 _gtk_tree_data_list_value_to_node (GtkTreeDataList *list,
201 switch (value->g_type)
204 list->data.v_int = g_value_get_boolean (value);
207 list->data.v_char = g_value_get_char (value);
210 list->data.v_uchar = g_value_get_uchar (value);
213 list->data.v_int = g_value_get_int (value);
216 list->data.v_uint = g_value_get_uint (value);
219 list->data.v_pointer = g_value_get_pointer (value);
222 list->data.v_float = g_value_get_float (value);
225 list->data.v_pointer = g_value_dup_string (value);
228 if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_OBJECT))
229 list->data.v_pointer = g_value_dup_object (value);
230 else if (g_type_is_a (G_VALUE_TYPE (value), G_TYPE_BOXED))
231 list->data.v_pointer = g_value_dup_boxed (value);
233 g_warning ("Unsupported type (%s) stored.", g_type_name (value->g_type));
239 _gtk_tree_data_list_node_copy (GtkTreeDataList *list,
242 GtkTreeDataList *new_list;
244 g_return_val_if_fail (list != NULL, NULL);
246 new_list = _gtk_tree_data_list_alloc ();
247 new_list->next = NULL;
258 new_list->data = list->data;
262 new_list->data.v_pointer = g_strdup (list->data.v_pointer);
266 if (g_type_is_a (type, G_TYPE_OBJECT))
268 new_list->data.v_pointer = list->data.v_pointer;
269 if (new_list->data.v_pointer)
270 g_object_ref (G_OBJECT (new_list->data.v_pointer));
272 else if (g_type_is_a (type, G_TYPE_BOXED))
274 if (list->data.v_pointer)
275 new_list->data.v_pointer = g_boxed_copy (type, list->data.v_pointer);
277 new_list->data.v_pointer = NULL;
280 g_warning ("Unsupported node type (%s) copied.", g_type_name (type));