encoding.c: Create a string decoding API; support US-ASCII decoding.

This commit is contained in:
Reece H. Dunn
2017-03-27 22:49:47 +01:00
parent da7eaa7b9c
commit 0590da5da7
5 changed files with 69 additions and 3 deletions
+1
View File
@@ -60,6 +60,7 @@ typedef enum {
/* eSpeak NG 1.49.2 */
ENS_UNKNOWN_PHONEME_FEATURE = 0x10000FFF,
ENS_UNKNOWN_TEXT_ENCODING = 0x100010FF,
} espeak_ng_STATUS;
typedef enum {
+35 -2
View File
@@ -52,6 +52,8 @@ espeak_ng_EncodingFromName(const char *encoding)
struct espeak_ng_TEXT_DECODER_
{
const char *current;
const char *end;
};
espeak_ng_TEXT_DECODER *
@@ -60,6 +62,8 @@ create_text_decoder(void)
espeak_ng_TEXT_DECODER *decoder = malloc(sizeof(espeak_ng_TEXT_DECODER));
if (!decoder) return NULL;
decoder->current = NULL;
decoder->end = NULL;
return decoder;
}
@@ -69,14 +73,43 @@ destroy_text_decoder(espeak_ng_TEXT_DECODER *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
text_decoder_eof(espeak_ng_TEXT_DECODER *decoder)
{
return 1;
return decoder->current == decoder->end;
}
uint32_t
text_decoder_getc(espeak_ng_TEXT_DECODER *decoder)
{
return 0;
uint8_t c = *decoder->current++ & 0xFF;
return (c >= 0x80) ? 0xFFFD : c;
}
+6
View File
@@ -30,6 +30,12 @@ create_text_decoder(void);
void
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
text_decoder_eof(espeak_ng_TEXT_DECODER *decoder);
+3
View File
@@ -135,6 +135,9 @@ espeak_ng_GetStatusCodeMessage(espeak_ng_STATUS status,
case ENS_UNKNOWN_PHONEME_FEATURE:
strncpy0(buffer, "The phoneme feature is not recognised", length);
break;
case ENS_UNKNOWN_TEXT_ENCODING:
strncpy0(buffer, "The text encoding is not supported", length);
break;
default:
if ((status & ENS_GROUP_MASK) == ENS_GROUP_ERRNO)
strerror_r(status, buffer, length);
+24 -1
View File
@@ -35,7 +35,6 @@ test_unbound_text_decoder()
assert(decoder != NULL);
assert(text_decoder_eof(decoder) == 1);
assert(text_decoder_getc(decoder) == 0);
destroy_text_decoder(decoder);
}
@@ -49,6 +48,13 @@ test_unknown_encoding()
assert(espeak_ng_EncodingFromName("") == ESPEAKNG_ENCODING_UNKNOWN);
assert(espeak_ng_EncodingFromName("abcxyz") == ESPEAKNG_ENCODING_UNKNOWN);
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
@@ -66,6 +72,23 @@ test_us_ascii_encoding()
assert(espeak_ng_EncodingFromName("IBM367") == ESPEAKNG_ENCODING_US_ASCII);
assert(espeak_ng_EncodingFromName("cp367") == 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