Home | History | Annotate | Download | only in src
      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