2 * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3 * Copyright (C) 2017 Ricardo Mones and the Claws Mail team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "claws-features.h"
27 #define ENTITY_MAX_LEN 8
28 #define DECODED_MAX_LEN 6
30 static GHashTable *symbol_table = NULL;
32 typedef struct _EntitySymbol EntitySymbol;
40 /* in alphabetical order with upper-case version first */
41 static EntitySymbol symbolic_entities[] = {
105 {"emsp", "\xE2\x80\x83"},
106 {"ensp", "\xE2\x80\x82"},
168 {"lrm", "\xE2\x80\x8E"},
182 {"nbsp", "\xC2\xA0"},
251 {"rlm", "\xE2\x80\x8F"},
282 {"thinsp", "\xE2\x80\x89"},
317 {"zwj", "\xE2\x80\x8D"},
318 {"zwnj", "\xE2\x80\x8C"},
322 static gchar* entity_extract_to_buffer(gchar *p, gchar b[])
326 while (*p != '\0' && *p != ';' && i < ENTITY_MAX_LEN) {
330 if (*p != ';' || i == ENTITY_MAX_LEN)
337 static gchar *entity_decode_numeric(gchar *str)
339 gchar b[ENTITY_MAX_LEN];
340 gchar *p = str, *res;
341 gboolean hex = FALSE;
355 if (entity_extract_to_buffer (p, b) == NULL)
358 c = g_ascii_strtoll (b, NULL, (hex? 16: 10));
359 res = g_malloc0 (DECODED_MAX_LEN + 1);
360 g_unichar_to_utf8 (c, res);
365 static gchar *entity_decode_symbol(gchar *str)
367 gchar b[ENTITY_MAX_LEN];
370 if (entity_extract_to_buffer (str, b) == NULL)
373 if (symbol_table == NULL) {
376 symbol_table = g_hash_table_new (g_str_hash, g_str_equal);
377 for (i = 0; symbolic_entities[i].key != NULL; ++i) {
378 g_hash_table_insert (symbol_table,
379 symbolic_entities[i].key, symbolic_entities[i].value);
381 debug_print("initialized entities table with %d symbols\n", i);
384 decoded = g_hash_table_lookup (symbol_table, b);
386 return g_strdup (decoded);
391 gchar *entity_decode(gchar *str)
394 if (p == NULL || *p != '&')
400 return entity_decode_numeric(p);
402 return entity_decode_symbol(p);