Home | History | Annotate | Download | only in src
      1 
      2 /*---------------------------------------------------------------------------*
      3  *  NametagImpl.c  *
      4  *                                                                           *
      5  *  Copyright 2007, 2008 Nuance Communciations, Inc.                               *
      6  *                                                                           *
      7  *  Licensed under the Apache License, Version 2.0 (the 'License');          *
      8  *  you may not use this file except in compliance with the License.         *
      9  *                                                                           *
     10  *  You may obtain a copy of the License at                                  *
     11  *      http://www.apache.org/licenses/LICENSE-2.0                           *
     12  *                                                                           *
     13  *  Unless required by applicable law or agreed to in writing, software      *
     14  *  distributed under the License is distributed on an 'AS IS' BASIS,        *
     15  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
     16  *  See the License for the specific language governing permissions and      *
     17  *  limitations under the License.                                           *
     18  *                                                                           *
     19  *---------------------------------------------------------------------------*/
     20 
     21 #include "SR_Nametag.h"
     22 #include "SR_NametagImpl.h"
     23 #include "SR_RecognizerImpl.h"
     24 #include "SR_VocabularyImpl.h"
     25 #include "plog.h"
     26 #include "pmemory.h"
     27 
     28 #define MTAG NULL
     29 #define MAX_STRING_LEN P_PATH_MAX
     30 
     31 ESR_ReturnCode SR_NametagCreate(const SR_RecognizerResult* result, const LCHAR* id, SR_Nametag** self)
     32 {
     33   ESR_Locale locale;
     34   ESR_ReturnCode rc;
     35   size_t len;
     36   LCHAR transcription[MAX_STRING_LEN];
     37 
     38   if (self == NULL)
     39   {
     40     PLogError(L("ESR_INVALID_ARGUMENT"));
     41     return ESR_INVALID_ARGUMENT;
     42   }
     43 
     44   rc = result->getSize(result, &len);
     45   if (rc != ESR_SUCCESS)
     46   {
     47     PLogError(ESR_rc2str(rc));
     48     goto CLEANUP;
     49   }
     50   if (len < 1)
     51   {
     52     PLogError(L("ESR_INVALID_ARGUMENT (recognition result nbest-list size=0)"));
     53     rc = ESR_INVALID_ARGUMENT;
     54     goto CLEANUP;
     55   }
     56   rc = result->getLocale(result, &locale);
     57 
     58   len = MAX_STRING_LEN;
     59 
     60   rc = result->getValue(result, 0, L("meaning"), transcription, &len);
     61 
     62   if (rc != ESR_SUCCESS && rc != ESR_BUFFER_OVERFLOW)
     63   {
     64     PLogError(ESR_rc2str(rc));
     65     goto CLEANUP;
     66   }
     67 
     68 #if USE_HMM_BASED_ENROLLMENT /* srec_context.h */
     69   len = LSTRLEN(transcription)+1;
     70   rc = SR_NametagCreateFromValue(id, transcription, (int)len, self);
     71   if(rc ) goto CLEANUP;
     72 #else
     73 
     74   if(1) {
     75     LCHAR short_pron[MAX_STRING_LEN], *short_pron_ptr;
     76     LCHAR* long_pron = transcription;
     77     LCHAR* multichar;
     78     LCHAR* p;
     79     LCHAR singlechar[2];
     80 
     81     *short_pron = 0;
     82     short_pron_ptr = short_pron;
     83     len = LSTRLEN(L("ph_"));
     84     for (multichar = strtok(long_pron, L(" \t\n\r")); multichar; multichar = strtok(NULL, L(" \t\n\r")))
     85       {
     86 	p = multichar;
     87 	if (LSTRNCMP(p, L("ph_"), len) != 0)
     88 	  {
     89 	    PLogError(L("Expecting 'ph_' prefix, got=%s"), p);
     90 	    rc = ESR_INVALID_STATE;
     91 	    goto CLEANUP;
     92 	  }
     93 	p += len;
     94 	multichar = p;
     95 	while (*p)
     96 	  {
     97 	    if (isdigit(*p))
     98 	      {
     99 		*p = L('\0');
    100 		break;
    101 	      }
    102 	    ++p;
    103 	  }
    104 	if ((rc = SR_Vocabulary_etiinf_conv_from_multichar(locale, multichar, singlechar)) != ESR_SUCCESS)
    105 	  {
    106 	    PLogError(L("Could not convert long to short pron (input=%s, locale=%s)"), multichar, ESR_locale2str(locale));
    107 	    goto CLEANUP;
    108 	  }
    109 	singlechar[1] = 0;
    110 	if((short_pron_ptr - short_pron + 3) >= MAX_STRING_LEN) {
    111 	  PLogError(L("Chopping too long pron in SR_NametagCreate()\n"));
    112 	  break; // just cut if off
    113 	}
    114 	*short_pron_ptr++ = *singlechar;
    115       }
    116     *short_pron_ptr++ = 0; // null-term
    117     *short_pron_ptr++ = 0; // double-null-term!
    118 
    119     /* +2 = +1 for null, +1 for double-null */
    120     rc = SR_NametagCreateFromValue(id, short_pron, (short_pron_ptr-short_pron), self);
    121     if(rc ) goto CLEANUP;
    122   }
    123 #endif
    124 
    125   return ESR_SUCCESS;
    126 CLEANUP:
    127   return rc;
    128 }
    129 
    130 ESR_ReturnCode SR_NametagCreateFromValue(const LCHAR* id, const char* value, size_t len, SR_Nametag** self)
    131 {
    132   SR_NametagImpl* impl;
    133   ESR_ReturnCode rc;
    134 
    135   passert(self != NULL);
    136   impl = NEW(SR_NametagImpl, MTAG);
    137   if (impl == NULL)
    138   {
    139     PLogError(L("ESR_OUT_OF_MEMORY"));
    140     return ESR_OUT_OF_MEMORY;
    141   }
    142 
    143   impl->Interface.setID = &SR_Nametag_SetID;
    144   impl->Interface.getID = &SR_Nametag_GetID;
    145   impl->Interface.getValue = &SR_Nametag_GetValue;
    146   impl->Interface.clone = &SR_Nametag_Clone;
    147   impl->Interface.destroy = &SR_Nametag_Destroy;
    148   impl->id = NULL;
    149   impl->value = NULL;
    150   impl->value = (LCHAR*) MALLOC(sizeof(LCHAR) * (len), MTAG);
    151 
    152   if (impl->value == NULL)
    153   {
    154     rc = ESR_OUT_OF_MEMORY;
    155     PLogError(ESR_rc2str(rc));
    156     goto CLEANUP;
    157   }
    158   impl->value_len = len;
    159   // make sure we have a double-null term
    160   memcpy( (void*)impl->value, value, len);
    161   LSTRNCPY(impl->value, value, len);
    162 
    163   rc = SR_NametagSetID(&impl->Interface, id);
    164   if (rc != ESR_SUCCESS)
    165   {
    166     PLogError(ESR_rc2str(rc));
    167     goto CLEANUP;
    168   }
    169 
    170   *self = (SR_Nametag*) impl;
    171   return ESR_SUCCESS;
    172 CLEANUP:
    173   impl->Interface.destroy(&impl->Interface);
    174   return rc;
    175 }
    176 
    177 ESR_ReturnCode SR_Nametag_Destroy(SR_Nametag* self)
    178 {
    179   SR_NametagImpl* impl = (SR_NametagImpl*) self;
    180   if (impl->value != NULL)
    181   {
    182     FREE(impl->value);
    183     impl->value = NULL;
    184   }
    185   if (impl->id != NULL)
    186   {
    187     FREE(impl->id);
    188     impl->id = NULL;
    189   }
    190   FREE(impl);
    191   return ESR_SUCCESS;
    192 }
    193 
    194 ESR_ReturnCode SR_Nametag_GetID(const SR_Nametag* self, LCHAR** id)
    195 {
    196   SR_NametagImpl* impl = (SR_NametagImpl*) self;
    197 
    198   *id = impl->id;
    199   return ESR_SUCCESS;
    200 }
    201 
    202 ESR_ReturnCode SR_Nametag_GetValue(const SR_Nametag* self, const char** pvalue, size_t* plen)
    203 {
    204   SR_NametagImpl* impl = (SR_NametagImpl*) self;
    205 
    206   *pvalue = (const char*)impl->value;
    207   if(!impl->value)
    208       return ESR_NO_MATCH_ERROR;
    209   *plen = impl->value_len;
    210   return ESR_SUCCESS;
    211 }
    212 
    213 ESR_ReturnCode SR_Nametag_SetID(SR_Nametag* self, const LCHAR* id)
    214 {
    215   SR_NametagImpl* impl = (SR_NametagImpl*) self;
    216   ESR_ReturnCode rc;
    217 
    218   FREE(impl->id);
    219   impl->id = (LCHAR*) MALLOC(sizeof(LCHAR) * (LSTRLEN(id) + 1), MTAG);
    220   if (impl->id == NULL)
    221   {
    222     rc = ESR_OUT_OF_MEMORY;
    223     PLogError(ESR_rc2str(rc));
    224     goto CLEANUP;
    225   }
    226   LSTRCPY(impl->id, id);
    227 
    228   return ESR_SUCCESS;
    229 CLEANUP:
    230   return rc;
    231 }
    232 
    233 ESR_ReturnCode SR_Nametag_Clone(const SR_Nametag* self, SR_Nametag** result)
    234 {
    235   SR_NametagImpl* impl = (SR_NametagImpl*) self;
    236   ESR_ReturnCode rc;
    237 
    238   CHKLOG(rc, SR_NametagCreateFromValue(impl->id, impl->value, LSTRLEN(impl->value)+1, result));
    239   return ESR_SUCCESS;
    240 CLEANUP:
    241   return rc;
    242 }
    243