• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  SessionTypeImpl.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 
21 #include "ESR_SessionType.h"
22 #include "ESR_SessionTypeImpl.h"
23 #include "HashMap.h"
24 #include "IntArrayList.h"
25 #include "LCHAR.h"
26 #include "lstring.h"
27 #include "passert.h"
28 #include "pendian.h"
29 #include "PFile.h"
30 #include "PFileSystem.h"
31 #include "plog.h"
32 #include "pmemory.h"
33 #include "pstdio.h"
34 #include "string.h"
35 #include "ESR_SessionTypeListener.h"
36 
37 #define MTAG NULL
38 
ESR_SessionTypeCreate(ESR_SessionType ** self)39 ESR_ReturnCode ESR_SessionTypeCreate(ESR_SessionType** self)
40 {
41   ESR_SessionType* Interface;
42   ESR_SessionTypeData* data;
43   ESR_ReturnCode rc;
44 
45   if (self == NULL)
46   {
47     PLogError(L("ESR_OUT_OF_MEMORY"));
48     return ESR_OUT_OF_MEMORY;
49   }
50   Interface = NEW(ESR_SessionType, MTAG);
51   if (Interface == NULL)
52   {
53     PLogError(L("ESR_OUT_OF_MEMORY"));
54     return ESR_OUT_OF_MEMORY;
55   }
56   data = NEW(ESR_SessionTypeData, MTAG);
57   if (data == NULL)
58   {
59     rc = ESR_OUT_OF_MEMORY;
60     goto CLEANUP;
61   }
62 
63 
64   Interface->addListener = &ESR_SessionTypeAddListenerImpl;
65   Interface->contains = &ESR_SessionTypeContainsImpl;
66   Interface->convertToBool = &ESR_SessionTypeConvertToBoolImpl;
67   Interface->convertToFloat = &ESR_SessionTypeConvertToFloatImpl;
68   Interface->convertToInt = &ESR_SessionTypeConvertToIntImpl;
69   Interface->convertToUint16_t = &ESR_SessionTypeConvertToUint16_tImpl;
70   Interface->convertToSize_t = &ESR_SessionTypeConvertToSize_tImpl;
71   Interface->destroy = &ESR_SessionTypeDestroyImpl;
72   Interface->getBool = &ESR_SessionTypeGetBoolImpl;
73   Interface->getFloat = &ESR_SessionTypeGetFloatImpl;
74   Interface->getInt = &ESR_SessionTypeGetIntImpl;
75   Interface->getUint16_t = &ESR_SessionTypeGetUint16_tImpl;
76   Interface->getKeyAtIndex = &ESR_SessionTypeGetKeyAtIndexImpl;
77   Interface->getLCHAR = &ESR_SessionTypeGetLCHARImpl;
78   Interface->getProperty = &ESR_SessionTypeGetPropertyImpl;
79   Interface->getPropertyType = &ESR_SessionTypeGetPropertyTypeImpl;
80   Interface->getSize = &ESR_SessionTypeGetSizeImpl;
81   Interface->getSize_t = &ESR_SessionTypeGetSize_tImpl;
82   Interface->importCommandLine = &ESR_SessionTypeImportCommandLineImpl;
83   Interface->importParFile = &ESR_SessionTypeImportParFileImpl;
84   Interface->removeProperty = &ESR_SessionTypeRemovePropertyImpl;
85   Interface->removeAndFreeProperty = &ESR_SessionTypeRemoveAndFreePropertyImpl;
86   Interface->setBool = &ESR_SessionTypeSetBoolImpl;
87   Interface->setBoolIfEmpty = &ESR_SessionTypeSetBoolIfEmptyImpl;
88   Interface->setFloat = &ESR_SessionTypeSetFloatImpl;
89   Interface->setFloatIfEmpty = &ESR_SessionTypeSetFloatIfEmptyImpl;
90   Interface->setInt = &ESR_SessionTypeSetIntImpl;
91   Interface->setIntIfEmpty = &ESR_SessionTypeSetIntIfEmptyImpl;
92   Interface->setUint16_t = &ESR_SessionTypeSetUint16_tImpl;
93   Interface->setUint16_tIfEmpty = &ESR_SessionTypeSetUint16_tIfEmptyImpl;
94   Interface->setLCHAR = &ESR_SessionTypeSetLCHARImpl;
95   Interface->setLCHARIfEmpty = &ESR_SessionTypeSetLCHARIfEmptyImpl;
96   Interface->setProperty = &ESR_SessionTypeSetPropertyImpl;
97   Interface->setSize_t = &ESR_SessionTypeSetSize_tImpl;
98   Interface->setSize_tIfEmpty = &ESR_SessionTypeSetSize_tIfEmptyImpl;
99   Interface->removeListener = &ESR_SessionTypeRemoveListenerImpl;
100 
101   Interface->data = data;
102   data->value = NULL;
103   data->listeners = NULL;
104 
105   CHK(rc, HashMapCreate(&data->value));
106   CHK(rc, ArrayListCreate(&data->listeners));
107   *self = Interface;
108   return ESR_SUCCESS;
109 CLEANUP:
110   Interface->destroy(Interface);
111   return rc;
112 }
113 
114 /*
115  * Because there are no functions to set and get int size_t parameters and because most if not
116  * all int parameters should be size_t anyway, I am adding code to allow size_t and int parameters
117  * to be considered equal. Besides, this check is kind of overkill anyway. SteveR
118  */
119 
ESR_SessionTypeGetPropertyImpl(ESR_SessionType * self,const LCHAR * name,void ** value,VariableTypes type)120 ESR_ReturnCode ESR_SessionTypeGetPropertyImpl(ESR_SessionType* self,
121     const LCHAR* name, void** value,
122     VariableTypes type)
123 {
124   ESR_SessionTypeData* data = self->data;
125   ESR_SessionPair* pair;
126   ESR_ReturnCode rc;
127 
128   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
129   if ( ( pair->type != type) && ( ( ( pair->type != TYPES_INT ) && ( type != TYPES_SIZE_T ) ) ||
130       ( ( type != TYPES_INT ) && ( pair->type != TYPES_SIZE_T ) ) ) )
131   {
132     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), type, pair->type);
133     return ESR_INVALID_RESULT_TYPE;
134   }
135   *value = pair->value;
136   return ESR_SUCCESS;
137 CLEANUP:
138   return rc;
139 }
140 
ESR_SessionTypeGetIntImpl(ESR_SessionType * self,const LCHAR * name,int * value)141 ESR_ReturnCode ESR_SessionTypeGetIntImpl(ESR_SessionType* self,
142     const LCHAR* name, int* value)
143 {
144   ESR_ReturnCode rc;
145   ESR_SessionTypeData* data;
146   ESR_SessionPair* pair;
147 
148   data = self->data;
149   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
150   if ( ( pair->type != TYPES_INT ) && ( pair->type != TYPES_SIZE_T ) )
151   {
152     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), TYPES_INT, pair->type);
153     return ESR_INVALID_RESULT_TYPE;
154   }
155   *value = *((int*) pair->value);
156   return ESR_SUCCESS;
157 CLEANUP:
158   return rc;
159 }
160 
ESR_SessionTypeGetUint16_tImpl(ESR_SessionType * self,const LCHAR * name,asr_uint16_t * value)161 ESR_ReturnCode ESR_SessionTypeGetUint16_tImpl(ESR_SessionType* self,
162     const LCHAR* name, asr_uint16_t* value)
163 {
164   ESR_ReturnCode rc;
165   ESR_SessionTypeData* data;
166   ESR_SessionPair* pair;
167 
168   data = self->data;
169   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
170   if (pair->type != TYPES_UINT16_T)
171   {
172     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), TYPES_UINT16_T, pair->type);
173     return ESR_INVALID_RESULT_TYPE;
174   }
175   *value = *((asr_uint16_t*) pair->value);
176   return ESR_SUCCESS;
177 CLEANUP:
178   return rc;
179 }
180 
ESR_SessionTypeGetSize_tImpl(ESR_SessionType * self,const LCHAR * name,size_t * value)181 ESR_ReturnCode ESR_SessionTypeGetSize_tImpl(ESR_SessionType* self,
182     const LCHAR* name,
183     size_t* value)
184 {
185   ESR_ReturnCode rc;
186   ESR_SessionTypeData* data;
187   ESR_SessionPair* pair;
188 
189   data = self->data;
190   CHKLOG(rc, HashMapGet(data->value, name, (void **)&pair));
191   if ( ( pair->type != TYPES_INT ) && ( pair->type != TYPES_SIZE_T ) )
192   {
193     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), TYPES_SIZE_T, pair->type);
194     return ESR_INVALID_RESULT_TYPE;
195   }
196   *value = *((size_t*) pair->value);
197   return ESR_SUCCESS;
198 CLEANUP:
199   return rc;
200 }
201 
ESR_SessionTypeGetFloatImpl(ESR_SessionType * self,const LCHAR * name,float * value)202 ESR_ReturnCode ESR_SessionTypeGetFloatImpl(ESR_SessionType* self,
203     const LCHAR* name, float* value)
204 {
205   ESR_ReturnCode rc;
206   ESR_SessionTypeData* data;
207   ESR_SessionPair* pair;
208 
209   data = self->data;
210   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
211   if (pair->type != TYPES_FLOAT)
212   {
213     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), TYPES_FLOAT, pair->type);
214     return ESR_INVALID_RESULT_TYPE;
215   }
216   *value = *((float*) pair->value);
217   return ESR_SUCCESS;
218 CLEANUP:
219   return rc;
220 }
221 
ESR_SessionTypeGetBoolImpl(ESR_SessionType * self,const LCHAR * name,ESR_BOOL * value)222 ESR_ReturnCode ESR_SessionTypeGetBoolImpl(ESR_SessionType* self,
223     const LCHAR* name, ESR_BOOL* value)
224 {
225   ESR_ReturnCode rc;
226   ESR_SessionTypeData* data;
227   ESR_SessionPair* pair;
228 
229   data = self->data;
230   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
231   if (pair->type != TYPES_BOOL)
232   {
233     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), TYPES_BOOL, pair->type);
234     return ESR_INVALID_RESULT_TYPE;
235   }
236   *value = *((ESR_BOOL*) pair->value);
237   return ESR_SUCCESS;
238 CLEANUP:
239   return rc;
240 }
241 
ESR_SessionTypeGetLCHARImpl(ESR_SessionType * self,const LCHAR * name,LCHAR * value,size_t * len)242 ESR_ReturnCode ESR_SessionTypeGetLCHARImpl(ESR_SessionType* self,
243     const LCHAR* name,
244     LCHAR* value, size_t* len)
245 {
246   LCHAR* lValue;
247   ESR_ReturnCode rc;
248   ESR_SessionTypeData* data;
249   ESR_SessionPair* pair;
250 
251   if (name == NULL || value == NULL || len == NULL)
252     return ESR_INVALID_ARGUMENT;
253   data = self->data;
254 
255   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
256   if (pair->type != TYPES_PLCHAR)
257   {
258     PLogError(L("ESR_INVALID_RESULT_TYPE: [got=%d, expected=%d]"), TYPES_PLCHAR, pair->type);
259     return ESR_INVALID_RESULT_TYPE;
260   }
261   lValue = (LCHAR*) pair->value;
262   if (LSTRLEN(pair->value) + 1 > *len)
263   {
264     *len = LSTRLEN(lValue) + 1;
265     return ESR_BUFFER_OVERFLOW;
266   }
267   LSTRCPY(value, lValue);
268   return ESR_SUCCESS;
269 CLEANUP:
270   return rc;
271 }
272 
ESR_SessionTypeContainsImpl(ESR_SessionType * self,const LCHAR * name,ESR_BOOL * exists)273 ESR_ReturnCode ESR_SessionTypeContainsImpl(ESR_SessionType* self,
274     const LCHAR* name, ESR_BOOL* exists)
275 {
276   ESR_SessionTypeData* data = self->data;
277 
278   return HashMapContainsKey(data->value, name, exists);
279 }
280 
firePropertyChanged(ESR_SessionType * self,const LCHAR * name,const void * oldValue,const void * newValue,enum VariableTypes_t type)281 static ESR_ReturnCode firePropertyChanged(ESR_SessionType* self, const LCHAR* name,
282     const void* oldValue, const void* newValue,
283     enum VariableTypes_t type)
284 {
285   ESR_SessionTypeData* data = self->data;
286   ArrayList* list = data->listeners;
287   size_t size, i;
288   ESR_SessionTypeListenerPair* listener;
289   ESR_ReturnCode rc;
290 
291   CHKLOG(rc, list->getSize(list, &size));
292   for (i = 0; i < size; ++i)
293   {
294     CHKLOG(rc, list->get(list, i, (void **)&listener));
295     CHKLOG(rc, listener->listener->propertyChanged(listener->listener, name, oldValue, newValue, type, listener->data));
296   }
297   return ESR_SUCCESS;
298 CLEANUP:
299   return rc;
300 }
301 
ESR_SessionTypeSetPropertyImpl(ESR_SessionType * self,const LCHAR * name,void * value,VariableTypes type)302 ESR_ReturnCode ESR_SessionTypeSetPropertyImpl(ESR_SessionType* self,
303     const LCHAR* name, void* value,
304     VariableTypes type)
305 {
306   ESR_SessionTypeData* data = self->data;
307   ESR_SessionPair* pair = NULL;
308   ESR_BOOL exists;
309   ESR_ReturnCode rc;
310 
311   CHKLOG(rc, HashMapContainsKey(data->value, name, &exists));
312   if ( exists )
313   {
314 /* We allow change of parameters through the recognizer and we rely on the recognizer to do
315  * all of the needed validation. SteveR
316  */
317 /* Deleting the old entry seems stupid, but it's the only way to prevent a memory leak,
318  * since the old data is not returned when you add the new data. SteveR
319  */
320     CHKLOG ( rc, ESR_SessionTypeRemoveAndFreePropertyImpl ( self, name ) );
321   }
322   pair = NEW(ESR_SessionPair, MTAG);
323   if (pair == NULL)
324   {
325     PLogError(L("ESR_OUT_OF_MEMORY"));
326     return ESR_OUT_OF_MEMORY;
327   }
328   pair->value = value;
329   pair->type = type;
330 
331   CHKLOG(rc, firePropertyChanged(self, name, NULL, value, type));
332   CHKLOG(rc, HashMapPut(data->value, name, pair));
333   return ESR_SUCCESS;
334 CLEANUP:
335 /* The cleanup potentially leaks memory which could be cleard up with  FREE ( pair->value );
336  * but you can't guarantee that the value was allocated. A leak is better than a crash. SteveR
337  */
338   FREE(pair);
339   return rc;
340 }
341 
ESR_SessionTypeSetIntImpl(ESR_SessionType * self,const LCHAR * name,int value)342 ESR_ReturnCode ESR_SessionTypeSetIntImpl(ESR_SessionType* self,
343     const LCHAR* name, int value)
344 {
345   ESR_SessionTypeData* data;
346   int* clone;
347 
348   data = self->data;
349   clone = MALLOC(sizeof(int), MTAG);
350   if (clone == NULL)
351   {
352     PLogError(L("ESR_OUT_OF_MEMORY"));
353     return ESR_OUT_OF_MEMORY;
354   }
355 
356   *clone = value;
357   return self->setProperty(self, name, clone, TYPES_INT);
358 }
359 
ESR_SessionTypeSetUint16_tImpl(ESR_SessionType * self,const LCHAR * name,asr_uint16_t value)360 ESR_ReturnCode ESR_SessionTypeSetUint16_tImpl(ESR_SessionType* self,
361     const LCHAR* name, asr_uint16_t value)
362 {
363   ESR_SessionTypeData* data;
364   asr_uint16_t* clone;
365 
366   data = self->data;
367   clone = MALLOC(sizeof(asr_uint16_t), MTAG);
368   if (clone == NULL)
369   {
370     PLogError(L("ESR_OUT_OF_MEMORY"));
371     return ESR_OUT_OF_MEMORY;
372   }
373 
374   *clone = value;
375   return self->setProperty(self, name, clone, TYPES_UINT16_T);
376 }
377 
ESR_SessionTypeSetSize_tImpl(ESR_SessionType * self,const LCHAR * name,size_t value)378 ESR_ReturnCode ESR_SessionTypeSetSize_tImpl(ESR_SessionType* self,
379     const LCHAR* name, size_t value)
380 {
381   ESR_SessionTypeData* data;
382   int* clone;
383 
384   data = self->data;
385   clone = MALLOC(sizeof(size_t), MTAG);
386   if (clone == NULL)
387   {
388     PLogError(L("ESR_OUT_OF_MEMORY"));
389     return ESR_OUT_OF_MEMORY;
390   }
391 
392   *clone = value;
393   return self->setProperty(self, name, clone, TYPES_SIZE_T);
394 }
395 
ESR_SessionTypeSetFloatImpl(ESR_SessionType * self,const LCHAR * name,float value)396 ESR_ReturnCode ESR_SessionTypeSetFloatImpl(ESR_SessionType* self,
397     const LCHAR* name, float value)
398 {
399   ESR_SessionTypeData* data;
400   float* clone;
401 
402   data = self->data;
403   clone = MALLOC(sizeof(float), MTAG);
404   if (clone == NULL)
405   {
406     PLogError(L("ESR_OUT_OF_MEMORY"));
407     return ESR_OUT_OF_MEMORY;
408   }
409 
410   *clone = value;
411   return self->setProperty(self, name, clone, TYPES_FLOAT);
412 }
413 
ESR_SessionTypeSetBoolImpl(ESR_SessionType * self,const LCHAR * name,ESR_BOOL value)414 ESR_ReturnCode ESR_SessionTypeSetBoolImpl(ESR_SessionType* self,
415     const LCHAR* name, ESR_BOOL value)
416 {
417   ESR_SessionTypeData* data;
418   ESR_BOOL* clone;
419 
420   data = self->data;
421   clone = MALLOC(sizeof(ESR_BOOL), MTAG);
422   if (clone == NULL)
423   {
424     PLogError(L("ESR_OUT_OF_MEMORY"));
425     return ESR_OUT_OF_MEMORY;
426   }
427 
428   *clone = value;
429   return self->setProperty(self, name, clone, TYPES_BOOL);
430 }
431 
ESR_SessionTypeSetLCHARImpl(ESR_SessionType * self,const LCHAR * name,LCHAR * value)432 ESR_ReturnCode ESR_SessionTypeSetLCHARImpl(ESR_SessionType* self,
433     const LCHAR* name, LCHAR* value)
434 {
435   ESR_SessionTypeData* data;
436   LCHAR* clone;
437 
438   data = self->data;
439   clone = MALLOC(sizeof(LCHAR) * (LSTRLEN(value) + 1), MTAG);
440   if (clone == NULL)
441   {
442     PLogError(L("ESR_OUT_OF_MEMORY"));
443     return ESR_OUT_OF_MEMORY;
444   }
445 
446   LSTRCPY(clone, value);
447   return self->setProperty(self, name, clone, TYPES_PLCHAR);
448 }
449 
ESR_SessionTypeSetIntIfEmptyImpl(ESR_SessionType * self,const LCHAR * name,int value)450 ESR_ReturnCode ESR_SessionTypeSetIntIfEmptyImpl(ESR_SessionType* self,
451     const LCHAR* name, int value)
452 {
453   ESR_BOOL exists;
454   ESR_ReturnCode rc;
455 
456   CHK(rc, self->contains(self, name, &exists));
457   if (exists)
458     return ESR_SUCCESS;
459   return self->setInt(self, name, value);
460 CLEANUP:
461   return rc;
462 }
463 
ESR_SessionTypeSetUint16_tIfEmptyImpl(ESR_SessionType * self,const LCHAR * name,asr_uint16_t value)464 ESR_ReturnCode ESR_SessionTypeSetUint16_tIfEmptyImpl(ESR_SessionType* self,
465     const LCHAR* name, asr_uint16_t value)
466 {
467   ESR_BOOL exists;
468   ESR_ReturnCode rc;
469 
470   CHK(rc, self->contains(self, name, &exists));
471   if (exists)
472     return ESR_SUCCESS;
473   return self->setInt(self, name, value);
474 CLEANUP:
475   return rc;
476 }
477 
ESR_SessionTypeSetSize_tIfEmptyImpl(ESR_SessionType * self,const LCHAR * name,size_t value)478 ESR_ReturnCode ESR_SessionTypeSetSize_tIfEmptyImpl(ESR_SessionType* self,
479     const LCHAR* name, size_t value)
480 {
481   ESR_BOOL exists;
482   ESR_ReturnCode rc;
483 
484   CHK(rc, self->contains(self, name, &exists));
485   if (exists)
486     return ESR_SUCCESS;
487   return self->setSize_t(self, name, value);
488 CLEANUP:
489   return rc;
490 }
491 
ESR_SessionTypeSetFloatIfEmptyImpl(ESR_SessionType * self,const LCHAR * name,float value)492 ESR_ReturnCode ESR_SessionTypeSetFloatIfEmptyImpl(ESR_SessionType* self,
493     const LCHAR* name, float value)
494 {
495   ESR_BOOL exists;
496   ESR_ReturnCode rc;
497 
498   CHK(rc, self->contains(self, name, &exists));
499   if (exists)
500     return ESR_SUCCESS;
501   return self->setFloat(self, name, value);
502 CLEANUP:
503   return rc;
504 }
505 
ESR_SessionTypeSetBoolIfEmptyImpl(ESR_SessionType * self,const LCHAR * name,ESR_BOOL value)506 ESR_ReturnCode ESR_SessionTypeSetBoolIfEmptyImpl(ESR_SessionType* self,
507     const LCHAR* name, ESR_BOOL value)
508 {
509   ESR_BOOL exists;
510   ESR_ReturnCode rc;
511 
512   CHK(rc, self->contains(self, name, &exists));
513   if (exists)
514     return ESR_SUCCESS;
515   return self->setBool(self, name, value);
516 CLEANUP:
517   return rc;
518 }
519 
ESR_SessionTypeSetLCHARIfEmptyImpl(ESR_SessionType * self,const LCHAR * name,LCHAR * value)520 ESR_ReturnCode ESR_SessionTypeSetLCHARIfEmptyImpl(ESR_SessionType* self,
521     const LCHAR* name, LCHAR* value)
522 {
523   ESR_BOOL exists;
524   ESR_ReturnCode rc;
525 
526   CHK(rc, self->contains(self, name, &exists));
527   if (exists)
528     return ESR_SUCCESS;
529   return self->setLCHAR(self, name, value);
530 CLEANUP:
531   return rc;
532 }
533 
ESR_SessionTypeRemovePropertyImpl(ESR_SessionType * self,const LCHAR * name)534 ESR_ReturnCode ESR_SessionTypeRemovePropertyImpl(ESR_SessionType* self,
535     const LCHAR* name)
536 {
537   ESR_ReturnCode rc;
538   ESR_SessionTypeData* data = self->data;
539   ESR_SessionPair* pair;
540 
541   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
542   CHKLOG(rc, firePropertyChanged(self, name, pair->value, NULL, pair->type));
543   CHK(rc, HashMapRemove(data->value, name));
544   FREE(pair);
545   return ESR_SUCCESS;
546 CLEANUP:
547   return rc;
548 }
549 
ESR_SessionTypeRemoveAndFreePropertyImpl(ESR_SessionType * self,const LCHAR * name)550 ESR_ReturnCode ESR_SessionTypeRemoveAndFreePropertyImpl(ESR_SessionType* self,
551     const LCHAR* name)
552 {
553   ESR_ReturnCode rc;
554   ESR_SessionTypeData* data = self->data;
555   ESR_SessionPair* pair;
556   ESR_SessionPair temp;
557   IntArrayList* intList;
558 
559   CHK(rc, data->value->get(data->value, name, (void **)&pair));
560   temp = *pair;
561   CHK(rc, self->removeProperty(self, name));
562   if (temp.value)
563   {
564     if (temp.type == TYPES_INTARRAYLIST)
565     {
566       intList = temp.value;
567       intList->destroy(intList);
568     }
569     else
570       FREE(temp.value);
571   }
572   return ESR_SUCCESS;
573 CLEANUP:
574   return rc;
575 }
576 
ESR_SessionTypeImportCommandLineImpl(ESR_SessionType * self,int argc,LCHAR * argv[])577 ESR_ReturnCode ESR_SessionTypeImportCommandLineImpl(ESR_SessionType* self,
578     int argc, LCHAR* argv[])
579 {
580   char* key = NULL;
581   char* value = NULL;
582   VariableTypes type;
583   ESR_ReturnCode rc;
584 
585   while (--argc > 0 && **++argv)
586   {
587     if (**argv != '-')
588     {
589       /* got value */
590       if (key == NULL)
591       {
592         /* but we don't have any key to associate it with */
593         pfprintf(PSTDERR, "Options must be prefixed by '-'%s\n", *argv);
594       }
595       else
596       {
597         rc = self->getPropertyType(self, key, &type);
598         if (rc == ESR_SUCCESS)
599         {
600           CHKLOG(rc, self->getProperty(self, key, (void **)&value, type));
601           CHKLOG(rc, self->removeProperty(self, key));
602           FREE(value);
603           value = NULL;
604         }
605         else if (rc != ESR_NO_MATCH_ERROR)
606         {
607           PLogError(ESR_rc2str(rc));
608           goto CLEANUP;
609         }
610         value = MALLOC(sizeof(LCHAR) * (strlen(*argv) + 1), MTAG);
611         if (value == NULL)
612         {
613           rc = ESR_OUT_OF_MEMORY;
614           PLogError(L("ESR_OUT_OF_MEMORY"));
615           goto CLEANUP;
616         }
617         LSTRCPY(value, *argv);
618         CHKLOG(rc, self->setProperty(self, key, value, TYPES_PLCHAR));
619         FREE(key);
620         key = NULL;
621         value = NULL;
622       }
623     }
624     else
625     {
626       /* got key */
627       if (key != NULL)
628       {
629         /* But we already have a key without a value, so set the old key's value to "" */
630         rc = self->getPropertyType(self, key, &type);
631         if (rc == ESR_SUCCESS)
632         {
633           CHKLOG(rc, self->getProperty(self, key, (void **)&value, type));
634           CHKLOG(rc, self->removeProperty(self, key));
635           FREE(value);
636           value = NULL;
637         }
638         else if (rc != ESR_NO_MATCH_ERROR)
639         {
640           PLogError(ESR_rc2str(rc));
641           goto CLEANUP;
642         }
643         value = MALLOC(sizeof(LCHAR) + 1, MTAG);
644         strcpy(value, "");
645         CHKLOG(rc, self->setProperty(self, key, value, TYPES_PLCHAR));
646         FREE(key);
647         value = NULL;
648       }
649       key = MALLOC(sizeof(LCHAR) * (LSTRLEN("cmdline.") + LSTRLEN(*argv) + 1), MTAG);
650       if (key == NULL)
651       {
652         rc = ESR_OUT_OF_MEMORY;
653         PLogError(L("ESR_OUT_OF_MEMORY"));
654         goto CLEANUP;
655       }
656       LSTRCPY(key, "cmdline.");
657       LSTRCAT(key, *argv + 1);
658     }
659   }
660   return ESR_SUCCESS;
661 CLEANUP:
662   if (key != NULL)
663     FREE(key);
664   if (value != NULL)
665     FREE(value);
666   return rc;
667 }
668 
ESR_SessionTypeGetSizeImpl(ESR_SessionType * self,size_t * size)669 ESR_ReturnCode ESR_SessionTypeGetSizeImpl(ESR_SessionType* self, size_t* size)
670 {
671   ESR_SessionTypeData* data = self->data;
672   ESR_ReturnCode rc;
673 
674   CHK(rc, HashMapGetSize(data->value, size));
675   return ESR_SUCCESS;
676 CLEANUP:
677   return rc;
678 }
679 
ESR_SessionTypeGetKeyAtIndexImpl(ESR_SessionType * self,size_t index,LCHAR ** key)680 ESR_ReturnCode ESR_SessionTypeGetKeyAtIndexImpl(ESR_SessionType* self,
681     size_t index, LCHAR** key)
682 {
683   ESR_SessionTypeData* data = self->data;
684   ESR_ReturnCode rc;
685 
686   CHK(rc, HashMapGetKeyAtIndex(data->value, index, key));
687   return ESR_SUCCESS;
688 CLEANUP:
689   return rc;
690 }
691 
ESR_SessionTypeConvertToIntImpl(ESR_SessionType * self,const LCHAR * key)692 ESR_ReturnCode ESR_SessionTypeConvertToIntImpl(ESR_SessionType* self,
693     const LCHAR* key)
694 {
695   LCHAR* value;
696   int *newValue = NULL;
697   ESR_ReturnCode rc;
698 
699   CHK(rc, self->getProperty(self, key, (void **)&value, TYPES_PLCHAR));
700   if (value == NULL)
701     return ESR_SUCCESS;
702   newValue = MALLOC(sizeof(long), MTAG);
703   if (newValue == NULL)
704   {
705     rc = ESR_OUT_OF_MEMORY;
706     goto CLEANUP;
707   }
708   CHKLOG(rc, lstrtoi(value, newValue, 10));
709   CHKLOG(rc, self->setProperty(self, key, newValue, TYPES_INT));
710   FREE(value);
711   return ESR_SUCCESS;
712 CLEANUP:
713   if (newValue != NULL)
714     FREE(newValue);
715   return rc;
716 }
717 
ESR_SessionTypeConvertToUint16_tImpl(ESR_SessionType * self,const LCHAR * key)718 ESR_ReturnCode ESR_SessionTypeConvertToUint16_tImpl(ESR_SessionType* self,
719     const LCHAR* key)
720 {
721   LCHAR* value;
722   int *newValue = NULL;
723   ESR_ReturnCode rc;
724 
725   CHK(rc, self->getProperty(self, key, (void **)&value, TYPES_PLCHAR));
726   if (value == NULL)
727     return ESR_SUCCESS;
728   newValue = MALLOC(sizeof(long), MTAG);
729   if (newValue == NULL)
730   {
731     rc = ESR_OUT_OF_MEMORY;
732     goto CLEANUP;
733   }
734   CHKLOG(rc, lstrtoi(value, newValue, 10));
735   CHKLOG(rc, self->setProperty(self, key, newValue, TYPES_UINT16_T));
736   FREE(value);
737   return ESR_SUCCESS;
738 CLEANUP:
739   if (newValue != NULL)
740     FREE(newValue);
741   return rc;
742 }
743 
ESR_SessionTypeConvertToSize_tImpl(ESR_SessionType * self,const LCHAR * key)744 ESR_ReturnCode ESR_SessionTypeConvertToSize_tImpl(ESR_SessionType* self,
745     const LCHAR* key)
746 {
747   LCHAR* value;
748   size_t* newValue = NULL;
749   ESR_ReturnCode rc;
750 
751   CHK(rc, self->getProperty(self, key, (void **)&value, TYPES_PLCHAR));
752   if (value == NULL)
753     return ESR_SUCCESS;
754   newValue = MALLOC(sizeof(size_t), MTAG);
755   if (newValue == NULL)
756   {
757     rc = ESR_OUT_OF_MEMORY;
758     goto CLEANUP;
759   }
760   CHKLOG(rc, lstrtoui(value, (unsigned int *)newValue, 10));
761   CHKLOG(rc, self->setProperty(self, key, newValue, TYPES_SIZE_T));
762   FREE(value);
763   return ESR_SUCCESS;
764 CLEANUP:
765   if (newValue != NULL)
766     FREE(newValue);
767   return rc;
768 }
769 
ESR_SessionTypeConvertToFloatImpl(ESR_SessionType * self,const LCHAR * key)770 ESR_ReturnCode ESR_SessionTypeConvertToFloatImpl(ESR_SessionType* self,
771     const LCHAR* key)
772 {
773   LCHAR* value;
774   float *newValue = NULL;
775   ESR_ReturnCode rc;
776 
777   CHK(rc, self->getProperty(self, key, (void **)&value, TYPES_PLCHAR));
778   if (value == NULL)
779     return ESR_SUCCESS;
780   newValue = MALLOC(sizeof(double), MTAG);
781   if (newValue == NULL)
782   {
783     rc = ESR_OUT_OF_MEMORY;
784     goto CLEANUP;
785   }
786   CHKLOG(rc, lstrtof(value, newValue));
787   CHKLOG(rc, self->setProperty(self, key, newValue, TYPES_FLOAT));
788   FREE(value);
789   return ESR_SUCCESS;
790 CLEANUP:
791   if (newValue != NULL)
792     FREE(newValue);
793   return rc;
794 }
795 
ESR_SessionTypeConvertToBoolImpl(ESR_SessionType * self,const LCHAR * key)796 ESR_ReturnCode ESR_SessionTypeConvertToBoolImpl(ESR_SessionType* self,
797     const LCHAR* key)
798 {
799   LCHAR* value;
800   ESR_BOOL *newValue = NULL;
801   ESR_ReturnCode rc;
802 
803   CHK(rc, self->getProperty(self, key, (void **)&value, TYPES_PLCHAR));
804   if (value == NULL)
805     return ESR_SUCCESS;
806   newValue = MALLOC(sizeof(ESR_BOOL), MTAG);
807   if (newValue == NULL)
808   {
809     rc = ESR_OUT_OF_MEMORY;
810     goto CLEANUP;
811   }
812   rc = lstrtob(value, newValue);
813   if (rc != ESR_SUCCESS)
814   {
815     FREE(newValue);
816     return rc;
817   }
818   rc = self->setProperty(self, key, newValue, TYPES_BOOL);
819   if (rc != ESR_SUCCESS)
820   {
821     FREE(newValue);
822     return rc;
823   }
824   FREE(value);
825   return ESR_SUCCESS;
826 CLEANUP:
827   if (newValue != NULL)
828     FREE(newValue);
829   return rc;
830 }
831 
832 /**
833  * Imports file containing [key, value] pairs into session.
834  *
835  * @param self ESR_SessionType handle
836  * @param filename File to read session from
837  * @param addMapping Function used to map keys to their type and add them to the session
838  * @param data Data used by the mapping function
839  */
importKeyValueFile(ESR_SessionType * self,const LCHAR * filename,ESR_ReturnCode (* addMapping)(ESR_SessionType * self,const LCHAR * key,LCHAR * value,void * data),void * data)840 static ESR_ReturnCode importKeyValueFile(ESR_SessionType* self,
841     const LCHAR* filename,
842     ESR_ReturnCode(*addMapping)(ESR_SessionType* self, const LCHAR* key, LCHAR* value, void* data),
843     void* data)
844 {
845   const size_t LINE_SIZE = 512;
846   LCHAR key[512];
847   LCHAR buffer[512];
848   LCHAR* value;
849   LCHAR* ending;
850   LCHAR* line;
851   PFile* file = NULL;
852   ESR_BOOL lineSpan = ESR_FALSE;
853   LString* valueBuffer = NULL;
854   ESR_ReturnCode rc = ESR_SUCCESS;
855 
856   if (filename == NULL)
857     return ESR_INVALID_ARGUMENT;
858 
859   file = pfopen ( filename, L("r") );
860 /*  CHKLOG(rc, PFileSystemCreatePFile(filename, ESR_TRUE, &file));
861   CHKLOG(rc, PFileOpen(file, L("r")));*/
862 
863   if (file == NULL)
864   {
865     LCHAR msg[P_PATH_MAX + 30];
866     LCHAR cwd[P_PATH_MAX];
867     size_t len;
868 
869     len = P_PATH_MAX;
870     CHKLOG(rc, pf_get_cwd (cwd, &len));
871     psprintf(msg, L("ESR_OPEN_FILE_ERROR(filename=%s, cwd=%s)"), filename, cwd);
872     rc = ESR_OPEN_ERROR;
873     PLogError(msg);
874     goto CLEANUP;
875   }
876 
877   rc = LStringCreate(&valueBuffer);
878   if (rc != ESR_SUCCESS)
879     goto CLEANUP;
880 
881   line = buffer;
882   while (ESR_TRUE)
883   {
884     line = pfgets(line, LINE_SIZE, file);
885     if (line == NULL)
886     {
887       if (pfeof(file))
888         break;
889       rc = ESR_READ_ERROR;
890       PLogError(ESR_rc2str(rc));
891       goto CLEANUP;
892     }
893     if (LSTRLEN(line) == LINE_SIZE)
894     {
895       PLogError(L("%s: line surpasses %d character limit: '%s'"), filename, line);
896       continue;
897     }
898     lstrtrim(line);
899     if (LSTRLEN(line) == 0 || line[0] == '#')
900       continue;
901 
902     if (!lineSpan)
903     {
904       if (rc != ESR_SUCCESS) goto CLEANUP;
905 
906       /* locate the key and value pair */
907       ending = LSTRCHR(line, '=');
908       if (ending == NULL)
909       {
910         fprintf(stderr, "Missing equal sign on line '%s'\n", line);
911         continue;
912       }
913       *ending = L('\0');
914       value = ending + 1;
915     }
916     else
917       value = line;
918 
919     /* Optionally use ';' to denote end of value */
920     ending = LSTRCHR(value, L(';'));
921     if (ending != NULL)
922       *ending = L('\0');
923     else
924     {
925       ending = LSTRCHR(value, L('\n'));
926       if (ending != NULL)
927         *ending = L('\0');
928     }
929     if (!lineSpan)
930     {
931       LSTRCPY(key, line);
932       lstrtrim(key);
933     }
934     if (LSTRLEN(value) == 0)
935     {
936       pfprintf(PSTDERR, L("Missing value for '%s'\n"), key);
937       continue;
938     }
939     lstrtrim(value);
940     if ((ending = LSTRCHR(value, '\\')) == (value + LSTRLEN(value) - 1))
941     {
942       /* found '\\' at end of line which means data will span to the next line */
943       lineSpan = ESR_TRUE;
944       *ending = L('\0');
945     }
946     else
947       lineSpan = ESR_FALSE;
948     rc = LStringAppend(valueBuffer, value);
949     if (rc != ESR_SUCCESS)
950     {
951       PLogError(ESR_rc2str(rc));
952       goto CLEANUP;
953     }
954     if (!lineSpan)
955     {
956       rc = LStringToLCHAR(valueBuffer, &value);
957       valueBuffer = NULL;
958       if (rc != ESR_SUCCESS)
959       {
960         PLogError(ESR_rc2str(rc));
961         goto CLEANUP;
962       }
963       rc = addMapping(self, key, value, data);
964       if (value != NULL)
965       {
966         FREE(value);
967         value = NULL;
968       }
969       if (rc != ESR_SUCCESS)
970       {
971         PLogError(ESR_rc2str(rc));
972         goto CLEANUP;
973       }
974       rc = LStringCreate(&valueBuffer);
975       if (rc != ESR_SUCCESS)
976       {
977         PLogError(ESR_rc2str(rc));
978         goto CLEANUP;
979       }
980     }
981   }
982 
983   if (pferror(file))
984   {
985     rc = ESR_READ_ERROR;
986     PLogError(ESR_rc2str(rc));
987     goto CLEANUP;
988   }
989   if (pfclose(file) != 0)
990   {
991     rc = ESR_CLOSE_ERROR;
992     PLogError(ESR_rc2str(rc));
993     goto CLEANUP;
994   }
995   if (valueBuffer != NULL)
996     LStringDestroy(valueBuffer);
997   return ESR_SUCCESS;
998 CLEANUP:
999   if (file != NULL)
1000     pfclose(file);
1001   if (valueBuffer != NULL)
1002     LStringDestroy(valueBuffer);
1003   return rc;
1004 }
1005 
1006 /**
1007  * Appends a collection of integers stored in string format to an IntArrayList.
1008  *
1009  * @param self ESR_SessionType handle
1010  * @param text Text containing integers
1011  * @param list List to be populated
1012  */
parseIntList(ESR_SessionType * self,LCHAR * text,IntArrayList * list)1013 static ESR_ReturnCode parseIntList(ESR_SessionType* self,
1014                                    LCHAR* text, IntArrayList* list)
1015 {
1016   size_t size, pos, beginning;
1017   int value;
1018   ESR_ReturnCode rc;
1019 
1020   size = LSTRLEN(text);
1021   pos = 0;
1022   while (ESR_TRUE)
1023   {
1024     /* Scan for beginning of next token */
1025     for (; pos < size && LISSPACE(text[pos]); ++pos);
1026 
1027     if (pos >= size)
1028     {
1029       /* Reached end of string while looking for beginning of next token */
1030       break;
1031     }
1032     beginning = pos;
1033 
1034     /* Scan for ending of current token */
1035     for (; pos < size && !LISSPACE(text[pos]); ++pos);
1036     text[pos] = L('\0');
1037     CHKLOG(rc, lstrtoi(text + beginning, &value, 10));
1038     CHKLOG(rc, IntArrayListAdd(list, value));
1039     ++pos;
1040   }
1041   return ESR_SUCCESS;
1042 CLEANUP:
1043   return rc;
1044 }
1045 
ESR_SessionTypeGetPropertyTypeImpl(ESR_SessionType * self,const LCHAR * name,VariableTypes * type)1046 ESR_ReturnCode ESR_SessionTypeGetPropertyTypeImpl(ESR_SessionType* self,
1047     const LCHAR* name, VariableTypes* type)
1048 {
1049   ESR_SessionTypeData* data = self->data;
1050   ESR_SessionPair* pair;
1051   ESR_ReturnCode rc;
1052 
1053   CHK(rc, HashMapGet(data->value, name, (void **)&pair));
1054   *type = pair->type;
1055   return ESR_SUCCESS;
1056 CLEANUP:
1057   return rc;
1058 }
1059 
1060 /**
1061  * Maps key -> type for PAR files.
1062  *
1063  * @param self ESR_Session handle
1064  * @param key Key name
1065  * @param value The value
1066  */
addParMapping(ESR_SessionType * self,const LCHAR * key,LCHAR * value,void * data)1067 static ESR_ReturnCode addParMapping(ESR_SessionType* self,
1068                                     const LCHAR* key, LCHAR* value, void* data)
1069 {
1070   IntArrayList* iList;
1071   ESR_ReturnCode rc;
1072   HashMap* map;
1073   VariableTypes* type;
1074   int iValue;
1075   size_t size_tValue;
1076   float fValue;
1077   ESR_BOOL bValue;
1078   ESR_BOOL exists;
1079 
1080   map = (HashMap*) data;
1081   rc = HashMapGet(data, key, (void **)&type);
1082   if (rc == ESR_NO_MATCH_ERROR)
1083   {
1084     /* If type is unknown, assume LCHAR* */
1085     PLogMessage(L("Unknown parfile key '%s'"), key);
1086     CHKLOG(rc, self->setLCHAR(self, key, value));
1087   }
1088   else if (rc == ESR_SUCCESS)
1089   {
1090     switch (*type)
1091     {
1092       case TYPES_INT:
1093         CHKLOG(rc, lstrtoi(value, &iValue, 10));
1094         CHKLOG(rc, self->contains(self, key, &exists));
1095         if (exists)
1096           CHKLOG(rc, self->removeAndFreeProperty(self, key));
1097         CHKLOG(rc, self->setInt(self, key, iValue));
1098         break;
1099       case TYPES_UINT16_T:
1100         CHKLOG(rc, lstrtoui(value, (unsigned int *)&size_tValue, 10));
1101         passert(size_tValue >= UINT16_TMIN && size_tValue <= UINT16_TMAX);
1102         CHKLOG(rc, self->contains(self, key, &exists));
1103         if (exists)
1104           CHKLOG(rc, self->removeAndFreeProperty(self, key));
1105         CHKLOG(rc, self->setUint16_t(self, key, (asr_uint16_t) size_tValue));
1106         break;
1107       case TYPES_SIZE_T:
1108         CHKLOG(rc, lstrtoui(value, (unsigned int *)&size_tValue, 10));
1109         CHKLOG(rc, self->contains(self, key, &exists));
1110         if (exists)
1111           CHKLOG(rc, self->removeAndFreeProperty(self, key));
1112         CHKLOG(rc, self->setSize_t(self, key, size_tValue));
1113         break;
1114       case TYPES_FLOAT:
1115         CHKLOG(rc, lstrtof(value, &fValue));
1116         CHKLOG(rc, self->contains(self, key, &exists));
1117         if (exists)
1118           CHKLOG(rc, self->removeAndFreeProperty(self, key));
1119         CHKLOG(rc, self->setFloat(self, key, fValue));
1120         break;
1121       case TYPES_BOOL:
1122         CHKLOG(rc, lstrtob(value, &bValue));
1123         CHKLOG(rc, self->contains(self, key, &exists));
1124         if (exists)
1125           CHKLOG(rc, self->removeAndFreeProperty(self, key));
1126         CHKLOG(rc, self->setBool(self, key, bValue));
1127         break;
1128       case TYPES_INTARRAYLIST:
1129         CHKLOG(rc, self->contains(self, key, &exists));
1130         if (exists)
1131         {
1132           CHKLOG(rc, self->getProperty(self, key, (void **)&iList, TYPES_INTARRAYLIST));
1133           CHKLOG(rc, self->removeProperty(self, key));
1134           CHKLOG(rc, iList->destroy(iList));
1135         }
1136         CHKLOG(rc, IntArrayListCreate(&iList));
1137         CHKLOG(rc, parseIntList(self, value, iList));
1138         CHKLOG(rc, self->setProperty(self, key, iList, TYPES_INTARRAYLIST));
1139         break;
1140       default:
1141         passert(0); /* Unknown variable type. Assuming LCHAR* */
1142       case TYPES_PLCHAR:
1143         CHKLOG(rc, self->contains(self, key, &exists));
1144         if (exists)
1145           CHKLOG(rc, self->removeAndFreeProperty(self, key));
1146         CHKLOG(rc, self->setLCHAR(self, key, value));
1147         break;
1148     }
1149   }
1150   return rc;
1151 CLEANUP:
1152   return rc;
1153 }
1154 
ESR_SessionTypeImportParFileImpl(ESR_SessionType * self,const LCHAR * filename)1155 ESR_ReturnCode ESR_SessionTypeImportParFileImpl(ESR_SessionType* self,
1156     const LCHAR* filename)
1157 {
1158   ESR_ReturnCode rc;
1159   HashMap* parameterList;
1160   VariableTypes Int = TYPES_INT;
1161   VariableTypes UInt16_t = TYPES_UINT16_T;
1162   VariableTypes Float = TYPES_FLOAT;
1163   VariableTypes Bool = TYPES_BOOL;
1164   VariableTypes IntArrayList = TYPES_INTARRAYLIST;
1165   VariableTypes PLChar = TYPES_PLCHAR;
1166   VariableTypes Size_t = TYPES_SIZE_T;
1167 
1168   /* Create [key, type] lookup table */
1169   CHKLOG(rc, HashMapCreate(&parameterList));
1170 
1171   CHKLOG(rc, parameterList->put(parameterList, "cmdline.arbfile", &PLChar));
1172   CHKLOG(rc, parameterList->put(parameterList, "cmdline.bgsniff", &Size_t));
1173   CHKLOG(rc, parameterList->put(parameterList, "cmdline.channel", &PLChar));
1174   CHKLOG(rc, parameterList->put(parameterList, "cmdline.datapath", &PLChar));
1175   CHKLOG(rc, parameterList->put(parameterList, "cmdline.DataCaptureDirectory", &PLChar));
1176   CHKLOG(rc, parameterList->put(parameterList, "cmdline.detail_res", &PLChar));
1177   CHKLOG(rc, parameterList->put(parameterList, "cmdline.lda", &PLChar));
1178   CHKLOG(rc, parameterList->put(parameterList, "cmdline.modelfiles", &PLChar));
1179   CHKLOG(rc, parameterList->put(parameterList, "cmdline.modelfiles11", &PLChar));
1180   CHKLOG(rc, parameterList->put(parameterList, "cmdline.modelfiles8", &PLChar));
1181   CHKLOG(rc, parameterList->put(parameterList, "cmdline.lda11", &PLChar));
1182   CHKLOG(rc, parameterList->put(parameterList, "cmdline.lda8", &PLChar));
1183   CHKLOG(rc, parameterList->put(parameterList, "cmdline.results", &PLChar));
1184   CHKLOG(rc, parameterList->put(parameterList, "cmdline.rules", &PLChar));
1185   CHKLOG(rc, parameterList->put(parameterList, "cmdline.tcp", &PLChar));
1186   CHKLOG(rc, parameterList->put(parameterList, "cmdline.multable", &PLChar));
1187   CHKLOG(rc, parameterList->put(parameterList, "cmdline.parfile", &PLChar));
1188   CHKLOG(rc, parameterList->put(parameterList, "cmdline.vocabulary", &PLChar));
1189   CHKLOG(rc, parameterList->put(parameterList, "cmdline.use_image", &Int));
1190   CHKLOG(rc, parameterList->put(parameterList, "cmdline.semproc_verbose", &Bool));
1191   CHKLOG(rc, parameterList->put(parameterList, "cmdline.nametagPath", &PLChar));
1192 
1193   /* Beginning of speech detection stuff */
1194   CHKLOG(rc, parameterList->put(parameterList, "cmdline.bgsniff_min", &Size_t));
1195   CHKLOG(rc, parameterList->put(parameterList, "cmdline.silence_duration_in_frames", &Size_t));
1196   CHKLOG(rc, parameterList->put(parameterList, "cmdline.end_of_utterance_hold_off_in_frames", &Size_t));
1197   CHKLOG(rc, parameterList->put(parameterList, "cmdline.gatedmode", &Bool));
1198 
1199   /* new param from SREC that did not exist in CREC */
1200   CHKLOG(rc, parameterList->put(parameterList, "SREC.Recognizer.utterance_timeout", &Size_t));
1201   CHKLOG(rc, parameterList->put(parameterList, "SREC.Recognizer.osi_log_level", &Size_t));
1202   CHKLOG(rc, parameterList->put(parameterList, "SREC.voice_enroll.bufsz_kB", &Size_t));
1203   CHKLOG(rc, parameterList->put(parameterList, "SREC.voice_enroll.eos_comfort_frames", &Size_t));
1204   CHKLOG(rc, parameterList->put(parameterList, "SREC.voice_enroll.bos_comfort_frames", &Size_t));
1205 
1206   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.gdiff.one_nbest", &PLChar));
1207   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.gdiff.many_nbest", &PLChar));
1208   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.sd.one_nbest", &PLChar));
1209   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.sd.many_nbest", &PLChar));
1210   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.sd13.one_nbest", &PLChar));
1211   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.sd13.many_nbest", &PLChar));
1212   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.spf.one_nbest", &PLChar));
1213   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.spf.many_nbest", &PLChar));
1214   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.abs.one_nbest", &PLChar));
1215   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.abs.many_nbest", &PLChar));
1216   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.gdiffpf.one_nbest", &PLChar));
1217   CHKLOG(rc, parameterList->put(parameterList, "SREC.Confidence.sigmoid_param.gdiffpf.many_nbest", &PLChar));
1218 
1219   CHKLOG(rc, parameterList->put(parameterList, "CREC.ParVersion", &Float));
1220   CHKLOG(rc, parameterList->put(parameterList, "CREC.useCREClogger", &Int));
1221   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.dimen", &Int));
1222   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.skip", &Int));
1223   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.stay", &Int));
1224   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.durscale", &Int));
1225   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.minvar", &Int));
1226   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.maxvar", &Int));
1227   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.frame_period", &Int));
1228   CHKLOG(rc, parameterList->put(parameterList, "CREC.Acoustic.load_models", &PLChar));
1229   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.mel_dim", &Int));
1230   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.samplerate", &Size_t));
1231   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.premel", &Float));
1232   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.lowcut", &Int));
1233   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.highcut", &Int));
1234   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.window_factor", &Float));
1235   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.offset", &Float));
1236   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.ddmel", &Bool));
1237   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.peakdecayup", &Float));
1238   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.peakdecaydown", &Float));
1239   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.do_skip_even_frames", &Bool));
1240   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.do_smooth_c0", &Bool));
1241   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.melA", &IntArrayList));
1242   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.melB", &IntArrayList));
1243   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.dmelA", &IntArrayList));
1244   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.dmelB", &IntArrayList));
1245   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.ddmelA", &IntArrayList));
1246   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.ddmelB", &IntArrayList));
1247 
1248   /* new for S2G 3 (read from parfile instead of hardcoding) */
1249   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.cmn", &IntArrayList));
1250   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.cmn8", &IntArrayList));
1251   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.cmn11", &IntArrayList));
1252   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.tmn", &IntArrayList));
1253   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.adjust", &IntArrayList));
1254   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.debug", &Bool));
1255   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.sbindex", &IntArrayList));
1256   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.forget_factor", &IntArrayList));
1257   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.cache_resolution", &IntArrayList));
1258   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.inutt.forget_factor2", &IntArrayList));
1259   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.inutt.disable_after", &IntArrayList));
1260   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.inutt.enable_after", &IntArrayList));
1261 
1262 
1263   /* zwz */
1264   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.swicms.do_VN", &Bool));
1265 
1266   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.speech_detect", &Int));
1267   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.ambient_within", &Int));
1268   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.speech_above", &Int));
1269   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.start_windback", &Int));
1270   CHKLOG(rc, parameterList->put(parameterList, "CREC.Frontend.utterance_allowance", &Int));
1271 
1272 
1273   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.dimen", &Int));
1274   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.whole_dimen", &Int));
1275   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.mix_score_scale", &Float));
1276   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.start", &Int));
1277   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.chelt_imelda", &Bool));
1278   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.vfrlimit", &Bool));
1279   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.vfrthresh", &Bool));
1280   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.mix_score_scale", &Float));
1281   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.imelda_scale", &Float));
1282   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.uni_score_scale", &Float));
1283   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.uni_score_offset", &Float));
1284   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.forget_speech", &Int));
1285   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.forget_background", &Int));
1286   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.rel_low", &Int));
1287   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.rel_high", &Int));
1288   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.gap_period", &Int));
1289   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.click_period", &Int));
1290   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.breath_period", &Int));
1291   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.extend_annotation", &Int));
1292   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.min_initial_quiet_frames", &Int));
1293   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.min_annotation_frames", &Int));
1294   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.min_initial_quiet_frames", &Int));
1295   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.max_annotation_frames", &Int));
1296   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.delete_leading_segments", &Int));
1297   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.leading_segment_min_frames", &Int));
1298   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.leading_segment_max_frames", &Int));
1299   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.leading_segment_min_silence_gap_frames", &Int));
1300   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.leading_segment_accept_if_not_found", &Int));
1301   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.snr_holdoff", &Int));
1302   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.min_acceptable_snr", &Int));
1303   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.param", &Int));
1304   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.beep_size", &Int));
1305   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.beep_threshold", &Int));
1306   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.partial_distance_dim", &Int));
1307   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.partial_distance_threshold", &Int));
1308   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.partial_distance_offset", &Int));
1309   CHKLOG(rc, parameterList->put(parameterList, "CREC.Pattern.global_model_means", &IntArrayList));
1310 
1311   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.NBest", &Int));
1312   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.reject", &Int));
1313   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.often", &Int));
1314   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.partial_results", &Bool));
1315   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.wordpen", &Int));
1316   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.viterbi_prune_thresh", &Int));
1317   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_hmm_tokens", &Int));
1318   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_fsmnode_tokens", &Int));
1319   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_word_tokens", &Int));
1320   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_altword_tokens", &Int));
1321   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.num_wordends_per_frame", &Int));
1322   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_fsm_nodes", &Int));
1323   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_fsm_arcs", &Int));
1324   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_searches", &Int));
1325   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.terminal_timeout", &Int));
1326   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.optional_terminal_timeout", &Int));
1327   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.non_terminal_timeout", &Int));
1328   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.eou_threshold", &Int));
1329   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_frames", &Int));
1330   CHKLOG(rc, parameterList->put(parameterList, "CREC.Recognizer.max_model_states", &Int));
1331   CHKLOG(rc, parameterList->put(parameterList, "thread.priority", &UInt16_t));
1332   /* for G2P */
1333   CHKLOG(rc, parameterList->put(parameterList, "G2P.Available", &Bool));
1334   CHKLOG(rc, parameterList->put(parameterList, "G2P.Data", &PLChar));
1335   CHKLOG(rc, parameterList->put(parameterList, "G2P.Dictionary", &PLChar));
1336   /* Enable Get Waveform */
1337   CHKLOG(rc, parameterList->put(parameterList, "enableGetWaveform", &Bool));
1338 
1339   rc = importKeyValueFile(self, filename, addParMapping, parameterList);
1340   if (rc != ESR_SUCCESS)
1341     goto CLEANUP;
1342   CHKLOG(rc, HashMapDestroy(parameterList));
1343   return ESR_SUCCESS;
1344 CLEANUP:
1345   HashMapDestroy(parameterList);
1346   return rc;
1347 }
1348 
ESR_SessionTypeAddListenerImpl(ESR_SessionType * self,ESR_SessionTypeListenerPair * listener)1349 ESR_ReturnCode ESR_SessionTypeAddListenerImpl(ESR_SessionType* self, ESR_SessionTypeListenerPair* listener)
1350 {
1351   ESR_SessionTypeData* data = self->data;
1352   ArrayList* listeners = data->listeners;
1353   ESR_ReturnCode rc;
1354 
1355   CHKLOG(rc, listeners->add(listeners, listener));
1356   return ESR_SUCCESS;
1357 CLEANUP:
1358   return rc;
1359 }
1360 
ESR_SessionTypeRemoveListenerImpl(ESR_SessionType * self,ESR_SessionTypeListenerPair * listener)1361 ESR_ReturnCode ESR_SessionTypeRemoveListenerImpl(ESR_SessionType* self, ESR_SessionTypeListenerPair* listener)
1362 {
1363   ESR_SessionTypeData* data = self->data;
1364   ArrayList* listeners = data->listeners;
1365   ESR_ReturnCode rc;
1366 
1367   CHKLOG(rc, listeners->remove(listeners, listener));
1368   return ESR_SUCCESS;
1369 CLEANUP:
1370   return rc;
1371 }
1372 
ESR_SessionTypeDestroyImpl(ESR_SessionType * self)1373 ESR_ReturnCode ESR_SessionTypeDestroyImpl(ESR_SessionType* self)
1374 {
1375   ESR_SessionTypeData* data = self->data;
1376   size_t hashSize;
1377   ESR_SessionPair* pair;
1378   ESR_ReturnCode rc;
1379 
1380   if (data != NULL)
1381   {
1382     if (data->value != NULL)
1383     {
1384       CHKLOG(rc, HashMapGetSize(data->value, &hashSize));
1385       while (hashSize > 0)
1386       {
1387         CHKLOG(rc, HashMapGetValueAtIndex(data->value, 0, (void **)&pair));
1388 
1389         if (pair->value)
1390         {
1391           if (pair->type == TYPES_INTARRAYLIST)
1392             CHKLOG(rc, IntArrayListDestroy((IntArrayList*) pair->value));
1393           else
1394             FREE(pair->value);
1395         }
1396         CHKLOG(rc, HashMapRemoveAtIndex(data->value, 0));
1397         --hashSize;
1398         FREE(pair);
1399       }
1400 
1401       CHKLOG(rc, HashMapDestroy(data->value));
1402       data->value = NULL;
1403     }
1404     if (data->listeners != NULL)
1405     {
1406       CHKLOG(rc, data->listeners->destroy(data->listeners));
1407       data->listeners = NULL;
1408     }
1409     FREE(data);
1410   }
1411 
1412   FREE(self);
1413   return ESR_SUCCESS;
1414 CLEANUP:
1415   return rc;
1416 }
1417