libpurple/protocols/gg/image.c

changeset 34362
758e72362ca4
parent 34361
ddcc82637afa
child 34365
25e4187ea5a7
--- a/libpurple/protocols/gg/image.c	Sat Sep 15 09:33:28 2012 +0200
+++ b/libpurple/protocols/gg/image.c	Sat Sep 15 10:20:42 2012 +0200
@@ -35,8 +35,12 @@
 #include "gg.h"
 #include "utils.h"
 
-#define GGP_PENDING_IMAGE_ID_PREFIX "gg-pending-image-"
-#define GGP_IMAGE_MAX_SIZE 255000
+struct _ggp_image_session_data
+{
+	GHashTable *got_images;
+	GHashTable *incoming_images;
+	GHashTable *pending_images;
+};
 
 typedef struct
 {
@@ -70,46 +74,43 @@
 	g_free(req);
 }
 
-static inline ggp_image_connection_data *
-ggp_image_get_imgdata(PurpleConnection *gc)
+static inline ggp_image_session_data *
+ggp_image_get_sdata(PurpleConnection *gc)
 {
 	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	return &accdata->image_data;
+	return accdata->image_data;
 }
 
 void ggp_image_setup(PurpleConnection *gc)
 {
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+	ggp_image_session_data *sdata = g_new0(ggp_image_session_data, 1);
 	
-	imgdata->incoming_images = g_hash_table_new_full(
+	accdata->image_data = sdata;
+	
+	sdata->got_images = g_hash_table_new_full(
+		g_int64_hash, g_int64_equal, g_free, NULL);
+	sdata->incoming_images = g_hash_table_new_full(
 		g_int64_hash, g_int64_equal,
 		g_free, ggp_image_requested_free);
-	imgdata->pending_images = g_hash_table_new_full(NULL, NULL, NULL,
+	sdata->pending_images = g_hash_table_new_full(NULL, NULL, NULL,
 		ggp_image_pending_image_free);
 }
 
 void ggp_image_cleanup(PurpleConnection *gc)
 {
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
 	
-	g_hash_table_destroy(imgdata->incoming_images);
-	g_hash_table_destroy(imgdata->pending_images);
-}
-
-const char * ggp_image_pending_placeholder(uint32_t id)
-{
-	static char buff[50];
-	
-	g_snprintf(buff, 50, "<img id=\"" GGP_PENDING_IMAGE_ID_PREFIX
-		"%u\">", id);
-	
-	return buff;
+	g_hash_table_destroy(sdata->got_images);
+	g_hash_table_destroy(sdata->incoming_images);
+	g_hash_table_destroy(sdata->pending_images);
+	g_free(sdata);
 }
 
 ggp_image_prepare_result ggp_image_prepare(PurpleConnection *gc, const int id,
 	const char *conv_name, struct gg_msg_richtext_image *image_info)
 {
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
 	PurpleStoredImage *image = purple_imgstore_find_by_id(id);
 	size_t image_size;
 	gconstpointer image_data;
@@ -145,7 +146,7 @@
 	pending_image = g_new(ggp_image_pending_image, 1);
 	pending_image->id = id;
 	pending_image->conv_name = g_strdup(conv_name);
-	g_hash_table_insert(imgdata->pending_images, GINT_TO_POINTER(image_crc),
+	g_hash_table_insert(sdata->pending_images, GINT_TO_POINTER(image_crc),
 		pending_image);
 	
 	image_info->unknown1 = 0x0109;
@@ -158,7 +159,7 @@
 void ggp_image_recv(PurpleConnection *gc,
 	const struct gg_event_image_reply *image_reply)
 {
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
 	int stored_id;
 	ggp_image_requested *req;
 	GList *it;
@@ -178,7 +179,10 @@
 		image_reply->size,
 		id);
 
-	req = g_hash_table_lookup(imgdata->incoming_images, &id);
+	g_hash_table_insert(sdata->got_images, ggp_uint64dup(id),
+		GINT_TO_POINTER(stored_id));
+
+	req = g_hash_table_lookup(sdata->incoming_images, &id);
 	if (!req)
 	{
 		purple_debug_warning("gg", "ggp_image_recv: "
@@ -194,14 +198,14 @@
 		
 		listener->cb(gc, id, stored_id, listener->user_data);
 	}
-	g_hash_table_remove(imgdata->incoming_images, &id);
+	g_hash_table_remove(sdata->incoming_images, &id);
 }
 
 void ggp_image_send(PurpleConnection *gc,
 	const struct gg_event_image_request *image_request)
 {
 	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
 	ggp_image_pending_image *pending_image;
 	PurpleStoredImage *image;
 	PurpleConversation *conv;
@@ -212,7 +216,7 @@
 		image_request->crc32,
 		image_request->size);
 	
-	pending_image = g_hash_table_lookup(imgdata->pending_images,
+	pending_image = g_hash_table_lookup(sdata->pending_images,
 		GINT_TO_POINTER(image_request->crc32));
 	
 	if (pending_image == NULL)
@@ -233,7 +237,7 @@
 	{
 		purple_debug_error("gg", "ggp_image_send: requested image "
 			"found, but doesn't exists in image store\n");
-		g_hash_table_remove(imgdata->pending_images,
+		g_hash_table_remove(sdata->pending_images,
 			GINT_TO_POINTER(image_request->crc32));
 		return;
 	}
@@ -253,7 +257,7 @@
 			PURPLE_MESSAGE_NO_LOG | PURPLE_MESSAGE_NOTIFY,
 			time(NULL));
 	
-	g_hash_table_remove(imgdata->pending_images,
+	g_hash_table_remove(sdata->pending_images,
 		GINT_TO_POINTER(image_request->crc32));
 }
 
@@ -261,13 +265,13 @@
 	ggp_image_request_cb cb, gpointer user_data)
 {
 	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
-	ggp_image_connection_data *imgdata = ggp_image_get_imgdata(gc);
+	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
 	ggp_image_requested *req;
 	ggp_image_requested_listener *listener;
 	uint32_t crc = id >> 32;
 	uint32_t size = id;
 	
-	if (size > GGP_IMAGE_MAX_SIZE && crc <= GGP_IMAGE_MAX_SIZE)
+	if (size > GGP_IMAGE_SIZE_MAX && crc <= GGP_IMAGE_SIZE_MAX)
 	{
 		uint32_t tmp;
 		purple_debug_warning("gg", "ggp_image_request: "
@@ -277,11 +281,11 @@
 		size = tmp;
 	}
 	
-	req = g_hash_table_lookup(imgdata->incoming_images, &id);
+	req = g_hash_table_lookup(sdata->incoming_images, &id);
 	if (!req)
 	{
 		req = g_new0(ggp_image_requested, 1);
-		g_hash_table_insert(imgdata->incoming_images,
+		g_hash_table_insert(sdata->incoming_images,
 			ggp_uint64dup(id), req);
 		purple_debug_info("gg", "ggp_image_request: "
 			"requesting image %016llx\n", id);
@@ -294,3 +298,10 @@
 	listener->user_data = user_data;
 	req->listeners = g_list_append(req->listeners, listener);
 }
+
+int ggp_image_get_cached(PurpleConnection *gc, uint64_t id)
+{
+	ggp_image_session_data *sdata = ggp_image_get_sdata(gc);
+
+	return GPOINTER_TO_INT(g_hash_table_lookup(sdata->got_images, &id));
+}

mercurial