Mercurial > pidgin
comparison libpurple/protocols/myspace/message.c @ 18895:f732d072b118
Change all code to better match the style of libpurple - use 8-space tabs
for indentation everywhere. Spaces are still used for alignment when needed,
as described on http://derkarl.org/why_to_tabs.html (ack for [^\t]\t to ensure
tabs are only being used for indentation). Lots of vim regexes made this
transformation possible.
Also cuddled a few braces that I missed before.
This is a big commit, but there are no actual code changes.
author | Jeffrey Connelly <jaconnel@calpoly.edu> |
---|---|
date | Sat, 11 Aug 2007 05:53:11 +0000 |
parents | 7db556e97dd1 |
children | d0be4366e876 |
comparison
equal
deleted
inserted
replaced
18894:daedc9647341 | 18895:f732d072b118 |
---|---|
30 static MsimMessage *msim_msg_new_v(va_list argp); | 30 static MsimMessage *msim_msg_new_v(va_list argp); |
31 | 31 |
32 /* Escape codes and associated replacement text, used for protocol message | 32 /* Escape codes and associated replacement text, used for protocol message |
33 * escaping and unescaping. */ | 33 * escaping and unescaping. */ |
34 static struct MSIM_ESCAPE_REPLACEMENT { | 34 static struct MSIM_ESCAPE_REPLACEMENT { |
35 gchar *code; | 35 gchar *code; |
36 gchar *text; | 36 gchar *text; |
37 } msim_escape_replacements[] = { | 37 } msim_escape_replacements[] = { |
38 { "/1", "/" }, | 38 { "/1", "/" }, |
39 { "/2", "\\" }, | 39 { "/2", "\\" }, |
40 /* { "/3", "|" }, */ /* Not used here -- only for within arrays */ | 40 /* { "/3", "|" }, */ /* Not used here -- only for within arrays */ |
41 { NULL, NULL } | 41 { NULL, NULL } |
42 }; | 42 }; |
43 | 43 |
44 /** | 44 /** |
45 * Unescape or escape a protocol message. | 45 * Unescape or escape a protocol message. |
46 * | 46 * |
52 static gchar * | 52 static gchar * |
53 msim_unescape_or_escape(const gchar *original_msg, gboolean escape) | 53 msim_unescape_or_escape(const gchar *original_msg, gboolean escape) |
54 { | 54 { |
55 gchar *tmp, *msg; | 55 gchar *tmp, *msg; |
56 guint i; | 56 guint i; |
57 struct MSIM_ESCAPE_REPLACEMENT* replacement; | 57 struct MSIM_ESCAPE_REPLACEMENT* replacement; |
58 | 58 |
59 /* Freed in loop below. */ | 59 /* Freed in loop below. */ |
60 msg = g_strdup(original_msg); | 60 msg = g_strdup(original_msg); |
61 | 61 |
62 /* Replace each code in msim_replacement_code with | 62 /* Replace each code in msim_replacement_code with |
63 * corresponding entry in msim_replacement_text. */ | 63 * corresponding entry in msim_replacement_text. */ |
64 for (i = 0; (replacement = &msim_escape_replacements[i]); ++i) { | 64 for (i = 0; (replacement = &msim_escape_replacements[i]); ++i) { |
65 gchar *code, *text; | 65 gchar *code, *text; |
66 | 66 |
67 code = replacement->code; | 67 code = replacement->code; |
68 text = replacement->text; | 68 text = replacement->text; |
69 | 69 |
70 if (!code || !text) | 70 if (!code || !text) |
71 break; | 71 break; |
72 | 72 |
73 if (escape) { | 73 if (escape) { |
74 tmp = str_replace(msg, text, code); | 74 tmp = str_replace(msg, text, code); |
75 } else { | 75 } else { |
76 tmp = str_replace(msg, code, text); | 76 tmp = str_replace(msg, code, text); |
113 | 113 |
114 va_start(argp, not_empty); | 114 va_start(argp, not_empty); |
115 | 115 |
116 if (not_empty) { | 116 if (not_empty) { |
117 return msim_msg_new_v(argp); | 117 return msim_msg_new_v(argp); |
118 } else { | 118 } else { |
119 return NULL; | 119 return NULL; |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 /** Create a new message from va_list and its first argument. | 123 /** Create a new message from va_list and its first argument. |
124 * | 124 * |
125 * @param argp A va_list of variadic arguments, already started with va_start(). Will be va_end()'d. | 125 * @param argp A va_list of variadic arguments, already started with va_start(). Will be va_end()'d. |
132 { | 132 { |
133 gchar *key, *value; | 133 gchar *key, *value; |
134 MsimMessageType type; | 134 MsimMessageType type; |
135 MsimMessage *msg; | 135 MsimMessage *msg; |
136 | 136 |
137 GString *gs; | 137 GString *gs; |
138 GList *gl; | 138 GList *gl; |
139 MsimMessage *dict; | 139 MsimMessage *dict; |
140 | 140 |
141 | 141 |
142 /* Begin with an empty message. */ | 142 /* Begin with an empty message. */ |
143 msg = NULL; | 143 msg = NULL; |
144 | 144 |
165 | 165 |
166 msg = msim_msg_append(msg, key, type, value); | 166 msg = msim_msg_append(msg, key, type, value); |
167 break; | 167 break; |
168 | 168 |
169 case MSIM_TYPE_BINARY: | 169 case MSIM_TYPE_BINARY: |
170 gs = va_arg(argp, GString *); | 170 gs = va_arg(argp, GString *); |
171 | 171 |
172 g_return_val_if_fail(gs != NULL, FALSE); | 172 g_return_val_if_fail(gs != NULL, FALSE); |
173 | 173 |
174 /* msim_msg_free() will free this GString the caller created. */ | 174 /* msim_msg_free() will free this GString the caller created. */ |
175 msg = msim_msg_append(msg, key, type, gs); | 175 msg = msim_msg_append(msg, key, type, gs); |
176 break; | 176 break; |
177 | 177 |
178 case MSIM_TYPE_LIST: | 178 case MSIM_TYPE_LIST: |
179 gl = va_arg(argp, GList *); | 179 gl = va_arg(argp, GList *); |
180 | 180 |
181 g_return_val_if_fail(gl != NULL, FALSE); | 181 g_return_val_if_fail(gl != NULL, FALSE); |
182 | 182 |
183 msg = msim_msg_append(msg, key, type, gl); | 183 msg = msim_msg_append(msg, key, type, gl); |
184 break; | 184 break; |
185 | 185 |
186 case MSIM_TYPE_DICTIONARY: | 186 case MSIM_TYPE_DICTIONARY: |
187 dict = va_arg(argp, MsimMessage *); | 187 dict = va_arg(argp, MsimMessage *); |
188 | 188 |
189 g_return_val_if_fail(dict != NULL, FALSE); | 189 g_return_val_if_fail(dict != NULL, FALSE); |
190 | 190 |
191 msg = msim_msg_append(msg, key, type, dict); | 191 msg = msim_msg_append(msg, key, type, dict); |
192 break; | 192 break; |
193 | 193 |
194 default: | 194 default: |
195 purple_debug_info("msim", "msim_send: unknown type %d\n", type); | 195 purple_debug_info("msim", "msim_send: unknown type %d\n", type); |
196 break; | 196 break; |
197 } | 197 } |
198 } while(key); | 198 } while(key); |
199 va_end(argp); | 199 va_end(argp); |
200 | 200 |
201 return msg; | 201 return msg; |
202 } | 202 } |
203 | 203 |
204 /** Perform a deep copy on a GList * of gchar * strings. Free with msim_msg_list_free(). */ | 204 /** Perform a deep copy on a GList * of gchar * strings. Free with msim_msg_list_free(). */ |
205 GList * | 205 GList * |
206 msim_msg_list_copy(GList *old) | 206 msim_msg_list_copy(GList *old) |
207 { | 207 { |
208 GList *new_list; | 208 GList *new_list; |
209 | 209 |
210 new_list = NULL; | 210 new_list = NULL; |
211 | 211 |
212 /* Deep copy (g_list_copy is shallow). Copy each string. */ | 212 /* Deep copy (g_list_copy is shallow). Copy each string. */ |
213 for (; old != NULL; old = g_list_next(old)) { | 213 for (; old != NULL; old = g_list_next(old)) { |
214 new_list = g_list_append(new_list, g_strdup(old->data)); | 214 new_list = g_list_append(new_list, g_strdup(old->data)); |
215 } | 215 } |
216 | 216 |
217 return new_list; | 217 return new_list; |
218 } | 218 } |
219 | 219 |
220 /** Free a GList * of gchar * strings. */ | 220 /** Free a GList * of gchar * strings. */ |
221 void | 221 void |
222 msim_msg_list_free(GList *l) | 222 msim_msg_list_free(GList *l) |
223 { | 223 { |
224 | 224 |
225 for (; l != NULL; l = g_list_next(l)) { | 225 for (; l != NULL; l = g_list_next(l)) { |
226 g_free((gchar *)(l->data)); | 226 g_free((gchar *)(l->data)); |
227 } | 227 } |
228 g_list_free(l); | 228 g_list_free(l); |
229 } | 229 } |
230 | 230 |
231 /** Parse a |-separated string into a new GList. Free with msim_msg_list_free(). */ | 231 /** Parse a |-separated string into a new GList. Free with msim_msg_list_free(). */ |
232 GList * | 232 GList * |
233 msim_msg_list_parse(const gchar *raw) | 233 msim_msg_list_parse(const gchar *raw) |
234 { | 234 { |
235 gchar **array; | 235 gchar **array; |
236 GList *list; | 236 GList *list; |
237 guint i; | 237 guint i; |
238 | 238 |
239 array = g_strsplit(raw, "|", 0); | 239 array = g_strsplit(raw, "|", 0); |
240 list = NULL; | 240 list = NULL; |
241 | 241 |
242 /* TODO: escape/unescape /3 <-> | within list elements */ | 242 /* TODO: escape/unescape /3 <-> | within list elements */ |
243 | 243 |
244 for (i = 0; array[i] != NULL; ++i) { | 244 for (i = 0; array[i] != NULL; ++i) { |
245 list = g_list_append(list, g_strdup(array[i])); | 245 list = g_list_append(list, g_strdup(array[i])); |
246 } | 246 } |
247 | 247 |
248 g_strfreev(array); | 248 g_strfreev(array); |
249 | 249 |
250 return list; | 250 return list; |
251 } | 251 } |
252 | 252 |
253 /** Clone an individual element. | 253 /** Clone an individual element. |
254 * | 254 * |
255 * @param data MsimMessageElement * to clone. | 255 * @param data MsimMessageElement * to clone. |
260 { | 260 { |
261 MsimMessageElement *elem; | 261 MsimMessageElement *elem; |
262 MsimMessage **new; | 262 MsimMessage **new; |
263 gpointer new_data; | 263 gpointer new_data; |
264 | 264 |
265 GString *gs; | 265 GString *gs; |
266 MsimMessage *dict; | 266 MsimMessage *dict; |
267 | 267 |
268 elem = (MsimMessageElement *)data; | 268 elem = (MsimMessageElement *)data; |
269 new = (MsimMessage **)user_data; | 269 new = (MsimMessage **)user_data; |
270 | 270 |
271 switch (elem->type) { | 271 switch (elem->type) { |
277 case MSIM_TYPE_RAW: | 277 case MSIM_TYPE_RAW: |
278 case MSIM_TYPE_STRING: | 278 case MSIM_TYPE_STRING: |
279 new_data = g_strdup((gchar *)elem->data); | 279 new_data = g_strdup((gchar *)elem->data); |
280 break; | 280 break; |
281 | 281 |
282 case MSIM_TYPE_LIST: | 282 case MSIM_TYPE_LIST: |
283 new_data = (gpointer)msim_msg_list_copy((GList *)(elem->data)); | 283 new_data = (gpointer)msim_msg_list_copy((GList *)(elem->data)); |
284 break; | 284 break; |
285 | 285 |
286 case MSIM_TYPE_BINARY: | 286 case MSIM_TYPE_BINARY: |
287 gs = (GString *)elem->data; | 287 gs = (GString *)elem->data; |
288 | 288 |
289 new_data = g_string_new_len(gs->str, gs->len); | 289 new_data = g_string_new_len(gs->str, gs->len); |
290 break; | 290 break; |
291 case MSIM_TYPE_DICTIONARY: | 291 case MSIM_TYPE_DICTIONARY: |
292 dict = (MsimMessage *)elem->data; | 292 dict = (MsimMessage *)elem->data; |
293 | 293 |
294 new_data = msim_msg_clone(dict); | 294 new_data = msim_msg_clone(dict); |
295 break; | 295 break; |
296 | 296 |
297 default: | 297 default: |
298 purple_debug_info("msim", "msim_msg_clone_element: unknown type %d\n", elem->type); | 298 purple_debug_info("msim", "msim_msg_clone_element: unknown type %d\n", elem->type); |
299 g_return_if_fail(NULL); | 299 g_return_if_fail(NULL); |
300 } | 300 } |
313 { | 313 { |
314 MsimMessage *new; | 314 MsimMessage *new; |
315 | 315 |
316 if (old == NULL) { | 316 if (old == NULL) { |
317 return NULL; | 317 return NULL; |
318 } | 318 } |
319 | 319 |
320 new = msim_msg_new(FALSE); | 320 new = msim_msg_new(FALSE); |
321 | 321 |
322 g_list_foreach(old, msim_msg_clone_element, &new); | 322 g_list_foreach(old, msim_msg_clone_element, &new); |
323 | 323 |
332 * element itself with g_free() (see msim_msg_free_element()). | 332 * element itself with g_free() (see msim_msg_free_element()). |
333 */ | 333 */ |
334 void | 334 void |
335 msim_msg_free_element_data(MsimMessageElement *elem) | 335 msim_msg_free_element_data(MsimMessageElement *elem) |
336 { | 336 { |
337 switch (elem->type) { | 337 switch (elem->type) { |
338 case MSIM_TYPE_BOOLEAN: | 338 case MSIM_TYPE_BOOLEAN: |
339 case MSIM_TYPE_INTEGER: | 339 case MSIM_TYPE_INTEGER: |
340 /* Integer value stored in gpointer - no need to free(). */ | 340 /* Integer value stored in gpointer - no need to free(). */ |
341 break; | 341 break; |
342 | 342 |
351 /* Free the GString itself and the binary data. */ | 351 /* Free the GString itself and the binary data. */ |
352 g_string_free((GString *)elem->data, TRUE); | 352 g_string_free((GString *)elem->data, TRUE); |
353 break; | 353 break; |
354 | 354 |
355 case MSIM_TYPE_DICTIONARY: | 355 case MSIM_TYPE_DICTIONARY: |
356 msim_msg_free((MsimMessage *)elem->data); | 356 msim_msg_free((MsimMessage *)elem->data); |
357 break; | 357 break; |
358 | 358 |
359 case MSIM_TYPE_LIST: | 359 case MSIM_TYPE_LIST: |
360 g_list_free((GList *)elem->data); | 360 g_list_free((GList *)elem->data); |
361 break; | 361 break; |
362 | 362 |
363 default: | 363 default: |
364 purple_debug_info("msim", "msim_msg_free_element_data: " | 364 purple_debug_info("msim", "msim_msg_free_element_data: " |
365 "not freeing unknown type %d\n", elem->type); | 365 "not freeing unknown type %d\n", elem->type); |
366 break; | 366 break; |
367 } | 367 } |
368 } | 368 } |
369 | 369 |
370 /** Free an individual message element. | 370 /** Free an individual message element. |
379 { | 379 { |
380 MsimMessageElement *elem; | 380 MsimMessageElement *elem; |
381 | 381 |
382 elem = (MsimMessageElement *)data; | 382 elem = (MsimMessageElement *)data; |
383 | 383 |
384 msim_msg_free_element_data(elem); | 384 msim_msg_free_element_data(elem); |
385 | 385 |
386 g_free(elem); | 386 g_free(elem); |
387 } | 387 } |
388 | 388 |
389 /** Free a complete message. */ | 389 /** Free a complete message. */ |
393 if (!msg) { | 393 if (!msg) { |
394 /* already free as can be */ | 394 /* already free as can be */ |
395 return; | 395 return; |
396 } | 396 } |
397 | 397 |
398 msim_msg_dump("msim_msg_free: freeing %s", msg); | 398 msim_msg_dump("msim_msg_free: freeing %s", msg); |
399 | 399 |
400 g_list_foreach(msg, msim_msg_free_element, NULL); | 400 g_list_foreach(msg, msim_msg_free_element, NULL); |
401 g_list_free(msg); | 401 g_list_free(msg); |
402 } | 402 } |
403 | 403 |
407 { | 407 { |
408 gchar *raw; | 408 gchar *raw; |
409 gboolean success; | 409 gboolean success; |
410 | 410 |
411 raw = msim_msg_pack(msg); | 411 raw = msim_msg_pack(msg); |
412 g_return_val_if_fail(raw != NULL, FALSE); | 412 g_return_val_if_fail(raw != NULL, FALSE); |
413 success = msim_send_raw(session, raw); | 413 success = msim_send_raw(session, raw); |
414 g_free(raw); | 414 g_free(raw); |
415 | 415 |
416 msim_msg_dump("msim_msg_send()ing %s\n", msg); | 416 msim_msg_dump("msim_msg_send()ing %s\n", msg); |
417 | 417 |
436 msim_send(MsimSession *session, ...) | 436 msim_send(MsimSession *session, ...) |
437 { | 437 { |
438 gboolean success; | 438 gboolean success; |
439 MsimMessage *msg; | 439 MsimMessage *msg; |
440 va_list argp; | 440 va_list argp; |
441 | 441 |
442 va_start(argp, session); | 442 va_start(argp, session); |
443 msg = msim_msg_new_v(argp); | 443 msg = msim_msg_new_v(argp); |
444 | 444 |
445 /* Actually send the message. */ | 445 /* Actually send the message. */ |
446 success = msim_msg_send(session, msg); | 446 success = msim_msg_send(session, msg); |
476 * @param type An MSIM_TYPE_* code. | 476 * @param type An MSIM_TYPE_* code. |
477 * @param data Pointer to data, see below. | 477 * @param data Pointer to data, see below. |
478 * | 478 * |
479 * @return The new message - must be assigned to as with GList*. For example: | 479 * @return The new message - must be assigned to as with GList*. For example: |
480 * | 480 * |
481 * msg = msim_msg_append(msg, ...) | 481 * msg = msim_msg_append(msg, ...) |
482 * | 482 * |
483 * The data parameter depends on the type given: | 483 * The data parameter depends on the type given: |
484 * | 484 * |
485 * * MSIM_TYPE_INTEGER: Use GUINT_TO_POINTER(x). | 485 * * MSIM_TYPE_INTEGER: Use GUINT_TO_POINTER(x). |
486 * | 486 * |
505 } | 505 } |
506 | 506 |
507 /** Insert a new element into a message, before the given element name. | 507 /** Insert a new element into a message, before the given element name. |
508 * | 508 * |
509 * @param name_before Name of the element to insert the new element before. If | 509 * @param name_before Name of the element to insert the new element before. If |
510 * could not be found or NULL, new element will be inserted at end. | 510 * could not be found or NULL, new element will be inserted at end. |
511 * | 511 * |
512 * See msim_msg_append() for usage of other parameters, and an important note about return value. | 512 * See msim_msg_append() for usage of other parameters, and an important note about return value. |
513 */ | 513 */ |
514 MsimMessage * | 514 MsimMessage * |
515 msim_msg_insert_before(MsimMessage *msg, const gchar *name_before, | 515 msim_msg_insert_before(MsimMessage *msg, const gchar *name_before, |
516 const gchar *name, MsimMessageType type, gpointer data) | 516 const gchar *name, MsimMessageType type, gpointer data) |
517 { | 517 { |
518 MsimMessageElement *new_elem; | 518 MsimMessageElement *new_elem; |
519 GList *node_before; | 519 GList *node_before; |
520 | 520 |
521 new_elem = msim_msg_element_new(name, type, data); | 521 new_elem = msim_msg_element_new(name, type, data); |
522 | 522 |
523 node_before = msim_msg_get_node(msg, name_before); | 523 node_before = msim_msg_get_node(msg, name_before); |
524 | 524 |
525 return g_list_insert_before(msg, node_before, new_elem); | 525 return g_list_insert_before(msg, node_before, new_elem); |
526 } | 526 } |
528 /** Pack a string using the given GFunc and seperator. | 528 /** Pack a string using the given GFunc and seperator. |
529 * Used by msim_msg_dump() and msim_msg_pack(). | 529 * Used by msim_msg_dump() and msim_msg_pack(). |
530 */ | 530 */ |
531 gchar * | 531 gchar * |
532 msim_msg_pack_using(MsimMessage *msg, | 532 msim_msg_pack_using(MsimMessage *msg, |
533 GFunc gf, | 533 GFunc gf, |
534 const gchar *sep, | 534 const gchar *sep, |
535 const gchar *begin, const gchar *end) | 535 const gchar *begin, const gchar *end) |
536 { | 536 { |
537 gchar **strings; | 537 gchar **strings; |
538 gchar **strings_tmp; | 538 gchar **strings_tmp; |
539 gchar *joined; | 539 gchar *joined; |
571 { | 571 { |
572 MsimMessageElement *elem; | 572 MsimMessageElement *elem; |
573 gchar *string; | 573 gchar *string; |
574 GString *gs; | 574 GString *gs; |
575 gchar *binary; | 575 gchar *binary; |
576 gchar ***items; /* wow, a pointer to a pointer to a pointer */ | 576 gchar ***items; /* wow, a pointer to a pointer to a pointer */ |
577 | 577 |
578 gchar *s; | 578 gchar *s; |
579 GList *gl; | 579 GList *gl; |
580 guint i; | 580 guint i; |
581 | 581 |
582 elem = (MsimMessageElement *)data; | 582 elem = (MsimMessageElement *)data; |
583 items = user_data; | 583 items = user_data; |
584 | 584 |
585 switch (elem->type) { | 585 switch (elem->type) { |
586 case MSIM_TYPE_INTEGER: | 586 case MSIM_TYPE_INTEGER: |
587 string = g_strdup_printf("%s(integer): %d", elem->name, | 587 string = g_strdup_printf("%s(integer): %d", elem->name, |
588 GPOINTER_TO_UINT(elem->data)); | 588 GPOINTER_TO_UINT(elem->data)); |
589 break; | 589 break; |
590 | 590 |
591 case MSIM_TYPE_RAW: | 591 case MSIM_TYPE_RAW: |
592 string = g_strdup_printf("%s(raw): %s", elem->name, | 592 string = g_strdup_printf("%s(raw): %s", elem->name, |
593 elem->data ? (gchar *)elem->data : "(NULL)"); | 593 elem->data ? (gchar *)elem->data : "(NULL)"); |
594 break; | 594 break; |
595 | 595 |
596 case MSIM_TYPE_STRING: | 596 case MSIM_TYPE_STRING: |
597 string = g_strdup_printf("%s(string): %s", elem->name, | 597 string = g_strdup_printf("%s(string): %s", elem->name, |
598 elem->data ? (gchar *)elem->data : "(NULL)"); | 598 elem->data ? (gchar *)elem->data : "(NULL)"); |
599 break; | 599 break; |
600 | 600 |
601 case MSIM_TYPE_BINARY: | 601 case MSIM_TYPE_BINARY: |
602 gs = (GString *)elem->data; | 602 gs = (GString *)elem->data; |
603 binary = purple_base64_encode((guchar*)gs->str, gs->len); | 603 binary = purple_base64_encode((guchar*)gs->str, gs->len); |
609 string = g_strdup_printf("%s(boolean): %s", elem->name, | 609 string = g_strdup_printf("%s(boolean): %s", elem->name, |
610 elem->data ? "TRUE" : "FALSE"); | 610 elem->data ? "TRUE" : "FALSE"); |
611 break; | 611 break; |
612 | 612 |
613 case MSIM_TYPE_DICTIONARY: | 613 case MSIM_TYPE_DICTIONARY: |
614 if (!elem->data) | 614 if (!elem->data) { |
615 s = g_strdup("(NULL)"); | 615 s = g_strdup("(NULL)"); |
616 else | 616 } else { |
617 s = msim_msg_dump_to_str((MsimMessage *)elem->data); | 617 s = msim_msg_dump_to_str((MsimMessage *)elem->data); |
618 | 618 } |
619 if (!s) | 619 |
620 s = g_strdup("(NULL, couldn't msim_msg_dump_to_str)"); | 620 if (!s) { |
621 | 621 s = g_strdup("(NULL, couldn't msim_msg_dump_to_str)"); |
622 string = g_strdup_printf("%s(dict): %s", elem->name, s); | 622 } |
623 | 623 |
624 g_free(s); | 624 string = g_strdup_printf("%s(dict): %s", elem->name, s); |
625 | |
626 g_free(s); | |
625 break; | 627 break; |
626 | 628 |
627 case MSIM_TYPE_LIST: | 629 case MSIM_TYPE_LIST: |
628 gs = g_string_new(""); | 630 gs = g_string_new(""); |
629 g_string_append_printf(gs, "%s(list): \n", elem->name); | 631 g_string_append_printf(gs, "%s(list): \n", elem->name); |
630 | 632 |
631 i = 0; | 633 i = 0; |
632 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) | 634 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) { |
633 { | 635 g_string_append_printf(gs, " %d. %s\n", i, (gchar *)(gl->data)); |
634 g_string_append_printf(gs, " %d. %s\n", i, (gchar *)(gl->data)); | 636 ++i; |
635 ++i; | 637 } |
636 } | 638 |
637 | 639 string = gs->str; |
638 string = gs->str; | |
639 break; | 640 break; |
640 | 641 |
641 default: | 642 default: |
642 string = g_strdup_printf("%s(unknown type %d", | 643 string = g_strdup_printf("%s(unknown type %d", |
643 elem->name ? elem->name : "(NULL)", elem->type); | 644 elem->name ? elem->name : "(NULL)", elem->type); |
644 break; | 645 break; |
645 } | 646 } |
646 | 647 |
647 **items = string; | 648 **items = string; |
648 ++(*items); | 649 ++(*items); |
653 * @param fmt_string A static string, in which '%s' will be replaced. | 654 * @param fmt_string A static string, in which '%s' will be replaced. |
654 */ | 655 */ |
655 void | 656 void |
656 msim_msg_dump(const gchar *fmt_string, MsimMessage *msg) | 657 msim_msg_dump(const gchar *fmt_string, MsimMessage *msg) |
657 { | 658 { |
658 gchar *debug_str; | 659 gchar *debug_str; |
659 | 660 |
660 g_return_if_fail(fmt_string != NULL); | 661 g_return_if_fail(fmt_string != NULL); |
661 | 662 |
662 debug_str = msim_msg_dump_to_str(msg); | 663 debug_str = msim_msg_dump_to_str(msg); |
663 | 664 |
664 g_return_if_fail(debug_str != NULL); | 665 g_return_if_fail(debug_str != NULL); |
665 | 666 |
666 purple_debug_info("msim_msg_dump", "debug_str=%s\n", debug_str); | 667 purple_debug_info("msim_msg_dump", "debug_str=%s\n", debug_str); |
667 | 668 |
668 | 669 |
669 purple_debug_info("msim", fmt_string, debug_str); | 670 purple_debug_info("msim", fmt_string, debug_str); |
670 | 671 |
671 g_free(debug_str); | 672 g_free(debug_str); |
685 } else { | 686 } else { |
686 debug_str = msim_msg_pack_using(msg, msim_msg_debug_string_element, | 687 debug_str = msim_msg_pack_using(msg, msim_msg_debug_string_element, |
687 "\n", "<MsimMessage: \n", "\n/MsimMessage>"); | 688 "\n", "<MsimMessage: \n", "\n/MsimMessage>"); |
688 } | 689 } |
689 | 690 |
690 return debug_str; | 691 return debug_str; |
691 } | 692 } |
692 | 693 |
693 /** Return a message element data as a new string for a raw protocol message, converting from other types (integer, etc.) if necessary. | 694 /** Return a message element data as a new string for a raw protocol message, converting from other types (integer, etc.) if necessary. |
694 * | 695 * |
695 * @return const gchar * The data as a string, or NULL. Caller must g_free(). | 696 * @return const gchar * The data as a string, or NULL. Caller must g_free(). |
699 * msim_msg_get_string() if you want a string, which in some cases is same as this. | 700 * msim_msg_get_string() if you want a string, which in some cases is same as this. |
700 */ | 701 */ |
701 gchar * | 702 gchar * |
702 msim_msg_pack_element_data(MsimMessageElement *elem) | 703 msim_msg_pack_element_data(MsimMessageElement *elem) |
703 { | 704 { |
704 GString *gs; | 705 GString *gs; |
705 GList *gl; | 706 GList *gl; |
706 | 707 |
707 g_return_val_if_fail(elem != NULL, NULL); | 708 g_return_val_if_fail(elem != NULL, NULL); |
708 | 709 |
709 switch (elem->type) { | 710 switch (elem->type) { |
710 case MSIM_TYPE_INTEGER: | 711 case MSIM_TYPE_INTEGER: |
711 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); | 712 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); |
712 | 713 |
714 /* Not un-escaped - this is a raw element, already escaped if necessary. */ | 715 /* Not un-escaped - this is a raw element, already escaped if necessary. */ |
715 return (gchar *)g_strdup((gchar *)elem->data); | 716 return (gchar *)g_strdup((gchar *)elem->data); |
716 | 717 |
717 case MSIM_TYPE_STRING: | 718 case MSIM_TYPE_STRING: |
718 /* Strings get escaped. msim_escape() creates a new string. */ | 719 /* Strings get escaped. msim_escape() creates a new string. */ |
719 g_return_val_if_fail(elem->data != NULL, NULL); | 720 g_return_val_if_fail(elem->data != NULL, NULL); |
720 return elem->data ? msim_escape((gchar *)elem->data) : | 721 return elem->data ? msim_escape((gchar *)elem->data) : |
721 g_strdup("(NULL)"); | 722 g_strdup("(NULL)"); |
722 | 723 |
723 case MSIM_TYPE_BINARY: | 724 case MSIM_TYPE_BINARY: |
724 gs = (GString *)elem->data; | 725 gs = (GString *)elem->data; |
725 /* Do not escape! */ | 726 /* Do not escape! */ |
726 return purple_base64_encode((guchar *)gs->str, gs->len); | 727 return purple_base64_encode((guchar *)gs->str, gs->len); |
727 | 728 |
728 case MSIM_TYPE_BOOLEAN: | 729 case MSIM_TYPE_BOOLEAN: |
729 /* Not used by messages in the wire protocol * -- see msim_msg_pack_element. | 730 /* Not used by messages in the wire protocol * -- see msim_msg_pack_element. |
730 * Only used by dictionaries, see msim_msg_pack_element_dict. */ | 731 * Only used by dictionaries, see msim_msg_pack_element_dict. */ |
731 return elem->data ? g_strdup("On") : g_strdup("Off"); | 732 return elem->data ? g_strdup("On") : g_strdup("Off"); |
732 | 733 |
733 case MSIM_TYPE_DICTIONARY: | 734 case MSIM_TYPE_DICTIONARY: |
734 /* TODO: pack using k=v\034k2=v2\034... */ | 735 /* TODO: pack using k=v\034k2=v2\034... */ |
735 return msim_msg_pack_dict((MsimMessage *)elem->data); | 736 return msim_msg_pack_dict((MsimMessage *)elem->data); |
736 | 737 |
737 case MSIM_TYPE_LIST: | 738 case MSIM_TYPE_LIST: |
738 /* Pack using a|b|c|d|... */ | 739 /* Pack using a|b|c|d|... */ |
739 gs = g_string_new(""); | 740 gs = g_string_new(""); |
740 | 741 |
741 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) { | 742 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) { |
742 g_string_append_printf(gs, "%s", (gchar*)(gl->data)); | 743 g_string_append_printf(gs, "%s", (gchar*)(gl->data)); |
743 | 744 |
744 /* All but last element is separated by a bar. */ | 745 /* All but last element is separated by a bar. */ |
745 if (g_list_next(gl)) | 746 if (g_list_next(gl)) |
746 g_string_append(gs, "|"); | 747 g_string_append(gs, "|"); |
747 } | 748 } |
748 | 749 |
749 return gs->str; | 750 return gs->str; |
750 | 751 |
751 default: | 752 default: |
752 purple_debug_info("msim", "field %s, unknown type %d\n", | 753 purple_debug_info("msim", "field %s, unknown type %d\n", |
753 elem->name ? elem->name : "(NULL)", | 754 elem->name ? elem->name : "(NULL)", |
754 elem->type); | 755 elem->type); |
755 return NULL; | 756 return NULL; |
756 } | 757 } |
757 } | 758 } |
758 | 759 |
759 /** Pack an element into its protcol representation inside a dictionary. | 760 /** Pack an element into its protcol representation inside a dictionary. |
761 * See msim_msg_pack_element(). | 762 * See msim_msg_pack_element(). |
762 */ | 763 */ |
763 static void | 764 static void |
764 msim_msg_pack_element_dict(gpointer data, gpointer user_data) | 765 msim_msg_pack_element_dict(gpointer data, gpointer user_data) |
765 { | 766 { |
766 MsimMessageElement *elem; | 767 MsimMessageElement *elem; |
767 gchar *string, *data_string, ***items; | 768 gchar *string, *data_string, ***items; |
768 | 769 |
769 elem = (MsimMessageElement *)data; | 770 elem = (MsimMessageElement *)data; |
770 items = (gchar ***)user_data; | 771 items = (gchar ***)user_data; |
771 | 772 |
772 /* Exclude elements beginning with '_' from packed protocol messages. */ | 773 /* Exclude elements beginning with '_' from packed protocol messages. */ |
773 if (elem->name[0] == '_') { | 774 if (elem->name[0] == '_') { |
774 return; | 775 return; |
775 } | 776 } |
776 | 777 |
777 data_string = msim_msg_pack_element_data(elem); | 778 data_string = msim_msg_pack_element_data(elem); |
778 | 779 |
779 g_return_if_fail(data_string != NULL); | 780 g_return_if_fail(data_string != NULL); |
780 | 781 |
781 switch (elem->type) { | 782 switch (elem->type) { |
782 /* These types are represented by key name/value pairs (converted above). */ | 783 /* These types are represented by key name/value pairs (converted above). */ |
783 case MSIM_TYPE_INTEGER: | 784 case MSIM_TYPE_INTEGER: |
784 case MSIM_TYPE_RAW: | 785 case MSIM_TYPE_RAW: |
785 case MSIM_TYPE_STRING: | 786 case MSIM_TYPE_STRING: |
786 case MSIM_TYPE_BINARY: | 787 case MSIM_TYPE_BINARY: |
787 case MSIM_TYPE_DICTIONARY: | 788 case MSIM_TYPE_DICTIONARY: |
788 case MSIM_TYPE_LIST: | 789 case MSIM_TYPE_LIST: |
789 case MSIM_TYPE_BOOLEAN: /* Boolean is On or Off */ | 790 case MSIM_TYPE_BOOLEAN: /* Boolean is On or Off */ |
790 string = g_strconcat(elem->name, "=", data_string, NULL); | 791 string = g_strconcat(elem->name, "=", data_string, NULL); |
791 break; | 792 break; |
792 | 793 |
793 default: | 794 default: |
794 g_free(data_string); | 795 g_free(data_string); |
881 * @return A string; caller must g_free(). | 882 * @return A string; caller must g_free(). |
882 */ | 883 */ |
883 gchar * | 884 gchar * |
884 msim_msg_pack_dict(MsimMessage *msg) | 885 msim_msg_pack_dict(MsimMessage *msg) |
885 { | 886 { |
886 g_return_val_if_fail(msg != NULL, NULL); | 887 g_return_val_if_fail(msg != NULL, NULL); |
887 | 888 |
888 return msim_msg_pack_using(msg, msim_msg_pack_element_dict, "\034", "", ""); | 889 return msim_msg_pack_using(msg, msim_msg_pack_element_dict, "\034", "", ""); |
889 } | 890 } |
890 | 891 |
891 /** | 892 /** |
892 * Parse a raw protocol message string into a MsimMessage *. | 893 * Parse a raw protocol message string into a MsimMessage *. |
893 * | 894 * |
897 */ | 898 */ |
898 MsimMessage * | 899 MsimMessage * |
899 msim_parse(gchar *raw) | 900 msim_parse(gchar *raw) |
900 { | 901 { |
901 MsimMessage *msg; | 902 MsimMessage *msg; |
902 gchar *token; | 903 gchar *token; |
903 gchar **tokens; | 904 gchar **tokens; |
904 gchar *key; | 905 gchar *key; |
905 gchar *value; | 906 gchar *value; |
906 int i; | 907 int i; |
907 | 908 |
908 g_return_val_if_fail(raw != NULL, NULL); | 909 g_return_val_if_fail(raw != NULL, NULL); |
909 | 910 |
910 purple_debug_info("msim", "msim_parse: got <%s>\n", raw); | 911 purple_debug_info("msim", "msim_parse: got <%s>\n", raw); |
911 | 912 |
912 key = NULL; | 913 key = NULL; |
913 | 914 |
914 /* All messages begin with a \. */ | 915 /* All messages begin with a \. */ |
915 if (raw[0] != '\\' || raw[1] == 0) { | 916 if (raw[0] != '\\' || raw[1] == 0) { |
916 purple_debug_info("msim", "msim_parse: incomplete/bad string, " | 917 purple_debug_info("msim", "msim_parse: incomplete/bad string, " |
917 "missing initial backslash: <%s>\n", raw); | 918 "missing initial backslash: <%s>\n", raw); |
918 /* XXX: Should we try to recover, and read to first backslash? */ | 919 /* XXX: Should we try to recover, and read to first backslash? */ |
919 | 920 |
920 g_free(raw); | 921 g_free(raw); |
921 return NULL; | 922 return NULL; |
922 } | 923 } |
923 | 924 |
924 msg = msim_msg_new(FALSE); | 925 msg = msim_msg_new(FALSE); |
925 | 926 |
926 for (tokens = g_strsplit(raw + 1, "\\", 0), i = 0; | 927 for (tokens = g_strsplit(raw + 1, "\\", 0), i = 0; |
927 (token = tokens[i]); | 928 (token = tokens[i]); |
928 i++) { | 929 i++) { |
929 #ifdef MSIM_DEBUG_PARSE | 930 #ifdef MSIM_DEBUG_PARSE |
930 purple_debug_info("msim", "tok=<%s>, i%2=%d\n", token, i % 2); | 931 purple_debug_info("msim", "tok=<%s>, i%2=%d\n", token, i % 2); |
931 #endif | 932 #endif |
932 if (i % 2) { | 933 if (i % 2) { |
933 /* Odd-numbered ordinal is a value. */ | 934 /* Odd-numbered ordinal is a value. */ |
934 | 935 |
935 value = token; | 936 value = token; |
936 | 937 |
937 /* Incoming protocol messages get tagged as MSIM_TYPE_RAW, which | 938 /* Incoming protocol messages get tagged as MSIM_TYPE_RAW, which |
939 * convert to appropriate types for caller, and handle unescaping if needed. */ | 940 * convert to appropriate types for caller, and handle unescaping if needed. */ |
940 msg = msim_msg_append(msg, g_strdup(key), MSIM_TYPE_RAW, g_strdup(value)); | 941 msg = msim_msg_append(msg, g_strdup(key), MSIM_TYPE_RAW, g_strdup(value)); |
941 #ifdef MSIM_DEBUG_PARSE | 942 #ifdef MSIM_DEBUG_PARSE |
942 purple_debug_info("msim", "insert string: |%s|=|%s|\n", key, value); | 943 purple_debug_info("msim", "insert string: |%s|=|%s|\n", key, value); |
943 #endif | 944 #endif |
944 } else { | 945 } else { |
945 /* Even numbered indexes are key names. */ | 946 /* Even numbered indexes are key names. */ |
946 key = token; | 947 key = token; |
947 } | 948 } |
948 } | 949 } |
949 g_strfreev(tokens); | 950 g_strfreev(tokens); |
950 | 951 |
951 /* Can free now since all data was copied to hash key/values */ | 952 /* Can free now since all data was copied to hash key/values */ |
952 g_free(raw); | 953 g_free(raw); |
953 | 954 |
954 return msg; | 955 return msg; |
955 } | 956 } |
956 | 957 |
957 /** | 958 /** |
958 * Parse a \x1c-separated "dictionary" of key=value pairs into a hash table. | 959 * Parse a \x1c-separated "dictionary" of key=value pairs into a hash table. |
959 * | 960 * |
960 * @param body_str The text of the dictionary to parse. Often the | 961 * @param body_str The text of the dictionary to parse. Often the |
961 * value for the 'body' field. | 962 * value for the 'body' field. |
962 * | 963 * |
963 * @return Hash table of the keys and values. Must g_hash_table_destroy() when done. | 964 * @return Hash table of the keys and values. Must g_hash_table_destroy() when done. |
964 */ | 965 */ |
965 GHashTable * | 966 GHashTable * |
966 msim_parse_body(const gchar *body_str) | 967 msim_parse_body(const gchar *body_str) |
967 { | 968 { |
968 GHashTable *table; | 969 GHashTable *table; |
969 gchar *item; | 970 gchar *item; |
970 gchar **items; | 971 gchar **items; |
971 gchar **elements; | 972 gchar **elements; |
972 guint i; | 973 guint i; |
973 | 974 |
974 g_return_val_if_fail(body_str != NULL, NULL); | 975 g_return_val_if_fail(body_str != NULL, NULL); |
975 | 976 |
976 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | 977 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
977 | 978 |
978 for (items = g_strsplit(body_str, "\x1c", 0), i = 0; | 979 for (items = g_strsplit(body_str, "\x1c", 0), i = 0; |
979 (item = items[i]); | 980 (item = items[i]); |
980 i++) { | 981 i++) { |
981 gchar *key, *value; | 982 gchar *key, *value; |
982 | 983 |
983 elements = g_strsplit(item, "=", 2); | 984 elements = g_strsplit(item, "=", 2); |
984 | 985 |
985 key = elements[0]; | 986 key = elements[0]; |
986 if (!key) { | 987 if (!key) { |
987 purple_debug_info("msim", "msim_parse_body(%s): null key\n", | 988 purple_debug_info("msim", "msim_parse_body(%s): null key\n", |
988 body_str); | 989 body_str); |
989 g_strfreev(elements); | 990 g_strfreev(elements); |
990 break; | 991 break; |
991 } | 992 } |
992 | 993 |
993 value = elements[1]; | 994 value = elements[1]; |
994 if (!value) { | 995 if (!value) { |
995 purple_debug_info("msim", "msim_parse_body(%s): null value\n", | 996 purple_debug_info("msim", "msim_parse_body(%s): null value\n", |
996 body_str); | 997 body_str); |
997 g_strfreev(elements); | 998 g_strfreev(elements); |
998 break; | 999 break; |
999 } | 1000 } |
1000 | 1001 |
1001 #ifdef MSIM_DEBUG_PARSE | 1002 #ifdef MSIM_DEBUG_PARSE |
1002 purple_debug_info("msim", "-- %s: %s\n", key ? key : "(NULL)", | 1003 purple_debug_info("msim", "-- %s: %s\n", key ? key : "(NULL)", |
1003 value ? value : "(NULL)"); | 1004 value ? value : "(NULL)"); |
1004 #endif | 1005 #endif |
1005 | 1006 |
1006 /* XXX: This overwrites duplicates. */ | 1007 /* XXX: This overwrites duplicates. */ |
1007 /* TODO: make the GHashTable values be GList's, and append to the list if | 1008 /* TODO: make the GHashTable values be GList's, and append to the list if |
1008 * there is already a value of the same key name. This is important for | 1009 * there is already a value of the same key name. This is important for |
1009 * the WebChallenge message. */ | 1010 * the WebChallenge message. */ |
1010 g_hash_table_insert(table, g_strdup(key), g_strdup(value)); | 1011 g_hash_table_insert(table, g_strdup(key), g_strdup(value)); |
1011 | 1012 |
1012 g_strfreev(elements); | 1013 g_strfreev(elements); |
1013 } | 1014 } |
1014 | 1015 |
1015 g_strfreev(items); | 1016 g_strfreev(items); |
1016 | 1017 |
1017 return table; | 1018 return table; |
1018 } | 1019 } |
1019 | 1020 |
1020 /** Search for and return the node in msg, matching name, or NULL. | 1021 /** Search for and return the node in msg, matching name, or NULL. |
1021 * | 1022 * |
1022 * @param msg Message to search within. | 1023 * @param msg Message to search within. |
1044 elem = i->data; | 1045 elem = i->data; |
1045 g_return_val_if_fail(elem != NULL, NULL); | 1046 g_return_val_if_fail(elem != NULL, NULL); |
1046 | 1047 |
1047 if (strcmp(elem->name, name) == 0) { | 1048 if (strcmp(elem->name, name) == 0) { |
1048 return i; | 1049 return i; |
1049 } | 1050 } |
1050 } | 1051 } |
1051 return NULL; | 1052 return NULL; |
1052 } | 1053 } |
1053 | 1054 |
1054 /** Return the first MsimMessageElement * with given name in the MsimMessage *. | 1055 /** Return the first MsimMessageElement * with given name in the MsimMessage *. |
1067 GList *node; | 1068 GList *node; |
1068 | 1069 |
1069 node = msim_msg_get_node(msg, name); | 1070 node = msim_msg_get_node(msg, name); |
1070 if (node) { | 1071 if (node) { |
1071 return (MsimMessageElement *)node->data; | 1072 return (MsimMessageElement *)node->data; |
1072 } else { | 1073 } else { |
1073 return NULL; | 1074 return NULL; |
1074 } | 1075 } |
1075 } | 1076 } |
1076 | 1077 |
1077 /** Return the data of an element of a given name, as a string. | 1078 /** Return the data of an element of a given name, as a string. |
1078 * | 1079 * |
1079 * @param name Name of element. | 1080 * @param name Name of element. |
1088 msim_msg_get_string(MsimMessage *msg, const gchar *name) | 1089 msim_msg_get_string(MsimMessage *msg, const gchar *name) |
1089 { | 1090 { |
1090 MsimMessageElement *elem; | 1091 MsimMessageElement *elem; |
1091 | 1092 |
1092 elem = msim_msg_get(msg, name); | 1093 elem = msim_msg_get(msg, name); |
1093 g_return_val_if_fail(elem != NULL , NULL); | 1094 g_return_val_if_fail(elem != NULL , NULL); |
1094 | 1095 |
1095 switch (elem->type) { | 1096 switch (elem->type) { |
1096 case MSIM_TYPE_INTEGER: | 1097 case MSIM_TYPE_INTEGER: |
1097 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); | 1098 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); |
1098 | 1099 |
1114 | 1115 |
1115 /** Return an element as a new list. Caller frees with msim_msg_list_free(). */ | 1116 /** Return an element as a new list. Caller frees with msim_msg_list_free(). */ |
1116 GList * | 1117 GList * |
1117 msim_msg_get_list(MsimMessage *msg, const gchar *name) | 1118 msim_msg_get_list(MsimMessage *msg, const gchar *name) |
1118 { | 1119 { |
1119 MsimMessageElement *elem; | 1120 MsimMessageElement *elem; |
1120 | 1121 |
1121 elem = msim_msg_get(msg, name); | 1122 elem = msim_msg_get(msg, name); |
1122 if (!elem) { | 1123 if (!elem) { |
1123 return NULL; | 1124 return NULL; |
1124 } | 1125 } |
1125 | 1126 |
1126 switch (elem->type) { | 1127 switch (elem->type) { |
1127 case MSIM_TYPE_LIST: | 1128 case MSIM_TYPE_LIST: |
1128 return msim_msg_list_copy((GList *)elem->data); | 1129 return msim_msg_list_copy((GList *)elem->data); |
1129 | 1130 |
1130 case MSIM_TYPE_RAW: | 1131 case MSIM_TYPE_RAW: |
1131 return msim_msg_list_parse((gchar *)elem->data); | 1132 return msim_msg_list_parse((gchar *)elem->data); |
1132 | 1133 |
1133 default: | 1134 default: |
1134 purple_debug_info("msim_msg_get_list", "type %d unknown, name %s\n", | 1135 purple_debug_info("msim_msg_get_list", "type %d unknown, name %s\n", |
1135 elem->type, name ? name : "(NULL)"); | 1136 elem->type, name ? name : "(NULL)"); |
1136 return NULL; | 1137 return NULL; |
1137 } | 1138 } |
1138 } | 1139 } |
1139 | 1140 |
1140 /** Parse a \034-deliminated and =-separated string into a dictionary. TODO */ | 1141 /** Parse a \034-deliminated and =-separated string into a dictionary. TODO */ |
1141 MsimMessage * | 1142 MsimMessage * |
1142 msim_msg_dictionary_parse(gchar *raw) | 1143 msim_msg_dictionary_parse(gchar *raw) |
1143 { | 1144 { |
1144 /* TODO - get code from msim_parse_body, but parse into MsimMessage */ | 1145 /* TODO - get code from msim_parse_body, but parse into MsimMessage */ |
1145 return NULL; | 1146 return NULL; |
1146 } | 1147 } |
1147 | 1148 |
1148 /** Return an element as a new dictionary. Caller frees with msim_msg_free(). */ | 1149 /** Return an element as a new dictionary. Caller frees with msim_msg_free(). */ |
1149 MsimMessage * | 1150 MsimMessage * |
1150 msim_msg_get_dictionary(MsimMessage *msg, const gchar *name) | 1151 msim_msg_get_dictionary(MsimMessage *msg, const gchar *name) |
1151 { | 1152 { |
1152 MsimMessageElement *elem; | 1153 MsimMessageElement *elem; |
1153 | 1154 |
1154 elem = msim_msg_get(msg, name); | 1155 elem = msim_msg_get(msg, name); |
1155 if (!elem) | 1156 if (!elem) { |
1156 { | 1157 return NULL; |
1157 return NULL; | 1158 } |
1158 } | 1159 |
1159 | 1160 switch (elem->type) { |
1160 switch (elem->type) { | 1161 case MSIM_TYPE_DICTIONARY: |
1161 case MSIM_TYPE_DICTIONARY: | 1162 return msim_msg_clone((MsimMessage *)elem->data); |
1162 return msim_msg_clone((MsimMessage *)elem->data); | 1163 |
1163 | 1164 case MSIM_TYPE_RAW: |
1164 case MSIM_TYPE_RAW: | 1165 return msim_msg_dictionary_parse((gchar *)elem->data); |
1165 return msim_msg_dictionary_parse((gchar *)elem->data); | 1166 |
1166 | 1167 default: |
1167 default: | 1168 purple_debug_info("msim_msg_get_dictionary", "type %d unknown, name %s\n", |
1168 purple_debug_info("msim_msg_get_dictionary", "type %d unknown, name %s\n", | 1169 elem->type, name ? name : "(NULL)"); |
1169 elem->type, name ? name : "(NULL)"); | 1170 return NULL; |
1170 return NULL; | 1171 } |
1171 } | |
1172 } | 1172 } |
1173 | 1173 |
1174 /** Return the data of an element of a given name, as an integer. | 1174 /** Return the data of an element of a given name, as an integer. |
1175 * | 1175 * |
1176 * @param name Name of element. | 1176 * @param name Name of element. |
1188 | 1188 |
1189 elem = msim_msg_get(msg, name); | 1189 elem = msim_msg_get(msg, name); |
1190 | 1190 |
1191 if (!elem) { | 1191 if (!elem) { |
1192 return 0; | 1192 return 0; |
1193 } | 1193 } |
1194 | 1194 |
1195 switch (elem->type) { | 1195 switch (elem->type) { |
1196 case MSIM_TYPE_INTEGER: | 1196 case MSIM_TYPE_INTEGER: |
1197 return GPOINTER_TO_UINT(elem->data); | 1197 return GPOINTER_TO_UINT(elem->data); |
1198 | 1198 |
1218 msim_msg_get_binary(MsimMessage *msg, const gchar *name, | 1218 msim_msg_get_binary(MsimMessage *msg, const gchar *name, |
1219 gchar **binary_data, gsize *binary_length) | 1219 gchar **binary_data, gsize *binary_length) |
1220 { | 1220 { |
1221 MsimMessageElement *elem; | 1221 MsimMessageElement *elem; |
1222 | 1222 |
1223 GString *gs; | 1223 GString *gs; |
1224 | 1224 |
1225 elem = msim_msg_get(msg, name); | 1225 elem = msim_msg_get(msg, name); |
1226 if (!elem) { | 1226 if (!elem) { |
1227 return FALSE; | 1227 return FALSE; |
1228 } | 1228 } |
1229 | 1229 |
1230 switch (elem->type) { | 1230 switch (elem->type) { |
1231 case MSIM_TYPE_RAW: | 1231 case MSIM_TYPE_RAW: |
1232 /* Incoming messages are tagged with MSIM_TYPE_RAW, and | 1232 /* Incoming messages are tagged with MSIM_TYPE_RAW, and |
1233 * converted appropriately. They can still be "strings", just they won't | 1233 * converted appropriately. They can still be "strings", just they won't |
1251 */ | 1251 */ |
1252 *binary_data = (gchar *)purple_base64_decode((const gchar *)elem->data, binary_length); | 1252 *binary_data = (gchar *)purple_base64_decode((const gchar *)elem->data, binary_length); |
1253 return TRUE; | 1253 return TRUE; |
1254 | 1254 |
1255 case MSIM_TYPE_BINARY: | 1255 case MSIM_TYPE_BINARY: |
1256 gs = (GString *)elem->data; | 1256 gs = (GString *)elem->data; |
1257 | 1257 |
1258 /* Duplicate data, so caller can g_free() it. */ | 1258 /* Duplicate data, so caller can g_free() it. */ |
1259 *binary_data = g_new0(char, gs->len); | 1259 *binary_data = g_new0(char, gs->len); |
1260 memcpy(*binary_data, gs->str, gs->len); | 1260 memcpy(*binary_data, gs->str, gs->len); |
1261 | 1261 |
1262 *binary_length = gs->len; | 1262 *binary_length = gs->len; |
1263 | 1263 |
1264 return TRUE; | 1264 return TRUE; |
1265 | 1265 |
1266 | 1266 |
1267 /* Rejected because if it isn't already a GString, have to g_new0 it and | 1267 /* Rejected because if it isn't already a GString, have to g_new0 it and |
1268 * then caller has to ALSO free the GString! | 1268 * then caller has to ALSO free the GString! |
1269 * | 1269 * |