changeset 17586:ba1478c35cc0

If a message is known to be too long to send to a chat or IM, and it's an HTML message, strip the HTML, re-encode, and try again. The chat part is particularly useful given the short maximum message length and the fact that purple_markup_linkify() will have linkified long links to being twice the number of characters. The IM part is not triggerred in my experience because MAXMSGLEN seems to be far above the number of characters allowed; perhaps it is a number of bytes, not characters?
author Evan Schoenberg <evan.s@dreskin.net>
date Sun, 10 Jun 2007 20:36:24 +0000
parents 9fafe265567f
children b2b91f6e84a9
files libpurple/protocols/oscar/oscar.c
diffstat 1 files changed, 51 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/oscar/oscar.c	Sun Jun 10 19:43:21 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Sun Jun 10 20:36:24 2007 +0000
@@ -2975,6 +2975,8 @@
 		purple_blist_update_buddy_status(b, status);
 	}
 
+	purple_signal_emit(purple_blist_get_handle(), "buddy-miscellaneous-changed", b);
+
 	return 1;
 }
 
@@ -4167,6 +4169,7 @@
 	PeerConnection *conn;
 	int ret;
 	char *tmp1, *tmp2;
+	gboolean is_html;
 
 	od = (OscarData *)gc->proto_data;
 	account = purple_connection_get_account(gc);
@@ -4185,7 +4188,6 @@
 	} else {
 		struct buddyinfo *bi;
 		struct aim_sendimext_args args;
-		gsize len;
 		PurpleConversation *conv;
 		PurpleStoredImage *img;
 
@@ -4276,22 +4278,43 @@
 		if (aim_sn_is_sms(name)) {
 			/* Messaging an SMS (mobile) user */
 			tmp2 = purple_markup_strip_html(tmp1);
+			is_html = FALSE;
 		} else if (aim_sn_is_icq(purple_account_get_username(account))) {
-			if (aim_sn_is_icq(name))
+			if (aim_sn_is_icq(name)) {
 				/* From ICQ to ICQ */
 				tmp2 = purple_markup_strip_html(tmp1);
-			else
+				is_html = FALSE;
+			} else {
 				/* From ICQ to AIM */
 				tmp2 = g_strdup(tmp1);
+				is_html = TRUE;
+			}
 		} else {
 			/* From AIM to AIM and AIM to ICQ */
 			tmp2 = g_strdup(tmp1);
+			is_html = TRUE;
 		}
 		g_free(tmp1);
 		tmp1 = tmp2;
-		len = strlen(tmp1);
 
 		purple_plugin_oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
+		if (is_html && (args.msglen > MAXMSGLEN)) {
+			/* If the length was too long, try stripping the HTML and then running it back through
+			* purple_strdup_withhtml() and the encoding process. The result may be shorter. */
+			g_free((char *)args.msg);
+			
+			tmp2 = purple_markup_strip_html(tmp1);
+			g_free(tmp1);
+			
+			tmp1 = purple_strdup_withhtml(tmp2);
+			g_free(tmp2);
+			
+			purple_plugin_oscar_convert_to_best_encoding(gc, name, tmp1, (char **)&args.msg, &args.msglen, &args.charset, &args.charsubset);
+
+			purple_debug_info("oscar", "Sending %s as %s because the original was too long.",
+								  message, (char *)args.msg);
+		}
+
 		purple_debug_info("oscar", "Sending IM, charset=0x%04hx, charsubset=0x%04hx, length=%d\n",
 						args.charset, args.charsubset, args.msglen);
 		ret = aim_im_sendch1_ext(od, &args);
@@ -5323,7 +5346,7 @@
 	OscarData *od = (OscarData *)gc->proto_data;
 	PurpleConversation *conv = NULL;
 	struct chat_connection *c = NULL;
-	char *buf, *buf2;
+	char *buf, *buf2, *buf3;
 	guint16 charset, charsubset;
 	char *charsetstr = NULL;
 	int len;
@@ -5349,8 +5372,29 @@
 	 * visible characters" and not "number of bytes"
 	 */
 	if ((len > c->maxlen) || (len > c->maxvis)) {
+		/* If the length was too long, try stripping the HTML and then running it back through
+		 * purple_strdup_withhtml() and the encoding process. The result may be shorter. */
 		g_free(buf2);
-		return -E2BIG;
+
+		buf3 = purple_markup_strip_html(buf);
+		g_free(buf);
+		
+		buf = purple_strdup_withhtml(buf3);
+		g_free(buf3);
+
+		len = strlen(buf);
+		purple_plugin_oscar_convert_to_best_encoding(gc, NULL, buf, &buf2, &len, &charset, &charsubset);
+
+		if ((len > c->maxlen) || (len > c->maxvis)) {
+			purple_debug_warning("oscar", "Could not send %s because (%i > maxlen %i) or (%i > maxvis %i)",
+					buf2, len, c->maxlen, len, c->maxvis);
+			g_free(buf);
+			g_free(buf2);
+			return -E2BIG;
+		} else {
+			purple_debug_info("oscar", "Sending %s as %s because the original was too long.",
+					message, buf2);
+		}
 	}
 
 	if (charset == AIM_CHARSET_ASCII)
@@ -5361,6 +5405,7 @@
 		charsetstr = "iso-8859-1";
 	aim_chat_send_im(od, c->conn, 0, buf2, len, charsetstr, "en");
 	g_free(buf2);
+	g_free(buf);
 
 	return 0;
 }