comparison libpurple/protocols/msn/user.c @ 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 de59c181e6aa
children edb7c80bf930
comparison
equal deleted inserted replaced
30727:e167de25e795 30728:2a5dbea6ab6b
23 */ 23 */
24 #include "msn.h" 24 #include "msn.h"
25 #include "user.h" 25 #include "user.h"
26 #include "slp.h" 26 #include "slp.h"
27 27
28 static void free_user_endpoint(MsnUserEndpoint *data); 28 static void free_user_endpoint(MsnUserEndpoint *data)
29 {
30 g_free(data->name);
31 g_free(data);
32 }
29 33
30 /*new a user object*/ 34 /*new a user object*/
31 MsnUser * 35 MsnUser *
32 msn_user_new(MsnUserList *userlist, const char *passport, 36 msn_user_new(MsnUserList *userlist, const char *passport,
33 const char *friendly_name) 37 const char *friendly_name)
39 user->userlist = userlist; 43 user->userlist = userlist;
40 44
41 msn_user_set_passport(user, passport); 45 msn_user_set_passport(user, passport);
42 msn_user_set_friendly_name(user, friendly_name); 46 msn_user_set_friendly_name(user, friendly_name);
43 47
44 user->endpoints = g_hash_table_new_full(g_str_hash, g_str_equal,
45 g_free, (GDestroyNotify)free_user_endpoint);
46
47 return user; 48 return user;
48 } 49 }
49 50
50 /*destroy a user object*/ 51 /*destroy a user object*/
51 void 52 void
52 msn_user_destroy(MsnUser *user) 53 msn_user_destroy(MsnUser *user)
53 { 54 {
54 g_return_if_fail(user != NULL); 55 g_return_if_fail(user != NULL);
55 56
56 if (user->endpoints != NULL) 57 while (user->endpoints != NULL) {
57 g_hash_table_destroy(user->endpoints); 58 free_user_endpoint(user->endpoints->data);
59 user->endpoints = g_slist_delete_link(user->endpoints, user->endpoints);
60 }
58 61
59 if (user->clientcaps != NULL) 62 if (user->clientcaps != NULL)
60 g_hash_table_destroy(user->clientcaps); 63 g_hash_table_destroy(user->clientcaps);
61 64
62 if (user->group_ids != NULL) 65 if (user->group_ids != NULL)
225 228
226 g_free(user->uid); 229 g_free(user->uid);
227 user->uid = g_strdup(uid); 230 user->uid = g_strdup(uid);
228 } 231 }
229 232
230 static void 233 void
231 free_user_endpoint(MsnUserEndpoint *data) 234 msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *newep)
232 { 235 {
233 g_free(data->name); 236 MsnUserEndpoint *ep;
234 g_free(data);
235 }
236
237 void
238 msn_user_set_endpoint_data(MsnUser *user, const char *input, MsnUserEndpoint *data)
239 {
240 MsnUserEndpoint *new;
241 char *endpoint; 237 char *endpoint;
238 GSList *l;
242 239
243 g_return_if_fail(user != NULL); 240 g_return_if_fail(user != NULL);
244 g_return_if_fail(input != NULL); 241 g_return_if_fail(input != NULL);
245 242
246 endpoint = g_ascii_strdown(input, -1); 243 endpoint = g_ascii_strdown(input, -1);
247 244
248 if (data == NULL) { 245 for (l = user->endpoints; l; l = l->next) {
249 g_hash_table_remove(user->endpoints, endpoint); 246 ep = l->data;
250 g_free(endpoint); 247 if (g_str_equal(ep->id, endpoint)) {
251 return; 248 /* We have info about this endpoint! */
252 } 249
253 250 g_free(endpoint);
254 new = g_hash_table_lookup(user->endpoints, endpoint); 251
255 if (!new) { 252 if (newep == NULL) {
256 new = g_new0(MsnUserEndpoint, 1); 253 /* Delete it and exit */
257 g_hash_table_insert(user->endpoints, g_strdup(endpoint), new); 254 user->endpoints = g_slist_delete_link(user->endpoints, l);
258 } 255 free_user_endpoint(ep);
259 256 return;
260 new->clientid = data->clientid; 257 }
261 new->extcaps = data->extcaps; 258
262 259 /* Break out of our loop and update it */
263 g_free(endpoint); 260 break;
261 }
262 }
263 if (l == NULL) {
264 /* Need to add a new endpoint */
265 ep = g_new0(MsnUserEndpoint, 1);
266 ep->id = endpoint;
267 user->endpoints = g_slist_prepend(user->endpoints, ep);
268 }
269
270 ep->clientid = newep->clientid;
271 ep->extcaps = newep->extcaps;
264 } 272 }
265 273
266 void 274 void
267 msn_user_set_op(MsnUser *user, MsnListOp list_op) 275 msn_user_set_op(MsnUser *user, MsnListOp list_op)
268 { 276 {
561 569
562 MsnUserEndpoint * 570 MsnUserEndpoint *
563 msn_user_get_endpoint_data(MsnUser *user, const char *input) 571 msn_user_get_endpoint_data(MsnUser *user, const char *input)
564 { 572 {
565 char *endpoint; 573 char *endpoint;
566 MsnUserEndpoint *data; 574 GSList *l;
575 MsnUserEndpoint *ep;
567 576
568 g_return_val_if_fail(user != NULL, NULL); 577 g_return_val_if_fail(user != NULL, NULL);
569 g_return_val_if_fail(input != NULL, NULL); 578 g_return_val_if_fail(input != NULL, NULL);
570 579
571 endpoint = g_ascii_strdown(input, -1); 580 endpoint = g_ascii_strdown(input, -1);
572 data = g_hash_table_lookup(user->endpoints, endpoint); 581
582 for (l = user->endpoints; l; l = l->next) {
583 ep = l->data;
584 if (g_str_equal(ep->id, endpoint)) {
585 g_free(endpoint);
586 return ep;
587 }
588 }
589
573 g_free(endpoint); 590 g_free(endpoint);
574 591
575 return data; 592 return NULL;
576 } 593 }
577 594
578 MsnObject * 595 MsnObject *
579 msn_user_get_object(const MsnUser *user) 596 msn_user_get_object(const MsnUser *user)
580 { 597 {
603 msn_user_is_capable(MsnUser *user, char *endpoint, guint capability, guint extcap) 620 msn_user_is_capable(MsnUser *user, char *endpoint, guint capability, guint extcap)
604 { 621 {
605 g_return_val_if_fail(user != NULL, FALSE); 622 g_return_val_if_fail(user != NULL, FALSE);
606 623
607 if (endpoint != NULL) { 624 if (endpoint != NULL) {
608 MsnUserEndpoint *ep = g_hash_table_lookup(user->endpoints, endpoint); 625 MsnUserEndpoint *ep = msn_user_get_endpoint_data(user, endpoint);
609 if (ep != NULL) 626 if (ep != NULL)
610 return (ep->clientid & capability) == capability 627 return (ep->clientid & capability) && (ep->extcaps & extcap);
611 && (ep->extcaps & extcap) == extcap;
612 else 628 else
613 return FALSE; 629 return FALSE;
614 } 630 }
615 631
616 return (user->clientid & capability) == capability 632 return (user->clientid & capability) && (user->extcaps & extcap);
617 && (user->extcaps & extcap) == extcap; 633 }
618 }
619
620