/dev/tomkiewicz/new-smileys: fe6aba70046e: Custom smileys: make ...

Tomasz Wasilczyk twasilczyk at pidgin.im
Fri Apr 4 16:23:41 EDT 2014


Changeset: fe6aba70046e2bc9d14a11c5776bf79d1f62396f
Author:	 Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date:	 2014-04-04 22:23 +0200
Branch:	 default
URL: https://hg.pidgin.im/dev/tomkiewicz/new-smileys/rev/fe6aba70046e

Description:

Custom smileys: make it possible to find them by prpl

diffstat:

 libpurple/conversation.c    |   3 -
 libpurple/smiley-list.c     |  18 +++-----
 libpurple/smiley-list.h     |   1 +
 libpurple/smiley-parser.c   |  69 +++++++++++++++++++-------------
 libpurple/smiley-parser.h   |   8 +-
 libpurple/tests/test_trie.c |  93 +++++++++++++++++++++++++++++++++++++++++++++
 libpurple/trie.c            |  68 +++++++++++++++++++++++++++++++-
 libpurple/trie.h            |   7 +++
 pidgin/libpidgin.c          |   2 -
 9 files changed, 218 insertions(+), 51 deletions(-)

diffs (truncated from 484 to 300 lines):

diff --git a/libpurple/conversation.c b/libpurple/conversation.c
--- a/libpurple/conversation.c
+++ b/libpurple/conversation.c
@@ -968,9 +968,6 @@ purple_conversation_add_remote_smiley(Pu
 		return NULL;
 	}
 
-	/* TODO: connect to the failed signal, to make it possible returning this smiley object again (later). Maybe just remove from the list on fail */
-	/* TODO: test it by doing failed on the first retrieval, succ on the second */
-
 	/* smiley was already added */
 	if (smiley)
 		return NULL;
diff --git a/libpurple/smiley-list.c b/libpurple/smiley-list.c
--- a/libpurple/smiley-list.c
+++ b/libpurple/smiley-list.c
@@ -113,7 +113,7 @@ purple_smiley_list_add(PurpleSmileyList 
 	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list);
 	const gchar *smiley_path;
 	gboolean succ;
-	gchar *tmp = NULL;
+	gchar *shortcut_escaped;
 	const gchar *shortcut;
 
 	g_return_val_if_fail(priv != NULL, FALSE);
@@ -130,11 +130,9 @@ purple_smiley_list_add(PurpleSmileyList 
 	if (g_hash_table_lookup(priv->shortcut_map, shortcut) != NULL)
 		return FALSE;
 
-	if (purple_smiley_parse_escape())
-		shortcut = tmp = g_markup_escape_text(shortcut, -1);
-	succ = purple_trie_add(priv->trie, shortcut, smiley);
-	g_free(tmp);
-	shortcut = purple_smiley_get_shortcut(smiley);
+	shortcut_escaped = g_markup_escape_text(shortcut, -1);
+	succ = purple_trie_add(priv->trie, shortcut_escaped, smiley);
+	g_free(shortcut_escaped);
 	if (!succ)
 		return FALSE;
 
@@ -175,7 +173,7 @@ purple_smiley_list_remove(PurpleSmileyLi
 	PurpleSmileyListPrivate *priv = PURPLE_SMILEY_LIST_GET_PRIVATE(list);
 	GList *list_elem, *it;
 	const gchar *shortcut, *path;
-	gchar *tmp;
+	gchar *shortcut_escaped;
 
 	g_return_if_fail(priv != NULL);
 	g_return_if_fail(PURPLE_IS_SMILEY(smiley));
@@ -195,11 +193,9 @@ purple_smiley_list_remove(PurpleSmileyLi
 	if (path)
 		g_hash_table_remove(priv->path_map, path);
 
-	if (purple_smiley_parse_escape())
-		shortcut = tmp = g_markup_escape_text(shortcut, -1);
+	shortcut_escaped = g_markup_escape_text(shortcut, -1);
 	purple_trie_remove(priv->trie, shortcut);
-	g_free(tmp);
-	shortcut = purple_smiley_get_shortcut(smiley);
+	g_free(shortcut_escaped);
 
 	_list_remove_link2(&priv->smileys, &priv->smileys_end, list_elem);
 
diff --git a/libpurple/smiley-list.h b/libpurple/smiley-list.h
--- a/libpurple/smiley-list.h
+++ b/libpurple/smiley-list.h
@@ -85,6 +85,7 @@ PurpleSmiley *
 purple_smiley_list_get_by_shortcut(PurpleSmileyList *list,
 	const gchar *shortcut);
 
+/* keys are HTML escaped shortcuts */
 PurpleTrie *
 purple_smiley_list_get_trie(PurpleSmileyList *list);
 
diff --git a/libpurple/smiley-parser.c b/libpurple/smiley-parser.c
--- a/libpurple/smiley-parser.c
+++ b/libpurple/smiley-parser.c
@@ -31,29 +31,6 @@ typedef struct
 	gpointer ui_data;
 } PurpleSmileyParseData;
 
-static gboolean escape_checked = FALSE;
-static gboolean escape_value;
-
-gboolean
-purple_smiley_parse_escape(void)
-{
-	GHashTable *ui_info;
-
-	if (escape_checked)
-		return escape_value;
-
-	ui_info = purple_core_get_ui_info();
-	if (!ui_info)
-		escape_value = FALSE;
-	else {
-		escape_value = GPOINTER_TO_INT(g_hash_table_lookup(ui_info,
-			"smiley-parser-escape"));
-	}
-
-	escape_checked = TRUE;
-	return escape_value;
-}
-
 static gboolean purple_smiley_parse_cb(GString *out, const gchar *word,
 	gpointer _smiley, gpointer _parse_data)
 {
@@ -66,7 +43,7 @@ static gboolean purple_smiley_parse_cb(G
 }
 
 gchar *
-purple_smiley_parse(PurpleConversation *conv, const gchar *message,
+purple_smiley_parse(PurpleConversation *conv, const gchar *html_message,
 	PurpleSmileyParseCb cb, gpointer ui_data)
 {
 	PurpleSmileyTheme *theme;
@@ -75,8 +52,8 @@ purple_smiley_parse(PurpleConversation *
 	GSList *tries = NULL, tries_theme, tries_custom, tries_remote;
 	PurpleSmileyParseData parse_data;
 
-	if (message == NULL || message[0] == '\0')
-		return g_strdup(message);
+	if (html_message == NULL || html_message[0] == '\0')
+		return g_strdup(html_message);
 
 	/* get remote smileys */
 	remote_smileys = purple_conversation_get_remote_smileys(conv);
@@ -104,7 +81,7 @@ purple_smiley_parse(PurpleConversation *
 
 	/* we have absolutely no smileys */
 	if (theme_trie == NULL && custom_trie == NULL && remote_trie == NULL)
-		return g_strdup(message);
+		return g_strdup(html_message);
 
 	/* Create a tries list on the stack. */
 	tries_theme.data = theme_trie;
@@ -133,6 +110,42 @@ purple_smiley_parse(PurpleConversation *
 	/* TODO: don't replace text within tags, ie. <span style=":)"> */
 	/* TODO: parse greedily (as much as possible) when PurpleTrie
 	 * provides support for it. */
-	return purple_trie_multi_replace(tries, message,
+	return purple_trie_multi_replace(tries, html_message,
 		purple_smiley_parse_cb, &parse_data);
 }
+
+static gboolean
+smiley_find_cb(const gchar *word, gpointer _smiley, gpointer _found_smileys)
+{
+	PurpleSmiley *smiley = _smiley;
+	GHashTable *found_smileys = _found_smileys;
+
+	g_hash_table_insert(found_smileys, smiley, smiley);
+
+	return TRUE;
+}
+
+GList *
+purple_smiley_find(PurpleSmileyList *smileys, const gchar *html_message)
+{
+	PurpleTrie *trie;
+	GHashTable *found_smileys;
+	GList *found_list;
+
+	if (html_message == NULL || html_message[0] == '\0')
+		return NULL;
+
+	if (smileys == NULL || purple_smiley_list_is_empty(smileys))
+		return NULL;
+
+	trie = purple_smiley_list_get_trie(smileys);
+	g_return_val_if_fail(trie != NULL, NULL);
+
+	found_smileys = g_hash_table_new(g_direct_hash, g_direct_equal);
+	purple_trie_find(trie, html_message, smiley_find_cb, found_smileys);
+
+	found_list = g_hash_table_get_values(found_smileys);
+	g_hash_table_destroy(found_smileys);
+
+	return found_list;
+}
diff --git a/libpurple/smiley-parser.h b/libpurple/smiley-parser.h
--- a/libpurple/smiley-parser.h
+++ b/libpurple/smiley-parser.h
@@ -27,9 +27,6 @@
 typedef void (*PurpleSmileyParseCb)(GString *out, PurpleSmiley *smiley,
 	PurpleConversation *conv, gpointer ui_data);
 
-gboolean
-purple_smiley_parse_escape(void);
-
 /* XXX: this shouldn't be a conv for incoming messages - see
  * PurpleConversationPrivate#remote_smileys.
  * For outgoing, we could pass conv in ui_data (or something).
@@ -40,7 +37,10 @@ purple_smiley_parse_escape(void);
  * outgoing messages. To be considered.
  */
 gchar *
-purple_smiley_parse(PurpleConversation *conv, const gchar *message,
+purple_smiley_parse(PurpleConversation *conv, const gchar *html_message,
 	PurpleSmileyParseCb cb, gpointer ui_data);
 
+GList *
+purple_smiley_find(PurpleSmileyList *smileys, const gchar *html_message);
+
 #endif /* _PURPLE_SMILEY_PARSER_H_ */
diff --git a/libpurple/tests/test_trie.c b/libpurple/tests/test_trie.c
--- a/libpurple/tests/test_trie.c
+++ b/libpurple/tests/test_trie.c
@@ -3,6 +3,8 @@
 #include "tests.h"
 #include "../trie.h"
 
+static gint find_sum;
+
 static gboolean
 test_trie_replace_cb(GString *out, const gchar *word, gpointer word_data,
 	gpointer user_data)
@@ -17,6 +19,19 @@ test_trie_replace_cb(GString *out, const
 	return TRUE;
 }
 
+static gboolean
+test_trie_find_cb(const gchar *word, gpointer word_data,
+	gpointer user_data)
+{
+	if ((gintptr)word_data == 0x7004)
+		return FALSE;
+
+	find_sum += (gintptr)word_data;
+	find_sum -= (gintptr)user_data * 0x1000;
+
+	return TRUE;
+}
+
 START_TEST(test_trie_replace)
 {
 	PurpleTrie *trie;
@@ -181,6 +196,81 @@ START_TEST(test_trie_remove)
 }
 END_TEST
 
+START_TEST(test_trie_find)
+{
+	PurpleTrie *trie;
+	const gchar *in;
+	gint out;
+
+	trie = purple_trie_new();
+
+	purple_trie_add(trie, "alice", (gpointer)0x7001);
+	purple_trie_add(trie, "bob", (gpointer)0x7002);
+	purple_trie_add(trie, "cherry", (gpointer)0x7003);
+	purple_trie_add(trie, "al", (gpointer)0x7004); /* not accepted */
+
+	in = "test alice bob test cherry alice";
+
+	find_sum = 0;
+	out = purple_trie_find(trie, in, test_trie_find_cb, (gpointer)7);
+
+	assert_int_equal(4, out);
+	assert_int_equal(2*1 + 2 + 3, find_sum);
+
+	g_object_unref(trie);
+}
+END_TEST
+
+START_TEST(test_trie_find_reset)
+{
+	PurpleTrie *trie;
+	const gchar *in;
+	gint out;
+
+	trie = purple_trie_new();
+	purple_trie_set_reset_on_match(trie, TRUE);
+
+	purple_trie_add(trie, "alice", (gpointer)0x8001);
+	purple_trie_add(trie, "ali", (gpointer)0x8002);
+	purple_trie_add(trie, "al", (gpointer)0x8003);
+
+	in = "al ali alice";
+
+	find_sum = 0;
+	out = purple_trie_find(trie, in, test_trie_find_cb, (gpointer)8);
+
+	assert_int_equal(3, out);
+	assert_int_equal(3 * 3, find_sum);
+
+	g_object_unref(trie);
+}
+END_TEST
+
+START_TEST(test_trie_find_noreset)
+{
+	PurpleTrie *trie;
+	const gchar *in;
+	gint out;
+
+	trie = purple_trie_new();
+	purple_trie_set_reset_on_match(trie, FALSE);
+



More information about the Commits mailing list