• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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