summaryrefslogtreecommitdiffstats
path: root/src/util.c
diff options
context:
space:
mode:
authorJeevaka Badrappan <jeevaka.badrappan@elektrobit.com>2010-09-13 16:00:11 -0700
committerDenis Kenzior <denkenz@gmail.com>2010-09-14 09:58:49 -0500
commit7cf26fef9d76eba8b1492294a44d68f73c395b38 (patch)
tree913a2174309066c8d168b2db0a3da808a7886f9d /src/util.c
parentfd9570500ef61caba52cc6494de96cdcf1ec725b (diff)
downloadofono-7cf26fef9d76eba8b1492294a44d68f73c395b38.tar.bz2
util: Add UCS2 to GSM 7bit converion function
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c108
1 files changed, 108 insertions, 0 deletions
diff --git a/src/util.c b/src/util.c
index 391bbb23..4b4a83c4 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1261,3 +1261,111 @@ unsigned char *utf8_to_sim_string(const char *utf,
return result;
}
+
+/*!
+ * Converts UCS2 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.
+ *
+ * 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_ucs2_to_gsm_with_lang(const unsigned char *text,
+ long len, long *items_read,
+ long *items_written,
+ unsigned char terminator,
+ enum gsm_dialect locking_lang,
+ enum gsm_dialect single_lang)
+{
+ long nchars = 0;
+ const unsigned char *in;
+ unsigned char *out;
+ unsigned char *res = NULL;
+ long res_len;
+ long i;
+
+ if (locking_lang >= GSM_DIALECT_INVALID)
+ return NULL;
+
+ if (single_lang >= GSM_DIALECT_INVALID)
+ return NULL;
+
+ if (len < 1 || len % 2)
+ return NULL;
+
+ in = text;
+ res_len = 0;
+
+ for (i = 0; i < len; i+=2) {
+ gunichar c = (in[i] << 8) | in[i+1];
+ unsigned short converted = GUND;
+
+ if (c > 0xffff)
+ goto err_out;
+
+ converted = unicode_locking_shift_lookup(c, locking_lang);
+
+ if (converted == GUND)
+ converted = unicode_single_shift_lookup(c, single_lang);
+
+ if (converted == GUND)
+ goto err_out;
+
+ if (converted & 0x1b00)
+ res_len += 2;
+ else
+ res_len += 1;
+
+ nchars += 1;
+ }
+
+ res = g_try_malloc(res_len + (terminator ? 1 : 0));
+ if (!res)
+ goto err_out;
+
+ in = text;
+ out = res;
+
+ for (i = 0; i < len; i+=2) {
+ gunichar c = (in[i] << 8) | in[i+1];
+ unsigned short converted = GUND;
+
+ converted = unicode_locking_shift_lookup(c, locking_lang);
+
+ if (converted == GUND)
+ converted = unicode_single_shift_lookup(c, single_lang);
+
+ if (converted & 0x1b00) {
+ *out = 0x1b;
+ ++out;
+ }
+
+ *out = converted;
+ ++out;
+ }
+
+ if (terminator)
+ *out = terminator;
+
+ if (items_written)
+ *items_written = out - res;
+
+err_out:
+ if (items_read)
+ *items_read = nchars;
+
+ return res;
+}
+
+unsigned char *convert_ucs2_to_gsm(const unsigned char *text, long len,
+ long *items_read, long *items_written,
+ unsigned char terminator)
+{
+ return convert_ucs2_to_gsm_with_lang(text, len, items_read,
+ items_written,
+ terminator,
+ GSM_DIALECT_DEFAULT,
+ GSM_DIALECT_DEFAULT);
+}