• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  SymbolTable.c  *
3  *                                                                           *
4  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
5  *                                                                           *
6  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
7  *  you may not use this file except in compliance with the License.         *
8  *                                                                           *
9  *  You may obtain a copy of the License at                                  *
10  *      http://www.apache.org/licenses/LICENSE-2.0                           *
11  *                                                                           *
12  *  Unless required by applicable law or agreed to in writing, software      *
13  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
14  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15  *  See the License for the specific language governing permissions and      *
16  *  limitations under the License.                                           *
17  *                                                                           *
18  *---------------------------------------------------------------------------*/
19 
20 #include "SR_SymbolTable.h"
21 #include "plog.h"
22 #include "pmemory.h"
23 
24 
25 static const char* MTAG = __FILE__;
26 
ST_Init(SymbolTable ** ptr)27 ESR_ReturnCode ST_Init(SymbolTable **ptr)
28 {
29   ESR_ReturnCode rc;
30 
31   if (ptr == NULL)
32   {
33     PLogError(L("ESR_INVALID_ARGUMENT"));
34     return ESR_INVALID_ARGUMENT;
35   }
36   *ptr = NEW(SymbolTable, MTAG);
37 
38   if (*ptr == NULL)
39   {
40     PLogError(L("ESR_OUT_OF_MEMORY"));
41     return ESR_OUT_OF_MEMORY;
42   }
43   CHKLOG(rc, HashMapCreate(&(*ptr)->hashmap));
44 
45   (*ptr)->num_special_symbols = 0;
46 
47   /* init the memory for the hashtable */
48   return ST_reset(*ptr);
49 CLEANUP:
50   return rc;
51 }
52 
ST_Free(SymbolTable * self)53 ESR_ReturnCode ST_Free(SymbolTable *self)
54 {
55   ESR_ReturnCode rc;
56 
57   if (self == NULL)
58   {
59     PLogError(L("ESR_INVALID_ARGUMENT"));
60     return ESR_INVALID_ARGUMENT;
61   }
62 
63   /* free all the slots that were used
64      and remove all hashtable entries */
65   ST_reset(self);
66 
67   /* delete the hash table */
68   if (self->hashmap)
69     CHKLOG(rc, HashMapDestroy(self->hashmap));
70 
71   /* delete the symbol table */
72   if (self != NULL)
73     FREE(self);
74   return ESR_SUCCESS;
75 CLEANUP:
76   return rc;
77 }
78 
ST_putKeyValue(SymbolTable * self,const LCHAR * key,const LCHAR * value)79 ESR_ReturnCode ST_putKeyValue(SymbolTable* self, const LCHAR* key, const LCHAR* value)
80 {
81   Symbol* symbol;
82   LCHAR* buf;
83   ESR_ReturnCode rc;
84 
85   if (self == NULL || key == NULL || value == NULL)
86   {
87     PLogError(L("ESR_INVALID_ARGUMENT"));
88     return ESR_INVALID_ARGUMENT;
89   }
90   /* reuse the old entry if it exists
91    but if no old entry exists for this key then I need to create a new one */
92   rc = HashMapGet(self->hashmap, key, (void**) & buf);
93   if (rc == ESR_NO_MATCH_ERROR)
94   {
95     CHKLOG(rc, ST_getSymbolSlot(self, &symbol));
96 
97     /* copy the key */
98     MEMCHK(rc, LSTRLEN(key), MAX_SEMPROC_KEY);
99     LSTRCPY(symbol->key, key);
100 
101     /* creates a new entry if it does not already exist */
102     CHKLOG(rc, HashMapPut(self->hashmap, symbol->key, symbol->value));
103 
104     /* for later */
105     buf = symbol->value;
106   }
107   else if (rc != ESR_SUCCESS)
108     return rc;
109 
110   if (LSTRLEN(value) >= MAX_SEMPROC_VALUE)
111     PLogError("Warning: chopping length of value len %d > %d (%s)\n", LSTRLEN(value), MAX_SEMPROC_VALUE, value);
112   LSTRNCPY(buf, value, MAX_SEMPROC_VALUE);
113   buf[MAX_SEMPROC_VALUE-1] = 0;
114   /* MEMCHK(rc, LSTRLEN(value), MAX_SEMPROC_VALUE);
115      LSTRCPY(buf, value); */
116   return ESR_SUCCESS;
117 CLEANUP:
118   return rc;
119 }
120 
ST_Copy(SymbolTable * self,HashMap * dst)121 ESR_ReturnCode ST_Copy(SymbolTable* self, HashMap* dst)
122 {
123   static const LCHAR* _MTAG = L("semproc.st.copy");
124   size_t i, size;
125   LCHAR *pkey;
126   LCHAR *pvalue;
127   LCHAR *copyValue;
128 
129   if (!dst) return ESR_INVALID_ARGUMENT;
130 
131   HashMapGetSize(self->hashmap, &size);
132   for (i = 0;i < size;i++)
133   {
134     HashMapGetKeyAtIndex(self->hashmap, i, &pkey);
135     HashMapGet(self->hashmap, pkey, (void **)&pvalue);
136     /* add one more space */
137     copyValue = (LCHAR*) CALLOC(LSTRLEN(pvalue) + 1, sizeof(LCHAR), _MTAG);
138     if (!copyValue)
139     {
140       PLogError(L("ESR_OUT_OF_MEMORY"));
141       return ESR_OUT_OF_MEMORY;
142     }
143     LSTRCPY(copyValue, pvalue);
144     HashMapPut(dst, pkey, copyValue);
145   }
146   return ESR_SUCCESS;
147 }
148 
ST_getKeyValue(SymbolTable * self,const LCHAR * key,LCHAR ** value)149 ESR_ReturnCode ST_getKeyValue(SymbolTable* self, const LCHAR* key, LCHAR** value)
150 {
151   ESR_ReturnCode rc;
152   LCHAR *dot;
153   size_t i;
154 
155   if (self == NULL || key == NULL || value == NULL)
156   {
157     PLogError(L("ESR_INVALID_ARGUMENT"));
158     return ESR_INVALID_ARGUMENT;
159   }
160 
161   rc = HashMapGet(self->hashmap, key, (void**)value);
162 
163   if (rc == ESR_SUCCESS || rc != ESR_NO_MATCH_ERROR)
164     return rc;
165 
166   if (rc == ESR_NO_MATCH_ERROR)
167   {
168     /* handle SPECIAL CASEs */
169     for (i = 0;i < self->num_special_symbols; i++)
170     {
171       /* try as is */
172       if (!LSTRCMP(key, self->SpecialSymbols[i].key))
173       {
174         *value = self->SpecialSymbols[i].value;
175         return ESR_SUCCESS;
176       }
177 
178       /* try without dot */
179       dot = LSTRCHR(key, L('.'));
180       if (dot)
181         key = ++dot;
182 
183       /* is it a match? */
184       if (!LSTRCMP(key, self->SpecialSymbols[i].key))
185       {
186         *value = self->SpecialSymbols[i].value;
187         return ESR_SUCCESS;
188       }
189     }
190   }
191 
192   *value = UNDEFINED_SYMBOL;
193   return ESR_SUCCESS;
194 }
195 
ST_getSymbolSlot(SymbolTable * ptr,Symbol ** slot)196 ESR_ReturnCode ST_getSymbolSlot(SymbolTable* ptr, Symbol** slot)
197 {
198   ESR_ReturnCode rc;
199 
200   if (ptr == NULL || slot == NULL)
201   {
202     PLogError(L("ESR_INVALID_ARGUMENT"));
203     return ESR_INVALID_ARGUMENT;
204   }
205 
206   *slot = ptr->next++;
207   MEMCHK(rc, ptr->next, &ptr->Symbols[MAX_SYMBOLS-1]);
208   return ESR_SUCCESS;
209 CLEANUP:
210   return rc;
211 }
212 
ST_reset(SymbolTable * ptr)213 ESR_ReturnCode ST_reset(SymbolTable *ptr)
214 {
215   int i;
216   ESR_ReturnCode rc;
217 
218   if (ptr == NULL)
219   {
220     PLogError(L("ESR_INVALID_ARGUMENT"));
221     return ESR_INVALID_ARGUMENT;
222   }
223   CHKLOG(rc, HashMapRemoveAll(ptr->hashmap));
224   ptr->next = &ptr->Symbols[0];
225   for (i = 0; i < MAX_SYMBOLS; i++)
226   {
227     ptr->Symbols[i].key[0] = 0;
228     ptr->Symbols[i].value[0] = 0;
229   }
230   return ESR_SUCCESS;
231 CLEANUP:
232   return rc;
233 }
234 
ST_reset_all(SymbolTable * ptr)235 ESR_ReturnCode ST_reset_all(SymbolTable *ptr)
236 {
237   int i;
238   ESR_ReturnCode rc;
239 
240   if (ptr == NULL)
241   {
242     PLogError(L("ESR_INVALID_ARGUMENT"));
243     return ESR_INVALID_ARGUMENT;
244   }
245   CHKLOG(rc, HashMapRemoveAll(ptr->hashmap));
246   ptr->next = &ptr->Symbols[0
247                            ];
248   for (i = 0; i < MAX_SYMBOLS; i++)
249   {
250     ptr->Symbols[i].key[0] = 0;
251     ptr->Symbols[i].value[0] = 0;
252   }
253   for (i = 0; i < MAX_SPECIAL_SYMBOLS; i++)
254   {
255     ptr->SpecialSymbols[i].key[0] = 0;
256     ptr->SpecialSymbols[i].value[0] = 0;
257   }
258   ptr->num_special_symbols = 0;
259   return ESR_SUCCESS;
260 CLEANUP:
261   return rc;
262 }
263 
ST_putSpecialKeyValue(SymbolTable * self,const LCHAR * key,const LCHAR * value)264 ESR_ReturnCode ST_putSpecialKeyValue(SymbolTable* self, const LCHAR* key, const LCHAR* value)
265 {
266   size_t i;
267 
268   if (self == NULL || key == NULL || value == NULL)
269   {
270     PLogError(L("ESR_INVALID_ARGUMENT"));
271     return ESR_INVALID_ARGUMENT;
272   }
273 
274   /* see if already there, and overwrite */
275   for (i = 0;i < self->num_special_symbols;i++)
276   {
277     if (!LSTRCMP(self->SpecialSymbols[i].key, key))
278     {
279       LSTRCPY(self->SpecialSymbols[i].value, value);
280       return ESR_SUCCESS;
281     }
282   }
283 
284   if (self->num_special_symbols < MAX_SPECIAL_SYMBOLS)
285   {
286     LSTRCPY(self->SpecialSymbols[self->num_special_symbols].key, key);
287     LSTRCPY(self->SpecialSymbols[self->num_special_symbols].value, value);
288     ++self->num_special_symbols;
289     return ESR_SUCCESS;
290   }
291   PLogError(L("Semproc: Symbol table has too many special symbols"));
292   return ESR_BUFFER_OVERFLOW;
293 }
294