diff --git a/src/util.c b/src/util.c index fd8b305..08f6c4f 100644 --- a/src/util.c +++ b/src/util.c @@ -500,26 +500,18 @@ static unsigned short gsm_single_shift_lookup(unsigned char k, } static unsigned short unicode_locking_shift_lookup(unsigned short k, - unsigned char lang) + const struct codepoint *table, + unsigned int len) { struct codepoint key = { k, 0 }; - const struct codepoint *table; - unsigned int len = 128; - - table = alphabet_lookup[lang].tounicode_locking_shift; - return codepoint_lookup(&key, table, len); } static unsigned short unicode_single_shift_lookup(unsigned short k, - unsigned char lang) + const struct codepoint *table, + unsigned int len) { struct codepoint key = { k, 0 }; - const struct codepoint *table; - unsigned int len; - - table = alphabet_lookup[lang].tounicode_single_shift; - len = alphabet_lookup[lang].tounicode_single_shift_len; return codepoint_lookup(&key, table, len); } @@ -632,21 +624,14 @@ char *convert_gsm_to_utf8(const unsigned char *text, long len, GSM_DIALECT_DEFAULT); } -/*! - * Converts UTF-8 encoded text to GSM alphabet. The result is unpacked, - * with the 7th bit always 0. If terminator is not 0, a terminator character - * is appended to the result. This should be in the range 0x80-0xf0 - * - * Returns the encoded data or NULL if the data could not be encoded. The - * data must be freed by the caller. If items_read is not NULL, it contains - * the actual number of bytes read. If items_written is not NULL, contains - * the number of bytes written. - */ -unsigned char *convert_utf8_to_gsm_with_lang(const char *text, long len, - long *items_read, long *items_written, - unsigned char terminator, - enum gsm_dialect locking_lang, - enum gsm_dialect single_lang) +static unsigned char *utf8_to_gsm_with_table(const char *text, long len, + long *items_read, + long *items_written, + unsigned char terminator, + const struct codepoint *locking, + unsigned int locking_len, + const struct codepoint *single, + unsigned int single_len) { long nchars = 0; const char *in; @@ -655,12 +640,6 @@ unsigned char *convert_utf8_to_gsm_with_lang(const char *text, long len, long res_len; long i; - if (locking_lang >= GSM_DIALECT_INVALID) - return NULL; - - if (single_lang >= GSM_DIALECT_INVALID) - return NULL; - in = text; res_len = 0; @@ -675,10 +654,12 @@ unsigned char *convert_utf8_to_gsm_with_lang(const char *text, long len, if (c > 0xffff) goto err_out; - converted = unicode_locking_shift_lookup(c, locking_lang); + converted = unicode_locking_shift_lookup(c, + locking, locking_len); if (converted == GUND) - converted = unicode_single_shift_lookup(c, single_lang); + converted = unicode_single_shift_lookup(c, + single, single_len); if (converted == GUND) goto err_out; @@ -704,10 +685,12 @@ unsigned char *convert_utf8_to_gsm_with_lang(const char *text, long len, gunichar c = g_utf8_get_char(in); - converted = unicode_locking_shift_lookup(c, locking_lang); + converted = unicode_locking_shift_lookup(c, + locking, locking_len); if (converted == GUND) - converted = unicode_single_shift_lookup(c, single_lang); + converted = unicode_single_shift_lookup(c, + single, single_len); if (converted & 0x1b00) { *out = 0x1b; @@ -733,6 +716,44 @@ err_out: return res; } +/*! + * Converts UTF-8 encoded text to GSM alphabet. The result is unpacked, + * with the 7th bit always 0. If terminator is not 0, a terminator character + * is appended to the result. This should be in the range 0x80-0xf0 + * + * Returns the encoded data or NULL if the data could not be encoded. The + * data must be freed by the caller. If items_read is not NULL, it contains + * the actual number of bytes read. If items_written is not NULL, contains + * the number of bytes written. + */ +unsigned char *convert_utf8_to_gsm_with_lang(const char *text, long len, + long *items_read, long *items_written, + unsigned char terminator, + enum gsm_dialect locking_lang, + enum gsm_dialect single_lang) +{ + const struct codepoint *locking; + unsigned int locking_len; + const struct codepoint *single; + unsigned int single_len; + + if (locking_lang >= GSM_DIALECT_INVALID) + return NULL; + + if (single_lang >= GSM_DIALECT_INVALID) + return NULL; + + locking = alphabet_lookup[locking_lang].tounicode_locking_shift; + locking_len = 128; + + single = alphabet_lookup[single_lang].tounicode_single_shift; + single_len = alphabet_lookup[single_lang].tounicode_single_shift_len; + + return utf8_to_gsm_with_table(text, len, items_read, items_written, + terminator, locking, locking_len, + single, single_len); +} + unsigned char *convert_utf8_to_gsm(const char *text, long len, long *items_read, long *items_written, unsigned char terminator)