diff options
author | Carlos Garnacho <carlosg@gnome.org> | 2018-09-22 22:40:05 +0200 |
---|---|---|
committer | Carlos Garnacho <carlosg@gnome.org> | 2018-11-13 11:17:31 +0100 |
commit | 1041d4ef1c89a02b7c3a059cfb74fcb7ae91ff99 (patch) | |
tree | f1d6c9acc04861caa756a20b0e193ffc55391c2a | |
parent | 8828814cdc08dbb7c31746e59dc13d2f3cd249cc (diff) | |
download | tracker-1041d4ef1c89a02b7c3a059cfb74fcb7ae91ff99.tar.gz |
libtracker-common: Add helper function to escape \u and \U sequences
-rw-r--r-- | src/libtracker-common/tracker-utils.c | 89 | ||||
-rw-r--r-- | src/libtracker-common/tracker-utils.h | 2 |
2 files changed, 91 insertions, 0 deletions
diff --git a/src/libtracker-common/tracker-utils.c b/src/libtracker-common/tracker-utils.c index a9cb70643..c5a5721c7 100644 --- a/src/libtracker-common/tracker-utils.c +++ b/src/libtracker-common/tracker-utils.c @@ -236,3 +236,92 @@ tracker_utf8_truncate (const gchar *str, return retv; } + +static gboolean +range_is_xdigit (const gchar *str, + gssize start, + gssize end) +{ + gssize i; + + g_assert (end > start); + + for (i = start; i < end; i++) { + if (!g_ascii_isxdigit (str[i])) + return FALSE; + } + + return TRUE; +} + +static gunichar +xdigit_to_unichar (const gchar *str, + gssize start, + gssize end) +{ + gunichar ch = 0; + gssize i; + + g_assert (end > start); + + for (i = start; i < end; i++) { + ch |= g_ascii_xdigit_value (str[i]); + if (i < end - 1) + ch <<= 4; + } + + return ch; +} + +/* + * tracker_unescape_unichars: + * @str: Input string + * @len: Length + * + * Unescapes \u and \U sequences into their respective unichars. + * + * Returns: a string with no \u nor \U sequences + */ +gchar * +tracker_unescape_unichars (const gchar *str, + gssize len) +{ + GString *copy; + gunichar ch; + gssize i = 0; + + if (len < 0) + len = strlen (str); + + copy = g_string_new (NULL); + + while (i < len) { + if (len - i >= 2 && + str[i] == '\\' && + g_ascii_tolower (str[i + 1]) != 'u') { + /* Not an unicode escape sequence */ + g_string_append_c (copy, str[i]); + g_string_append_c (copy, str[i + 1]); + i += 2; + } if (len - i >= 6 && + strncmp (&str[i], "\\u", 2) == 0 && + range_is_xdigit (&str[i], 2, 6)) { + ch = xdigit_to_unichar (&str[i], 2, 6); + g_string_append_unichar (copy, ch); + i += 6; + continue; + } else if (len - i >= 10 && + strncmp (&str[i], "\\U", 2) == 0 && + range_is_xdigit (&str[i], 2, 10)) { + ch = xdigit_to_unichar (&str[i], 2, 10); + g_string_append_unichar (copy, ch); + i += 10; + continue; + } else { + g_string_append_c (copy, str[i]); + i++; + } + } + + return g_string_free (copy, FALSE); +} diff --git a/src/libtracker-common/tracker-utils.h b/src/libtracker-common/tracker-utils.h index 87ca7b395..2cb78e5ba 100644 --- a/src/libtracker-common/tracker-utils.h +++ b/src/libtracker-common/tracker-utils.h @@ -45,6 +45,8 @@ gchar * tracker_strhex (const guint8 *data, gchar delimiter); gchar * tracker_utf8_truncate (const gchar *str, gsize max_size); +gchar * tracker_unescape_unichars (const gchar *str, + gssize len); G_END_DECLS |