/pidgin/main: e97d93132751: Image store: most of the implementation
Tomasz Wasilczyk
twasilczyk at pidgin.im
Wed Apr 9 18:32:09 EDT 2014
Changeset: e97d9313275138eb3bc1ae379ddd0798c6a35726
Author: Tomasz Wasilczyk <twasilczyk at pidgin.im>
Date: 2014-04-10 00:32 +0200
Branch: default
URL: https://hg.pidgin.im/pidgin/main/rev/e97d93132751
Description:
Image store: most of the implementation
diffstat:
libpurple/glibcompat.h | 32 ++++++------
libpurple/image-store.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 130 insertions(+), 19 deletions(-)
diffs (207 lines):
diff --git a/libpurple/glibcompat.h b/libpurple/glibcompat.h
--- a/libpurple/glibcompat.h
+++ b/libpurple/glibcompat.h
@@ -33,21 +33,6 @@
#include <glib.h>
-
-#ifdef __clang__
-
-#undef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
-#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
- _Pragma ("clang diagnostic push") \
- _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"")
-
-#undef G_GNUC_END_IGNORE_DEPRECATIONS
-#define G_GNUC_END_IGNORE_DEPRECATIONS \
- _Pragma ("clang diagnostic pop")
-
-#endif /* __clang__ */
-
-
#if !GLIB_CHECK_VERSION(2, 36, 0)
#include <errno.h>
@@ -84,6 +69,9 @@ static inline gboolean g_close(gint fd,
#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS
#define G_GNUC_END_IGNORE_DEPRECATIONS
+#define G_SOURCE_REMOVE FALSE
+#define G_SOURCE_CONTINUE TRUE
+
#define g_signal_handlers_disconnect_by_data(instance, data) \
g_signal_handlers_disconnect_matched((instance), G_SIGNAL_MATCH_DATA, \
0, 0, NULL, NULL, (data))
@@ -159,4 +147,18 @@ static inline void g_object_class_instal
#endif /* < 2.36.0 */
+
+#ifdef __clang__
+
+#undef G_GNUC_BEGIN_IGNORE_DEPRECATIONS
+#define G_GNUC_BEGIN_IGNORE_DEPRECATIONS \
+ _Pragma ("clang diagnostic push") \
+ _Pragma ("clang diagnostic ignored \"-Wdeprecated-declarations\"")
+
+#undef G_GNUC_END_IGNORE_DEPRECATIONS
+#define G_GNUC_END_IGNORE_DEPRECATIONS \
+ _Pragma ("clang diagnostic pop")
+
+#endif /* __clang__ */
+
#endif /* _GLIBCOMPAT_H_ */
diff --git a/libpurple/image-store.c b/libpurple/image-store.c
--- a/libpurple/image-store.c
+++ b/libpurple/image-store.c
@@ -21,36 +21,145 @@
#include "image-store.h"
+#include "eventloop.h"
+#include "glibcompat.h"
+
+#define TEMP_IMAGE_TIMEOUT 5
+
+static GHashTable *id_to_image;
+static guint last_id = 0;
+
+/* keys: timeout handle */
+static GHashTable *temp_images = NULL;
+
+/* keys: img id */
+static GSList *perm_images = NULL;
+
+static guint
+image_set_id(PurpleImage *image)
+{
+ /* Use the next unused id number. We do it in a loop on the off chance
+ * that next id wraps back around to 0 and the hash table still contains
+ * entries from the first time around.
+ */
+ while (TRUE) {
+ last_id++;
+
+ if (G_UNLIKELY(last_id == 0))
+ continue;
+
+ if (purple_image_store_get(last_id) == NULL)
+ break;
+ }
+
+ g_object_set_data(G_OBJECT(image), "purple-image-store-id",
+ GINT_TO_POINTER(last_id));
+ g_hash_table_insert(id_to_image, GINT_TO_POINTER(last_id), image);
+ /* TODO: hook map removal after object destruction */
+ return last_id;
+}
+
+static guint
+image_get_id(PurpleImage *image)
+{
+ return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(image),
+ "purple-image-store-id"));
+}
+
guint
purple_image_store_add(PurpleImage *image)
{
- return 0;
+ guint id;
+
+ g_return_val_if_fail(PURPLE_IS_IMAGE(image), 0);
+
+ id = image_get_id(image);
+ if (id > 0)
+ return id;
+
+ id = image_set_id(image);
+
+ g_object_ref(image);
+ perm_images = g_slist_prepend(perm_images, image);
+
+ return id;
}
guint
purple_image_store_add_weak(PurpleImage *image)
{
- return 0;
+ guint id;
+
+ g_return_val_if_fail(PURPLE_IS_IMAGE(image), 0);
+
+ id = image_get_id(image);
+ if (id > 0)
+ return id;
+
+ return image_set_id(image);
+}
+
+static gboolean
+remove_temporary(gpointer _image)
+{
+ PurpleImage *image = _image;
+ guint handle;
+
+ handle = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(image),
+ "purple-image-store-handle"));
+
+ g_hash_table_remove(temp_images, GINT_TO_POINTER(handle));
+
+ return G_SOURCE_REMOVE;
}
guint
purple_image_store_add_temporary(PurpleImage *image)
{
- return 0;
+ guint id;
+ guint handle;
+
+ g_return_val_if_fail(PURPLE_IS_IMAGE(image), 0);
+
+ id = image_get_id(image);
+ if (id > 0)
+ return id;
+
+ id = image_set_id(image);
+
+ g_object_ref(image);
+ handle = purple_timeout_add_seconds(TEMP_IMAGE_TIMEOUT,
+ remove_temporary, image);
+ g_object_set_data(G_OBJECT(image), "purple-image-store-handle",
+ GINT_TO_POINTER(handle));
+ g_hash_table_insert(temp_images, GINT_TO_POINTER(handle), image);
+
+ return id;
}
PurpleImage *
purple_image_store_get(guint id)
{
- return NULL;
+ return g_hash_table_lookup(id_to_image, GINT_TO_POINTER(id));
}
void
_purple_image_store_init(void)
{
+ id_to_image = g_hash_table_new(g_direct_hash, g_direct_equal);
+ temp_images = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+ NULL, g_object_unref);
}
void
_purple_image_store_uninit(void)
{
+ g_slist_free_full(perm_images, g_object_unref);
+ perm_images = NULL;
+
+ g_hash_table_destroy(temp_images);
+ temp_images = NULL;
+
+ g_hash_table_destroy(id_to_image);
+ id_to_image = NULL;
}
More information about the Commits
mailing list