1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include "../base/defines.h"
11
12
13
14 //////////////////////////////////////////////////////////////////////////////
15
16 #include <string.h>
17
18 #include "DXStrings.h"
19 #include "Dictionary.h"
20 #include "Definition.h"
21 #include "ListIterator.h"
22 #include "DictionaryIterator.h"
23
24 #ifndef STRCMP
25 #ifdef NON_NULL_STRCMP
26 #define STRCMP(a,b) ((a) ? ((b) ? strcmp(a,b) : strcmp(a,"")) : \
27 ((b) ? strcmp("",b) : 0))
28 #else
29 #define STRCMP(a,b) strcmp(a,b)
30 #endif
31 #endif
32
33 #if 0 /* Never used */
34 //
35 // Determine if two symbol values entries have the same name.
36 //
37 static boolean _EqualName(const void *sv1, const void *sv2)
38 {
39 return ((DictionaryEntry*)sv1)->name == ((DictionaryEntry*)sv2)->name;
40 }
41 #endif
42
43 //
44 // Determine if two symbol values entries have the same name.
45 //
_EqualValue(const void * sv1,const void * sv2)46 static boolean _EqualValue(const void *sv1, const void *sv2)
47 {
48 return ((DictionaryEntry*)sv1)->definition ==
49 ((DictionaryEntry*)sv2)->definition;
50 }
51
Dictionary(boolean sorted,boolean privateSymbols)52 Dictionary::Dictionary(boolean sorted, boolean privateSymbols )
53 {
54 this->isSorted = sorted;
55 if (privateSymbols)
56 this->symbolManager = new SymbolManager;
57 else
58 this->symbolManager = NULL;
59 }
60 //
61 // When we destroy 'this' we must a free the DictionaryEntries
62 //
~Dictionary()63 Dictionary::~Dictionary()
64 {
65 this->clear();
66 if (this->symbolManager)
67 delete this->symbolManager;
68 }
69
clear()70 void Dictionary::clear()
71 {
72 DictionaryEntry *de;
73 ListIterator iterator(*this);
74
75 while ((de=(DictionaryEntry*)iterator.getNext()))
76 delete de;
77 this->List::clear();
78
79 // FIXME: should be clear the local symbol table.
80 }
81
82 //
83 // Retrieve the symbol table associated with this instance.
84 // By default, see the constructor, we use the global static symbol
85 // table, but can use one local to this instance if desired.
86 // This table holds a list of symbol/string pairs and is used to
87 // generate keys.
88 //
getSymbolManager()89 SymbolManager *Dictionary::getSymbolManager()
90 {
91 if (this->symbolManager)
92 return this->symbolManager;
93 else
94 return theSymbolManager;
95 }
96 //
97 // Get the Nth definition in the dictionary, indexed from 1.
98 //
getDefinition(int n)99 const void *Dictionary::getDefinition(int n)
100 {
101 DictionaryEntry *de = (DictionaryEntry*)(this->getElement(n));
102 return de? de->definition: NUL(void*);
103 }
104 //
105 // Get the symbol for the Nth definition.
106 //
getSymbol(int n)107 Symbol Dictionary::getSymbol(int n)
108 {
109 DictionaryEntry *de = (DictionaryEntry*)(this->getElement(n));
110 return de ? de->name : 0;
111 }
112 //
113 // Get the string key for the n'th definition.
114 //
getStringKey(int n)115 const char *Dictionary::getStringKey(int n)
116 {
117 DictionaryEntry *de = (DictionaryEntry*)(this->getElement(n));
118 return de ? this->getSymbolManager()->getSymbolString(de->name) :
119 NUL(const char*);
120 }
121
getPosition(Symbol s)122 int Dictionary::getPosition(Symbol s)
123 {
124 DictionaryEntry *de;
125 ListIterator iterator(*this);
126 int pos = 0;
127
128 while ((de=(DictionaryEntry*)iterator.getNext())) {
129 pos++;
130 if (de->name == s)
131 return pos;
132 }
133 return 0;
134 }
135 //
136 // Add an instance of class Definition or class derived from Definition to
137 // this dictionary. Definitions are inserted in alphabetic order.
138 // If a definition already exists for the given name then fail.
139 // FIXME: should we be adding a copy of definition instead of definition.
140 //
addDefinition(const char * name,const void * def)141 boolean Dictionary::addDefinition(const char *name, const void *def)
142 {
143 const char *str;
144 int r, pos;
145 Symbol s;
146 DictionaryEntry *de, *newde;
147 ListIterator iterator(*this);
148 SymbolManager *sm = getSymbolManager();
149
150
151 if (this->isSorted) {
152 pos = 1;
153 while ((de=(DictionaryEntry*)iterator.getNext())) {
154 str = sm->getSymbolString(de->name);
155 ASSERT(str);
156 r = STRCMP(str, name);
157 if (r == 0)
158 return FALSE;
159 else if (r >= 0)
160 break;
161 pos++;
162 }
163 } else {
164 pos = 0;
165 }
166 s = sm->registerSymbol(name);
167 newde = new DictionaryEntry(s,(void*)def);
168 if (pos == 0)
169 return this->appendElement(newde);
170 else
171 return this->insertElement(newde, pos);
172 }
addDefinition(Symbol name,const void * def)173 boolean Dictionary::addDefinition(Symbol name, const void *def)
174 {
175 const char *str;
176 SymbolManager *sm = this->getSymbolManager();
177
178 str = sm->getSymbolString(name);
179 if (!str)
180 return FALSE;
181
182 return this->addDefinition(str, def);
183 }
184 //
185 // Replace the current element by the new one.
186 //
replaceDefinition(const char * name,const void * def,void ** v)187 boolean Dictionary::replaceDefinition(const char *name,
188 const void *def, void **v)
189 {
190 void *old_def = this->removeDefinition(name);
191 if (v)
192 *v = old_def;
193 this->addDefinition(name, def);
194 return TRUE;
195 }
replaceDefinition(Symbol name,const void * def,void ** v)196 boolean Dictionary::replaceDefinition(Symbol name, const void *def, void **v)
197 {
198 const char *str;
199 SymbolManager *sm = this->getSymbolManager();
200
201 str = sm->getSymbolString(name);
202 if (!str)
203 return FALSE;
204
205 return this->replaceDefinition(str, def, v);
206 }
207 //
208 // Replace the current elements with those in the given dictionary.
209 // If olddefList is not NULL, the return a list containing the old definitions.
210 //
replaceDefinitions(Dictionary * d,Dictionary * olddefDict)211 boolean Dictionary::replaceDefinitions(Dictionary *d, Dictionary *olddefDict)
212 {
213 DictionaryEntry *de;
214 ListIterator iterator(*d);
215
216 while ((de=(DictionaryEntry*)iterator.getNext())) {
217 Symbol sym = de->name;
218 void *olddef;
219 void *def = de->definition;
220 if (!this->replaceDefinition(sym,def, &olddef))
221 return FALSE;
222 if (olddefDict && olddef)
223 olddefDict->addDefinition(sym,olddef);
224
225 }
226
227 return TRUE;
228 }
229 //
230 // Find the Dictionary Element that has the give key value.
231 //
getDictionaryEntry(Symbol findkey)232 DictionaryEntry* Dictionary::getDictionaryEntry(Symbol findkey)
233 {
234 DictionaryEntry *d;
235
236 ListIterator di(*this);
237 while ((d=(DictionaryEntry*)di.getNext())) {
238 if (d->name == findkey)
239 break;
240 }
241 return d;
242 }
243
244 //
245 // Find the Definition associated with the given symbol.
246 // If the symbol is not found return FALSE, otherwise TRUE.
247 //
findDefinition(Symbol findkey)248 void *Dictionary::findDefinition(Symbol findkey)
249 {
250 void *d;
251 DictionaryEntry *de;
252
253 if (findkey == 0)
254 return NULL;
255
256 if (!(de = this->getDictionaryEntry(findkey)))
257 return NUL(void*);
258
259 d = de->definition;
260
261 return d;
262 }
263 //
264 // Find the Definition associated with the given string
265 // Return a pointer to the symbol found there.
266 //
findDefinition(const char * n)267 void *Dictionary::findDefinition(const char *n)
268 {
269 SymbolManager *sm = this->getSymbolManager();
270 Symbol s = sm->getSymbol(n);
271 if (s == 0)
272 return NULL;
273 else
274 return this->findDefinition(s);
275 }
276 //
277 // Find the definition associated with the given symbol.
278 // If the symbol is not found return FALSE, otherwise TRUE.
279 //
removeDefinition(Symbol findkey)280 void *Dictionary::removeDefinition(Symbol findkey)
281 {
282 int index;
283 void *d;
284 DictionaryEntry *de;
285
286
287 if (!(de = this->getDictionaryEntry(findkey)))
288 return NUL(void*);
289
290 d = de->definition;
291
292 index = this->List::getPosition(de);
293 ASSERT(index);
294
295 if (!this->deleteElement(index))
296 return NUL(void*);
297
298 delete de;
299
300 return d;
301 }
302 //
303 // Find the definition associated with the given string and remove it from
304 // the Dictionary.
305 // Return a pointer to the Definition found there.
306 //
removeDefinition(const char * n)307 void *Dictionary::removeDefinition(const char *n)
308 {
309 SymbolManager *sm = this->getSymbolManager();
310 Symbol s = sm->getSymbol(n);
311 if (s == 0)
312 return NULL;
313 else
314 return this->removeDefinition(s);
315 }
316 //
317 // Find the definition associated with the given string and remove it from
318 // the Dictionary.
319 // Return a pointer to the Definition found there.
320 //
removeDefinition(const void * def)321 void *Dictionary::removeDefinition(const void *def)
322 {
323 int index;
324 DictionaryEntry *d;
325 DictionaryEntry de(0,(void*)def);
326
327 if (!this->findElementValue((const void*)&de, _EqualValue, index))
328 return NUL(void*);
329
330 d = (DictionaryEntry*)this->getElement(index);
331 ASSERT(d);
332
333 index = this->List::getPosition(d);
334 ASSERT(index);
335
336 boolean r = this->deleteElement(index);
337 ASSERT(r);
338
339 delete d;
340
341 return (void*)def;
342
343 }
344
345