blob: 53dc7862f2fb5b3242d9ed3a1b64b43289867045 [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 *
16 * History:
17 * 2009-06-29 -- initial version
18 *
19 */
20
21#include "svox_ssml_parser.h"
22#include <utils/Log.h>
23#include <cutils/jstring.h>
24#include <string.h>
25
26
27#define SSML_PITCH_XLOW "50"
28#define SSML_PITCH_LOW "75"
29#define SSML_PITCH_MEDIUM "100"
30#define SSML_PITCH_HIGH "150"
31#define SSML_PITCH_XHIGH "200"
32#define SSML_RATE_XSLOW "30"
33#define SSML_RATE_SLOW "60"
34#define SSML_RATE_MEDIUM "100"
35#define SSML_RATE_FAST "250"
36#define SSML_RATE_XFAST "500"
37#define SSML_VOLUME_SILENT "0"
38#define SSML_VOLUME_XLOW "20"
39#define SSML_VOLUME_LOW "60"
40#define SSML_VOLUME_MEDIUM "100"
41#define SSML_VOLUME_LOUD "300"
42#define SSML_VOLUME_XLOUD "450"
43#define SSML_BREAK_NONE "0ms"
44#define SSML_BREAK_XWEAK "100ms"
45#define SSML_BREAK_WEAK "300ms"
46#define SSML_BREAK_MEDIUM "600ms"
47#define SSML_BREAK_STRONG "1s"
48#define SSML_BREAK_XSTRONG "3s"
49
50//TODO JMT remove comment
51//extern int cnvIpaToXsampa(const char16_t* ipaString, char** outXsampaString);
52
53SvoxSsmlParser::SvoxSsmlParser() : m_isInBreak(0), m_appendix(NULL), m_docLanguage(NULL)
54{
55 mParser = XML_ParserCreate("UTF-8");
56 if (mParser)
57 {
58 XML_SetElementHandler(mParser, starttagHandler, endtagHandler);
59 XML_SetCharacterDataHandler(mParser, textHandler);
60 XML_SetUserData(mParser, (void*)this);
61 m_datasize = 512;
62 m_data = new char[m_datasize];
63 m_data[0] = '\0';
64 }
65}
66
67SvoxSsmlParser::~SvoxSsmlParser()
68{
69 if (mParser)
70 XML_ParserFree(mParser);
71 if (m_data)
72 delete [] m_data;
73 if (m_appendix)
74 delete [] m_appendix;
75 if (m_docLanguage)
76 delete [] m_docLanguage;
77}
78
79int SvoxSsmlParser::initSuccessful()
80{
81 return (mParser && m_data);
82}
83
84int SvoxSsmlParser::parseDocument(const char* ssmldoc, int isFinal)
85{
86 int doclen = (int)strlen(ssmldoc) + 1;
87 int status = XML_Parse(mParser, ssmldoc, doclen, isFinal);
88 if (status == XML_STATUS_ERROR)
89 {
90 /* Note: for some reason Expat almost always complains about invalid tokens, even when document is well formed */
91 LOGI("Parser error at line %d: %s\n", (int)XML_GetCurrentLineNumber(mParser), XML_ErrorString(XML_GetErrorCode(mParser)));
92 }
93 return status;
94}
95
96char* SvoxSsmlParser::getParsedDocument()
97{
98 return m_data;
99}
100
101char* SvoxSsmlParser::getParsedDocumentLanguage()
102{
103 return m_docLanguage;
104}
105
106void SvoxSsmlParser::starttagHandler(void* data, const XML_Char* element, const XML_Char** attributes)
107{
108 ((SvoxSsmlParser*)data)->startElement(element, attributes);
109}
110
111void SvoxSsmlParser::startElement(const XML_Char* element, const XML_Char** attributes)
112{
113 if (strcmp(element, "speak") == 0)
114 {
115 if (strlen(m_data) > 0)
116 {
117 /* we have old data, get rid of it and reallocate memory */
118 delete m_data;
119 m_data = NULL;
120 m_datasize = 512;
121 m_data = new char[m_datasize];
122 if (!m_data)
123 {
124 LOGE("Error: failed to allocate memory for string!\n");
125 return;
126 }
127 }
128
129 /* the only attribute supported in the speak tag is xml:lang, all others are ignored */
130 for (int i = 0; attributes[i]; i += 2)
131 {
132 if (strcmp(attributes[i], "xml:lang") == 0)
133 {
134 if (!m_docLanguage)
135 {
136 m_docLanguage = new char[strlen(attributes[i+1])+1];
137 }
138 strcpy(m_docLanguage, attributes[i+1]);
139 break;
140 }
141 }
142 }
143 else if (strcmp(element, "p") == 0) /* currently no attributes are supported for <p> */
144 {
145 if (strlen(m_data) + 4 > (size_t)m_datasize)
146 {
147 if (!growDataSize(100))
148 {
149 LOGE("Error: failed to allocate memory for string!\n");
150 return;
151 }
152 }
153 strcat(m_data, "<p>");
154 }
155 else if (strcmp(element, "s") == 0) /* currently no attributes are supported for <s> */
156 {
157 if (strlen(m_data) + 4 > (size_t)m_datasize)
158 {
159 if (!growDataSize(100))
160 {
161 LOGE("Error: failed to allocate memory for string!\n");
162 return;
163 }
164 }
165 strcat(m_data, "<s>");
166 }
167 else if (strcmp(element, "phoneme") == 0) /* only ipa and xsampa alphabets are supported */
168 {
169 if (strlen(m_data) + 9 > (size_t)m_datasize)
170 {
171 if (!growDataSize(100))
172 {
173 LOGE("Error: failed to allocate memory for string!\n");
174 return;
175 }
176 }
177 strcat(m_data, "<phoneme");
178
179 int alpha = 1; /* set to 1 if alphabet is ipa */
180 char* ph = NULL;
181
182 for (int i = 0; attributes[i]; i += 2)
183 {
184 if (strcmp(attributes[i], "alphabet") == 0)
185 {
186 if (strcmp(attributes[i+1], "xsampa") == 0)
187 {
188 alpha = 0;
189 }
190 }
191 if (strcmp(attributes[i], "ph") == 0)
192 {
193 ph = new char[strlen(attributes[i+1]) + 1];
194 strcpy(ph, attributes[i+1]);
195 }
196 }
197 if (alpha)
198 {
199 /* need to convert phoneme string to xsampa */
200 size_t size = 0;
201 char16_t* ipastr = strdup8to16(ph, &size);
202 char16_t* xsampastr = NULL;
203 if (!ipastr)
204 {
205 LOGE("Error: failed to allocate memory for IPA string conversion");
206 return;
207 }
208 //TODO JMT remove comment
209 //size = cnvIpaToXsampa(ipastr, &xsampastr);
210 free(ipastr);
211 char* xsampa = strndup16to8(xsampastr, size);
212 if (!xsampa)
213 {
214 LOGE("Error: failed to allocate memory for IPA string conversion");
215 delete [] xsampastr;
216 return;
217 }
218 if (strlen(m_data) + strlen(xsampa) + 7 > (size_t)m_datasize)
219 {
220 if (!growDataSize(100))
221 {
222 LOGE("Error: failed to allocate memory for string!");
223 delete [] xsampastr;
224 free(xsampa);
225 return;
226 }
227 }
228 strcat(m_data, " ph='");
229 strcat(m_data, xsampa);
230 delete [] xsampastr;
231 free(xsampa);
232 }
233 else
234 {
235 strcat(m_data, " ph='");
236 strcat(m_data, ph);
237 }
238 if (ph)
239 delete [] ph;
240
241 if (strlen(m_data) + 3 > (size_t)m_datasize)
242 {
243 if (!growDataSize(100))
244 {
245 LOGE("Error: failed to allocate memory for string!\n");
246 return;
247 }
248 }
249 strcat(m_data, "'>");
250 }
251 else if (strcmp(element, "break") == 0)
252 {
253 if (strlen(m_data) + 17 > (size_t)m_datasize)
254 {
255 if (!growDataSize(100))
256 {
257 LOGE("Error: failed to allocate memory for string!\n");
258 return;
259 }
260 }
261 strcat(m_data, "<break time='");
262 char* time = NULL;
263
264 for (int i = 0; attributes[i]; i += 2)
265 {
266 if (strcmp(attributes[i], "time") == 0)
267 {
268 time = new char[strlen(attributes[i+1]) + 1];
269 if (!time)
270 {
271 LOGE("Error: failed to allocate memory for string!\n");
272 return;
273 }
274 strcpy(time, attributes[i+1]);
275 }
276 else if (strcmp(attributes[i], "strength") == 0 && !time)
277 {
278 time = convertBreakStrengthToTime(attributes[i+1]);
279 }
280 }
281 if (!time)
282 {
283 time = new char[6];
284 if (!time)
285 {
286 LOGE("Error: failed to allocate memory for string!\n");
287 return;
288 }
289 strcpy(time, SSML_BREAK_WEAK); /* if no time or strength attributes are specified, default to weak break */
290 }
291 if (strlen(m_data) + strlen(time) + 4 > (size_t)m_datasize)
292 {
293 if (!growDataSize(100))
294 {
295 LOGE("Error: failed to allocate memory for string!\n");
296 return;
297 }
298 }
299 strcat(m_data, time);
300 strcat(m_data, "'/>");
301 m_isInBreak = 1;
302 }
303 else if (strcmp(element, "prosody") == 0) /* only pitch, rate and volume attributes are supported */
304 {
305 for (int i = 0; attributes[i]; i += 2)
306 {
307 if (strcmp(attributes[i], "pitch") == 0)
308 {
309 char* svoxpitch = convertToSvoxPitch(attributes[i+1]);
310 if (!svoxpitch)
311 {
312 LOGE("Error: failed to allocate memory for string!\n");
313 return;
314 }
315 if (!svoxpitch)
316 {
317 svoxpitch = new char[4];
318 if (!svoxpitch)
319 {
320 LOGE("Error: failed to allocate memory for string!\n");
321 return;
322 }
323 strcpy(svoxpitch, "100");
324 }
325 char* pitch = new char[17 + strlen(svoxpitch)];
326 if (!pitch)
327 {
328 LOGE("Error: failed to allocate memory for string!\n");
329 return;
330 }
331 sprintf(pitch, "<pitch level='%s'>", svoxpitch);
332 if (strlen(m_data) + strlen(pitch) + 1 > (size_t)m_datasize)
333 {
334 if (!growDataSize(100))
335 {
336 LOGE("Error: failed to allocate memory for string!\n");
337 return;
338 }
339 }
340 strcat(m_data, pitch);
341 if (!m_appendix)
342 {
343 m_appendix = new char[30];
344 m_appendix[0] = '\0';
345 }
346 strcat(m_appendix, "</pitch>");
347 delete [] svoxpitch;
348 delete [] pitch;
349 }
350 else if (strcmp(attributes[i], "rate") == 0)
351 {
352 char* svoxrate = convertToSvoxRate(attributes[i+1]);
353 if (!svoxrate)
354 {
355 svoxrate = new char[4];
356 if (!svoxrate)
357 {
358 LOGE("Error: failed to allocate memory for string!\n");
359 return;
360 }
361 strcpy(svoxrate, "100");
362 }
363 char* rate = new char[17 + strlen(svoxrate)];
364 if (!rate)
365 {
366 LOGE("Error: failed to allocate memory for string!\n");
367 return;
368 }
369 sprintf(rate, "<speed level='%s'>", svoxrate);
370 if (strlen(m_data) + strlen(rate) + 1 > (size_t)m_datasize)
371 {
372 if (!growDataSize(100))
373 {
374 LOGE("Error: failed to allocate memory for string!\n");
375 return;
376 }
377 }
378 strcat(m_data, rate);
379 if (!m_appendix)
380 {
381 m_appendix = new char[30];
382 if (!m_appendix)
383 {
384 LOGE("Error: failed to allocate memory for string!\n");
385 return;
386 }
387 m_appendix[0] = '\0';
388 }
389 strcat(m_appendix, "</speed>");
390 delete [] svoxrate;
391 delete [] rate;
392 }
393 else if (strcmp(attributes[i], "volume") == 0)
394 {
395 char* svoxvol = convertToSvoxVolume(attributes[i+1]);
396 if (!svoxvol)
397 {
398 svoxvol = new char[4];
399 if (!svoxvol)
400 {
401 LOGE("Error: failed to allocate memory for string!\n");
402 return;
403 }
404 strcpy(svoxvol, "100");
405 }
406 char* volume = new char[18 + strlen(svoxvol)];
407 if (!volume)
408 {
409 LOGE("Error: failed to allocate memory for string!\n");
410 return;
411 }
412 sprintf(volume, "<volume level='%s'>", svoxvol);
413 if (strlen(m_data) + strlen(volume) + 1 > (size_t)m_datasize)
414 {
415 if (!growDataSize(100))
416 {
417 LOGE("Error: failed to allocate memory for string!\n");
418 return;
419 }
420 }
421 strcat(m_data, volume);
422 if (!m_appendix)
423 {
424 m_appendix = new char[30];
425 m_appendix[0] = '\0';
426 }
427 strcat(m_appendix, "</volume>");
428 delete [] svoxvol;
429 delete [] volume;
430 }
431 }
432 }
433 else if (strcmp(element, "audio") == 0) /* only 16kHz 16bit wav files are supported as src */
434 {
435 if (strlen(m_data) + 17 > (size_t)m_datasize)
436 {
437 if (!growDataSize(100))
438 {
439 LOGE("Error: failed to allocate memory for string!\n");
440 return;
441 }
442 }
443 strcat(m_data, "<usesig file='");
444
445 for (int i = 0; attributes[i]; i += 2)
446 {
447 if (strcmp(attributes[i], "src") == 0)
448 {
449 if (strlen(m_data) + strlen(attributes[i+1]) + 1 > (size_t)m_datasize)
450 {
451 if (!growDataSize(100))
452 {
453 LOGE("Error: failed to allocate memory for string!\n");
454 return;
455 }
456 }
457 strcat(m_data, attributes[i+1]);
458 }
459 }
460 strcat(m_data, "'>");
461 }
462}
463
464void SvoxSsmlParser::endtagHandler(void* data, const XML_Char* element)
465{
466 ((SvoxSsmlParser*)data)->endElement(element);
467}
468
469void SvoxSsmlParser::endElement(const XML_Char* element)
470{
471 if (strcmp(element, "speak") == 0)
472 {
473
474 }
475 else if (strcmp(element, "p") == 0)
476 {
477 if (strlen(m_data) + 5 > (size_t)m_datasize)
478 {
479 if (!growDataSize(100))
480 {
481 LOGE("Error: failed to allocate memory for string!\n");
482 return;
483 }
484 }
485 strcat(m_data, "</p>");
486 }
487 else if (strcmp(element, "s") == 0)
488 {
489 if (strlen(m_data) + 5 > (size_t)m_datasize)
490 {
491 if (!growDataSize(100))
492 {
493 LOGE("Error: failed to allocate memory for string!\n");
494 return;
495 }
496 }
497 strcat(m_data, "</s>");
498 }
499 else if (strcmp(element, "phoneme") == 0)
500 {
501 if (strlen(m_data) + 11 > (size_t)m_datasize)
502 {
503 if (!growDataSize(100))
504 {
505 LOGE("Error: failed to allocate memory for string!\n");
506 return;
507 }
508 }
509 strcat(m_data, "</phoneme>");
510 }
511 else if (strcmp(element, "break") == 0)
512 {
513 m_isInBreak = 0; /* indicate we are no longer in break tag */
514 }
515 else if (strcmp(element, "prosody") == 0)
516 {
517 if (m_appendix)
518 {
519 if (strlen(m_data) + strlen(m_appendix) + 1 > (size_t)m_datasize)
520 {
521 if (!growDataSize(100))
522 {
523 LOGE("Error: failed to allocate memory for string!\n");
524 return;
525 }
526 }
527 strcat(m_data, m_appendix);
528 delete [] m_appendix;
529 m_appendix = NULL;
530 }
531 }
532 else if (strcmp(element, "audio") == 0)
533 {
534 if (strlen(m_data) + 10 > (size_t)m_datasize)
535 {
536 if (!growDataSize(100))
537 {
538 LOGE("Error: failed to allocate memory for string!\n");
539 return;
540 }
541 }
542 strcat(m_data, "</usesig>");
543 }
544}
545
546void SvoxSsmlParser::textHandler(void* data, const XML_Char* text, int length)
547{
548 ((SvoxSsmlParser*)data)->textElement(text, length);
549}
550
551void SvoxSsmlParser::textElement(const XML_Char* text, int length)
552{
553 if (m_isInBreak)
554 {
555 return; /* handles the case when someone has added text inside the break tag - this text is thrown away */
556 }
557
558 char* content = new char[length + 1];
559 if (!content)
560 {
561 LOGE("Error: failed to allocate memory for string!\n");
562 return;
563 }
564 strncpy(content, text, length);
565 content[length] = '\0';
566
567 if (strlen(m_data) + strlen(content) + 1 > (size_t)m_datasize)
568 {
569 if (!growDataSize(100))
570 {
571 LOGE("Error: failed to allocate memory for string!\n");
572 return;
573 }
574 }
575 strcat(m_data, content);
576 delete [] content;
577}
578
579/**
580 convertToSvoxPitch
581 Converts SSML pitch labels to SVOX pitch levels
582*/
583char* SvoxSsmlParser::convertToSvoxPitch(const char* value)
584{
585 char* converted = NULL;
586 if (strcmp(value, "x-low") == 0)
587 {
588 converted = new char[4];
589 if (!converted)
590 {
591 LOGE("Error: failed to allocate memory for string!\n");
592 return NULL;
593 }
594 strcpy(converted, SSML_PITCH_XLOW);
595 }
596 else if (strcmp(value, "low") == 0)
597 {
598 converted = new char[4];
599 if (!converted)
600 {
601 LOGE("Error: failed to allocate memory for string!\n");
602 return NULL;
603 }
604 strcpy(converted, SSML_PITCH_LOW);
605 }
606 else if (strcmp(value, "medium") == 0)
607 {
608 converted = new char[4];
609 if (!converted)
610 {
611 LOGE("Error: failed to allocate memory for string!\n");
612 return NULL;
613 }
614 strcpy(converted, SSML_PITCH_MEDIUM);
615 }
616 else if (strcmp(value, "default") == 0)
617 {
618 converted = new char[4];
619 if (!converted)
620 {
621 LOGE("Error: failed to allocate memory for string!\n");
622 return NULL;
623 }
624 strcpy(converted, SSML_PITCH_MEDIUM);
625 }
626 else if (strcmp(value, "high") == 0)
627 {
628 converted = new char[4];
629 if (!converted)
630 {
631 LOGE("Error: failed to allocate memory for string!\n");
632 return NULL;
633 }
634 strcpy(converted, SSML_PITCH_HIGH);
635 }
636 else if (strcmp(value, "x-high") == 0)
637 {
638 converted = new char[4];
639 if (!converted)
640 {
641 LOGE("Error: failed to allocate memory for string!\n");
642 return NULL;
643 }
644 strcpy(converted, SSML_PITCH_XHIGH);
645 }
646 return converted;
647}
648
649/**
650 convertToSvoxRate
651 Converts SSML rate labels to SVOX speed levels
652*/
653char* SvoxSsmlParser::convertToSvoxRate(const char* value)
654{
655 char* converted = NULL;
656 if (strcmp(value, "x-slow") == 0)
657 {
658 converted = new char[4];
659 if (!converted)
660 {
661 LOGE("Error: failed to allocate memory for string!\n");
662 return NULL;
663 }
664 strcpy(converted, SSML_RATE_XSLOW);
665 }
666 else if (strcmp(value, "slow") == 0)
667 {
668 converted = new char[4];
669 if (!converted)
670 {
671 LOGE("Error: failed to allocate memory for string!\n");
672 return NULL;
673 }
674 strcpy(converted, SSML_RATE_SLOW);
675 }
676 else if (strcmp(value, "medium") == 0)
677 {
678 converted = new char[4];
679 if (!converted)
680 {
681 LOGE("Error: failed to allocate memory for string!\n");
682 return NULL;
683 }
684 strcpy(converted, SSML_RATE_MEDIUM);
685 }
686 else if (strcmp(value, "default") == 0)
687 {
688 converted = new char[4];
689 if (!converted)
690 {
691 LOGE("Error: failed to allocate memory for string!\n");
692 return NULL;
693 }
694 strcpy(converted, SSML_RATE_MEDIUM);
695 }
696 else if (strcmp(value, "fast") == 0)
697 {
698 converted = new char[4];
699 if (!converted)
700 {
701 LOGE("Error: failed to allocate memory for string!\n");
702 return NULL;
703 }
704 strcpy(converted, SSML_RATE_FAST);
705 }
706 else if (strcmp(value, "x-fast") == 0)
707 {
708 converted = new char[4];
709 if (!converted)
710 {
711 LOGE("Error: failed to allocate memory for string!\n");
712 return NULL;
713 }
714 strcpy(converted, SSML_RATE_XFAST);
715 }
716 return converted;
717}
718
719/**
720 convertToSvoxVolume
721 Converts SSML volume labels to SVOX volume levels
722*/
723char* SvoxSsmlParser::convertToSvoxVolume(const char* value)
724{
725 char* converted = NULL;
726 if (strcmp(value, "silent") == 0)
727 {
728 converted = new char[4];
729 if (!converted)
730 {
731 LOGE("Error: failed to allocate memory for string!\n");
732 return NULL;
733 }
734 strcpy(converted, SSML_VOLUME_SILENT);
735 }
736 else if (strcmp(value, "x-low") == 0)
737 {
738 converted = new char[4];
739 if (!converted)
740 {
741 LOGE("Error: failed to allocate memory for string!\n");
742 return NULL;
743 }
744 strcpy(converted, SSML_VOLUME_XLOW);
745 }
746 else if (strcmp(value, "low") == 0)
747 {
748 converted = new char[4];
749 if (!converted)
750 {
751 LOGE("Error: failed to allocate memory for string!\n");
752 return NULL;
753 }
754 strcpy(converted, SSML_VOLUME_LOW);
755 }
756 else if (strcmp(value, "medium") == 0)
757 {
758 converted = new char[4];
759 if (!converted)
760 {
761 LOGE("Error: failed to allocate memory for string!\n");
762 return NULL;
763 }
764 strcpy(converted, SSML_VOLUME_MEDIUM);
765 }
766 else if (strcmp(value, "default") == 0)
767 {
768 converted = new char[4];
769 if (!converted)
770 {
771 LOGE("Error: failed to allocate memory for string!\n");
772 return NULL;
773 }
774 strcpy(converted, SSML_VOLUME_MEDIUM);
775 }
776 else if (strcmp(value, "loud") == 0)
777 {
778 converted = new char[4];
779 if (!converted)
780 {
781 LOGE("Error: failed to allocate memory for string!\n");
782 return NULL;
783 }
784 strcpy(converted, SSML_VOLUME_LOUD);
785 }
786 else if (strcmp(value, "x-loud") == 0)
787 {
788 converted = new char[4];
789 if (!converted)
790 {
791 LOGE("Error: failed to allocate memory for string!\n");
792 return NULL;
793 }
794 strcpy(converted, SSML_VOLUME_XLOUD);
795 }
796 return converted;
797}
798
799/**
800 convertBreakStrengthToTime
801 Converts SSML break strength labels to SVOX break time
802*/
803char* SvoxSsmlParser::convertBreakStrengthToTime(const char* value)
804{
805 char* converted = NULL;
806 if (strcmp(value, "none") == 0)
807 {
808 converted = new char[6];
809 if (!converted)
810 {
811 LOGE("Error: failed to allocate memory for string!\n");
812 return NULL;
813 }
814 strcpy(converted, SSML_BREAK_NONE);
815 }
816 else if (strcmp(value, "x-weak") == 0)
817 {
818 converted = new char[6];
819 if (!converted)
820 {
821 LOGE("Error: failed to allocate memory for string!\n");
822 return NULL;
823 }
824 strcpy(converted, SSML_BREAK_XWEAK);
825 }
826 else if (strcmp(value, "weak") == 0)
827 {
828 converted = new char[6];
829 if (!converted)
830 {
831 LOGE("Error: failed to allocate memory for string!\n");
832 return NULL;
833 }
834 strcpy(converted, SSML_BREAK_WEAK);
835 }
836 else if (strcmp(value, "medium") == 0)
837 {
838 converted = new char[6];
839 if (!converted)
840 {
841 LOGE("Error: failed to allocate memory for string!\n");
842 return NULL;
843 }
844 strcpy(converted, SSML_BREAK_MEDIUM);
845 }
846 else if (strcmp(value, "strong") == 0)
847 {
848 converted = new char[6];
849 if (!converted)
850 {
851 LOGE("Error: failed to allocate memory for string!\n");
852 return NULL;
853 }
854 strcpy(converted, SSML_BREAK_STRONG);
855 }
856 else if (strcmp(value, "x-strong") == 0)
857 {
858 converted = new char[6];
859 if (!converted)
860 {
861 LOGE("Error: failed to allocate memory for string!\n");
862 return NULL;
863 }
864 strcpy(converted, SSML_BREAK_XSTRONG);
865 }
866 return converted;
867}
868
869/**
870 growDataSize
871 Increases the size of the internal text storage member
872*/
873int SvoxSsmlParser::growDataSize(int sizeToGrow)
874{
875 char* tmp = new char[m_datasize];
876 if (!tmp)
877 return 0;
878
879 strcpy(tmp, m_data);
880 delete [] m_data;
881 m_data = NULL;
882 m_data = new char[m_datasize + sizeToGrow];
883 if (!m_data)
884 {
885 m_data = tmp;
886 return 0;
887 }
888 m_datasize += sizeToGrow;
889 strcpy(m_data, tmp);
890 delete [] tmp;
891 tmp = NULL;
892 return 1;
893}