/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