1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 Copyright (C) 2004 Sebastien Granjoux
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Store all project property values (= just the name and the value
23 * without other high level information like the associated widget)
25 * The property values are stored independently because we want to keep
26 * all values entered by the user even if it goes back in the wizard and
27 * regenerate all properties.
28 * Moreover it removes dependencies between the installer part and the
29 * properties. The installer part could work with the values only.
30 *---------------------------------------------------------------------------*/
38 /*---------------------------------------------------------------------------*/
40 #define STRING_CHUNK_SIZE 256
42 /*---------------------------------------------------------------------------*/
44 /* This stores all the values. It's basically an hash table with a string
45 * and a mem chunk to allocate all memories inside the object.
46 * After adding a new property, there is no way to remove it, but you can
47 * use the tag to mark it as obsolete */
52 GStringChunk
* string_pool
;
53 GMemChunk
* value_pool
;
56 /* One property value, so just a name and a value plus a tag !
57 * The tag is defined in the header file, but is not really used in this code */
66 /* Creation and Destruction
67 *---------------------------------------------------------------------------*/
70 npw_value_heap_initialize (NPWValueHeap
* this)
72 this->string_pool
= g_string_chunk_new (STRING_CHUNK_SIZE
);
73 this->value_pool
= g_mem_chunk_new ("value pool", sizeof(NPWValue
), (STRING_CHUNK_SIZE
/ 4) * sizeof(NPWValue
), G_ALLOC_ONLY
);
74 this->hash
= g_hash_table_new (g_str_hash
, g_str_equal
);
80 npw_value_heap_deinitialize (NPWValueHeap
* this)
82 g_string_chunk_free (this->string_pool
);
83 g_mem_chunk_destroy (this->value_pool
);
84 g_hash_table_destroy (this->hash
);
89 npw_value_heap_new (void)
93 this = g_new0 (NPWValueHeap
, 1);
94 return npw_value_heap_initialize (this);
98 npw_value_heap_free (NPWValueHeap
* this)
101 g_return_if_fail (this != NULL
);
103 npw_value_heap_deinitialize (this);
107 /* Find a value or list all values
108 *---------------------------------------------------------------------------*/
110 /* Return key corresponding to name, create key if it doesn't exist */
113 npw_value_heap_find_value (NPWValueHeap
* this, const gchar
* name
)
117 if (!g_hash_table_lookup_extended (this->hash
, name
, NULL
, (gpointer
)&node
))
121 node
= g_chunk_new (NPWValue
, this->value_pool
);
122 new_name
= g_string_chunk_insert (this->string_pool
, name
);
123 node
->name
= new_name
;
124 node
->tag
= NPW_EMPTY_VALUE
;
126 g_hash_table_insert (this->hash
, new_name
, node
);
132 typedef struct _NPWValueHeapForeachValueData
134 NPWValueHeapForeachFunc func
;
136 } NPWValueHeapForeachValueData
;
139 cb_value_heap_foreach_value (gpointer key
, gpointer value
, gpointer user_data
)
141 NPWValueHeapForeachValueData
* data
= (NPWValueHeapForeachValueData
*)user_data
;
142 NPWValue
* node
= (NPWValue
*)value
;
144 (data
->func
)(node
->name
, node
->value
, node
->tag
, data
->data
);
148 npw_value_heap_foreach_value (const NPWValueHeap
* this, NPWValueHeapForeachFunc func
, gpointer user_data
)
150 NPWValueHeapForeachValueData data
;
153 data
.data
= user_data
;
154 g_hash_table_foreach (this->hash
, cb_value_heap_foreach_value
, &data
);
157 /* Access value attributes
158 *---------------------------------------------------------------------------*/
161 npw_value_heap_get_name (const NPWValueHeap
* this, const NPWValue
* node
)
163 g_return_val_if_fail (node
!= NULL
, NULL
);
168 /* set new value, return FALSE if value has not changed */
171 npw_value_heap_set_value (NPWValueHeap
* this, NPWValue
* node
, const gchar
* value
, NPWValueTag tag
)
173 gboolean change
= FALSE
;
175 g_return_val_if_fail (node
!= NULL
, FALSE
);
177 if (tag
== NPW_EMPTY_VALUE
)
179 if (node
->tag
!= NPW_EMPTY_VALUE
)
181 node
->tag
= NPW_EMPTY_VALUE
;
190 if (node
->value
!= NULL
)
198 if ((node
->value
== NULL
) || (strcmp (node
->value
, value
) != 0))
200 node
->value
= g_string_chunk_insert (this->string_pool
, value
);
207 /* remove valid tag if value change */
208 node
->tag
&= ~NPW_VALID_VALUE
;
210 else if ((tag
& NPW_VALID_VALUE
) != (node
->tag
& NPW_VALID_VALUE
))
212 /* Changing valid tag count as a change */
215 node
->tag
&= NPW_VALID_VALUE
;
223 npw_value_heap_get_value (const NPWValueHeap
* this, const NPWValue
* node
)
225 g_return_val_if_fail (node
!= NULL
, NULL
);
227 return node
->tag
== NPW_EMPTY_VALUE
? NULL
: node
->value
;
231 npw_value_heap_get_tag (const NPWValueHeap
* this, const NPWValue
* node
)
233 g_return_val_if_fail (node
!= NULL
, NPW_EMPTY_VALUE
);