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