Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/user.c @ 31166: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
31165:e167de25e795 | 31166: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 |