1 /*---------------------------------------------------------------------------* 2 * NametagsImpl.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 "ESR_Session.h" 21 #include "HashMap.h" 22 #include "LCHAR.h" 23 #include "plog.h" 24 #include "pmemory.h" 25 #include "SR_NametagImpl.h" 26 #include "SR_NametagsImpl.h" 27 28 #define MTAG NULL 29 30 ESR_ReturnCode SR_NametagsCreate(SR_Nametags** self) 31 { 32 SR_NametagsImpl* impl; 33 ESR_ReturnCode rc; 34 35 if (self == NULL) 36 { 37 PLogError(L("ESR_INVALID_ARGUMENT")); 38 return ESR_INVALID_ARGUMENT; 39 } 40 impl = NEW(SR_NametagsImpl, MTAG); 41 if (impl == NULL) 42 { 43 PLogError(L("ESR_OUT_OF_MEMORY")); 44 return ESR_OUT_OF_MEMORY; 45 } 46 47 impl->Interface.load = &SR_NametagsLoadImpl; 48 impl->Interface.save = &SR_NametagsSaveImpl; 49 impl->Interface.add = &SR_NametagsAddImpl; 50 impl->Interface.remove = &SR_NametagsRemoveImpl; 51 impl->Interface.getSize = &SR_NametagsGetSizeImpl; 52 impl->Interface.get = &SR_NametagsGetImpl; 53 impl->Interface.getAtIndex = &SR_NametagsGetAtIndexImpl; 54 impl->Interface.contains = &SR_NametagsContainsImpl; 55 impl->Interface.destroy = &SR_NametagsDestroyImpl; 56 impl->value = NULL; 57 impl->eventLog = NULL; 58 59 CHKLOG(rc, HashMapCreate(&impl->value)); 60 CHKLOG(rc, ESR_SessionGetSize_t(L("SREC.Recognizer.osi_log_level"), &impl->logLevel)); 61 if (impl->logLevel > 0) 62 CHKLOG(rc, ESR_SessionGetProperty(L("eventlog"), (void **)&impl->eventLog, TYPES_SR_EVENTLOG)); 63 CHKLOG(rc, SR_EventLogTokenPointer_BASIC(impl->eventLog, impl->logLevel, L("pointer"), self)); 64 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsCreate"))); 65 *self = (SR_Nametags*) impl; 66 return ESR_SUCCESS; 67 CLEANUP: 68 impl->Interface.destroy(&impl->Interface); 69 return rc; 70 } 71 72 ESR_ReturnCode SR_NametagsLoadImpl(SR_Nametags* self, const LCHAR* filename) 73 { 74 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 75 ESR_ReturnCode rc; 76 PFile* file = NULL; 77 LCHAR line[256]; 78 LCHAR* result = NULL; 79 LCHAR* id; 80 LCHAR* value; 81 SR_Nametag* newNametag = NULL; 82 SR_Nametag* oldNametag; 83 HashMap* nametags = impl->value; 84 size_t size, len, i; 85 LCHAR devicePath[P_PATH_MAX]; 86 LCHAR number[MAX_UINT_DIGITS+1]; 87 #define NAMETAGID_LENGTH 20 88 /* strlen("token\0") == 6 */ 89 #define TOKEN_LENGTH 6 + NAMETAGID_LENGTH 90 LCHAR tokenName[TOKEN_LENGTH]; 91 92 if (filename == NULL) 93 { 94 rc = ESR_INVALID_STATE; 95 PLogError(ESR_rc2str(rc)); 96 goto CLEANUP; 97 } 98 size = P_PATH_MAX; 99 CHKLOG(rc, ESR_SessionGetLCHAR(L("cmdline.nametagPath"), devicePath, &size)); 100 /* check if the filename has the path */ 101 if (LSTRNCMP(filename, devicePath, LSTRLEN(devicePath)) != 0) 102 LSTRCAT(devicePath, filename); 103 else 104 LSTRCPY(devicePath, filename); 105 file = pfopen ( devicePath, L("r")); 106 /* CHKLOG(rc, PFileSystemCreatePFile(devicePath, ESR_TRUE, &file)); 107 CHKLOG(rc, file->open(file, L("r")));*/ 108 109 if ( file == NULL ) 110 goto CLEANUP; 111 112 /* Flush collection */ 113 CHKLOG(rc, nametags->getSize(nametags, &size)); 114 for (i = 0; i < size; ++i) 115 { 116 CHKLOG(rc, nametags->getValueAtIndex(nametags, 0, (void **)&oldNametag)); 117 CHKLOG(rc, nametags->removeAtIndex(nametags, 0)); 118 CHKLOG(rc, oldNametag->destroy(oldNametag)); 119 } 120 len = MAX_UINT_DIGITS + 1; 121 CHKLOG(rc, lultostr(size, number, &len, 10)); 122 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("removeCount"), number)); 123 124 while (ESR_TRUE) 125 { 126 result = pfgets ( line, 256, file ); 127 if (result == NULL) 128 break; 129 if (LSTRLEN(line) == 255) 130 { 131 rc = ESR_BUFFER_OVERFLOW; 132 PLogError(ESR_rc2str(rc)); 133 goto CLEANUP; 134 } 135 lstrtrim(line); 136 137 /* Get the Nametag ID */ 138 id = line; 139 140 /* Find next whitespace */ 141 for (value = id + 1; *value != L('\0') && !LISSPACE(*value); ++value); 142 if (*value == L('\0')) 143 { 144 rc = ESR_INVALID_STATE; 145 PLogError(L("%s: Cannot find end of Nametag id"), ESR_rc2str(rc)); 146 goto CLEANUP; 147 } 148 /* Delimit end of nametag ID */ 149 *value = L('\0'); 150 151 /* Find next non-whitespace */ 152 for (++value; *value != L('\0') && LISSPACE(*value); ++value); 153 if (*value == L('\0')) 154 { 155 rc = ESR_INVALID_STATE; 156 PLogError(L("%s: Cannot find Nametag value"), ESR_rc2str(rc)); 157 goto CLEANUP; 158 } 159 160 /* We now have both the Nametag ID and value */ 161 len = (LSTRLEN(value)+1) * sizeof(LCHAR) ; 162 CHKLOG(rc, SR_NametagCreateFromValue(id, (const char*)value, len, &newNametag)); 163 /* Add Nametag to collection */ 164 CHKLOG(rc, impl->value->put(impl->value, id, newNametag)); 165 166 if (LSTRLEN(id) > NAMETAGID_LENGTH) 167 { 168 rc = ESR_BUFFER_OVERFLOW; 169 PLogError(ESR_rc2str(rc)); 170 goto CLEANUP; 171 } 172 psprintf(tokenName, L("nametag[%s]"), id); 173 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, tokenName, value)); 174 newNametag = NULL; 175 } 176 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("filename"), filename)); 177 CHKLOG(rc, nametags->getSize(nametags, &size)); 178 len = MAX_UINT_DIGITS + 1; 179 CHKLOG(rc, lultostr(size, number, &len, 10)); 180 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("addCount"), number)); 181 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsLoad"))); 182 pfclose (file); 183 return ESR_SUCCESS; 184 CLEANUP: 185 if (file != NULL) 186 pfclose (file); 187 if (newNametag != NULL) 188 newNametag->destroy(newNametag); 189 return rc; 190 } 191 192 ESR_ReturnCode SR_NametagsSaveImpl(SR_Nametags* self, const LCHAR* filename) 193 { 194 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 195 ESR_ReturnCode rc; 196 PFile* file = NULL; 197 size_t size, i; 198 HashMap* nametags = impl->value; 199 SR_NametagImpl* nametag; 200 LCHAR* id; 201 size_t len; 202 LCHAR devicePath[P_PATH_MAX]; 203 #define NAMETAG_LENGTH 200 204 LCHAR nametagBuffer[NAMETAG_LENGTH]; 205 LCHAR number[MAX_UINT_DIGITS+1]; 206 #define NAMETAGID_LENGTH 20 207 /* "token\0" == 6 */ 208 #define TOKEN_LENGTH 6 + NAMETAGID_LENGTH 209 LCHAR tokenName[TOKEN_LENGTH]; 210 size_t num_written; 211 212 if (filename == NULL) 213 { 214 rc = ESR_INVALID_STATE; 215 PLogError(ESR_rc2str(rc)); 216 goto CLEANUP; 217 } 218 size = P_PATH_MAX; 219 CHKLOG(rc, ESR_SessionGetLCHAR(L("cmdline.nametagPath"), devicePath, &size)); 220 221 if (LSTRNCMP(filename, devicePath, LSTRLEN(devicePath)) != 0) 222 LSTRCAT(devicePath, filename); 223 else 224 LSTRCPY(devicePath, filename); 225 226 file = pfopen ( devicePath, L("w")); 227 /* CHKLOG(rc, PFileSystemCreatePFile(devicePath, ESR_TRUE, &file)); 228 CHKLOG(rc, file->open(file, L("w")));*/ 229 CHKLOG(rc, nametags->getSize(nametags, &size)); 230 231 if ( file == NULL ) 232 goto CLEANUP; 233 234 for (i = 0; i < size; ++i) 235 { 236 CHKLOG(rc, nametags->getValueAtIndex(nametags, i, (void **)&nametag)); 237 238 CHKLOG(rc, nametag->Interface.getID(&nametag->Interface, &id)); 239 240 if (LSTRLEN(id) + 1 + LSTRLEN(nametag->value) + 2 >= NAMETAG_LENGTH) 241 { 242 rc = ESR_BUFFER_OVERFLOW; 243 PLogError(ESR_rc2str(rc)); 244 goto CLEANUP; 245 } 246 psprintf(nametagBuffer, L("%s %s\n"), id, nametag->value); 247 len = LSTRLEN(nametagBuffer); 248 /* CHKLOG(rc, file->write(file, nametagBuffer, sizeof(LCHAR), &len));*/ 249 num_written = pfwrite ( nametagBuffer, sizeof ( LCHAR ), len, file ); 250 251 if ( num_written != len ) 252 goto CLEANUP; 253 254 if (LSTRLEN(id) > NAMETAGID_LENGTH) 255 { 256 rc = ESR_BUFFER_OVERFLOW; 257 PLogError(ESR_rc2str(rc)); 258 goto CLEANUP; 259 } 260 psprintf(tokenName, L("nametag[%s]"), id); 261 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, tokenName, nametag->value)); 262 } 263 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("filename"), filename)); 264 len = MAX_UINT_DIGITS + 1; 265 CHKLOG(rc, lultostr(size, (LCHAR*) &number, &len, 10)); 266 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("saveCount"), number)); 267 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsSave"))); 268 pfclose (file); 269 return ESR_SUCCESS; 270 CLEANUP: 271 if (file != NULL) 272 pfclose (file); 273 return rc; 274 } 275 276 ESR_ReturnCode SR_NametagsAddImpl(SR_Nametags* self, SR_Nametag* nametag) 277 { 278 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 279 HashMap* nametags = impl->value; 280 LCHAR* id; 281 ESR_BOOL exists; 282 ESR_ReturnCode rc; 283 284 CHKLOG(rc, nametag->getID(nametag, &id)); 285 CHKLOG(rc, nametags->containsKey(nametags, id, &exists)); 286 if (exists) 287 { 288 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("id"), id)); 289 rc = ESR_IDENTIFIER_COLLISION; 290 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("rc"), ESR_rc2str(rc))); 291 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsAdd"))); 292 rc = ESR_IDENTIFIER_COLLISION; 293 PLogError(ESR_rc2str(rc)); 294 goto CLEANUP; 295 } 296 CHKLOG(rc, nametags->put(nametags, id, nametag)); 297 298 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("id"), id)); 299 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsAdd"))); 300 return ESR_SUCCESS; 301 CLEANUP: 302 return rc; 303 } 304 305 ESR_ReturnCode SR_NametagsRemoveImpl(SR_Nametags* self, const LCHAR* id) 306 { 307 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 308 HashMap* nametags = impl->value; 309 ESR_ReturnCode rc; 310 311 CHKLOG(rc, nametags->remove(nametags, id)); 312 313 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("id"), id)); 314 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsRemove"))); 315 return ESR_SUCCESS; 316 CLEANUP: 317 return rc; 318 } 319 320 ESR_ReturnCode SR_NametagsGetSizeImpl(SR_Nametags* self, size_t* result) 321 { 322 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 323 HashMap* nametags = impl->value; 324 ESR_ReturnCode rc; 325 326 CHKLOG(rc, nametags->getSize(nametags, result)); 327 return ESR_SUCCESS; 328 CLEANUP: 329 return rc; 330 } 331 332 ESR_ReturnCode SR_NametagsGetImpl(SR_Nametags* self, const LCHAR* id, SR_Nametag** nametag) 333 { 334 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 335 HashMap* nametags = impl->value; 336 ESR_ReturnCode rc; 337 338 CHKLOG(rc, nametags->get(nametags, id, (void **)nametag)); 339 340 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("id"), id)); 341 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsGet"))); 342 return ESR_SUCCESS; 343 CLEANUP: 344 return rc; 345 } 346 347 ESR_ReturnCode SR_NametagsGetAtIndexImpl(SR_Nametags* self, size_t index, SR_Nametag** nametag) 348 { 349 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 350 HashMap* nametags = impl->value; 351 LCHAR* id; 352 ESR_ReturnCode rc; 353 354 CHKLOG(rc, nametags->getValueAtIndex(nametags, index, (void **)nametag)); 355 356 CHKLOG(rc, (*nametag)->getID(*nametag, &id)); 357 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("id"), id)); 358 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsGetAtIndex"))); 359 return ESR_SUCCESS; 360 CLEANUP: 361 return rc; 362 } 363 364 ESR_ReturnCode SR_NametagsContainsImpl(SR_Nametags* self, const LCHAR* id, ESR_BOOL* result) 365 { 366 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 367 HashMap* nametags = impl->value; 368 ESR_ReturnCode rc; 369 370 CHKLOG(rc, nametags->containsKey(nametags, id, result)); 371 return ESR_SUCCESS; 372 CLEANUP: 373 return rc; 374 } 375 376 ESR_ReturnCode SR_NametagsDestroyImpl(SR_Nametags* self) 377 { 378 SR_NametagsImpl* impl = (SR_NametagsImpl*) self; 379 LCHAR number[MAX_UINT_DIGITS+1]; 380 ESR_ReturnCode rc; 381 382 if (impl->value != NULL) 383 { 384 size_t size, i, len; 385 HashMap* list = impl->value; 386 SR_Nametag* nametag; 387 388 CHKLOG(rc, list->getSize(list, &size)); 389 for (i = 0; i < size; ++i) 390 { 391 CHKLOG(rc, list->getValueAtIndex(list, 0, (void **)&nametag)); 392 CHKLOG(rc, list->removeAtIndex(list, 0)); 393 CHKLOG(rc, nametag->destroy(nametag)); 394 } 395 396 len = MAX_UINT_DIGITS + 1; 397 CHKLOG(rc, lultostr(size, (LCHAR*) &number, &len, 10)); 398 CHKLOG(rc, SR_EventLogToken_BASIC(impl->eventLog, impl->logLevel, L("removeCount"), number)); 399 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsDestroy"))); 400 list->destroy(list); 401 impl->value = NULL; 402 } 403 CHKLOG(rc, SR_EventLogTokenPointer_BASIC(impl->eventLog, impl->logLevel, L("pointer"), self)); 404 CHKLOG(rc, SR_EventLogEvent_BASIC(impl->eventLog, impl->logLevel, L("SR_NametagsDestroy"))); 405 impl->eventLog = NULL; 406 FREE(self); 407 return ESR_SUCCESS; 408 CLEANUP: 409 return rc; 410 } 411