/soc/2012/tomkiewicz/gg: 519acf37d16e: Gadu-Gadu: fix receiving ...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Thu Jul 5 13:31:50 EDT 2012


Changeset: 519acf37d16e02774d600a4e77f14be02c200fd5
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-06-26 22:38 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/519acf37d16e

Description:

Gadu-Gadu: fix receiving of inline images after 3.x changes; code refactoring here as well

diffstat:

 libpurple/protocols/gg/Makefile.am       |    4 +-
 libpurple/protocols/gg/gg-utils.c        |    9 +
 libpurple/protocols/gg/gg-utils.h        |    3 +
 libpurple/protocols/gg/gg.c              |   87 +++++-------------
 libpurple/protocols/gg/gg.h              |    6 +-
 libpurple/protocols/gg/image.c           |  141 +++++++++++++++++++++++++++++++
 libpurple/protocols/gg/image.h           |   24 +++++
 libpurple/protocols/gg/resolver-purple.h |    6 +-
 8 files changed, 212 insertions(+), 68 deletions(-)

diffs (truncated from 471 to 300 lines):

diff --git a/libpurple/protocols/gg/Makefile.am b/libpurple/protocols/gg/Makefile.am
--- a/libpurple/protocols/gg/Makefile.am
+++ b/libpurple/protocols/gg/Makefile.am
@@ -55,7 +55,9 @@
 	gg.h \
 	gg.c \
 	resolver-purple.h \
-	resolver-purple.c
+	resolver-purple.c \
+	image.h \
+	image.c
 
 AM_CFLAGS = $(st)
 
diff --git a/libpurple/protocols/gg/gg-utils.c b/libpurple/protocols/gg/gg-utils.c
--- a/libpurple/protocols/gg/gg-utils.c
+++ b/libpurple/protocols/gg/gg-utils.c
@@ -50,6 +50,15 @@
 }
 /* }}} */
 
+const char * ggp_uin_to_str(uin_t uin)
+{
+	static char buff[GGP_UIN_LEN_MAX + 1];
+	
+	g_snprintf(buff, GGP_UIN_LEN_MAX + 1, "%u", uin);
+	
+	return buff;
+}
+
 /* unsigned int ggp_array_size(char **array) {{{ */
 unsigned int ggp_array_size(char **array)
 {
diff --git a/libpurple/protocols/gg/gg-utils.h b/libpurple/protocols/gg/gg-utils.h
--- a/libpurple/protocols/gg/gg-utils.h
+++ b/libpurple/protocols/gg/gg-utils.h
@@ -37,6 +37,7 @@
 
 #include "gg.h"
 
+#define GGP_UIN_LEN_MAX 10
 
 /**
  * Convert a base 10 string to a UIN.
@@ -48,6 +49,8 @@
 uin_t
 ggp_str_to_uin(const char *str);
 
+const char * ggp_uin_to_str(uin_t uin);
+
 /**
  * Calculate size of a NULL-terminated array.
  *
diff --git a/libpurple/protocols/gg/gg.c b/libpurple/protocols/gg/gg.c
--- a/libpurple/protocols/gg/gg.c
+++ b/libpurple/protocols/gg/gg.c
@@ -1456,47 +1456,6 @@
 	}
 }
 
-static void ggp_recv_image_handler(PurpleConnection *gc, const struct gg_event *ev)
-{
-	gint imgid = 0;
-	GGPInfo *info = purple_connection_get_protocol_data(gc);
-	GList *entry = g_list_first(info->pending_richtext_messages);
-	gchar *handlerid = g_strdup_printf("IMGID_HANDLER-%i", ev->event.image_reply.crc32);
-
-	imgid = purple_imgstore_add_with_id(
-		g_memdup(ev->event.image_reply.image, ev->event.image_reply.size),
-		ev->event.image_reply.size,
-		ev->event.image_reply.filename);
-
-	purple_debug_info("gg", "ggp_recv_image_handler: got image with crc32: %u\n", ev->event.image_reply.crc32);
-
-	while(entry) {
-		if (strstr((gchar *)entry->data, handlerid) != NULL) {
-			gchar **split = g_strsplit((gchar *)entry->data, handlerid, 3);
-			gchar *text = g_strdup_printf("%s%i%s", split[0], imgid, split[1]);
-			purple_debug_info("gg", "ggp_recv_image_handler: found message matching crc32: %s\n", (gchar *)entry->data);
-			g_strfreev(split);
-			info->pending_richtext_messages = g_list_remove(info->pending_richtext_messages, entry->data);
-			/* We don't have any more images to download */
-			if (strstr(text, "<IMG ID=\"IMGID_HANDLER") == NULL) {
-				gchar *buf = g_strdup_printf("%lu", (unsigned long int)ev->event.image_reply.sender);
-				serv_got_im(gc, buf, text, PURPLE_MESSAGE_IMAGES, time(NULL));
-				g_free(buf);
-				purple_debug_info("gg", "ggp_recv_image_handler: richtext message: %s\n", text);
-				g_free(text);
-				break;
-			}
-			info->pending_richtext_messages = g_list_append(info->pending_richtext_messages, text);
-			break;
-		}
-		entry = g_list_next(entry);
-	}
-	g_free(handlerid);
-
-	return;
-}
-
-
 /**
  * Dispatch a message received from a buddy.
  *
@@ -1513,6 +1472,7 @@
 	gchar *msg;
 	gchar *tmp;
 	time_t mtime;
+	uin_t sender = ev->event.msg.sender;
 
 	if (ev->event.msg.message == NULL)
 	{
@@ -1531,6 +1491,11 @@
 	msg = g_markup_escape_text(tmp, -1);
 	g_free(tmp);
 
+	if (ev->event.msg.msgclass & GG_CLASS_QUEUED)
+		mtime = ev->event.msg.time;
+	else
+		mtime = time(NULL);
+
 	/* We got richtext message */
 	if (ev->event.msg.formats_length)
 	{
@@ -1541,7 +1506,6 @@
 		struct gg_msg_richtext_format *actformat;
 		struct gg_msg_richtext_image *actimage;
 		GString *message = g_string_new(msg);
-		gchar *handlerid;
 
 		purple_debug_info("gg", "ggp_recv_message_handler: richtext msg from (%s): %s %i formats\n", from, msg, ev->event.msg.formats_length);
 
@@ -1564,7 +1528,10 @@
 				(actformat->font & GG_FONT_UNDERLINE) != 0,
 				increased_len);
 
-			if (actformat->font & GG_FONT_IMAGE) {
+			if (actformat->font & GG_FONT_IMAGE)
+			{
+				const char *placeholder;
+			
 				got_image = TRUE;
 				actimage = (struct gg_msg_richtext_image*)(cformats);
 				cformats += sizeof(struct gg_msg_richtext_image);
@@ -1580,10 +1547,9 @@
 				gg_image_request(info->session, ev->event.msg.sender,
 					actimage->size, actimage->crc32);
 
-				handlerid = g_strdup_printf("<IMG ID=\"IMGID_HANDLER-%i\">", actimage->crc32);
-				g_string_insert(message, byteoffset, handlerid);
-				increased_len += strlen(handlerid);
-				g_free(handlerid);
+				placeholder = ggp_image_pending_placeholder(actimage->crc32);
+				g_string_insert(message, byteoffset, placeholder);
+				increased_len += strlen(placeholder);
 				continue;
 			}
 
@@ -1631,8 +1597,9 @@
 		msg = message->str;
 		g_string_free(message, FALSE);
 
-		if (got_image) {
-			info->pending_richtext_messages = g_list_append(info->pending_richtext_messages, msg);
+		if (got_image)
+		{
+			ggp_image_got_im(gc, sender, msg, mtime);
 			return;
 		}
 	}
@@ -1641,11 +1608,6 @@
 			from, msg, ev->event.msg.msgclass,
 			ev->event.msg.recipients_count);
 
-	if (ev->event.msg.msgclass & GG_CLASS_QUEUED)
-		mtime = ev->event.msg.time;
-	else
-		mtime = time(NULL);
-
 	if (ev->event.msg.recipients_count == 0) {
 		serv_got_im(gc, from, msg, 0, mtime);
 	} else {
@@ -1680,11 +1642,12 @@
 	g_free(from);
 }
 
+/* TODO: image */
 static void ggp_send_image_handler(PurpleConnection *gc, const struct gg_event *ev)
 {
 	GGPInfo *info = purple_connection_get_protocol_data(gc);
 	PurpleStoredImage *image;
-	gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32)));
+	gint imgid = GPOINTER_TO_INT(g_hash_table_lookup(info->image_data.pending_images, GINT_TO_POINTER(ev->event.image_request.crc32)));
 
 	purple_debug_info("gg", "ggp_send_image_handler: image request received, crc32: %u, imgid: %d\n", ev->event.image_request.crc32, imgid);
 
@@ -1701,7 +1664,7 @@
 		} else {
 			purple_debug_error("gg", "ggp_send_image_handler: image imgid: %i, crc: %u in hash but not found in imgstore!\n", imgid, ev->event.image_request.crc32);
 		}
-		g_hash_table_remove(info->pending_images, GINT_TO_POINTER(ev->event.image_request.crc32));
+		g_hash_table_remove(info->image_data.pending_images, GINT_TO_POINTER(ev->event.image_request.crc32));
 	}
 }
 
@@ -1816,7 +1779,7 @@
 				ev->event.ack.seq);
 			break;
 		case GG_EVENT_IMAGE_REPLY:
-			ggp_recv_image_handler(gc, ev);
+			ggp_image_recv(gc, &ev->event.image_reply);
 			break;
 		case GG_EVENT_IMAGE_REQUEST:
 			ggp_send_image_handler(gc, ev);
@@ -2276,12 +2239,12 @@
 	info->chats_count = 0;
 	info->token = NULL;
 	info->searches = ggp_search_new();
-	info->pending_richtext_messages = NULL;
-	info->pending_images = g_hash_table_new(g_direct_hash, g_direct_equal);
 	info->status_broadcasting = purple_account_get_bool(account, "status_broadcasting", TRUE);
 	
 	purple_connection_set_protocol_data(gc, info);
 
+	ggp_image_setup(gc);
+	
 	glp->uin = ggp_get_uin(account);
 	glp->password = charset_convert(purple_account_get_password(account),
 		"UTF-8", "CP1250");
@@ -2395,8 +2358,7 @@
 		purple_notify_close_with_handle(gc);
 
 		ggp_search_destroy(info->searches);
-		g_list_free(info->pending_richtext_messages);
-		g_hash_table_destroy(info->pending_images);
+		ggp_image_free(gc);
 
 		if (info->inpa > 0)
 			purple_input_remove(info->inpa);
@@ -2443,6 +2405,7 @@
 				g_string_append_len(string_buffer, last, start - last);
 			}
 
+			/* TODO: image */
 			if((id = g_datalist_get_data(&attribs, "id")) && (image = purple_imgstore_find_by_id(atoi(id)))) {
 				struct gg_msg_richtext_format actformat;
 				struct gg_msg_richtext_image actimage;
@@ -2451,7 +2414,7 @@
 				const char *image_filename = purple_imgstore_get_filename(image);
 				uint32_t crc32 = gg_crc32(0, image_bin, image_size);
 
-				g_hash_table_insert(info->pending_images, GINT_TO_POINTER(crc32), GINT_TO_POINTER(atoi(id)));
+				g_hash_table_insert(info->image_data.pending_images, GINT_TO_POINTER(crc32), GINT_TO_POINTER(atoi(id)));
 				purple_imgstore_ref(image);
 				purple_debug_info("gg", "ggp_send_im_richtext: got crc: %u for imgid: %i\n", crc32, atoi(id));
 
diff --git a/libpurple/protocols/gg/gg.h b/libpurple/protocols/gg/gg.h
--- a/libpurple/protocols/gg/gg.h
+++ b/libpurple/protocols/gg/gg.h
@@ -30,6 +30,8 @@
 #include "search.h"
 #include "connection.h"
 
+#include "image.h"
+
 
 #define PUBDIR_RESULTS_MAX 20
 
@@ -64,9 +66,9 @@
 	GList *chats;
 	GGPSearches *searches;
 	int chats_count;
-	GList *pending_richtext_messages;
-	GHashTable *pending_images;
 	gboolean status_broadcasting; //When TRUE status is visible to all, when FALSE status is visible only to friends.
+
+	ggp_image_connection_data image_data;
 } GGPInfo;
 
 #endif /* _PURPLE_GG_H */
diff --git a/libpurple/protocols/gg/image.c b/libpurple/protocols/gg/image.c
new file mode 100644
--- /dev/null
+++ b/libpurple/protocols/gg/image.c
@@ -0,0 +1,141 @@
+#include "image.h"
+
+#include <debug.h>
+
+#include "gg.h"
+#include "gg-utils.h"
+
+#define GGP_PENDING_IMAGE_ID_PREFIX "gg-pending-image-"
+
+typedef struct
+{
+	uin_t from;
+	gchar *text;
+	time_t mtime;
+} ggp_image_pending_message;



More information about the Commits mailing list