/* eSpeak NG 1.49.2 */ | /* eSpeak NG 1.49.2 */ | ||||
ENS_UNKNOWN_PHONEME_FEATURE = 0x10000FFF, | ENS_UNKNOWN_PHONEME_FEATURE = 0x10000FFF, | ||||
ENS_UNKNOWN_TEXT_ENCODING = 0x100010FF, | |||||
} espeak_ng_STATUS; | } espeak_ng_STATUS; | ||||
typedef enum { | typedef enum { |
struct espeak_ng_TEXT_DECODER_ | struct espeak_ng_TEXT_DECODER_ | ||||
{ | { | ||||
const char *current; | |||||
const char *end; | |||||
}; | }; | ||||
espeak_ng_TEXT_DECODER * | espeak_ng_TEXT_DECODER * | ||||
espeak_ng_TEXT_DECODER *decoder = malloc(sizeof(espeak_ng_TEXT_DECODER)); | espeak_ng_TEXT_DECODER *decoder = malloc(sizeof(espeak_ng_TEXT_DECODER)); | ||||
if (!decoder) return NULL; | if (!decoder) return NULL; | ||||
decoder->current = NULL; | |||||
decoder->end = NULL; | |||||
return decoder; | return decoder; | ||||
} | } | ||||
if (decoder) free(decoder); | if (decoder) free(decoder); | ||||
} | } | ||||
static int | |||||
initialize_encoding(espeak_ng_TEXT_DECODER *decoder, | |||||
espeak_ng_ENCODING encoding) | |||||
{ | |||||
switch (encoding) | |||||
{ | |||||
case ESPEAKNG_ENCODING_US_ASCII: | |||||
break; | |||||
default: | |||||
return 0; | |||||
} | |||||
return 1; | |||||
} | |||||
espeak_ng_STATUS | |||||
text_decoder_decode_string(espeak_ng_TEXT_DECODER *decoder, | |||||
const char *string, | |||||
int length, | |||||
espeak_ng_ENCODING encoding) | |||||
{ | |||||
if (!initialize_encoding(decoder, encoding)) | |||||
return ENS_UNKNOWN_TEXT_ENCODING; | |||||
decoder->current = string; | |||||
decoder->end = string + length; | |||||
return ENS_OK; | |||||
} | |||||
int | int | ||||
text_decoder_eof(espeak_ng_TEXT_DECODER *decoder) | text_decoder_eof(espeak_ng_TEXT_DECODER *decoder) | ||||
{ | { | ||||
return 1; | |||||
return decoder->current == decoder->end; | |||||
} | } | ||||
uint32_t | uint32_t | ||||
text_decoder_getc(espeak_ng_TEXT_DECODER *decoder) | text_decoder_getc(espeak_ng_TEXT_DECODER *decoder) | ||||
{ | { | ||||
return 0; | |||||
uint8_t c = *decoder->current++ & 0xFF; | |||||
return (c >= 0x80) ? 0xFFFD : c; | |||||
} | } |
void | void | ||||
destroy_text_decoder(espeak_ng_TEXT_DECODER *decoder); | destroy_text_decoder(espeak_ng_TEXT_DECODER *decoder); | ||||
espeak_ng_STATUS | |||||
text_decoder_decode_string(espeak_ng_TEXT_DECODER *decoder, | |||||
const char *string, | |||||
int length, | |||||
espeak_ng_ENCODING encoding); | |||||
int | int | ||||
text_decoder_eof(espeak_ng_TEXT_DECODER *decoder); | text_decoder_eof(espeak_ng_TEXT_DECODER *decoder); | ||||
case ENS_UNKNOWN_PHONEME_FEATURE: | case ENS_UNKNOWN_PHONEME_FEATURE: | ||||
strncpy0(buffer, "The phoneme feature is not recognised", length); | strncpy0(buffer, "The phoneme feature is not recognised", length); | ||||
break; | break; | ||||
case ENS_UNKNOWN_TEXT_ENCODING: | |||||
strncpy0(buffer, "The text encoding is not supported", length); | |||||
break; | |||||
default: | default: | ||||
if ((status & ENS_GROUP_MASK) == ENS_GROUP_ERRNO) | if ((status & ENS_GROUP_MASK) == ENS_GROUP_ERRNO) | ||||
strerror_r(status, buffer, length); | strerror_r(status, buffer, length); |
assert(decoder != NULL); | assert(decoder != NULL); | ||||
assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
assert(text_decoder_getc(decoder) == 0); | |||||
destroy_text_decoder(decoder); | destroy_text_decoder(decoder); | ||||
} | } | ||||
assert(espeak_ng_EncodingFromName("") == ESPEAKNG_ENCODING_UNKNOWN); | assert(espeak_ng_EncodingFromName("") == ESPEAKNG_ENCODING_UNKNOWN); | ||||
assert(espeak_ng_EncodingFromName("abcxyz") == ESPEAKNG_ENCODING_UNKNOWN); | assert(espeak_ng_EncodingFromName("abcxyz") == ESPEAKNG_ENCODING_UNKNOWN); | ||||
assert(espeak_ng_EncodingFromName("US") == ESPEAKNG_ENCODING_UNKNOWN); // wrong case | assert(espeak_ng_EncodingFromName("US") == ESPEAKNG_ENCODING_UNKNOWN); // wrong case | ||||
espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | |||||
assert(text_decoder_decode_string(decoder, "aG\x92\xA0\xDE", 5, ESPEAKNG_ENCODING_UNKNOWN) == ENS_UNKNOWN_TEXT_ENCODING); | |||||
assert(text_decoder_eof(decoder) == 1); | |||||
destroy_text_decoder(decoder); | |||||
} | } | ||||
void | void | ||||
assert(espeak_ng_EncodingFromName("IBM367") == ESPEAKNG_ENCODING_US_ASCII); | assert(espeak_ng_EncodingFromName("IBM367") == ESPEAKNG_ENCODING_US_ASCII); | ||||
assert(espeak_ng_EncodingFromName("cp367") == ESPEAKNG_ENCODING_US_ASCII); | assert(espeak_ng_EncodingFromName("cp367") == ESPEAKNG_ENCODING_US_ASCII); | ||||
assert(espeak_ng_EncodingFromName("csASCII") == ESPEAKNG_ENCODING_US_ASCII); | assert(espeak_ng_EncodingFromName("csASCII") == ESPEAKNG_ENCODING_US_ASCII); | ||||
espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | |||||
assert(text_decoder_decode_string(decoder, "aG\x92\xA0\xDE", 5, ESPEAKNG_ENCODING_US_ASCII) == ENS_OK); | |||||
assert(text_decoder_eof(decoder) == 0); | |||||
assert(text_decoder_getc(decoder) == 'a'); | |||||
assert(text_decoder_eof(decoder) == 0); | |||||
assert(text_decoder_getc(decoder) == 'G'); | |||||
assert(text_decoder_eof(decoder) == 0); | |||||
assert(text_decoder_getc(decoder) == 0xFFFD); | |||||
assert(text_decoder_eof(decoder) == 0); | |||||
assert(text_decoder_getc(decoder) == 0xFFFD); | |||||
assert(text_decoder_eof(decoder) == 0); | |||||
assert(text_decoder_getc(decoder) == 0xFFFD); | |||||
assert(text_decoder_eof(decoder) == 1); | |||||
destroy_text_decoder(decoder); | |||||
} | } | ||||
int | int |