cpw.qulogic.msnp16: a5c1c82f: Use a linked list to store MsnUserEndpoi...

markdoliner at pidgin.im markdoliner at pidgin.im
Thu Apr 22 20:25:46 EDT 2010


-----------------------------------------------------------------
Revision: a5c1c82f8125e75899073eec7fa5a872b5f3df3c
Ancestor: b8e65f4136176bbd988d662c03cca5d00ba81a4f
Author: markdoliner at pidgin.im
Date: 2010-04-23T00:24:07
Branch: im.pidgin.cpw.qulogic.msnp16
URL: http://d.pidgin.im/viewmtn/revision/info/a5c1c82f8125e75899073eec7fa5a872b5f3df3c

Modified files:
        libpurple/protocols/msn/msn.c libpurple/protocols/msn/user.c
        libpurple/protocols/msn/user.h

ChangeLog: 

Use a linked list to store MsnUserEndpoints instead of a hash table.
This is per-buddy on MSN, and I expect most buddies to only have
one or two endpoints (only be signed in from one or two locations),
so I expect this to use less memory and not much less efficient.

-------------- next part --------------
============================================================
--- libpurple/protocols/msn/msn.c	1eac851bb01bb9c7629064f472326fffa82b75c5
+++ libpurple/protocols/msn/msn.c	40d71c1926a5739ae7a879f22246210a426fe02c
@@ -416,21 +416,6 @@ static void
 }
 
 static void
-create_endpoint_fields(gpointer key, gpointer value, gpointer user_data)
-{
-	const char *id = key;
-	MsnUserEndpoint *ep = value;
-	MsnLocationData *data = user_data;
-	PurpleRequestField *field;
-
-	if (g_str_equal(id, data->session->guid))
-		return;
-
-	field = purple_request_field_bool_new(id, ep->name, FALSE);
-	purple_request_field_group_add_field(data->group, field);
-}
-
-static void
 msn_show_locations(PurplePluginAction *action)
 {
 	PurpleConnection *pc;
@@ -439,6 +424,7 @@ msn_show_locations(PurplePluginAction *a
 	PurpleRequestFields *fields;
 	PurpleRequestFieldGroup *group;
 	PurpleRequestField *field;
+	GSList *l;
 	MsnLocationData *data;
 
 	pc = (PurpleConnection *)action->context;
@@ -462,12 +448,22 @@ msn_show_locations(PurplePluginAction *a
 	purple_request_fields_add_group(fields, group);
 	field = purple_request_field_label_new("others-label", _("You can sign out from other locations here"));
 	purple_request_field_group_add_field(group, field);
-	
+
+	for (l = session->user->endpoints; l; l = l->next) {
+		MsnUserEndpoint *ep = l->data;
+
+		if (g_str_equal(ep->id, session->guid))
+			/* Don't add myself to the list */
+			continue;
+
+		field = purple_request_field_bool_new(ep->id, ep->name, FALSE);
+		purple_request_field_group_add_field(group, field);
+	}
+
 	data = g_new0(MsnLocationData, 1);
 	data->account = account;
 	data->session = session;
 	data->group = group;
-	g_hash_table_foreach(session->user->endpoints, create_endpoint_fields, data);
 
 	purple_request_fields(pc, NULL, NULL, NULL,
 	                      fields,
============================================================
--- libpurple/protocols/msn/user.c	bc9cd46afb769a54e363512b81ae74948a1cba2b
+++ libpurple/protocols/msn/user.c	ef08cf200a486bb70209eea3af1a15e1b4374ffd
@@ -25,7 +25,11 @@
 #include "user.h"
 #include "slp.h"
 
-static void free_user_endpoint(MsnUserEndpoint *data);
+static void free_user_endpoint(MsnUserEndpoint *data)
+{
+	g_free(data->name);
+	g_free(data);
+}
 
 /*new a user object*/
 MsnUser *
@@ -41,9 +45,6 @@ msn_user_new(MsnUserList *userlist, cons
 	msn_user_set_passport(user, passport);
 	msn_user_set_friendly_name(user, friendly_name);
 
-	user->endpoints = g_hash_table_new_full(g_str_hash, g_str_equal,
-	                                        g_free, (GDestroyNotify)free_user_endpoint);
-
 	return user;
 }
 
@@ -53,8 +54,10 @@ msn_user_destroy(MsnUser *user)
 {
 	g_return_if_fail(user != NULL);
 
-	if (user->endpoints != NULL)
-		g_hash_table_destroy(user->endpoints);
+	while (user->endpoints != NULL) {
+		free_user_endpoint(user->endpoints->data);
+		user->endpoints = g_slist_delete_link(user->endpoints, user->endpoints);
+	}
 
 	if (user->clientcaps != NULL)
 		g_hash_table_destroy(user->clientcaps);
@@ -227,40 +230,45 @@ msn_user_set_uid(MsnUser *user, const ch
 	user->uid = g_strdup(uid);
 }
 
-static void
-free_user_endpoint(MsnUserEndpoint *data)
-{
-	g_free(data->name);
-	g_free(data);
-}
-
 void
-msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *data)
+msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *newep)
 {
-	MsnUserEndpoint *new;
+	MsnUserEndpoint *ep;
 	char *endpoint;
+	GSList *l;
 
 	g_return_if_fail(user != NULL);
 	g_return_if_fail(input != NULL);
 
 	endpoint = g_ascii_strdown(input, -1);
 
-	if (data == NULL) {
-		g_hash_table_remove(user->endpoints, endpoint);
-		g_free(endpoint);
-		return;
+	for (l = user->endpoints; l; l = l->next) {
+		ep = l->data;
+		if (g_str_equal(ep->id, endpoint)) {
+			/* We have info about this endpoint! */
+
+			g_free(endpoint);
+
+			if (newep == NULL) {
+				/* Delete it and exit */
+				user->endpoints = g_slist_delete_link(user->endpoints, l);
+				free_user_endpoint(ep);
+				return;
+			}
+
+			/* Break out of our loop and update it */
+			break;
+		}
 	}
-
-	new = g_hash_table_lookup(user->endpoints, endpoint);
-	if (!new) {
-		new = g_new0(MsnUserEndpoint, 1);
-		g_hash_table_insert(user->endpoints, g_strdup(endpoint), new);
+	if (l == NULL) {
+		/* Need to add a new endpoint */
+		ep = g_new0(MsnUserEndpoint, 1);
+		ep->id = endpoint;
+		user->endpoints = g_slist_prepend(user->endpoints, ep);
 	}
 
-	new->clientid = data->clientid;
-	new->extcaps = data->extcaps;
-
-	g_free(endpoint);
+	ep->clientid = newep->clientid;
+	ep->extcaps = newep->extcaps;
 }
 
 void
@@ -563,16 +571,25 @@ msn_user_get_endpoint_data(MsnUser *user
 msn_user_get_endpoint_data(MsnUser *user, const char *input)
 {
 	char *endpoint;
-	MsnUserEndpoint *data;
+	GSList *l;
+	MsnUserEndpoint *ep;
 
 	g_return_val_if_fail(user != NULL, NULL);
 	g_return_val_if_fail(input != NULL, NULL);
 
 	endpoint = g_ascii_strdown(input, -1);
-	data = g_hash_table_lookup(user->endpoints, endpoint);
+
+	for (l = user->endpoints; l; l = l->next) {
+		ep = l->data;
+		if (g_str_equal(ep->id, endpoint)) {
+			g_free(endpoint);
+			return ep;
+		}
+	}
+
 	g_free(endpoint);
 
-	return data;
+	return NULL;
 }
 
 MsnObject *
@@ -605,16 +622,12 @@ msn_user_is_capable(MsnUser *user, char 
 	g_return_val_if_fail(user != NULL, FALSE);
 
 	if (endpoint != NULL) {
-		MsnUserEndpoint *ep = g_hash_table_lookup(user->endpoints, endpoint);
+		MsnUserEndpoint *ep = msn_user_get_endpoint_data(user, endpoint);
 		if (ep != NULL)
-			return (ep->clientid & capability) == capability
-			    && (ep->extcaps & extcap) == extcap;
+			return (ep->clientid & capability) && (ep->extcaps & extcap);
 		else
 			return FALSE;
 	}
 
-	return (user->clientid & capability) == capability
-	    && (user->extcaps & extcap) == extcap;
+	return (user->clientid & capability) && (user->extcaps & extcap);
 }
-
-
============================================================
--- libpurple/protocols/msn/user.h	b333731cd8fed57a3163a965a140e570deb9efa5
+++ libpurple/protocols/msn/user.h	c75bea13e94df4e858b4fe5b3806476a8f195c56
@@ -83,7 +83,7 @@ struct _MsnUser
 	char *friendly_name;    /**< The friendly name.             */
 
 	char *uid;              /*< User ID                         */
-	GHashTable *endpoints;  /*< Endpoint-specific data          */
+	GSList *endpoints;      /*< Endpoint-specific data          */
 
 	const char *status;     /**< The state of the user.         */
 	char *statusline;       /**< The state of the user.         */
@@ -122,10 +122,11 @@ typedef struct MsnUserEndpoint {
  * A specific user endpoint.
  */
 typedef struct MsnUserEndpoint {
-	char *name;				/**< The client's endpoint's name      */
-	int type;				/**< The client's endpoint type        */
+	char *id;               /**< The client's endpoint ID          */
+	char *name;             /**< The client's endpoint's name      */
+	int type;               /**< The client's endpoint type        */
 	guint clientid;         /**< The client's ID                   */
-	guint extcaps;			/**< The client's extended capabilites */
+	guint extcaps;          /**< The client's extended capabilites */
 
 } MsnUserEndpoint;
 


More information about the Commits mailing list