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