1 /*
2 * Copyright (C) 2004-2005 Vadim Berezniker
3 * http://www.kryptolus.com
4 *
5 * This Program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2, or (at your option)
8 * any later version.
9 *
10 * This Program 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
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with GNU Make; see the file COPYING. If not, write to
17 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 */
21
22 #include "stdafx.h"
23
24 #include "common.h"
25 /*
26 * This is just a wrapper around the GHashTable except this class allows easy iteration of keys in the hash.
27 * GHashTable only makes it possible through a callback, which I find a bit annoying.
28 *
29 * NOTE: Because this is just a wrapper class around GHashTable, only pointers can be stored inside.
30 */
31
32 /*
33 * Creates a new hash with the given hashing and comparison functions.
34 * See glib documentation for GHashTable for more info.
35 */
36 template <class T, class V>
kryHash(GHashFunc hash_func,GEqualFunc key_equal_func)37 kryHash<T,V>::kryHash(GHashFunc hash_func, GEqualFunc key_equal_func)
38 {
39 this->m_hash = g_hash_table_new_full(hash_func, key_equal_func, NULL, NULL);
40 this->m_equalFunc = key_equal_func;
41 }
42
43 /*
44 * Creates a new hash with the given hashing and comparison functions and the given key/value destroy functions.
45 * See glib documentation for GHashTable for more info.
46 */
47 template <class T, class V>
kryHash(GHashFunc hash_func,GEqualFunc key_equal_func,GDestroyNotify key_destroy_func,GDestroyNotify value_destroy_func)48 kryHash<T,V>::kryHash(GHashFunc hash_func, GEqualFunc key_equal_func, GDestroyNotify key_destroy_func, GDestroyNotify value_destroy_func)
49 {
50 this->m_hash = g_hash_table_new_full(hash_func, key_equal_func, key_destroy_func, value_destroy_func);
51 this->m_equalFunc = key_equal_func;
52 }
53
54 /*
55 * Destroys the data stored in the hash.
56 * If key and/or value destroy functions were specified they are called on each key/value.
57 */
58 template <class T, class V>
~kryHash()59 kryHash<T,V>::~kryHash()
60 {
61 g_hash_table_destroy(this->m_hash);
62 }
63
64 /*
65 * Returns an Iterator for the keys inside the hash.
66 */
67 template <class T, class V>
GetKeysIterator(kryListIterator<T> * iter)68 void kryHash<T,V>::GetKeysIterator(kryListIterator<T> *iter)
69 {
70 this->m_keys.GetIterator(iter);
71 }
72
73 /*
74 * Returns the number of keys in the hash.
75 */
76 template <class T, class V>
GetKeyCount()77 int kryHash<T, V>::GetKeyCount()
78 {
79 return this->m_keys.GetLength();
80 }
81
82 /*
83 * Looks up the given key and returns any associated data.
84 *
85 * Returns NULL if the key was not found.
86 */
87 template <class T, class V>
Lookup(T key)88 V kryHash<T,V>::Lookup(T key)
89 {
90 return (V) (long) g_hash_table_lookup(this->m_hash, (gconstpointer) key);
91 }
92
93 /*
94 * Looks up a key and removes any associated data.
95 */
96 template <class T, class V>
Remove(T key)97 void kryHash<T,V>::Remove(T key)
98 {
99 /*
100 * Remove the key from the list of keys if it exists there
101 * We must remove it from this list first because the key might
102 * get destroyed upon removal from the hash
103 */
104 if(g_hash_table_lookup(this->m_hash, (gconstpointer) key))
105 this->m_keys.Remove(key, this->m_equalFunc);
106
107 g_hash_table_remove(this->m_hash, (gconstpointer) key);
108 }
109
110 /*
111 * Adds a key/value pair to the hash.
112 * If the key is already in the hash, both the key and the value within the hash are replaced
113 * with the given ones.
114 */
115 template <class T, class V>
Replace(T key,V value)116 void kryHash<T,V>::Replace(T key, V value)
117 {
118 /* If it's a new key, we must add it to our keys list */
119 if(!this->Lookup(key))
120 {
121 this->m_keys.Append(key);
122 }
123 /* If it's not, we replace the stored key with the given one. */
124 else
125 {
126 this->m_keys.Remove(key, this->m_equalFunc);
127 this->m_keys.Append(key);
128 }
129
130 g_hash_table_replace(this->m_hash, (gpointer) key, (gpointer) value);
131 }
132
133 /*
134 * Inserts a key/value pair into the hash.
135 * If the key is already in the hash, the value is replaced with the given value.
136 * The key is not replaced.
137 */
138 template <class T, class V>
Insert(T key,V value)139 void kryHash<T,V>::Insert(T key, V value)
140 {
141 /* If this is a new key, we must add it to our keys list */
142 if(!this->Lookup(key))
143 this->m_keys.Append(key);
144
145 g_hash_table_insert(this->m_hash, (gpointer) key, (gpointer) value);
146 }
147
148 template class kryHash<char *, struct pref *>;
149 template class kryHash<char *, char *>;
150 template class kryHash<char *, kryStyle *>;
151 template class kryHash<char *, int>;
152 template class kryHash<int, kryColor*>;
153 template class kryHash<void *, struct alloc_info *>;
154 template class kryHash<char *, kryPrefSection *>;
155 template class kryHash<char *, kryPrefValue *>;
156 template class kryHash<char *, struct style_iconv_map *>;
157