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