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
SR_NametagCreate(const SR_RecognizerResult * result,const LCHAR * id,SR_Nametag ** self)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
SR_NametagCreateFromValue(const LCHAR * id,const char * value,size_t len,SR_Nametag ** self)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
SR_Nametag_Destroy(SR_Nametag * self)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
SR_Nametag_GetID(const SR_Nametag * self,LCHAR ** id)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
SR_Nametag_GetValue(const SR_Nametag * self,const char ** pvalue,size_t * plen)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
SR_Nametag_SetID(SR_Nametag * self,const LCHAR * id)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
SR_Nametag_Clone(const SR_Nametag * self,SR_Nametag ** result)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