| #include "config.h" | #include "config.h" | ||||
| #include <string.h> | |||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <wchar.h> | |||||
| #include <espeak-ng/espeak_ng.h> | #include <espeak-ng/espeak_ng.h> | ||||
| if (enc->get == NULL) | if (enc->get == NULL) | ||||
| return ENS_UNKNOWN_TEXT_ENCODING; | return ENS_UNKNOWN_TEXT_ENCODING; | ||||
| if (length < 0) length = string ? strlen(string) + 1 : 0; | |||||
| decoder->get = string ? enc->get : null_decoder_getc; | decoder->get = string ? enc->get : null_decoder_getc; | ||||
| decoder->codepage = enc->codepage; | decoder->codepage = enc->codepage; | ||||
| decoder->current = (const uint8_t *)string; | decoder->current = (const uint8_t *)string; | ||||
| if (enc->get == NULL) | if (enc->get == NULL) | ||||
| return ENS_UNKNOWN_TEXT_ENCODING; | return ENS_UNKNOWN_TEXT_ENCODING; | ||||
| if (length < 0) length = string ? strlen(string) + 1 : 0; | |||||
| decoder->get = string ? string_decoder_getc_auto : null_decoder_getc; | decoder->get = string ? string_decoder_getc_auto : null_decoder_getc; | ||||
| decoder->codepage = enc->codepage; | decoder->codepage = enc->codepage; | ||||
| decoder->current = (const uint8_t *)string; | decoder->current = (const uint8_t *)string; | ||||
| const wchar_t *string, | const wchar_t *string, | ||||
| int length) | int length) | ||||
| { | { | ||||
| if (length < 0) length = string ? wcslen(string) + 1 : 0; | |||||
| decoder->get = string ? string_decoder_getc_wchar : null_decoder_getc; | decoder->get = string ? string_decoder_getc_wchar : null_decoder_getc; | ||||
| decoder->codepage = NULL; | decoder->codepage = NULL; | ||||
| decoder->current = (const uint8_t *)string; | decoder->current = (const uint8_t *)string; |
| /* | /* | ||||
| * Copyright (C) 2005 to 2015 by Jonathan Duddington | * Copyright (C) 2005 to 2015 by Jonathan Duddington | ||||
| * email: [email protected] | * email: [email protected] | ||||
| * Copyright (C) 2015-2016 Reece H. Dunn | |||||
| * Copyright (C) 2015-2017 Reece H. Dunn | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by |
| /* | /* | ||||
| * Copyright (C) 2005 to 2014 by Jonathan Duddington | * Copyright (C) 2005 to 2014 by Jonathan Duddington | ||||
| * email: [email protected] | * email: [email protected] | ||||
| * Copyright (C) 2015-2016 Reece H. Dunn | |||||
| * Copyright (C) 2015-2017 Reece H. Dunn | |||||
| * | * | ||||
| * This program is free software; you can redistribute it and/or modify | * This program is free software; you can redistribute it and/or modify | ||||
| * it under the terms of the GNU General Public License as published by | * it under the terms of the GNU General Public License as published by | ||||
| return 0; | return 0; | ||||
| } | } | ||||
| static inline espeak_ng_STATUS init_wstring_decoder(const wchar_t *text) | |||||
| { | |||||
| return text_decoder_decode_wstring(p_decoder, text, wcslen(text) + 1); | |||||
| } | |||||
| static inline espeak_ng_STATUS init_string_decoder(const char *text, espeak_ng_ENCODING encoding) | |||||
| { | |||||
| return text_decoder_decode_string(p_decoder, text, strlen(text) + 1, encoding); | |||||
| } | |||||
| static inline espeak_ng_STATUS init_string_decoder_auto(const char *text, espeak_ng_ENCODING encoding) | |||||
| { | |||||
| return text_decoder_decode_string_auto(p_decoder, text, strlen(text) + 1, encoding); | |||||
| } | |||||
| const void *TranslateClause(Translator *tr, const void *vp_input, int *tone_out, char **voice_change) | const void *TranslateClause(Translator *tr, const void *vp_input, int *tone_out, char **voice_change) | ||||
| { | { | ||||
| int ix; | int ix; | ||||
| switch (option_multibyte) | switch (option_multibyte) | ||||
| { | { | ||||
| case espeakCHARS_WCHAR: | case espeakCHARS_WCHAR: | ||||
| init_wstring_decoder((const wchar_t *)vp_input); | |||||
| text_decoder_decode_wstring(p_decoder, (const wchar_t *)vp_input, -1); | |||||
| break; | break; | ||||
| case espeakCHARS_AUTO: | case espeakCHARS_AUTO: | ||||
| init_string_decoder_auto((const char *)vp_input, tr->encoding); | |||||
| text_decoder_decode_string_auto(p_decoder, (const char *)vp_input, -1, tr->encoding); | |||||
| break; | break; | ||||
| case espeakCHARS_UTF8: | case espeakCHARS_UTF8: | ||||
| init_string_decoder((const char *)vp_input, ESPEAKNG_ENCODING_UTF_8); | |||||
| text_decoder_decode_string(p_decoder, (const char *)vp_input, -1, ESPEAKNG_ENCODING_UTF_8); | |||||
| break; | break; | ||||
| case espeakCHARS_8BIT: | case espeakCHARS_8BIT: | ||||
| init_string_decoder((const char *)vp_input, tr->encoding); | |||||
| text_decoder_decode_string(p_decoder, (const char *)vp_input, -1, tr->encoding); | |||||
| break; | break; | ||||
| case espeakCHARS_16BIT: | case espeakCHARS_16BIT: | ||||
| init_string_decoder((const char *)vp_input, ESPEAKNG_ENCODING_ISO_10646_UCS_2); | |||||
| text_decoder_decode_string(p_decoder, (const char *)vp_input, -1, ESPEAKNG_ENCODING_ISO_10646_UCS_2); | |||||
| break; | break; | ||||
| default: | default: | ||||
| return NULL; // unknown multibyte option value | return NULL; // unknown multibyte option value |
| espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | ||||
| // null string | // null string | ||||
| assert(text_decoder_decode_string(decoder, NULL, 5, ESPEAKNG_ENCODING_ISO_8859_1) == ENS_OK); | |||||
| assert(text_decoder_decode_string(decoder, NULL, -1, ESPEAKNG_ENCODING_ISO_8859_1) == ENS_OK); | |||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| assert(text_decoder_getc(decoder) == 0); | assert(text_decoder_getc(decoder) == 0); | ||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| // string length | |||||
| assert(text_decoder_decode_string(decoder, "aG", -1, ESPEAKNG_ENCODING_ISO_8859_1) == 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) == 0); | |||||
| assert(text_decoder_eof(decoder) == 1); | |||||
| destroy_text_decoder(decoder); | destroy_text_decoder(decoder); | ||||
| } | } | ||||
| espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | ||||
| // null string | // null string | ||||
| assert(text_decoder_decode_wstring(decoder, NULL, 5) == ENS_OK); | |||||
| assert(text_decoder_decode_wstring(decoder, NULL, -1) == ENS_OK); | |||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| assert(text_decoder_getc(decoder) == 0); | assert(text_decoder_getc(decoder) == 0); | ||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| // wide-character string | |||||
| assert(text_decoder_decode_wstring(decoder, L"aG\xA0\x2045", 4) == ENS_OK); | assert(text_decoder_decode_wstring(decoder, L"aG\xA0\x2045", 4) == ENS_OK); | ||||
| assert(text_decoder_eof(decoder) == 0); | assert(text_decoder_eof(decoder) == 0); | ||||
| assert(text_decoder_getc(decoder) == 'a'); | assert(text_decoder_getc(decoder) == 'a'); | ||||
| assert(text_decoder_getc(decoder) == 0x2045); | assert(text_decoder_getc(decoder) == 0x2045); | ||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| // string length | |||||
| assert(text_decoder_decode_wstring(decoder, L"aG\xA0\x2045", -1) == 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) == 0xA0); | |||||
| assert(text_decoder_eof(decoder) == 0); | |||||
| assert(text_decoder_getc(decoder) == 0x2045); | |||||
| assert(text_decoder_eof(decoder) == 0); | |||||
| assert(text_decoder_getc(decoder) == 0); | |||||
| assert(text_decoder_eof(decoder) == 1); | |||||
| destroy_text_decoder(decoder); | destroy_text_decoder(decoder); | ||||
| } | } | ||||
| espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); | ||||
| // null string | // null string | ||||
| assert(text_decoder_decode_string_auto(decoder, NULL, 5, ESPEAKNG_ENCODING_ISO_8859_1) == ENS_OK); | |||||
| assert(text_decoder_decode_string_auto(decoder, NULL, -1, ESPEAKNG_ENCODING_ISO_8859_1) == ENS_OK); | |||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| assert(text_decoder_getc(decoder) == 0); | assert(text_decoder_getc(decoder) == 0); | ||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| assert(text_decoder_getc(decoder) == 'f'); | assert(text_decoder_getc(decoder) == 'f'); | ||||
| assert(text_decoder_eof(decoder) == 1); | assert(text_decoder_eof(decoder) == 1); | ||||
| // string length | |||||
| assert(text_decoder_decode_string_auto(decoder, "aG", -1, ESPEAKNG_ENCODING_ISO_8859_1) == 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) == 0); | |||||
| assert(text_decoder_eof(decoder) == 1); | |||||
| destroy_text_decoder(decoder); | destroy_text_decoder(decoder); | ||||
| } | } | ||||