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);