int parcel_w_string(struct parcel *p, char *str) { char16_t *s16; size_t s16_len; size_t len; if(str == NULL) { parcel_w_int32(p, -1); return 0; } s16_len = strlen8to16(str); s16 = malloc(sizeof(char16_t) * s16_len); strcpy8to16(s16, str, &s16_len); if(parcel_w_int32(p, s16_len) == -1) { return -1; } len = (s16_len + 1) * sizeof(char16_t); for(;;) { size_t padded = PAD_SIZE(len); /*printf("parcel_w_string(\"%s\"): offset %d, cap %d, size %d\n", str, p->offset, p->capacity, p->size);*/ if(p->offset + len < p->capacity) { // There's enough space memcpy(p->data + p->offset, s16, s16_len * sizeof(char16_t)); *((char16_t *) (p->data + p->offset + len)) = 0; p->offset += padded; p->size += padded; if (padded != len) { //printf("Writing %ld bytes, padded to %ld\n", len, padded); #if BYTE_ORDER == BIG_ENDIAN static const uint32_t mask[4] = { 0x00000000, 0xffffff00, 0xffff0000, 0xff000000 }; #endif #if BYTE_ORDER == LITTLE_ENDIAN static const uint32_t mask[4] = { 0x00000000, 0x00ffffff, 0x0000ffff, 0x000000ff }; #endif *((uint32_t*)(p->data+p->offset+padded-4)) &= mask[padded-len]; } break; } else { // Grow data and retry if(parcel_grow(p, padded) == -1) { free(s16); return -1; } } } free(s16); return 0; }
extern char16_t * strdup8to16 (const char* s, size_t *out_len) { char16_t *ret; size_t len; if (s == NULL) return NULL; len = strlen8to16(s); // no plus-one here. UTF-16 strings are not null terminated ret = (char16_t *) malloc (sizeof(char16_t) * len); return strcpy8to16 (ret, s, out_len); }
void SvoxSsmlParser::startElement(const XML_Char* element, const XML_Char** attributes) { if (strcmp(element, "speak") == 0) { if (strlen(m_data) > 0) { /* we have old data, get rid of it and reallocate memory */ delete m_data; m_data = NULL; m_datasize = 512; m_data = new char[m_datasize]; if (!m_data) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } /* the only attribute supported in the speak tag is xml:lang, all others are ignored */ for (int i = 0; attributes[i]; i += 2) { if (strcmp(attributes[i], "xml:lang") == 0) { if (!m_docLanguage) { m_docLanguage = new char[strlen(attributes[i+1])+1]; } strcpy(m_docLanguage, attributes[i+1]); break; } } } else if (strcmp(element, "p") == 0) /* currently no attributes are supported for <p> */ { if (strlen(m_data) + 4 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, "<p>"); } else if (strcmp(element, "s") == 0) /* currently no attributes are supported for <s> */ { if (strlen(m_data) + 4 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, "<s>"); } else if (strcmp(element, "phoneme") == 0) /* only ipa and xsampa alphabets are supported */ { int alpha = 1; /* set to 1 if alphabet is ipa */ int tagComplete = 0; /* set to 1 if phoneme tag has already been added */ char16_t* ph = NULL; char* xsampastr = NULL; size_t phsize = 0; size_t xsampasize = 0; for (int i = 0; attributes[i]; i += 2) { if (strcmp(attributes[i], "alphabet") == 0) { if (strcmp(attributes[i+1], "xsampa") == 0) { alpha = 0; } } if (strcmp(attributes[i], "ph") == 0) { ph = new char16_t[strlen8to16(attributes[i+1]) + 1]; ph = strdup8to16(attributes[i+1], &phsize); } } if (!ph) { /* error, no phonetic string */ ALOGE("Error: bad SSML syntax, ph attribute not supplied."); return; } if (alpha) { /* need to convert phoneme string to xsampa */ xsampasize = cnvIpaToXsampa(ph, phsize, &xsampastr); delete [] ph; if (!xsampastr) { ALOGE("Error: failed to allocate memory for IPA string conversion"); return; } } else { xsampastr = strndup16to8(ph, phsize); xsampasize = strlen(xsampastr); delete [] ph; } /* split XSAMPA string into multiple phonemes if needed */ if (strstr(xsampastr, " ") || strstr(xsampastr, "#")) /* check again to see if we have multiple words */ { char* phonstr = createPhonemeString(xsampastr, strlen(xsampastr) + 1); free(xsampastr); xsampastr = NULL; xsampastr = (char*)malloc(strlen(phonstr) + 1); strcpy(xsampastr, phonstr); free(phonstr); phonstr = NULL; tagComplete = 1; } if (tagComplete) { if (strlen(m_data) + strlen(xsampastr) + 1 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!"); free(xsampastr); return; } } } else { if (strlen(m_data) + strlen(xsampastr) + 17 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!"); free(xsampastr); return; } } strcat(m_data, "<phoneme ph='"); } strcat(m_data, xsampastr); free(xsampastr); if (!tagComplete) { if (strlen(m_data) + 4 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, "'/>"); } m_isInBreak = 1; /* set flag to indicate any text between open and close tag is to be discarded */ } else if (strcmp(element, "break") == 0) { if (strlen(m_data) + 17 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, "<break time='"); char* time = NULL; for (int i = 0; attributes[i]; i += 2) { if (strcmp(attributes[i], "time") == 0) { time = new char[strlen(attributes[i+1]) + 1]; if (!time) { ALOGE("Error: failed to allocate memory for string!\n"); return; } strcpy(time, attributes[i+1]); } else if (strcmp(attributes[i], "strength") == 0 && !time) { time = convertBreakStrengthToTime(attributes[i+1]); } } if (!time) { time = new char[6]; if (!time) { ALOGE("Error: failed to allocate memory for string!\n"); return; } strcpy(time, SSML_BREAK_WEAK); /* if no time or strength attributes are specified, default to weak break */ } if (strlen(m_data) + strlen(time) + 4 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, time); strcat(m_data, "'/>"); m_isInBreak = 1; /* set flag to indicate any text between open and close tag is to be discarded */ } else if (strcmp(element, "prosody") == 0) /* only pitch, rate and volume attributes are supported */ { for (int i = 0; attributes[i]; i += 2) { if (strcmp(attributes[i], "pitch") == 0) { char* svoxpitch = convertToSvoxPitch(attributes[i+1]); if (!svoxpitch) { ALOGE("Error: failed to allocate memory for string!\n"); return; } if (!svoxpitch) { svoxpitch = new char[4]; if (!svoxpitch) { ALOGE("Error: failed to allocate memory for string!\n"); return; } strcpy(svoxpitch, "100"); } char* pitch = new char[17 + strlen(svoxpitch)]; if (!pitch) { ALOGE("Error: failed to allocate memory for string!\n"); return; } sprintf(pitch, "<pitch level='%s'>", svoxpitch); if (strlen(m_data) + strlen(pitch) + 1 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, pitch); if (!m_appendix) { m_appendix = new char[30]; m_appendix[0] = '\0'; } strcat(m_appendix, "</pitch>"); delete [] svoxpitch; delete [] pitch; } else if (strcmp(attributes[i], "rate") == 0) { char* svoxrate = convertToSvoxRate(attributes[i+1]); if (!svoxrate) { svoxrate = new char[4]; if (!svoxrate) { ALOGE("Error: failed to allocate memory for string!\n"); return; } strcpy(svoxrate, "100"); } char* rate = new char[17 + strlen(svoxrate)]; if (!rate) { ALOGE("Error: failed to allocate memory for string!\n"); return; } sprintf(rate, "<speed level='%s'>", svoxrate); if (strlen(m_data) + strlen(rate) + 1 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, rate); if (!m_appendix) { m_appendix = new char[30]; if (!m_appendix) { ALOGE("Error: failed to allocate memory for string!\n"); return; } m_appendix[0] = '\0'; } strcat(m_appendix, "</speed>"); delete [] svoxrate; delete [] rate; } else if (strcmp(attributes[i], "volume") == 0) { char* svoxvol = convertToSvoxVolume(attributes[i+1]); if (!svoxvol) { svoxvol = new char[4]; if (!svoxvol) { ALOGE("Error: failed to allocate memory for string!\n"); return; } strcpy(svoxvol, "100"); } char* volume = new char[18 + strlen(svoxvol)]; if (!volume) { ALOGE("Error: failed to allocate memory for string!\n"); return; } sprintf(volume, "<volume level='%s'>", svoxvol); if (strlen(m_data) + strlen(volume) + 1 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, volume); if (!m_appendix) { m_appendix = new char[30]; m_appendix[0] = '\0'; } strcat(m_appendix, "</volume>"); delete [] svoxvol; delete [] volume; } } } else if (strcmp(element, "audio") == 0) /* only 16kHz 16bit wav files are supported as src */ { if (strlen(m_data) + 17 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, "<usesig file='"); for (int i = 0; attributes[i]; i += 2) { if (strcmp(attributes[i], "src") == 0) { if (strlen(m_data) + strlen(attributes[i+1]) + 1 > (size_t)m_datasize) { if (!growDataSize(100)) { ALOGE("Error: failed to allocate memory for string!\n"); return; } } strcat(m_data, attributes[i+1]); } } strcat(m_data, "'>"); } }