blob: 1e869408e3f4de06fc03592c6fe95c04d873f827 [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];
60 m_data[0] = '\0';
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070061 }
62}
63
64SvoxSsmlParser::~SvoxSsmlParser()
65{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070066 if (mParser)
67 XML_ParserFree(mParser);
68 if (m_data)
69 delete [] m_data;
70 if (m_appendix)
71 delete [] m_appendix;
72 if (m_docLanguage)
73 delete [] m_docLanguage;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070074}
75
76int SvoxSsmlParser::initSuccessful()
77{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070078 return (mParser && m_data);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070079}
80
81int SvoxSsmlParser::parseDocument(const char* ssmldoc, int isFinal)
82{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070083 int doclen = (int)strlen(ssmldoc) + 1;
84 int status = XML_Parse(mParser, ssmldoc, doclen, isFinal);
85 if (status == XML_STATUS_ERROR)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070086 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070087 /* Note: for some reason Expat almost always complains about invalid tokens, even when document is well formed */
Steve Block659851c2012-01-04 20:01:45 +000088 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 -070089 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070090 return status;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070091}
92
93char* SvoxSsmlParser::getParsedDocument()
94{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -070095 return m_data;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -070096}
97
98char* SvoxSsmlParser::getParsedDocumentLanguage()
99{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700100 return m_docLanguage;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700101}
102
103void SvoxSsmlParser::starttagHandler(void* data, const XML_Char* element, const XML_Char** attributes)
104{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700105 ((SvoxSsmlParser*)data)->startElement(element, attributes);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700106}
107
108void SvoxSsmlParser::startElement(const XML_Char* element, const XML_Char** attributes)
109{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700110 if (strcmp(element, "speak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700111 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700112 if (strlen(m_data) > 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700113 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700114 /* we have old data, get rid of it and reallocate memory */
115 delete m_data;
116 m_data = NULL;
117 m_datasize = 512;
118 m_data = new char[m_datasize];
119 if (!m_data)
120 {
Steve Block31a809c2012-01-06 19:10:34 +0000121 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700122 return;
123 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700124 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700125
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700126 /* the only attribute supported in the speak tag is xml:lang, all others are ignored */
127 for (int i = 0; attributes[i]; i += 2)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700128 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700129 if (strcmp(attributes[i], "xml:lang") == 0)
130 {
131 if (!m_docLanguage)
132 {
133 m_docLanguage = new char[strlen(attributes[i+1])+1];
134 }
135 strcpy(m_docLanguage, attributes[i+1]);
136 break;
137 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700138 }
139 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700140 else if (strcmp(element, "p") == 0) /* currently no attributes are supported for <p> */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700141 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700142 if (strlen(m_data) + 4 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700143 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700144 if (!growDataSize(100))
145 {
Steve Block31a809c2012-01-06 19:10:34 +0000146 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700147 return;
148 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700149 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700150 strcat(m_data, "<p>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700151 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700152 else if (strcmp(element, "s") == 0) /* currently no attributes are supported for <s> */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700153 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700154 if (strlen(m_data) + 4 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700155 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700156 if (!growDataSize(100))
157 {
Steve Block31a809c2012-01-06 19:10:34 +0000158 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700159 return;
160 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700161 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700162 strcat(m_data, "<s>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700163 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700164 else if (strcmp(element, "phoneme") == 0) /* only ipa and xsampa alphabets are supported */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700165 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700166 int alpha = 1; /* set to 1 if alphabet is ipa */
167 int tagComplete = 0; /* set to 1 if phoneme tag has already been added */
168 char16_t* ph = NULL;
169 char* xsampastr = NULL;
170 size_t phsize = 0;
171 size_t xsampasize = 0;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700172
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700173 for (int i = 0; attributes[i]; i += 2)
174 {
175 if (strcmp(attributes[i], "alphabet") == 0)
176 {
177 if (strcmp(attributes[i+1], "xsampa") == 0)
178 {
179 alpha = 0;
180 }
181 }
182 if (strcmp(attributes[i], "ph") == 0)
183 {
184 ph = new char16_t[strlen8to16(attributes[i+1]) + 1];
185 ph = strdup8to16(attributes[i+1], &phsize);
186 }
187 }
188 if (!ph)
189 {
190 /* error, no phonetic string */
Steve Block31a809c2012-01-06 19:10:34 +0000191 ALOGE("Error: bad SSML syntax, ph attribute not supplied.");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700192 return;
193 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700194
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700195 if (alpha)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700196 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700197 /* need to convert phoneme string to xsampa */
198 xsampasize = cnvIpaToXsampa(ph, phsize, &xsampastr);
199 delete [] ph;
200 if (!xsampastr)
201 {
Steve Block31a809c2012-01-06 19:10:34 +0000202 ALOGE("Error: failed to allocate memory for IPA string conversion");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700203 return;
204 }
205 }
206 else
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700207 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700208 xsampastr = strndup16to8(ph, phsize);
209 xsampasize = strlen(xsampastr);
210 delete [] ph;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700211 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700212
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700213 /* split XSAMPA string into multiple phonemes if needed */
214 if (strstr(xsampastr, " ") || strstr(xsampastr, "#")) /* check again to see if we have multiple words */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700215 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700216 char* phonstr = createPhonemeString(xsampastr, strlen(xsampastr) + 1);
217 free(xsampastr);
218 xsampastr = NULL;
219 xsampastr = (char*)malloc(strlen(phonstr) + 1);
220 strcpy(xsampastr, phonstr);
221 free(phonstr);
222 phonstr = NULL;
223 tagComplete = 1;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700224 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700225
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700226 if (tagComplete)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700227 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700228 if (strlen(m_data) + strlen(xsampastr) + 1 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700229 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700230 if (!growDataSize(100))
231 {
Steve Block31a809c2012-01-06 19:10:34 +0000232 ALOGE("Error: failed to allocate memory for string!");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700233 free(xsampastr);
234 return;
235 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700236 }
237 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700238 else
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700239 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700240 if (strlen(m_data) + strlen(xsampastr) + 17 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700241 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700242 if (!growDataSize(100))
243 {
Steve Block31a809c2012-01-06 19:10:34 +0000244 ALOGE("Error: failed to allocate memory for string!");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700245 free(xsampastr);
246 return;
247 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700248 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700249 strcat(m_data, "<phoneme ph='");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700250 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700251
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700252 strcat(m_data, xsampastr);
253 free(xsampastr);
254
255 if (!tagComplete)
256 {
257 if (strlen(m_data) + 4 > (size_t)m_datasize)
258 {
259 if (!growDataSize(100))
260 {
Steve Block31a809c2012-01-06 19:10:34 +0000261 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700262 return;
263 }
264 }
265 strcat(m_data, "'/>");
266 }
267
268 m_isInBreak = 1; /* set flag to indicate any text between open and close tag is to be discarded */
269 }
270 else if (strcmp(element, "break") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700271 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700272 if (strlen(m_data) + 17 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700273 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700274 if (!growDataSize(100))
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700275 {
Steve Block31a809c2012-01-06 19:10:34 +0000276 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700277 return;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700278 }
279 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700280 strcat(m_data, "<break time='");
281 char* time = NULL;
282
283 for (int i = 0; attributes[i]; i += 2)
284 {
285 if (strcmp(attributes[i], "time") == 0)
286 {
287 time = new char[strlen(attributes[i+1]) + 1];
288 if (!time)
289 {
Steve Block31a809c2012-01-06 19:10:34 +0000290 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700291 return;
292 }
293 strcpy(time, attributes[i+1]);
294 }
295 else if (strcmp(attributes[i], "strength") == 0 && !time)
296 {
297 time = convertBreakStrengthToTime(attributes[i+1]);
298 }
299 }
300 if (!time)
301 {
302 time = new char[6];
303 if (!time)
304 {
Steve Block31a809c2012-01-06 19:10:34 +0000305 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700306 return;
307 }
308 strcpy(time, SSML_BREAK_WEAK); /* if no time or strength attributes are specified, default to weak break */
309 }
310 if (strlen(m_data) + strlen(time) + 4 > (size_t)m_datasize)
311 {
312 if (!growDataSize(100))
313 {
Steve Block31a809c2012-01-06 19:10:34 +0000314 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700315 return;
316 }
317 }
318 strcat(m_data, time);
319 strcat(m_data, "'/>");
320 m_isInBreak = 1; /* set flag to indicate any text between open and close tag is to be discarded */
321 }
322 else if (strcmp(element, "prosody") == 0) /* only pitch, rate and volume attributes are supported */
323 {
324 for (int i = 0; attributes[i]; i += 2)
325 {
326 if (strcmp(attributes[i], "pitch") == 0)
327 {
328 char* svoxpitch = convertToSvoxPitch(attributes[i+1]);
329 if (!svoxpitch)
330 {
Steve Block31a809c2012-01-06 19:10:34 +0000331 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700332 return;
333 }
334 if (!svoxpitch)
335 {
336 svoxpitch = new char[4];
337 if (!svoxpitch)
338 {
Steve Block31a809c2012-01-06 19:10:34 +0000339 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700340 return;
341 }
342 strcpy(svoxpitch, "100");
343 }
344 char* pitch = new char[17 + strlen(svoxpitch)];
345 if (!pitch)
346 {
Steve Block31a809c2012-01-06 19:10:34 +0000347 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700348 return;
349 }
350 sprintf(pitch, "<pitch level='%s'>", svoxpitch);
351 if (strlen(m_data) + strlen(pitch) + 1 > (size_t)m_datasize)
352 {
353 if (!growDataSize(100))
354 {
Steve Block31a809c2012-01-06 19:10:34 +0000355 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700356 return;
357 }
358 }
359 strcat(m_data, pitch);
360 if (!m_appendix)
361 {
362 m_appendix = new char[30];
363 m_appendix[0] = '\0';
364 }
365 strcat(m_appendix, "</pitch>");
366 delete [] svoxpitch;
367 delete [] pitch;
368 }
369 else if (strcmp(attributes[i], "rate") == 0)
370 {
371 char* svoxrate = convertToSvoxRate(attributes[i+1]);
372 if (!svoxrate)
373 {
374 svoxrate = new char[4];
375 if (!svoxrate)
376 {
Steve Block31a809c2012-01-06 19:10:34 +0000377 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700378 return;
379 }
380 strcpy(svoxrate, "100");
381 }
382 char* rate = new char[17 + strlen(svoxrate)];
383 if (!rate)
384 {
Steve Block31a809c2012-01-06 19:10:34 +0000385 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700386 return;
387 }
388 sprintf(rate, "<speed level='%s'>", svoxrate);
389 if (strlen(m_data) + strlen(rate) + 1 > (size_t)m_datasize)
390 {
391 if (!growDataSize(100))
392 {
Steve Block31a809c2012-01-06 19:10:34 +0000393 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700394 return;
395 }
396 }
397 strcat(m_data, rate);
398 if (!m_appendix)
399 {
400 m_appendix = new char[30];
401 if (!m_appendix)
402 {
Steve Block31a809c2012-01-06 19:10:34 +0000403 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700404 return;
405 }
406 m_appendix[0] = '\0';
407 }
408 strcat(m_appendix, "</speed>");
409 delete [] svoxrate;
410 delete [] rate;
411 }
412 else if (strcmp(attributes[i], "volume") == 0)
413 {
414 char* svoxvol = convertToSvoxVolume(attributes[i+1]);
415 if (!svoxvol)
416 {
417 svoxvol = new char[4];
418 if (!svoxvol)
419 {
Steve Block31a809c2012-01-06 19:10:34 +0000420 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700421 return;
422 }
423 strcpy(svoxvol, "100");
424 }
425 char* volume = new char[18 + strlen(svoxvol)];
426 if (!volume)
427 {
Steve Block31a809c2012-01-06 19:10:34 +0000428 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700429 return;
430 }
431 sprintf(volume, "<volume level='%s'>", svoxvol);
432 if (strlen(m_data) + strlen(volume) + 1 > (size_t)m_datasize)
433 {
434 if (!growDataSize(100))
435 {
Steve Block31a809c2012-01-06 19:10:34 +0000436 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700437 return;
438 }
439 }
440 strcat(m_data, volume);
441 if (!m_appendix)
442 {
443 m_appendix = new char[30];
444 m_appendix[0] = '\0';
445 }
446 strcat(m_appendix, "</volume>");
447 delete [] svoxvol;
448 delete [] volume;
449 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700450 }
451 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700452 else if (strcmp(element, "audio") == 0) /* only 16kHz 16bit wav files are supported as src */
453 {
454 if (strlen(m_data) + 17 > (size_t)m_datasize)
455 {
456 if (!growDataSize(100))
457 {
Steve Block31a809c2012-01-06 19:10:34 +0000458 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700459 return;
460 }
461 }
462 strcat(m_data, "<usesig file='");
463
464 for (int i = 0; attributes[i]; i += 2)
465 {
466 if (strcmp(attributes[i], "src") == 0)
467 {
468 if (strlen(m_data) + strlen(attributes[i+1]) + 1 > (size_t)m_datasize)
469 {
470 if (!growDataSize(100))
471 {
Steve Block31a809c2012-01-06 19:10:34 +0000472 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700473 return;
474 }
475 }
476 strcat(m_data, attributes[i+1]);
477 }
478 }
479 strcat(m_data, "'>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700480 }
481}
482
483void SvoxSsmlParser::endtagHandler(void* data, const XML_Char* element)
484{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700485 ((SvoxSsmlParser*)data)->endElement(element);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700486}
487
488void SvoxSsmlParser::endElement(const XML_Char* element)
489{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700490 if (strcmp(element, "speak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700491 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700492 /* do nothing */
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700493 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700494 else if (strcmp(element, "p") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700495 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700496 if (strlen(m_data) + 5 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700497 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700498 if (!growDataSize(100))
499 {
Steve Block31a809c2012-01-06 19:10:34 +0000500 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700501 return;
502 }
503 }
504 strcat(m_data, "</p>");
505 }
506 else if (strcmp(element, "s") == 0)
507 {
508 if (strlen(m_data) + 5 > (size_t)m_datasize)
509 {
510 if (!growDataSize(100))
511 {
Steve Block31a809c2012-01-06 19:10:34 +0000512 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700513 return;
514 }
515 }
516 strcat(m_data, "</s>");
517 }
518 else if (strcmp(element, "phoneme") == 0)
519 {
520 m_isInBreak = 0; /* indicate we are no longer in phoneme tag */
521 }
522 else if (strcmp(element, "break") == 0)
523 {
524 m_isInBreak = 0; /* indicate we are no longer in break tag */
525 }
526 else if (strcmp(element, "prosody") == 0)
527 {
528 if (m_appendix)
529 {
530 if (strlen(m_data) + strlen(m_appendix) + 1 > (size_t)m_datasize)
531 {
532 if (!growDataSize(100))
533 {
Steve Block31a809c2012-01-06 19:10:34 +0000534 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700535 return;
536 }
537 }
538 strcat(m_data, m_appendix);
539 delete [] m_appendix;
540 m_appendix = NULL;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700541 }
542 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700543 else if (strcmp(element, "audio") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700544 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700545 if (strlen(m_data) + 10 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700546 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700547 if (!growDataSize(100))
548 {
Steve Block31a809c2012-01-06 19:10:34 +0000549 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700550 return;
551 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700552 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700553 strcat(m_data, "</usesig>");
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700554 }
555}
556
557void SvoxSsmlParser::textHandler(void* data, const XML_Char* text, int length)
558{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700559 ((SvoxSsmlParser*)data)->textElement(text, length);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700560}
561
562void SvoxSsmlParser::textElement(const XML_Char* text, int length)
563{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700564 if (m_isInBreak)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700565 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700566 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 -0700567 }
568
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700569 char* content = new char[length + 1];
570 if (!content)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700571 {
Steve Block31a809c2012-01-06 19:10:34 +0000572 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700573 return;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700574 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700575 strncpy(content, text, length);
576 content[length] = '\0';
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700577
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700578 if (strlen(m_data) + strlen(content) + 1 > (size_t)m_datasize)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700579 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700580 if (!growDataSize(100))
581 {
Steve Block31a809c2012-01-06 19:10:34 +0000582 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700583 return;
584 }
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700585 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700586 strcat(m_data, content);
587 delete [] content;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700588}
589
590/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700591convertToSvoxPitch
592Converts SSML pitch labels to SVOX pitch levels
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700593*/
594char* SvoxSsmlParser::convertToSvoxPitch(const char* value)
595{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700596 char* converted = NULL;
597 if (strcmp(value, "x-low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700598 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700599 converted = new char[4];
600 if (!converted)
601 {
Steve Block31a809c2012-01-06 19:10:34 +0000602 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700603 return NULL;
604 }
605 strcpy(converted, SSML_PITCH_XLOW);
606 }
607 else if (strcmp(value, "low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700608 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700609 converted = new char[4];
610 if (!converted)
611 {
Steve Block31a809c2012-01-06 19:10:34 +0000612 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700613 return NULL;
614 }
615 strcpy(converted, SSML_PITCH_LOW);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700616 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700617 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700618 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700619 converted = new char[4];
620 if (!converted)
621 {
Steve Block31a809c2012-01-06 19:10:34 +0000622 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700623 return NULL;
624 }
625 strcpy(converted, SSML_PITCH_MEDIUM);
626 }
627 else if (strcmp(value, "default") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700628 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700629 converted = new char[4];
630 if (!converted)
631 {
Steve Block31a809c2012-01-06 19:10:34 +0000632 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700633 return NULL;
634 }
635 strcpy(converted, SSML_PITCH_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700636 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700637 else if (strcmp(value, "high") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700638 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700639 converted = new char[4];
640 if (!converted)
641 {
Steve Block31a809c2012-01-06 19:10:34 +0000642 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700643 return NULL;
644 }
645 strcpy(converted, SSML_PITCH_HIGH);
646 }
647 else if (strcmp(value, "x-high") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700648 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700649 converted = new char[4];
650 if (!converted)
651 {
Steve Block31a809c2012-01-06 19:10:34 +0000652 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700653 return NULL;
654 }
655 strcpy(converted, SSML_PITCH_XHIGH);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700656 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700657 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700658}
659
660/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700661 convertToSvoxRate
662 Converts SSML rate labels to SVOX speed levels
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700663*/
664char* SvoxSsmlParser::convertToSvoxRate(const char* value)
665{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700666 char* converted = NULL;
667 if (strcmp(value, "x-slow") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700668 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700669 converted = new char[4];
670 if (!converted)
671 {
Steve Block31a809c2012-01-06 19:10:34 +0000672 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700673 return NULL;
674 }
675 strcpy(converted, SSML_RATE_XSLOW);
676 }
677 else if (strcmp(value, "slow") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700678 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700679 converted = new char[4];
680 if (!converted)
681 {
Steve Block31a809c2012-01-06 19:10:34 +0000682 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700683 return NULL;
684 }
685 strcpy(converted, SSML_RATE_SLOW);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700686 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700687 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700688 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700689 converted = new char[4];
690 if (!converted)
691 {
Steve Block31a809c2012-01-06 19:10:34 +0000692 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700693 return NULL;
694 }
695 strcpy(converted, SSML_RATE_MEDIUM);
696 }
697 else if (strcmp(value, "default") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700698 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700699 converted = new char[4];
700 if (!converted)
701 {
Steve Block31a809c2012-01-06 19:10:34 +0000702 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700703 return NULL;
704 }
705 strcpy(converted, SSML_RATE_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700706 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700707 else if (strcmp(value, "fast") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700708 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700709 converted = new char[4];
710 if (!converted)
711 {
Steve Block31a809c2012-01-06 19:10:34 +0000712 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700713 return NULL;
714 }
715 strcpy(converted, SSML_RATE_FAST);
716 }
717 else if (strcmp(value, "x-fast") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700718 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700719 converted = new char[4];
720 if (!converted)
721 {
Steve Block31a809c2012-01-06 19:10:34 +0000722 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700723 return NULL;
724 }
725 strcpy(converted, SSML_RATE_XFAST);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700726 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700727 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700728}
729
730/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700731convertToSvoxVolume
732Converts SSML volume labels to SVOX volume levels
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700733*/
734char* SvoxSsmlParser::convertToSvoxVolume(const char* value)
735{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700736 char* converted = NULL;
737 if (strcmp(value, "silent") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700738 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700739 converted = new char[4];
740 if (!converted)
741 {
Steve Block31a809c2012-01-06 19:10:34 +0000742 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700743 return NULL;
744 }
745 strcpy(converted, SSML_VOLUME_SILENT);
746 }
747 else if (strcmp(value, "x-low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700748 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700749 converted = new char[4];
750 if (!converted)
751 {
Steve Block31a809c2012-01-06 19:10:34 +0000752 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700753 return NULL;
754 }
755 strcpy(converted, SSML_VOLUME_XLOW);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700756 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700757 else if (strcmp(value, "low") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700758 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700759 converted = new char[4];
760 if (!converted)
761 {
Steve Block31a809c2012-01-06 19:10:34 +0000762 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700763 return NULL;
764 }
765 strcpy(converted, SSML_VOLUME_LOW);
766 }
767 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700768 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700769 converted = new char[4];
770 if (!converted)
771 {
Steve Block31a809c2012-01-06 19:10:34 +0000772 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700773 return NULL;
774 }
775 strcpy(converted, SSML_VOLUME_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700776 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700777 else if (strcmp(value, "default") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700778 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700779 converted = new char[4];
780 if (!converted)
781 {
Steve Block31a809c2012-01-06 19:10:34 +0000782 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700783 return NULL;
784 }
785 strcpy(converted, SSML_VOLUME_MEDIUM);
786 }
787 else if (strcmp(value, "loud") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700788 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700789 converted = new char[4];
790 if (!converted)
791 {
Steve Block31a809c2012-01-06 19:10:34 +0000792 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700793 return NULL;
794 }
795 strcpy(converted, SSML_VOLUME_LOUD);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700796 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700797 else if (strcmp(value, "x-loud") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700798 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700799 converted = new char[4];
800 if (!converted)
801 {
Steve Block31a809c2012-01-06 19:10:34 +0000802 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700803 return NULL;
804 }
805 strcpy(converted, SSML_VOLUME_XLOUD);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700806 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700807 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700808}
809
810/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700811convertBreakStrengthToTime
812Converts SSML break strength labels to SVOX break time
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700813*/
814char* SvoxSsmlParser::convertBreakStrengthToTime(const char* value)
815{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700816 char* converted = NULL;
817 if (strcmp(value, "none") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700818 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700819 converted = new char[6];
820 if (!converted)
821 {
Steve Block31a809c2012-01-06 19:10:34 +0000822 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700823 return NULL;
824 }
825 strcpy(converted, SSML_BREAK_NONE);
826 }
827 else if (strcmp(value, "x-weak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700828 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700829 converted = new char[6];
830 if (!converted)
831 {
Steve Block31a809c2012-01-06 19:10:34 +0000832 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700833 return NULL;
834 }
835 strcpy(converted, SSML_BREAK_XWEAK);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700836 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700837 else if (strcmp(value, "weak") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700838 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700839 converted = new char[6];
840 if (!converted)
841 {
Steve Block31a809c2012-01-06 19:10:34 +0000842 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700843 return NULL;
844 }
845 strcpy(converted, SSML_BREAK_WEAK);
846 }
847 else if (strcmp(value, "medium") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700848 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700849 converted = new char[6];
850 if (!converted)
851 {
Steve Block31a809c2012-01-06 19:10:34 +0000852 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700853 return NULL;
854 }
855 strcpy(converted, SSML_BREAK_MEDIUM);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700856 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700857 else if (strcmp(value, "strong") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700858 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700859 converted = new char[6];
860 if (!converted)
861 {
Steve Block31a809c2012-01-06 19:10:34 +0000862 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700863 return NULL;
864 }
865 strcpy(converted, SSML_BREAK_STRONG);
866 }
867 else if (strcmp(value, "x-strong") == 0)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700868 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700869 converted = new char[6];
870 if (!converted)
871 {
Steve Block31a809c2012-01-06 19:10:34 +0000872 ALOGE("Error: failed to allocate memory for string!\n");
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700873 return NULL;
874 }
875 strcpy(converted, SSML_BREAK_XSTRONG);
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700876 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700877 return converted;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700878}
879
880/**
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700881growDataSize
882Increases the size of the internal text storage member
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700883*/
884int SvoxSsmlParser::growDataSize(int sizeToGrow)
885{
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700886 char* tmp = new char[m_datasize];
887 if (!tmp)
888 return 0;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700889
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700890 strcpy(tmp, m_data);
891 delete [] m_data;
892 m_data = NULL;
893 m_data = new char[m_datasize + sizeToGrow];
894 if (!m_data)
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700895 {
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700896 m_data = tmp;
897 return 0;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700898 }
Jean-Michel Trivi4bbdb2d2009-07-08 12:22:43 -0700899 m_datasize += sizeToGrow;
900 strcpy(m_data, tmp);
901 delete [] tmp;
902 tmp = NULL;
903 return 1;
Jean-Michel Trivi39358f02009-07-01 18:13:11 -0700904}