/soc/2012/tomkiewicz/gg: 458d578d553d: Gadu-Gadu: status refacto...

Tomasz Wasilczyk tomkiewicz at cpw.pidgin.im
Wed Aug 8 05:23:06 EDT 2012


Changeset: 458d578d553d4aa648cb66ccebcab80840b7ca56
Author:	 Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date:	 2012-08-08 11:22 +0200
Branch:	 soc.2012.gg
URL: http://hg.pidgin.im/soc/2012/tomkiewicz/gg/rev/458d578d553d

Description:

Gadu-Gadu: status refactoring - fix bug with long status

diffstat:

 libpurple/protocols/gg/gg.c     |  25 +----------------
 libpurple/protocols/gg/status.c |  56 +++++++++++++++++++++++++++++++++++-----
 libpurple/protocols/gg/status.h |   1 +
 libpurple/protocols/gg/utils.c  |  23 ++++++++++++++++
 libpurple/protocols/gg/utils.h  |   2 +
 5 files changed, 77 insertions(+), 30 deletions(-)

diffs (213 lines):

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
@@ -1802,30 +1802,9 @@ static void ggp_add_buddy(PurpleConnecti
 
 	gg_add_notify(info->session, ggp_str_to_uin(name));
 
-	// gg server won't tell us our status
+	// gg server won't tell us our status here
 	if (strcmp(purple_account_get_username(account), name) == 0)
-	{
-		PurpleStatus *status = purple_presence_get_active_status(
-			purple_account_get_presence(account));
-		const char *status_msg = purple_status_get_attr_string(status,
-			"message");
-		gchar *status_msg_gg = NULL;
-		
-		if (status_msg != NULL && status_msg[0] != '\0')
-		{
-			status_msg_gg = g_new0(gchar,
-				GG_STATUS_DESCR_MAXSIZE + 1);
-			g_utf8_strncpy(status_msg_gg, status_msg,
-				GG_STATUS_DESCR_MAXSIZE);
-		}
-		
-		purple_prpl_got_user_status(account,
-			purple_account_get_username(account),
-			purple_status_get_id(status),
-			status_msg_gg ? "message" : NULL, status_msg_gg, NULL);
-		
-		g_free(status_msg_gg);
-	}
+		ggp_status_fake_to_self(gc);
 	
 	ggp_roster_add_buddy(gc, buddy, group, message);
 }
diff --git a/libpurple/protocols/gg/status.c b/libpurple/protocols/gg/status.c
--- a/libpurple/protocols/gg/status.c
+++ b/libpurple/protocols/gg/status.c
@@ -5,6 +5,7 @@
 #include <request.h>
 
 #include "gg.h"
+#include "utils.h"
 
 struct _ggp_status_session_data
 {
@@ -15,11 +16,9 @@ struct _ggp_status_session_data
 static inline ggp_status_session_data *
 ggp_status_get_ssdata(PurpleConnection *gc);
 
+gchar * ggp_status_validate_description(const gchar* msg);
 static int ggp_status_from_purplestatus(PurpleStatus *status, gchar **message);
 
-static void ggp_status_broadcasting_dialog_ok(PurpleConnection *gc,
-	PurpleRequestFields *fields);
-
 ////
 
 static inline ggp_status_session_data *
@@ -48,6 +47,14 @@ void ggp_status_cleanup(PurpleConnection
 	g_free(ssdata);
 }
 
+gchar * ggp_status_validate_description(const gchar* msg)
+{
+	if (msg == NULL || msg[0] == '\0')
+		return NULL;
+	
+	return ggp_utf8_strndup(msg, GG_STATUS_DESCR_MAXSIZE);
+}
+
 static int ggp_status_from_purplestatus(PurpleStatus *status, gchar **message)
 {
 	const char *status_id = purple_status_get_id(status);
@@ -58,7 +65,11 @@ static int ggp_status_from_purplestatus(
 	
 	*message = NULL;
 	if (status_message)
-		*message = purple_markup_strip_html(status_message);
+	{
+		gchar *stripped = purple_markup_strip_html(status_message);
+		*message = ggp_status_validate_description(stripped);
+		g_free(stripped);
+	}
 	
 	if (0 == strcmp(status_id, "available"))
 		return status_message ? GG_STATUS_AVAIL_DESCR : GG_STATUS_AVAIL;
@@ -84,6 +95,11 @@ static int ggp_status_from_purplestatus(
  * Own status.
  ******************************************************************************/
 
+static void ggp_status_broadcasting_dialog_ok(PurpleConnection *gc,
+	PurpleRequestFields *fields);
+
+/******************************************************************************/
+
 void ggp_status_set_initial(PurpleConnection *gc, struct gg_login_params *glp)
 {
 	ggp_status_session_data *ssdata = ggp_status_get_ssdata(gc);
@@ -101,25 +117,27 @@ gboolean ggp_status_set(PurpleAccount *a
 	PurpleConnection *gc = purple_account_get_connection(account);
 	ggp_status_session_data *ssdata = ggp_status_get_ssdata(gc);
 	GGPInfo *accdata = purple_connection_get_protocol_data(gc);
+	gchar *new_description = ggp_status_validate_description(msg);
 	
 	if (!ssdata->status_broadcasting)
 		status |= GG_STATUS_FRIENDS_MASK;
 	
 	if ((status == GG_STATUS_NOT_AVAIL ||
 		status == GG_STATUS_NOT_AVAIL_DESCR) &&
-		0 == g_strcmp0(ssdata->current_description, msg))
+		0 == g_strcmp0(ssdata->current_description, new_description))
 	{
 		purple_debug_info("gg", "ggp_status_set: new status doesn't "
 			"differ when closing connection - ignore\n");
+		g_free(new_description);
 		return FALSE;
 	}
 	g_free(ssdata->current_description);
-	ssdata->current_description = g_strdup(msg);
+	ssdata->current_description = new_description;
 	
 	if (msg == NULL)
 		gg_change_status(accdata->session, status);
 	else
-		gg_change_status_descr(accdata->session, status, msg);
+		gg_change_status_descr(accdata->session, status, new_description);
 	
 	return TRUE;
 }
@@ -137,6 +155,30 @@ void ggp_status_set_purplestatus(PurpleA
 	g_free(msg);
 }
 
+void ggp_status_fake_to_self(PurpleConnection *gc)
+{
+	PurpleAccount *account = purple_connection_get_account(gc);
+	PurpleStatus *status = purple_presence_get_active_status(
+		purple_account_get_presence(account));
+	const char *status_msg = purple_status_get_attr_string(status,
+		"message");
+	gchar *status_msg_gg = NULL;
+	
+	if (status_msg != NULL && status_msg[0] != '\0')
+	{
+		status_msg_gg = g_new0(gchar, GG_STATUS_DESCR_MAXSIZE + 1);
+		g_utf8_strncpy(status_msg_gg, status_msg,
+			GG_STATUS_DESCR_MAXSIZE);
+	}
+	
+	purple_prpl_got_user_status(account,
+		purple_account_get_username(account),
+		purple_status_get_id(status),
+		status_msg_gg ? "message" : NULL, status_msg_gg, NULL);
+	
+	g_free(status_msg_gg);
+}
+
 gboolean ggp_status_get_status_broadcasting(PurpleConnection *gc)
 {
 	return ggp_status_get_ssdata(gc)->status_broadcasting;
diff --git a/libpurple/protocols/gg/status.h b/libpurple/protocols/gg/status.h
--- a/libpurple/protocols/gg/status.h
+++ b/libpurple/protocols/gg/status.h
@@ -15,6 +15,7 @@ void ggp_status_set_initial(PurpleConnec
 
 gboolean ggp_status_set(PurpleAccount *account, int status, const gchar* msg);
 void ggp_status_set_purplestatus(PurpleAccount *account, PurpleStatus *status);
+void ggp_status_fake_to_self(PurpleConnection *gc);
 
 gboolean ggp_status_get_status_broadcasting(PurpleConnection *gc);
 void ggp_status_set_status_broadcasting(PurpleConnection *gc,
diff --git a/libpurple/protocols/gg/utils.c b/libpurple/protocols/gg/utils.c
--- a/libpurple/protocols/gg/utils.c
+++ b/libpurple/protocols/gg/utils.c
@@ -104,3 +104,26 @@ guint64 ggp_microtime(void)
 	
 	return ((guint64)time_s.tv_sec << 32) | time_s.tv_usec;
 }
+
+gchar * ggp_utf8_strndup(const gchar *str, gsize n)
+{
+	int raw_len = strlen(str);
+	gchar *end_ptr;
+	if (str == NULL)
+		return NULL;
+	if (raw_len <= n)
+		return g_strdup(str);
+	
+	end_ptr = g_utf8_offset_to_pointer(str, g_utf8_pointer_to_offset(str, &str[n]));
+	raw_len = end_ptr - str;
+	
+	if (raw_len > n)
+	{
+		end_ptr = g_utf8_prev_char(end_ptr);
+		raw_len = end_ptr - str;
+	}
+	
+	g_assert(raw_len <= n);
+	
+	return g_strndup(str, raw_len);
+}
diff --git a/libpurple/protocols/gg/utils.h b/libpurple/protocols/gg/utils.h
--- a/libpurple/protocols/gg/utils.h
+++ b/libpurple/protocols/gg/utils.h
@@ -68,4 +68,6 @@ gboolean ggp_password_validate(const gch
 
 guint64 ggp_microtime(void);
 
+gchar * ggp_utf8_strndup(const gchar *str, gsize n);
+
 #endif /* _GGP_UTILS_H */



More information about the Commits mailing list