From b74f756f00bff5a69b1c3dbcd826c6010c438a66 Mon Sep 17 00:00:00 2001 From: "Reece H. Dunn" Date: Thu, 30 Mar 2017 22:33:22 +0100 Subject: [PATCH] encoding.c: Support the ISO-10646-UCS-2 encoding. --- src/include/espeak-ng/espeak_ng.h | 1 + src/libespeak-ng/encoding.c | 18 +++++++++++++++++- tests/encoding.c | 27 +++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/src/include/espeak-ng/espeak_ng.h b/src/include/espeak-ng/espeak_ng.h index 6e9079be..12491cee 100644 --- a/src/include/espeak-ng/espeak_ng.h +++ b/src/include/espeak-ng/espeak_ng.h @@ -209,6 +209,7 @@ typedef enum ESPEAKNG_ENCODING_KOI8_R, ESPEAKNG_ENCODING_ISCII, ESPEAKNG_ENCODING_UTF_8, + ESPEAKNG_ENCODING_ISO_10646_UCS_2, } espeak_ng_ENCODING; ESPEAK_NG_API espeak_ng_ENCODING diff --git a/src/libespeak-ng/encoding.c b/src/libespeak-ng/encoding.c index 2c514e02..a16332be 100644 --- a/src/libespeak-ng/encoding.c +++ b/src/libespeak-ng/encoding.c @@ -66,6 +66,7 @@ MNEM_TAB mnem_encoding[] = { { "ISO_8859-16", ESPEAKNG_ENCODING_ISO_8859_16 }, { "ISO_8859-16:2001", ESPEAKNG_ENCODING_ISO_8859_16 }, { "ISO646-US", ESPEAKNG_ENCODING_US_ASCII }, + { "ISO-10646-UCS-2", ESPEAKNG_ENCODING_ISO_10646_UCS_2 }, { "ISO-8859-1", ESPEAKNG_ENCODING_ISO_8859_1 }, { "ISO-8859-2", ESPEAKNG_ENCODING_ISO_8859_2 }, { "ISO-8859-3", ESPEAKNG_ENCODING_ISO_8859_3 }, @@ -106,6 +107,7 @@ MNEM_TAB mnem_encoding[] = { { "csKOI8R", ESPEAKNG_ENCODING_KOI8_R }, { "csTIS620", ESPEAKNG_ENCODING_ISO_8859_11 }, { "csUTF8", ESPEAKNG_ENCODING_UTF_8 }, + { "csUnicode", ESPEAKNG_ENCODING_ISO_10646_UCS_2 }, { "arabic", ESPEAKNG_ENCODING_ISO_8859_6 }, { "cyrillic", ESPEAKNG_ENCODING_ISO_8859_5 }, { "greek", ESPEAKNG_ENCODING_ISO_8859_7 }, @@ -566,6 +568,19 @@ eof: return 0xFFFD; } +static uint32_t +string_decoder_getc_iso_10646_ucs_2(espeak_ng_TEXT_DECODER *decoder) +{ + if (decoder->current + 1 >= decoder->end) { + decoder->current = decoder->end; + return 0xFFFD; + } + + uint8_t c1 = *decoder->current++ & 0xFF; + uint8_t c2 = *decoder->current++ & 0xFF; + return c1 + (c2 << 8); +} + typedef struct { uint32_t (*get)(espeak_ng_TEXT_DECODER *decoder); @@ -594,6 +609,7 @@ static const encoding_t string_decoders[] = { { string_decoder_getc_codepage, KOI8_R }, { string_decoder_getc_codepage, ISCII }, { string_decoder_getc_utf_8, NULL }, + { string_decoder_getc_iso_10646_ucs_2, NULL }, }; espeak_ng_TEXT_DECODER * @@ -621,7 +637,7 @@ text_decoder_decode_string(espeak_ng_TEXT_DECODER *decoder, int length, espeak_ng_ENCODING encoding) { - if (encoding > ESPEAKNG_ENCODING_UTF_8) + if (encoding > ESPEAKNG_ENCODING_ISO_10646_UCS_2) return ENS_UNKNOWN_TEXT_ENCODING; const encoding_t *enc = string_decoders + encoding; diff --git a/tests/encoding.c b/tests/encoding.c index 8ec8a503..b8140b05 100644 --- a/tests/encoding.c +++ b/tests/encoding.c @@ -702,6 +702,32 @@ test_utf_8_encoding() destroy_text_decoder(decoder); } +void +test_iso_10646_ucs_2_encoding() +{ + printf("testing ISO-10646-UCS-2 encoding\n"); + + assert(espeak_ng_EncodingFromName("ISO-10646-UCS-2") == ESPEAKNG_ENCODING_ISO_10646_UCS_2); + assert(espeak_ng_EncodingFromName("csUnicode") == ESPEAKNG_ENCODING_ISO_10646_UCS_2); + + espeak_ng_TEXT_DECODER *decoder = create_text_decoder(); + + assert(text_decoder_decode_string(decoder, "a\00G\00\xA0\00\x22\x21\x23\x21", 9, ESPEAKNG_ENCODING_ISO_10646_UCS_2) == 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) == 0x2122); + assert(text_decoder_eof(decoder) == 0); + assert(text_decoder_getc(decoder) == 0xFFFD); + assert(text_decoder_eof(decoder) == 1); + + destroy_text_decoder(decoder); +} + int main(int argc, char **argv) { @@ -730,6 +756,7 @@ main(int argc, char **argv) test_iso_8859_16_encoding(); test_utf_8_encoding(); + test_iso_10646_ucs_2_encoding(); printf("done\n");