blob: 94cd25ab364f3093d8c1d6305f9616a4251738fa [file] [log] [blame]
Jean-Michel Trivi39358f02009-07-01 18:13:11 -07001/*
2 * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070016*/
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070017
18#include "svox_ssml_parser.h"
19#include <utils/Log.h>
20#include <cutils/jstring.h>
21#include <string.h>
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070022#include <utils/String16.h>
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070023
24#define SSML_PITCH_XLOW "50"
25#define SSML_PITCH_LOW "75"
26#define SSML_PITCH_MEDIUM "100"
27#define SSML_PITCH_HIGH "150"
28#define SSML_PITCH_XHIGH "200"
29#define SSML_RATE_XSLOW "30"
30#define SSML_RATE_SLOW "60"
31#define SSML_RATE_MEDIUM "100"
32#define SSML_RATE_FAST "250"
33#define SSML_RATE_XFAST "500"
34#define SSML_VOLUME_SILENT "0"
Charles Chen474a3192009-07-17 18:02:16 -070035#define SSML_VOLUME_XLOW "25"
36#define SSML_VOLUME_LOW "70"
Jean-Michel Trivi0e684c32009-07-21 18:17:27 -070037#define SSML_VOLUME_MEDIUM "120"
38#define SSML_VOLUME_LOUD "300"
39#define SSML_VOLUME_XLOUD "450"
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070040#define SSML_BREAK_NONE "0ms"
41#define SSML_BREAK_XWEAK "100ms"
42#define SSML_BREAK_WEAK "300ms"
43#define SSML_BREAK_MEDIUM "600ms"
44#define SSML_BREAK_STRONG "1s"
45#define SSML_BREAK_XSTRONG "3s"
46
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070047extern int cnvIpaToXsampa(const char16_t* ipaString, size_t ipaStringSize, char** outXsampaString);
48extern char * createPhonemeString( const char * xsampa, int length );
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070049
50SvoxSsmlParser::SvoxSsmlParser() : m_isInBreak(0), m_appendix(NULL), m_docLanguage(NULL)
51{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070052 mParser = XML_ParserCreate("UTF-8");
53 if (mParser)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070054 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070055 XML_SetElementHandler(mParser, starttagHandler, endtagHandler);
56 XML_SetCharacterDataHandler(mParser, textHandler);
57 XML_SetUserData(mParser, (void*)this);
58 m_datasize = 512;
59 m_data = new char[m_datasize];
Narayan Kamathc3a05c02018-02-06 11:02:21 +000060 if (!m_data)
61 {
62 ALOGE("Error: failed to allocate memory for string!\n");
63 } else {
64 memset(m_data, 0, m_datasize);
65 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070066 }
67}
68
69SvoxSsmlParser::~SvoxSsmlParser()
70{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070071 if (mParser)
72 XML_ParserFree(mParser);
73 if (m_data)
74 delete [] m_data;
75 if (m_appendix)
76 delete [] m_appendix;
77 if (m_docLanguage)
78 delete [] m_docLanguage;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070079}
80
81int SvoxSsmlParser::initSuccessful()
82{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070083 return (mParser && m_data);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070084}
85
86int SvoxSsmlParser::parseDocument(const char* ssmldoc, int isFinal)
87{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070088 int doclen = (int)strlen(ssmldoc) + 1;
89 int status = XML_Parse(mParser, ssmldoc, doclen, isFinal);
90 if (status == XML_STATUS_ERROR)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070091 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070092 /* Note: for some reason Expat almost always complains about invalid tokens, even when document is well formed */
Steve Block659851c2012-01-04 20:01:45 +000093 ALOGI("Parser error at line %d: %s\n", (int)XML_GetCurrentLineNumber(mParser), XML_ErrorString(XML_GetErrorCode(mParser)));
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070094 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070095 return status;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070096}
97
98char* SvoxSsmlParser::getParsedDocument()
99{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700100 return m_data;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700101}
102
103char* SvoxSsmlParser::getParsedDocumentLanguage()
104{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700105 return m_docLanguage;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700106}
107
108void SvoxSsmlParser::starttagHandler(void* data, const XML_Char* element, const XML_Char** attributes)
109{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700110 ((SvoxSsmlParser*)data)->startElement(element, attributes);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700111}
112
113void SvoxSsmlParser::startElement(const XML_Char* element, const XML_Char** attributes)
114{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700115 if (strcmp(element, "speak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700116 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700117 if (strlen(m_data) > 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700118 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700119 /* we have old data, get rid of it and reallocate memory */
120 delete m_data;
121 m_data = NULL;
122 m_datasize = 512;
123 m_data = new char[m_datasize];
124 if (!m_data)
125 {
Steve Block31a809c2012-01-06 19:10:34 +0000126 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700127 return;
Narayan Kamathc3a05c02018-02-06 11:02:21 +0000128 } else {
129 memset(m_data, 0, m_datasize);
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700130 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700131 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700132
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700133 /* the only attribute supported in the speak tag is xml:lang, all others are ignored */
134 for (int i = 0; attributes[i]; i += 2)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700135 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700136 if (strcmp(attributes[i], "xml:lang") == 0)
137 {
138 if (!m_docLanguage)
139 {
140 m_docLanguage = new char[strlen(attributes[i+1])+1];
141 }
142 strcpy(m_docLanguage, attributes[i+1]);
143 break;
144 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700145 }
146 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700147 else if (strcmp(element, "p") == 0) /* currently no attributes are supported for <p> */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700148 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700149 if (strlen(m_data) + 4 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700150 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700151 if (!growDataSize(100))
152 {
Steve Block31a809c2012-01-06 19:10:34 +0000153 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700154 return;
155 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700156 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700157 strcat(m_data, "<p>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700158 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700159 else if (strcmp(element, "s") == 0) /* currently no attributes are supported for <s> */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700160 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700161 if (strlen(m_data) + 4 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700162 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700163 if (!growDataSize(100))
164 {
Steve Block31a809c2012-01-06 19:10:34 +0000165 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700166 return;
167 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700168 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700169 strcat(m_data, "<s>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700170 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700171 else if (strcmp(element, "phoneme") == 0) /* only ipa and xsampa alphabets are supported */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700172 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700173 int alpha = 1; /* set to 1 if alphabet is ipa */
174 int tagComplete = 0; /* set to 1 if phoneme tag has already been added */
175 char16_t* ph = NULL;
176 char* xsampastr = NULL;
177 size_t phsize = 0;
178 size_t xsampasize = 0;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700179
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700180 for (int i = 0; attributes[i]; i += 2)
181 {
182 if (strcmp(attributes[i], "alphabet") == 0)
183 {
184 if (strcmp(attributes[i+1], "xsampa") == 0)
185 {
186 alpha = 0;
187 }
188 }
189 if (strcmp(attributes[i], "ph") == 0)
190 {
191 ph = new char16_t[strlen8to16(attributes[i+1]) + 1];
192 ph = strdup8to16(attributes[i+1], &phsize);
193 }
194 }
195 if (!ph)
196 {
197 /* error, no phonetic string */
Steve Block31a809c2012-01-06 19:10:34 +0000198 ALOGE("Error: bad SSML syntax, ph attribute not supplied.");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700199 return;
200 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700201
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700202 if (alpha)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700203 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700204 /* need to convert phoneme string to xsampa */
205 xsampasize = cnvIpaToXsampa(ph, phsize, &xsampastr);
206 delete [] ph;
207 if (!xsampastr)
208 {
Steve Block31a809c2012-01-06 19:10:34 +0000209 ALOGE("Error: failed to allocate memory for IPA string conversion");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700210 return;
211 }
212 }
213 else
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700214 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700215 xsampastr = strndup16to8(ph, phsize);
216 xsampasize = strlen(xsampastr);
217 delete [] ph;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700218 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700219
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700220 /* split XSAMPA string into multiple phonemes if needed */
221 if (strstr(xsampastr, " ") || strstr(xsampastr, "#")) /* check again to see if we have multiple words */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700222 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700223 char* phonstr = createPhonemeString(xsampastr, strlen(xsampastr) + 1);
224 free(xsampastr);
225 xsampastr = NULL;
226 xsampastr = (char*)malloc(strlen(phonstr) + 1);
227 strcpy(xsampastr, phonstr);
228 free(phonstr);
229 phonstr = NULL;
230 tagComplete = 1;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700231 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700232
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700233 if (tagComplete)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700234 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700235 if (strlen(m_data) + strlen(xsampastr) + 1 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700236 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700237 if (!growDataSize(100))
238 {
Steve Block31a809c2012-01-06 19:10:34 +0000239 ALOGE("Error: failed to allocate memory for string!");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700240 free(xsampastr);
241 return;
242 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700243 }
244 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700245 else
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700246 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700247 if (strlen(m_data) + strlen(xsampastr) + 17 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700248 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700249 if (!growDataSize(100))
250 {
Steve Block31a809c2012-01-06 19:10:34 +0000251 ALOGE("Error: failed to allocate memory for string!");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700252 free(xsampastr);
253 return;
254 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700255 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700256 strcat(m_data, "<phoneme ph='");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700257 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700258
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700259 strcat(m_data, xsampastr);
260 free(xsampastr);
261
262 if (!tagComplete)
263 {
264 if (strlen(m_data) + 4 > (size_t)m_datasize)
265 {
266 if (!growDataSize(100))
267 {
Steve Block31a809c2012-01-06 19:10:34 +0000268 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700269 return;
270 }
271 }
272 strcat(m_data, "'/>");
273 }
274
275 m_isInBreak = 1; /* set flag to indicate any text between open and close tag is to be discarded */
276 }
277 else if (strcmp(element, "break") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700278 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700279 if (strlen(m_data) + 17 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700280 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700281 if (!growDataSize(100))
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700282 {
Steve Block31a809c2012-01-06 19:10:34 +0000283 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700284 return;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700285 }
286 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700287 strcat(m_data, "<break time='");
288 char* time = NULL;
289
290 for (int i = 0; attributes[i]; i += 2)
291 {
292 if (strcmp(attributes[i], "time") == 0)
293 {
294 time = new char[strlen(attributes[i+1]) + 1];
295 if (!time)
296 {
Steve Block31a809c2012-01-06 19:10:34 +0000297 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700298 return;
299 }
300 strcpy(time, attributes[i+1]);
301 }
302 else if (strcmp(attributes[i], "strength") == 0 && !time)
303 {
304 time = convertBreakStrengthToTime(attributes[i+1]);
305 }
306 }
307 if (!time)
308 {
309 time = new char[6];
310 if (!time)
311 {
Steve Block31a809c2012-01-06 19:10:34 +0000312 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700313 return;
314 }
315 strcpy(time, SSML_BREAK_WEAK); /* if no time or strength attributes are specified, default to weak break */
316 }
317 if (strlen(m_data) + strlen(time) + 4 > (size_t)m_datasize)
318 {
319 if (!growDataSize(100))
320 {
Steve Block31a809c2012-01-06 19:10:34 +0000321 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700322 return;
323 }
324 }
325 strcat(m_data, time);
326 strcat(m_data, "'/>");
327 m_isInBreak = 1; /* set flag to indicate any text between open and close tag is to be discarded */
328 }
329 else if (strcmp(element, "prosody") == 0) /* only pitch, rate and volume attributes are supported */
330 {
331 for (int i = 0; attributes[i]; i += 2)
332 {
333 if (strcmp(attributes[i], "pitch") == 0)
334 {
335 char* svoxpitch = convertToSvoxPitch(attributes[i+1]);
336 if (!svoxpitch)
337 {
Steve Block31a809c2012-01-06 19:10:34 +0000338 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700339 return;
340 }
341 if (!svoxpitch)
342 {
343 svoxpitch = new char[4];
344 if (!svoxpitch)
345 {
Steve Block31a809c2012-01-06 19:10:34 +0000346 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700347 return;
348 }
349 strcpy(svoxpitch, "100");
350 }
351 char* pitch = new char[17 + strlen(svoxpitch)];
352 if (!pitch)
353 {
Steve Block31a809c2012-01-06 19:10:34 +0000354 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700355 return;
356 }
357 sprintf(pitch, "<pitch level='%s'>", svoxpitch);
358 if (strlen(m_data) + strlen(pitch) + 1 > (size_t)m_datasize)
359 {
360 if (!growDataSize(100))
361 {
Steve Block31a809c2012-01-06 19:10:34 +0000362 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700363 return;
364 }
365 }
366 strcat(m_data, pitch);
367 if (!m_appendix)
368 {
369 m_appendix = new char[30];
370 m_appendix[0] = '\0';
371 }
372 strcat(m_appendix, "</pitch>");
373 delete [] svoxpitch;
374 delete [] pitch;
375 }
376 else if (strcmp(attributes[i], "rate") == 0)
377 {
378 char* svoxrate = convertToSvoxRate(attributes[i+1]);
379 if (!svoxrate)
380 {
381 svoxrate = new char[4];
382 if (!svoxrate)
383 {
Steve Block31a809c2012-01-06 19:10:34 +0000384 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700385 return;
386 }
387 strcpy(svoxrate, "100");
388 }
389 char* rate = new char[17 + strlen(svoxrate)];
390 if (!rate)
391 {
Steve Block31a809c2012-01-06 19:10:34 +0000392 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700393 return;
394 }
395 sprintf(rate, "<speed level='%s'>", svoxrate);
396 if (strlen(m_data) + strlen(rate) + 1 > (size_t)m_datasize)
397 {
398 if (!growDataSize(100))
399 {
Steve Block31a809c2012-01-06 19:10:34 +0000400 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700401 return;
402 }
403 }
404 strcat(m_data, rate);
405 if (!m_appendix)
406 {
407 m_appendix = new char[30];
408 if (!m_appendix)
409 {
Steve Block31a809c2012-01-06 19:10:34 +0000410 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700411 return;
412 }
413 m_appendix[0] = '\0';
414 }
415 strcat(m_appendix, "</speed>");
416 delete [] svoxrate;
417 delete [] rate;
418 }
419 else if (strcmp(attributes[i], "volume") == 0)
420 {
421 char* svoxvol = convertToSvoxVolume(attributes[i+1]);
422 if (!svoxvol)
423 {
424 svoxvol = new char[4];
425 if (!svoxvol)
426 {
Steve Block31a809c2012-01-06 19:10:34 +0000427 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700428 return;
429 }
430 strcpy(svoxvol, "100");
431 }
432 char* volume = new char[18 + strlen(svoxvol)];
433 if (!volume)
434 {
Steve Block31a809c2012-01-06 19:10:34 +0000435 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700436 return;
437 }
438 sprintf(volume, "<volume level='%s'>", svoxvol);
439 if (strlen(m_data) + strlen(volume) + 1 > (size_t)m_datasize)
440 {
441 if (!growDataSize(100))
442 {
Steve Block31a809c2012-01-06 19:10:34 +0000443 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700444 return;
445 }
446 }
447 strcat(m_data, volume);
448 if (!m_appendix)
449 {
450 m_appendix = new char[30];
451 m_appendix[0] = '\0';
452 }
453 strcat(m_appendix, "</volume>");
454 delete [] svoxvol;
455 delete [] volume;
456 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700457 }
458 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700459 else if (strcmp(element, "audio") == 0) /* only 16kHz 16bit wav files are supported as src */
460 {
461 if (strlen(m_data) + 17 > (size_t)m_datasize)
462 {
463 if (!growDataSize(100))
464 {
Steve Block31a809c2012-01-06 19:10:34 +0000465 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700466 return;
467 }
468 }
469 strcat(m_data, "<usesig file='");
470
471 for (int i = 0; attributes[i]; i += 2)
472 {
473 if (strcmp(attributes[i], "src") == 0)
474 {
475 if (strlen(m_data) + strlen(attributes[i+1]) + 1 > (size_t)m_datasize)
476 {
477 if (!growDataSize(100))
478 {
Steve Block31a809c2012-01-06 19:10:34 +0000479 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700480 return;
481 }
482 }
483 strcat(m_data, attributes[i+1]);
484 }
485 }
486 strcat(m_data, "'>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700487 }
488}
489
490void SvoxSsmlParser::endtagHandler(void* data, const XML_Char* element)
491{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700492 ((SvoxSsmlParser*)data)->endElement(element);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700493}
494
495void SvoxSsmlParser::endElement(const XML_Char* element)
496{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700497 if (strcmp(element, "speak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700498 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700499 /* do nothing */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700500 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700501 else if (strcmp(element, "p") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700502 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700503 if (strlen(m_data) + 5 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700504 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700505 if (!growDataSize(100))
506 {
Steve Block31a809c2012-01-06 19:10:34 +0000507 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700508 return;
509 }
510 }
511 strcat(m_data, "</p>");
512 }
513 else if (strcmp(element, "s") == 0)
514 {
515 if (strlen(m_data) + 5 > (size_t)m_datasize)
516 {
517 if (!growDataSize(100))
518 {
Steve Block31a809c2012-01-06 19:10:34 +0000519 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700520 return;
521 }
522 }
523 strcat(m_data, "</s>");
524 }
525 else if (strcmp(element, "phoneme") == 0)
526 {
527 m_isInBreak = 0; /* indicate we are no longer in phoneme tag */
528 }
529 else if (strcmp(element, "break") == 0)
530 {
531 m_isInBreak = 0; /* indicate we are no longer in break tag */
532 }
533 else if (strcmp(element, "prosody") == 0)
534 {
535 if (m_appendix)
536 {
537 if (strlen(m_data) + strlen(m_appendix) + 1 > (size_t)m_datasize)
538 {
539 if (!growDataSize(100))
540 {
Steve Block31a809c2012-01-06 19:10:34 +0000541 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700542 return;
543 }
544 }
545 strcat(m_data, m_appendix);
546 delete [] m_appendix;
547 m_appendix = NULL;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700548 }
549 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700550 else if (strcmp(element, "audio") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700551 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700552 if (strlen(m_data) + 10 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700553 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700554 if (!growDataSize(100))
555 {
Steve Block31a809c2012-01-06 19:10:34 +0000556 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700557 return;
558 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700559 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700560 strcat(m_data, "</usesig>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700561 }
562}
563
564void SvoxSsmlParser::textHandler(void* data, const XML_Char* text, int length)
565{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700566 ((SvoxSsmlParser*)data)->textElement(text, length);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700567}
568
569void SvoxSsmlParser::textElement(const XML_Char* text, int length)
570{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700571 if (m_isInBreak)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700572 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700573 return; /* handles the case when someone has added text inside the break or phoneme tag - this text is thrown away */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700574 }
575
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700576 char* content = new char[length + 1];
577 if (!content)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700578 {
Steve Block31a809c2012-01-06 19:10:34 +0000579 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700580 return;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700581 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700582 strncpy(content, text, length);
583 content[length] = '\0';
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700584
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700585 if (strlen(m_data) + strlen(content) + 1 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700586 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700587 if (!growDataSize(100))
588 {
Steve Block31a809c2012-01-06 19:10:34 +0000589 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700590 return;
591 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700592 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700593 strcat(m_data, content);
594 delete [] content;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700595}
596
597/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700598convertToSvoxPitch
599Converts SSML pitch labels to SVOX pitch levels
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700600*/
601char* SvoxSsmlParser::convertToSvoxPitch(const char* value)
602{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700603 char* converted = NULL;
604 if (strcmp(value, "x-low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700605 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700606 converted = new char[4];
607 if (!converted)
608 {
Steve Block31a809c2012-01-06 19:10:34 +0000609 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700610 return NULL;
611 }
612 strcpy(converted, SSML_PITCH_XLOW);
613 }
614 else if (strcmp(value, "low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700615 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700616 converted = new char[4];
617 if (!converted)
618 {
Steve Block31a809c2012-01-06 19:10:34 +0000619 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700620 return NULL;
621 }
622 strcpy(converted, SSML_PITCH_LOW);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700623 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700624 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700625 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700626 converted = new char[4];
627 if (!converted)
628 {
Steve Block31a809c2012-01-06 19:10:34 +0000629 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700630 return NULL;
631 }
632 strcpy(converted, SSML_PITCH_MEDIUM);
633 }
634 else if (strcmp(value, "default") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700635 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700636 converted = new char[4];
637 if (!converted)
638 {
Steve Block31a809c2012-01-06 19:10:34 +0000639 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700640 return NULL;
641 }
642 strcpy(converted, SSML_PITCH_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700643 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700644 else if (strcmp(value, "high") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700645 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700646 converted = new char[4];
647 if (!converted)
648 {
Steve Block31a809c2012-01-06 19:10:34 +0000649 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700650 return NULL;
651 }
652 strcpy(converted, SSML_PITCH_HIGH);
653 }
654 else if (strcmp(value, "x-high") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700655 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700656 converted = new char[4];
657 if (!converted)
658 {
Steve Block31a809c2012-01-06 19:10:34 +0000659 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700660 return NULL;
661 }
662 strcpy(converted, SSML_PITCH_XHIGH);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700663 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700664 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700665}
666
667/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700668 convertToSvoxRate
669 Converts SSML rate labels to SVOX speed levels
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700670*/
671char* SvoxSsmlParser::convertToSvoxRate(const char* value)
672{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700673 char* converted = NULL;
674 if (strcmp(value, "x-slow") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700675 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700676 converted = new char[4];
677 if (!converted)
678 {
Steve Block31a809c2012-01-06 19:10:34 +0000679 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700680 return NULL;
681 }
682 strcpy(converted, SSML_RATE_XSLOW);
683 }
684 else if (strcmp(value, "slow") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700685 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700686 converted = new char[4];
687 if (!converted)
688 {
Steve Block31a809c2012-01-06 19:10:34 +0000689 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700690 return NULL;
691 }
692 strcpy(converted, SSML_RATE_SLOW);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700693 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700694 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700695 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700696 converted = new char[4];
697 if (!converted)
698 {
Steve Block31a809c2012-01-06 19:10:34 +0000699 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700700 return NULL;
701 }
702 strcpy(converted, SSML_RATE_MEDIUM);
703 }
704 else if (strcmp(value, "default") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700705 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700706 converted = new char[4];
707 if (!converted)
708 {
Steve Block31a809c2012-01-06 19:10:34 +0000709 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700710 return NULL;
711 }
712 strcpy(converted, SSML_RATE_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700713 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700714 else if (strcmp(value, "fast") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700715 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700716 converted = new char[4];
717 if (!converted)
718 {
Steve Block31a809c2012-01-06 19:10:34 +0000719 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700720 return NULL;
721 }
722 strcpy(converted, SSML_RATE_FAST);
723 }
724 else if (strcmp(value, "x-fast") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700725 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700726 converted = new char[4];
727 if (!converted)
728 {
Steve Block31a809c2012-01-06 19:10:34 +0000729 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700730 return NULL;
731 }
732 strcpy(converted, SSML_RATE_XFAST);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700733 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700734 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700735}
736
737/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700738convertToSvoxVolume
739Converts SSML volume labels to SVOX volume levels
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700740*/
741char* SvoxSsmlParser::convertToSvoxVolume(const char* value)
742{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700743 char* converted = NULL;
744 if (strcmp(value, "silent") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700745 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700746 converted = new char[4];
747 if (!converted)
748 {
Steve Block31a809c2012-01-06 19:10:34 +0000749 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700750 return NULL;
751 }
752 strcpy(converted, SSML_VOLUME_SILENT);
753 }
754 else if (strcmp(value, "x-low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700755 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700756 converted = new char[4];
757 if (!converted)
758 {
Steve Block31a809c2012-01-06 19:10:34 +0000759 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700760 return NULL;
761 }
762 strcpy(converted, SSML_VOLUME_XLOW);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700763 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700764 else if (strcmp(value, "low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700765 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700766 converted = new char[4];
767 if (!converted)
768 {
Steve Block31a809c2012-01-06 19:10:34 +0000769 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700770 return NULL;
771 }
772 strcpy(converted, SSML_VOLUME_LOW);
773 }
774 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700775 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700776 converted = new char[4];
777 if (!converted)
778 {
Steve Block31a809c2012-01-06 19:10:34 +0000779 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700780 return NULL;
781 }
782 strcpy(converted, SSML_VOLUME_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700783 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700784 else if (strcmp(value, "default") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700785 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700786 converted = new char[4];
787 if (!converted)
788 {
Steve Block31a809c2012-01-06 19:10:34 +0000789 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700790 return NULL;
791 }
792 strcpy(converted, SSML_VOLUME_MEDIUM);
793 }
794 else if (strcmp(value, "loud") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700795 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700796 converted = new char[4];
797 if (!converted)
798 {
Steve Block31a809c2012-01-06 19:10:34 +0000799 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700800 return NULL;
801 }
802 strcpy(converted, SSML_VOLUME_LOUD);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700803 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700804 else if (strcmp(value, "x-loud") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700805 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700806 converted = new char[4];
807 if (!converted)
808 {
Steve Block31a809c2012-01-06 19:10:34 +0000809 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700810 return NULL;
811 }
812 strcpy(converted, SSML_VOLUME_XLOUD);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700813 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700814 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700815}
816
817/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700818convertBreakStrengthToTime
819Converts SSML break strength labels to SVOX break time
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700820*/
821char* SvoxSsmlParser::convertBreakStrengthToTime(const char* value)
822{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700823 char* converted = NULL;
824 if (strcmp(value, "none") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700825 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700826 converted = new char[6];
827 if (!converted)
828 {
Steve Block31a809c2012-01-06 19:10:34 +0000829 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700830 return NULL;
831 }
832 strcpy(converted, SSML_BREAK_NONE);
833 }
834 else if (strcmp(value, "x-weak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700835 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700836 converted = new char[6];
837 if (!converted)
838 {
Steve Block31a809c2012-01-06 19:10:34 +0000839 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700840 return NULL;
841 }
842 strcpy(converted, SSML_BREAK_XWEAK);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700843 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700844 else if (strcmp(value, "weak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700845 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700846 converted = new char[6];
847 if (!converted)
848 {
Steve Block31a809c2012-01-06 19:10:34 +0000849 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700850 return NULL;
851 }
852 strcpy(converted, SSML_BREAK_WEAK);
853 }
854 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700855 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700856 converted = new char[6];
857 if (!converted)
858 {
Steve Block31a809c2012-01-06 19:10:34 +0000859 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700860 return NULL;
861 }
862 strcpy(converted, SSML_BREAK_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700863 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700864 else if (strcmp(value, "strong") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700865 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700866 converted = new char[6];
867 if (!converted)
868 {
Steve Block31a809c2012-01-06 19:10:34 +0000869 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700870 return NULL;
871 }
872 strcpy(converted, SSML_BREAK_STRONG);
873 }
874 else if (strcmp(value, "x-strong") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700875 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700876 converted = new char[6];
877 if (!converted)
878 {
Steve Block31a809c2012-01-06 19:10:34 +0000879 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700880 return NULL;
881 }
882 strcpy(converted, SSML_BREAK_XSTRONG);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700883 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700884 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700885}
886
887/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700888growDataSize
889Increases the size of the internal text storage member
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700890*/
891int SvoxSsmlParser::growDataSize(int sizeToGrow)
892{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700893 char* tmp = new char[m_datasize];
894 if (!tmp)
895 return 0;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700896
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700897 strcpy(tmp, m_data);
898 delete [] m_data;
899 m_data = NULL;
900 m_data = new char[m_datasize + sizeToGrow];
901 if (!m_data)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700902 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700903 m_data = tmp;
904 return 0;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700905 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700906 m_datasize += sizeToGrow;
907 strcpy(m_data, tmp);
908 delete [] tmp;
909 tmp = NULL;
910 return 1;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700911}