/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