From 9dabf64680de6c0ef3b09fb19436ffdb3549017a Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Sat, 1 Apr 2017 13:23:09 +0100 Subject: [PATCH] encoding.c: Support determining the string length for length < 0. --- src/libespeak-ng/encoding.c | 8 +++++++ src/libespeak-ng/readclause.c | 2 +- src/libespeak-ng/translate.c | 27 +++++------------------ tests/encoding.c | 41 ++++++++++++++++++++++++++++++++--- 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/src/libespeak-ng/encoding.c b/src/libespeak-ng/encoding.c index 05651068..785e8483 100644 --- a/src/libespeak-ng/encoding.c +++ b/src/libespeak-ng/encoding.c @@ -17,8 +17,10 @@ #include "config.h" +#include #include #include +#include #include @@ -684,6 +686,8 @@ text_decoder_decode_string(espeak_ng_TEXT_DECODER *decoder, if (enc->get == NULL) return ENS_UNKNOWN_TEXT_ENCODING; + if (length < 0) length = string ? strlen(string) + 1 : 0; + decoder->get = string ? enc->get : null_decoder_getc; decoder->codepage = enc->codepage; decoder->current = (const uint8_t *)string; @@ -704,6 +708,8 @@ text_decoder_decode_string_auto(espeak_ng_TEXT_DECODER *decoder, if (enc->get == NULL) 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->codepage = enc->codepage; decoder->current = (const uint8_t *)string; @@ -716,6 +722,8 @@ text_decoder_decode_wstring(espeak_ng_TEXT_DECODER *decoder, const wchar_t *string, int length) { + if (length < 0) length = string ? wcslen(string) + 1 : 0; + decoder->get = string ? string_decoder_getc_wchar : null_decoder_getc; decoder->codepage = NULL; decoder->current = (const uint8_t *)string; diff --git a/src/libespeak-ng/readclause.c b/src/libespeak-ng/readclause.c index 1e458492..5c8a0633 100644 --- a/src/libespeak-ng/readclause.c +++ b/src/libespeak-ng/readclause.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 to 2015 by Jonathan Duddington * email: jonsd@users.sourceforge.net - * 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 * it under the terms of the GNU General Public License as published by diff --git a/src/libespeak-ng/translate.c b/src/libespeak-ng/translate.c index 42d0fe60..009dabae 100644 --- a/src/libespeak-ng/translate.c +++ b/src/libespeak-ng/translate.c @@ -1,7 +1,7 @@ /* * Copyright (C) 2005 to 2014 by Jonathan Duddington * email: jonsd@users.sourceforge.net - * 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 * it under the terms of the GNU General Public License as published by @@ -1916,21 +1916,6 @@ int UpperCaseInWord(Translator *tr, char *word, int c) 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) { int ix; @@ -1988,19 +1973,19 @@ const void *TranslateClause(Translator *tr, const void *vp_input, int *tone_out, switch (option_multibyte) { case espeakCHARS_WCHAR: - init_wstring_decoder((const wchar_t *)vp_input); + text_decoder_decode_wstring(p_decoder, (const wchar_t *)vp_input, -1); break; 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; 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; 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; 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; default: return NULL; // unknown multibyte option value diff --git a/tests/encoding.c b/tests/encoding.c index af1e812e..fa6daffb 100644 --- a/tests/encoding.c +++ b/tests/encoding.c @@ -736,11 +736,21 @@ test_char_decoder() espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); // 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_getc(decoder) == 0); 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); } @@ -752,11 +762,12 @@ test_wchar_decoder() espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); // 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_getc(decoder) == 0); 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_eof(decoder) == 0); assert(text_decoder_getc(decoder) == 'a'); @@ -768,6 +779,20 @@ test_wchar_decoder() assert(text_decoder_getc(decoder) == 0x2045); 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); } @@ -779,7 +804,7 @@ test_auto_decoder() espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); // 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_getc(decoder) == 0); assert(text_decoder_eof(decoder) == 1); @@ -808,6 +833,16 @@ test_auto_decoder() assert(text_decoder_getc(decoder) == 'f'); 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); }