changeset 30728:2a5dbea6ab6b

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.
author Mark Doliner <mark@kingant.net>
date Fri, 23 Apr 2010 00:24:07 +0000
parents e167de25e795
children edb7c80bf930
files libpurple/protocols/msn/msn.c libpurple/protocols/msn/user.c libpurple/protocols/msn/user.h
diffstat 3 files changed, 71 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/msn.c	Thu Apr 22 21:06:41 2010 +0000
+++ b/libpurple/protocols/msn/msn.c	Fri Apr 23 00:24:07 2010 +0000
@@ -416,21 +416,6 @@
 }
 
 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 @@
 	PurpleRequestFields *fields;
 	PurpleRequestFieldGroup *group;
 	PurpleRequestField *field;
+	GSList *l;
 	MsnLocationData *data;
 
 	pc = (PurpleConnection *)action->context;
@@ -462,12 +448,22 @@
 	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,
--- a/libpurple/protocols/msn/user.c	Thu Apr 22 21:06:41 2010 +0000
+++ b/libpurple/protocols/msn/user.c	Fri Apr 23 00:24:07 2010 +0000
@@ -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_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 @@
 {
 	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 @@
 	user->uid = g_strdup(uid);
 }
 
-static void
-free_user_endpoint(MsnUserEndpoint *data)
+void
+msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *newep)
 {
-	g_free(data->name);
-	g_free(data);
-}
-
-void
-msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *data)
-{
-	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;
+		}
+	}
+	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 = g_hash_table_lookup(user->endpoints, endpoint);
-	if (!new) {
-		new = g_new0(MsnUserEndpoint, 1);
-		g_hash_table_insert(user->endpoints, g_strdup(endpoint), new);
-	}
-
-	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, 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 @@
 	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);
 }
-
-
--- a/libpurple/protocols/msn/user.h	Thu Apr 22 21:06:41 2010 +0000
+++ b/libpurple/protocols/msn/user.h	Fri Apr 23 00:24:07 2010 +0000
@@ -83,7 +83,7 @@
 	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 @@
  * 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;