Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/caps.c @ 26927:70fdb6fc8aee
Make the JabberCapsTuple (nee Key) available to the rest of the prpl
author | Paul Aurich <paul@darkrain42.org> |
---|---|
date | Thu, 07 May 2009 23:46:11 +0000 |
parents | bcc577785c2b |
children | d0a049ede31e |
comparison
equal
deleted
inserted
replaced
26924:33f98d662db8 | 26927:70fdb6fc8aee |
---|---|
33 typedef struct _JabberDataFormField { | 33 typedef struct _JabberDataFormField { |
34 gchar *var; | 34 gchar *var; |
35 GList *values; | 35 GList *values; |
36 } JabberDataFormField; | 36 } JabberDataFormField; |
37 | 37 |
38 typedef struct _JabberCapsKey { | 38 static GHashTable *capstable = NULL; /* JabberCapsTuple -> JabberCapsClientInfo */ |
39 char *node; | |
40 char *ver; | |
41 char *hash; | |
42 } JabberCapsKey; | |
43 | |
44 static GHashTable *capstable = NULL; /* JabberCapsKey -> JabberCapsClientInfo */ | |
45 static GHashTable *nodetable = NULL; /* char *node -> JabberCapsNodeExts */ | 39 static GHashTable *nodetable = NULL; /* char *node -> JabberCapsNodeExts */ |
46 static guint save_timer = 0; | 40 static guint save_timer = 0; |
47 | 41 |
48 /** | 42 /** |
49 * Processes a query-node and returns a JabberCapsClientInfo object with all relevant info. | 43 * Processes a query-node and returns a JabberCapsClientInfo object with all relevant info. |
84 g_hash_table_destroy(exts->exts); | 78 g_hash_table_destroy(exts->exts); |
85 g_free(exts); | 79 g_free(exts); |
86 } | 80 } |
87 | 81 |
88 static guint jabber_caps_hash(gconstpointer data) { | 82 static guint jabber_caps_hash(gconstpointer data) { |
89 const JabberCapsKey *key = data; | 83 const JabberCapsTuple *key = data; |
90 guint nodehash = g_str_hash(key->node); | 84 guint nodehash = g_str_hash(key->node); |
91 guint verhash = g_str_hash(key->ver); | 85 guint verhash = g_str_hash(key->ver); |
92 /* | 86 /* |
93 * 'hash' was optional in XEP-0115 v1.4 and g_str_hash crashes on NULL >:O. | 87 * 'hash' was optional in XEP-0115 v1.4 and g_str_hash crashes on NULL >:O. |
94 * Okay, maybe I've played too much Zelda, but that looks like | 88 * Okay, maybe I've played too much Zelda, but that looks like |
97 guint hashhash = (key->hash ? g_str_hash(key->hash) : 0); | 91 guint hashhash = (key->hash ? g_str_hash(key->hash) : 0); |
98 return nodehash ^ verhash ^ hashhash; | 92 return nodehash ^ verhash ^ hashhash; |
99 } | 93 } |
100 | 94 |
101 static gboolean jabber_caps_compare(gconstpointer v1, gconstpointer v2) { | 95 static gboolean jabber_caps_compare(gconstpointer v1, gconstpointer v2) { |
102 const JabberCapsKey *name1 = v1; | 96 const JabberCapsTuple *name1 = v1; |
103 const JabberCapsKey *name2 = v2; | 97 const JabberCapsTuple *name2 = v2; |
104 | 98 |
105 return g_str_equal(name1->node, name2->node) && | 99 return g_str_equal(name1->node, name2->node) && |
106 g_str_equal(name1->ver, name2->ver) && | 100 g_str_equal(name1->ver, name2->ver) && |
107 purple_strequal(name1->hash, name2->hash); | 101 purple_strequal(name1->hash, name2->hash); |
108 } | |
109 | |
110 void jabber_caps_destroy_key(gpointer data) { | |
111 JabberCapsKey *key = data; | |
112 g_free(key->node); | |
113 g_free(key->ver); | |
114 g_free(key->hash); | |
115 g_free(key); | |
116 } | 102 } |
117 | 103 |
118 static void | 104 static void |
119 jabber_caps_client_info_destroy(JabberCapsClientInfo *info) | 105 jabber_caps_client_info_destroy(JabberCapsClientInfo *info) |
120 { | 106 { |
138 info->forms = g_list_delete_link(info->forms, info->forms); | 124 info->forms = g_list_delete_link(info->forms, info->forms); |
139 } | 125 } |
140 | 126 |
141 jabber_caps_node_exts_unref(info->exts); | 127 jabber_caps_node_exts_unref(info->exts); |
142 | 128 |
129 g_free((char *)info->tuple.node); | |
130 g_free((char *)info->tuple.ver); | |
131 g_free((char *)info->tuple.hash); | |
132 | |
143 g_free(info); | 133 g_free(info); |
144 } | 134 } |
145 | 135 |
146 /* NOTE: Takes a reference to the exts, unref it if you don't really want to | 136 /* NOTE: Takes a reference to the exts, unref it if you don't really want to |
147 * keep it around. */ | 137 * keep it around. */ |
174 xmlnode_set_attrib(feature, "var", (const gchar *)node->data); | 164 xmlnode_set_attrib(feature, "var", (const gchar *)node->data); |
175 } | 165 } |
176 } | 166 } |
177 | 167 |
178 static void jabber_caps_store_client(gpointer key, gpointer value, gpointer user_data) { | 168 static void jabber_caps_store_client(gpointer key, gpointer value, gpointer user_data) { |
179 JabberCapsKey *clientinfo = key; | 169 const JabberCapsTuple *tuple = key; |
180 JabberCapsClientInfo *props = value; | 170 const JabberCapsClientInfo *props = value; |
181 xmlnode *root = user_data; | 171 xmlnode *root = user_data; |
182 xmlnode *client = xmlnode_new_child(root, "client"); | 172 xmlnode *client = xmlnode_new_child(root, "client"); |
183 GList *iter; | 173 GList *iter; |
184 | 174 |
185 xmlnode_set_attrib(client, "node", clientinfo->node); | 175 xmlnode_set_attrib(client, "node", tuple->node); |
186 xmlnode_set_attrib(client, "ver", clientinfo->ver); | 176 xmlnode_set_attrib(client, "ver", tuple->ver); |
187 if (clientinfo->hash) | 177 if (tuple->hash) |
188 xmlnode_set_attrib(client, "hash", clientinfo->hash); | 178 xmlnode_set_attrib(client, "hash", tuple->hash); |
189 for(iter = props->identities; iter; iter = g_list_next(iter)) { | 179 for(iter = props->identities; iter; iter = g_list_next(iter)) { |
190 JabberIdentity *id = iter->data; | 180 JabberIdentity *id = iter->data; |
191 xmlnode *identity = xmlnode_new_child(client, "identity"); | 181 xmlnode *identity = xmlnode_new_child(client, "identity"); |
192 xmlnode_set_attrib(identity, "category", id->category); | 182 xmlnode_set_attrib(identity, "category", id->category); |
193 xmlnode_set_attrib(identity, "type", id->type); | 183 xmlnode_set_attrib(identity, "type", id->type); |
253 | 243 |
254 for(client = capsdata->child; client; client = client->next) { | 244 for(client = capsdata->child; client; client = client->next) { |
255 if(client->type != XMLNODE_TYPE_TAG) | 245 if(client->type != XMLNODE_TYPE_TAG) |
256 continue; | 246 continue; |
257 if(!strcmp(client->name, "client")) { | 247 if(!strcmp(client->name, "client")) { |
258 JabberCapsKey *key = g_new0(JabberCapsKey, 1); | |
259 JabberCapsClientInfo *value = g_new0(JabberCapsClientInfo, 1); | 248 JabberCapsClientInfo *value = g_new0(JabberCapsClientInfo, 1); |
249 JabberCapsTuple *key = (JabberCapsTuple*)&value->tuple; | |
260 xmlnode *child; | 250 xmlnode *child; |
261 JabberCapsNodeExts *exts = NULL; | 251 JabberCapsNodeExts *exts = NULL; |
262 key->node = g_strdup(xmlnode_get_attrib(client,"node")); | 252 key->node = g_strdup(xmlnode_get_attrib(client,"node")); |
263 key->ver = g_strdup(xmlnode_get_attrib(client,"ver")); | 253 key->ver = g_strdup(xmlnode_get_attrib(client,"ver")); |
264 key->hash = g_strdup(xmlnode_get_attrib(client,"hash")); | 254 key->hash = g_strdup(xmlnode_get_attrib(client,"hash")); |
338 } | 328 } |
339 | 329 |
340 void jabber_caps_init(void) | 330 void jabber_caps_init(void) |
341 { | 331 { |
342 nodetable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)jabber_caps_node_exts_unref); | 332 nodetable = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, (GDestroyNotify)jabber_caps_node_exts_unref); |
343 capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, jabber_caps_destroy_key, (GDestroyNotify)jabber_caps_client_info_destroy); | 333 capstable = g_hash_table_new_full(jabber_caps_hash, jabber_caps_compare, NULL, (GDestroyNotify)jabber_caps_client_info_destroy); |
344 jabber_caps_load(); | 334 jabber_caps_load(); |
345 } | 335 } |
346 | 336 |
347 void jabber_caps_uninit(void) | 337 void jabber_caps_uninit(void) |
348 { | 338 { |
427 { | 417 { |
428 xmlnode *query = xmlnode_get_child_with_namespace(packet, "query", | 418 xmlnode *query = xmlnode_get_child_with_namespace(packet, "query", |
429 "http://jabber.org/protocol/disco#info"); | 419 "http://jabber.org/protocol/disco#info"); |
430 jabber_caps_cbplususerdata *userdata = data; | 420 jabber_caps_cbplususerdata *userdata = data; |
431 JabberCapsClientInfo *info = NULL, *value; | 421 JabberCapsClientInfo *info = NULL, *value; |
432 JabberCapsKey key; | 422 JabberCapsTuple key; |
433 | 423 |
434 if (!query || type == JABBER_IQ_ERROR) { | 424 if (!query || type == JABBER_IQ_ERROR) { |
435 /* Any outstanding exts will be dealt with via ref-counting */ | 425 /* Any outstanding exts will be dealt with via ref-counting */ |
436 userdata->cb(NULL, NULL, userdata->cb_data); | 426 userdata->cb(NULL, NULL, userdata->cb_data); |
437 cbplususerdata_unref(userdata); | 427 cbplususerdata_unref(userdata); |
479 * a new one if we need to */ | 469 * a new one if we need to */ |
480 if ((value = g_hash_table_lookup(capstable, &key))) { | 470 if ((value = g_hash_table_lookup(capstable, &key))) { |
481 jabber_caps_client_info_destroy(info); | 471 jabber_caps_client_info_destroy(info); |
482 info = value; | 472 info = value; |
483 } else { | 473 } else { |
484 JabberCapsKey *n_key = g_new(JabberCapsKey, 1); | 474 JabberCapsTuple *n_key = (JabberCapsTuple *)&info->tuple; |
485 n_key->node = userdata->node; | 475 n_key->node = userdata->node; |
486 n_key->ver = userdata->ver; | 476 n_key->ver = userdata->ver; |
487 n_key->hash = userdata->hash; | 477 n_key->hash = userdata->hash; |
488 userdata->node = userdata->ver = userdata->hash = NULL; | 478 userdata->node = userdata->ver = userdata->hash = NULL; |
489 | 479 |
551 void jabber_caps_get_info(JabberStream *js, const char *who, const char *node, | 541 void jabber_caps_get_info(JabberStream *js, const char *who, const char *node, |
552 const char *ver, const char *hash, const char *ext, | 542 const char *ver, const char *hash, const char *ext, |
553 jabber_caps_get_info_cb cb, gpointer user_data) | 543 jabber_caps_get_info_cb cb, gpointer user_data) |
554 { | 544 { |
555 JabberCapsClientInfo *info; | 545 JabberCapsClientInfo *info; |
556 JabberCapsKey key; | 546 JabberCapsTuple key; |
557 jabber_caps_cbplususerdata *userdata; | 547 jabber_caps_cbplususerdata *userdata; |
558 | 548 |
559 if (ext && *ext && hash) | 549 if (ext && *ext && hash) |
560 purple_debug_info("jabber", "Ignoring exts in new-style caps from %s\n", | 550 purple_debug_info("jabber", "Ignoring exts in new-style caps from %s\n", |
561 who); | 551 who); |