# HG changeset patch # User Mark Doliner # Date 1271982247 0 # Node ID 2a5dbea6ab6b837a11ab866b4bc1297e247a69ae # Parent e167de25e795a1ffede7bb0675687842a55c6066 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. diff -r e167de25e795 -r 2a5dbea6ab6b libpurple/protocols/msn/msn.c --- 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, diff -r e167de25e795 -r 2a5dbea6ab6b libpurple/protocols/msn/user.c --- 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); } - - diff -r e167de25e795 -r 2a5dbea6ab6b libpurple/protocols/msn/user.h --- 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;