Mercurial > pidgin
comparison libpurple/protocols/myspace/message.c @ 18890:00499df91ffe
Use cuddled if's etc. everywhere, to better match style of Pidgin/libpurple.
author | Jeffrey Connelly <jaconnel@calpoly.edu> |
---|---|
date | Sat, 11 Aug 2007 04:34:20 +0000 |
parents | a3a5b2e9079a |
children | 7db556e97dd1 |
comparison
equal
deleted
inserted
replaced
18889:a3a5b2e9079a | 18890:00499df91ffe |
---|---|
29 static GList *msim_msg_get_node(MsimMessage *msg, const gchar *name); | 29 static GList *msim_msg_get_node(MsimMessage *msg, const gchar *name); |
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 { | |
36 gchar *code; | 35 gchar *code; |
37 gchar *text; | 36 gchar *text; |
38 } msim_escape_replacements[] = { | 37 } msim_escape_replacements[] = { |
39 { "/1", "/" }, | 38 { "/1", "/" }, |
40 { "/2", "\\" }, | 39 { "/2", "\\" }, |
57 guint i; | 56 guint i; |
58 struct MSIM_ESCAPE_REPLACEMENT* replacement; | 57 struct MSIM_ESCAPE_REPLACEMENT* replacement; |
59 | 58 |
60 /* Replace each code in msim_replacement_code with | 59 /* Replace each code in msim_replacement_code with |
61 * corresponding entry in msim_replacement_text. */ | 60 * corresponding entry in msim_replacement_text. */ |
62 for (i = 0; (replacement = &msim_escape_replacements[i]); ++i) | 61 for (i = 0; (replacement = &msim_escape_replacements[i]); ++i) { |
63 { | |
64 gchar *code, *text; | 62 gchar *code, *text; |
65 | 63 |
66 code = replacement->code; | 64 code = replacement->code; |
67 text = replacement->text; | 65 text = replacement->text; |
68 | 66 |
69 if (!code || !text) | 67 if (!code || !text) |
70 break; | 68 break; |
71 | 69 |
72 if (escape) | 70 if (escape) { |
73 { | |
74 tmp = str_replace(msg, text, code); | 71 tmp = str_replace(msg, text, code); |
75 } | 72 } else { |
76 else | |
77 { | |
78 tmp = str_replace(msg, code, text); | 73 tmp = str_replace(msg, code, text); |
79 } | 74 } |
80 g_free(msg); | 75 g_free(msg); |
81 msg = tmp; | 76 msg = tmp; |
82 } | 77 } |
113 { | 108 { |
114 va_list argp; | 109 va_list argp; |
115 | 110 |
116 va_start(argp, not_empty); | 111 va_start(argp, not_empty); |
117 | 112 |
118 if (not_empty) | 113 if (not_empty) { |
119 return msim_msg_new_v(argp); | 114 return msim_msg_new_v(argp); |
120 else | 115 } else { |
121 return NULL; | 116 return NULL; |
117 } | |
122 } | 118 } |
123 | 119 |
124 /** Create a new message from va_list and its first argument. | 120 /** Create a new message from va_list and its first argument. |
125 * | 121 * |
126 * @param argp A va_list of variadic arguments, already started with va_start(). Will be va_end()'d. | 122 * @param argp A va_list of variadic arguments, already started with va_start(). Will be va_end()'d. |
133 { | 129 { |
134 gchar *key, *value; | 130 gchar *key, *value; |
135 MsimMessageType type; | 131 MsimMessageType type; |
136 MsimMessage *msg; | 132 MsimMessage *msg; |
137 | 133 |
134 GString *gs; | |
135 GList *gl; | |
136 MsimMessage *dict; | |
137 | |
138 | |
138 /* Begin with an empty message. */ | 139 /* Begin with an empty message. */ |
139 msg = NULL; | 140 msg = NULL; |
140 | 141 |
141 /* Read key, type, value triplets until NULL. */ | 142 /* Read key, type, value triplets until NULL. */ |
142 do | 143 do { |
143 { | |
144 key = va_arg(argp, gchar *); | 144 key = va_arg(argp, gchar *); |
145 if (!key) | 145 if (!key) { |
146 { | |
147 break; | 146 break; |
148 } | 147 } |
149 | 148 |
150 type = va_arg(argp, int); | 149 type = va_arg(argp, int); |
151 | 150 |
152 /* Interpret variadic arguments. */ | 151 /* Interpret variadic arguments. */ |
153 switch (type) | 152 switch (type) { |
154 { | |
155 case MSIM_TYPE_INTEGER: | 153 case MSIM_TYPE_INTEGER: |
156 case MSIM_TYPE_BOOLEAN: | 154 case MSIM_TYPE_BOOLEAN: |
157 msg = msim_msg_append(msg, key, type, GUINT_TO_POINTER(va_arg(argp, int))); | 155 msg = msim_msg_append(msg, key, type, GUINT_TO_POINTER(va_arg(argp, int))); |
158 break; | 156 break; |
159 | 157 |
164 | 162 |
165 msg = msim_msg_append(msg, key, type, value); | 163 msg = msim_msg_append(msg, key, type, value); |
166 break; | 164 break; |
167 | 165 |
168 case MSIM_TYPE_BINARY: | 166 case MSIM_TYPE_BINARY: |
169 { | 167 gs = va_arg(argp, GString *); |
170 GString *gs; | 168 |
171 | 169 g_return_val_if_fail(gs != NULL, FALSE); |
172 gs = va_arg(argp, GString *); | 170 |
173 | 171 /* msim_msg_free() will free this GString the caller created. */ |
174 g_return_val_if_fail(gs != NULL, FALSE); | 172 msg = msim_msg_append(msg, key, type, gs); |
175 | 173 break; |
176 /* msim_msg_free() will free this GString the caller created. */ | 174 |
177 msg = msim_msg_append(msg, key, type, gs); | |
178 break; | |
179 } | |
180 | |
181 case MSIM_TYPE_LIST: | 175 case MSIM_TYPE_LIST: |
182 { | 176 gl = va_arg(argp, GList *); |
183 GList *gl; | 177 |
184 | 178 g_return_val_if_fail(gl != NULL, FALSE); |
185 gl = va_arg(argp, GList *); | 179 |
186 | 180 msg = msim_msg_append(msg, key, type, gl); |
187 g_return_val_if_fail(gl != NULL, FALSE); | 181 break; |
188 | |
189 msg = msim_msg_append(msg, key, type, gl); | |
190 break; | |
191 } | |
192 | 182 |
193 case MSIM_TYPE_DICTIONARY: | 183 case MSIM_TYPE_DICTIONARY: |
194 { | 184 dict = va_arg(argp, MsimMessage *); |
195 MsimMessage *dict; | 185 |
196 | 186 g_return_val_if_fail(dict != NULL, FALSE); |
197 dict = va_arg(argp, MsimMessage *); | 187 |
198 | 188 msg = msim_msg_append(msg, key, type, dict); |
199 g_return_val_if_fail(dict != NULL, FALSE); | 189 break; |
200 | |
201 msg = msim_msg_append(msg, key, type, dict); | |
202 break; | |
203 } | |
204 | 190 |
205 default: | 191 default: |
206 purple_debug_info("msim", "msim_send: unknown type %d\n", type); | 192 purple_debug_info("msim", "msim_send: unknown type %d\n", type); |
207 break; | 193 break; |
208 } | 194 } |
219 GList *new_list; | 205 GList *new_list; |
220 | 206 |
221 new_list = NULL; | 207 new_list = NULL; |
222 | 208 |
223 /* Deep copy (g_list_copy is shallow). Copy each string. */ | 209 /* Deep copy (g_list_copy is shallow). Copy each string. */ |
224 for (; old != NULL; old = g_list_next(old)) | 210 for (; old != NULL; old = g_list_next(old)) { |
225 { | |
226 new_list = g_list_append(new_list, g_strdup(old->data)); | 211 new_list = g_list_append(new_list, g_strdup(old->data)); |
227 } | 212 } |
228 | 213 |
229 return new_list; | 214 return new_list; |
230 } | 215 } |
232 /** Free a GList * of gchar * strings. */ | 217 /** Free a GList * of gchar * strings. */ |
233 void | 218 void |
234 msim_msg_list_free(GList *l) | 219 msim_msg_list_free(GList *l) |
235 { | 220 { |
236 | 221 |
237 for (; l != NULL; l = g_list_next(l)) | 222 for (; l != NULL; l = g_list_next(l)) { |
238 { | |
239 g_free((gchar *)(l->data)); | 223 g_free((gchar *)(l->data)); |
240 } | 224 } |
241 g_list_free(l); | 225 g_list_free(l); |
242 } | 226 } |
243 | 227 |
249 GList *list; | 233 GList *list; |
250 guint i; | 234 guint i; |
251 | 235 |
252 array = g_strsplit(raw, "|", 0); | 236 array = g_strsplit(raw, "|", 0); |
253 list = NULL; | 237 list = NULL; |
238 | |
239 /* TODO: escape/unescape /3 <-> | within list elements */ | |
254 | 240 |
255 for (i = 0; array[i] != NULL; ++i) | 241 for (i = 0; array[i] != NULL; ++i) { |
256 { | |
257 list = g_list_append(list, g_strdup(array[i])); | 242 list = g_list_append(list, g_strdup(array[i])); |
258 } | 243 } |
259 | 244 |
260 g_strfreev(array); | 245 g_strfreev(array); |
261 | 246 |
271 msim_msg_clone_element(gpointer data, gpointer user_data) | 256 msim_msg_clone_element(gpointer data, gpointer user_data) |
272 { | 257 { |
273 MsimMessageElement *elem; | 258 MsimMessageElement *elem; |
274 MsimMessage **new; | 259 MsimMessage **new; |
275 gpointer new_data; | 260 gpointer new_data; |
261 | |
262 GString *gs; | |
263 MsimMessage *dict; | |
276 | 264 |
277 elem = (MsimMessageElement *)data; | 265 elem = (MsimMessageElement *)data; |
278 new = (MsimMessage **)user_data; | 266 new = (MsimMessage **)user_data; |
279 | 267 |
280 switch (elem->type) | 268 switch (elem->type) { |
281 { | |
282 case MSIM_TYPE_BOOLEAN: | 269 case MSIM_TYPE_BOOLEAN: |
283 case MSIM_TYPE_INTEGER: | 270 case MSIM_TYPE_INTEGER: |
284 new_data = elem->data; | 271 new_data = elem->data; |
285 break; | 272 break; |
286 | 273 |
292 case MSIM_TYPE_LIST: | 279 case MSIM_TYPE_LIST: |
293 new_data = (gpointer)msim_msg_list_copy((GList *)(elem->data)); | 280 new_data = (gpointer)msim_msg_list_copy((GList *)(elem->data)); |
294 break; | 281 break; |
295 | 282 |
296 case MSIM_TYPE_BINARY: | 283 case MSIM_TYPE_BINARY: |
297 { | 284 gs = (GString *)elem->data; |
298 GString *gs; | 285 |
299 | 286 new_data = g_string_new_len(gs->str, gs->len); |
300 gs = (GString *)elem->data; | |
301 | |
302 new_data = g_string_new_len(gs->str, gs->len); | |
303 } | |
304 break; | 287 break; |
305 case MSIM_TYPE_DICTIONARY: | 288 case MSIM_TYPE_DICTIONARY: |
306 { | 289 dict = (MsimMessage *)elem->data; |
307 MsimMessage *dict; | 290 |
308 | 291 new_data = msim_msg_clone(dict); |
309 dict = (MsimMessage *)elem->data; | |
310 | |
311 new_data = msim_msg_clone(dict); | |
312 } | |
313 break; | 292 break; |
314 | 293 |
315 default: | 294 default: |
316 purple_debug_info("msim", "msim_msg_clone_element: unknown type %d\n", elem->type); | 295 purple_debug_info("msim", "msim_msg_clone_element: unknown type %d\n", elem->type); |
317 g_return_if_fail(NULL); | 296 g_return_if_fail(NULL); |
329 MsimMessage * | 308 MsimMessage * |
330 msim_msg_clone(MsimMessage *old) | 309 msim_msg_clone(MsimMessage *old) |
331 { | 310 { |
332 MsimMessage *new; | 311 MsimMessage *new; |
333 | 312 |
334 if (old == NULL) | 313 if (old == NULL) { |
335 return NULL; | 314 return NULL; |
315 } | |
336 | 316 |
337 new = msim_msg_new(FALSE); | 317 new = msim_msg_new(FALSE); |
338 | 318 |
339 g_list_foreach(old, msim_msg_clone_element, &new); | 319 g_list_foreach(old, msim_msg_clone_element, &new); |
340 | 320 |
349 * element itself with g_free() (see msim_msg_free_element()). | 329 * element itself with g_free() (see msim_msg_free_element()). |
350 */ | 330 */ |
351 void | 331 void |
352 msim_msg_free_element_data(MsimMessageElement *elem) | 332 msim_msg_free_element_data(MsimMessageElement *elem) |
353 { | 333 { |
354 switch (elem->type) | 334 switch (elem->type) { |
355 { | |
356 case MSIM_TYPE_BOOLEAN: | 335 case MSIM_TYPE_BOOLEAN: |
357 case MSIM_TYPE_INTEGER: | 336 case MSIM_TYPE_INTEGER: |
358 /* Integer value stored in gpointer - no need to free(). */ | 337 /* Integer value stored in gpointer - no need to free(). */ |
359 break; | 338 break; |
360 | 339 |
406 | 385 |
407 /** Free a complete message. */ | 386 /** Free a complete message. */ |
408 void | 387 void |
409 msim_msg_free(MsimMessage *msg) | 388 msim_msg_free(MsimMessage *msg) |
410 { | 389 { |
411 if (!msg) | 390 if (!msg) { |
412 { | |
413 /* already free as can be */ | 391 /* already free as can be */ |
414 return; | 392 return; |
415 } | 393 } |
416 | 394 |
417 msim_msg_dump("msim_msg_free: freeing %s", msg); | 395 msim_msg_dump("msim_msg_free: freeing %s", msg); |
570 joined = g_strjoinv(sep, strings); | 548 joined = g_strjoinv(sep, strings); |
571 final = g_strconcat(begin, joined, end, NULL); | 549 final = g_strconcat(begin, joined, end, NULL); |
572 g_free(joined); | 550 g_free(joined); |
573 | 551 |
574 /* Clean up. */ | 552 /* Clean up. */ |
575 for (i = 0; i < g_list_length(msg); ++i) | 553 for (i = 0; i < g_list_length(msg); ++i) { |
576 { | |
577 g_free(strings[i]); | 554 g_free(strings[i]); |
578 } | 555 } |
579 | 556 |
580 g_free(strings); | 557 g_free(strings); |
581 | 558 |
592 MsimMessageElement *elem; | 569 MsimMessageElement *elem; |
593 gchar *string; | 570 gchar *string; |
594 GString *gs; | 571 GString *gs; |
595 gchar *binary; | 572 gchar *binary; |
596 gchar ***items; /* wow, a pointer to a pointer to a pointer */ | 573 gchar ***items; /* wow, a pointer to a pointer to a pointer */ |
574 | |
575 gchar *s; | |
576 GList *gl; | |
577 guint i; | |
597 | 578 |
598 elem = (MsimMessageElement *)data; | 579 elem = (MsimMessageElement *)data; |
599 items = user_data; | 580 items = user_data; |
600 | 581 |
601 switch (elem->type) | 582 switch (elem->type) { |
602 { | |
603 case MSIM_TYPE_INTEGER: | 583 case MSIM_TYPE_INTEGER: |
604 string = g_strdup_printf("%s(integer): %d", elem->name, | 584 string = g_strdup_printf("%s(integer): %d", elem->name, |
605 GPOINTER_TO_UINT(elem->data)); | 585 GPOINTER_TO_UINT(elem->data)); |
606 break; | 586 break; |
607 | 587 |
626 string = g_strdup_printf("%s(boolean): %s", elem->name, | 606 string = g_strdup_printf("%s(boolean): %s", elem->name, |
627 elem->data ? "TRUE" : "FALSE"); | 607 elem->data ? "TRUE" : "FALSE"); |
628 break; | 608 break; |
629 | 609 |
630 case MSIM_TYPE_DICTIONARY: | 610 case MSIM_TYPE_DICTIONARY: |
631 { | 611 if (!elem->data) |
632 gchar *s; | 612 s = g_strdup("(NULL)"); |
633 | 613 else |
634 if (!elem->data) | 614 s = msim_msg_dump_to_str((MsimMessage *)elem->data); |
635 s = g_strdup("(NULL)"); | 615 |
636 else | 616 if (!s) |
637 s = msim_msg_dump_to_str((MsimMessage *)elem->data); | 617 s = g_strdup("(NULL, couldn't msim_msg_dump_to_str)"); |
638 | 618 |
639 if (!s) | 619 string = g_strdup_printf("%s(dict): %s", elem->name, s); |
640 s = g_strdup("(NULL, couldn't msim_msg_dump_to_str)"); | 620 |
641 | 621 g_free(s); |
642 string = g_strdup_printf("%s(dict): %s", elem->name, s); | |
643 | |
644 g_free(s); | |
645 } | |
646 break; | 622 break; |
647 | 623 |
648 case MSIM_TYPE_LIST: | 624 case MSIM_TYPE_LIST: |
625 gs = g_string_new(""); | |
626 g_string_append_printf(gs, "%s(list): \n", elem->name); | |
627 | |
628 i = 0; | |
629 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) | |
649 { | 630 { |
650 GString *gs; | 631 g_string_append_printf(gs, " %d. %s\n", i, (gchar *)(gl->data)); |
651 GList *gl; | 632 ++i; |
652 guint i; | |
653 | |
654 gs = g_string_new(""); | |
655 g_string_append_printf(gs, "%s(list): \n", elem->name); | |
656 | |
657 i = 0; | |
658 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) | |
659 { | |
660 g_string_append_printf(gs, " %d. %s\n", i, (gchar *)(gl->data)); | |
661 ++i; | |
662 } | |
663 | |
664 string = gs->str; | |
665 } | 633 } |
634 | |
635 string = gs->str; | |
666 break; | 636 break; |
667 | 637 |
668 default: | 638 default: |
669 string = g_strdup_printf("%s(unknown type %d", | 639 string = g_strdup_printf("%s(unknown type %d", |
670 elem->name ? elem->name : "(NULL)", elem->type); | 640 elem->name ? elem->name : "(NULL)", elem->type); |
705 gchar * | 675 gchar * |
706 msim_msg_dump_to_str(MsimMessage *msg) | 676 msim_msg_dump_to_str(MsimMessage *msg) |
707 { | 677 { |
708 gchar *debug_str; | 678 gchar *debug_str; |
709 | 679 |
710 if (!msg) | 680 if (!msg) { |
711 { | |
712 debug_str = g_strdup("<MsimMessage: empty>"); | 681 debug_str = g_strdup("<MsimMessage: empty>"); |
713 } else { | 682 } else { |
714 debug_str = msim_msg_pack_using(msg, msim_msg_debug_string_element, | 683 debug_str = msim_msg_pack_using(msg, msim_msg_debug_string_element, |
715 "\n", "<MsimMessage: \n", "\n/MsimMessage>"); | 684 "\n", "<MsimMessage: \n", "\n/MsimMessage>"); |
716 } | 685 } |
727 * msim_msg_get_string() if you want a string, which in some cases is same as this. | 696 * msim_msg_get_string() if you want a string, which in some cases is same as this. |
728 */ | 697 */ |
729 gchar * | 698 gchar * |
730 msim_msg_pack_element_data(MsimMessageElement *elem) | 699 msim_msg_pack_element_data(MsimMessageElement *elem) |
731 { | 700 { |
701 GString *gs; | |
702 GList *gl; | |
703 | |
732 g_return_val_if_fail(elem != NULL, NULL); | 704 g_return_val_if_fail(elem != NULL, NULL); |
733 | 705 |
734 switch (elem->type) | 706 switch (elem->type) { |
735 { | |
736 case MSIM_TYPE_INTEGER: | 707 case MSIM_TYPE_INTEGER: |
737 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); | 708 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); |
738 | 709 |
739 case MSIM_TYPE_RAW: | 710 case MSIM_TYPE_RAW: |
740 /* Not un-escaped - this is a raw element, already escaped if necessary. */ | 711 /* Not un-escaped - this is a raw element, already escaped if necessary. */ |
745 g_return_val_if_fail(elem->data != NULL, NULL); | 716 g_return_val_if_fail(elem->data != NULL, NULL); |
746 return elem->data ? msim_escape((gchar *)elem->data) : | 717 return elem->data ? msim_escape((gchar *)elem->data) : |
747 g_strdup("(NULL)"); | 718 g_strdup("(NULL)"); |
748 | 719 |
749 case MSIM_TYPE_BINARY: | 720 case MSIM_TYPE_BINARY: |
750 { | 721 gs = (GString *)elem->data; |
751 GString *gs; | 722 /* Do not escape! */ |
752 | 723 return purple_base64_encode((guchar *)gs->str, gs->len); |
753 gs = (GString *)elem->data; | |
754 /* Do not escape! */ | |
755 return purple_base64_encode((guchar *)gs->str, gs->len); | |
756 } | |
757 | 724 |
758 case MSIM_TYPE_BOOLEAN: | 725 case MSIM_TYPE_BOOLEAN: |
759 /* Not used by messages in the wire protocol * -- see msim_msg_pack_element. | 726 /* Not used by messages in the wire protocol * -- see msim_msg_pack_element. |
760 * Only used by dictionaries, see msim_msg_pack_element_dict. */ | 727 * Only used by dictionaries, see msim_msg_pack_element_dict. */ |
761 return elem->data ? g_strdup("On") : g_strdup("Off"); | 728 return elem->data ? g_strdup("On") : g_strdup("Off"); |
764 /* TODO: pack using k=v\034k2=v2\034... */ | 731 /* TODO: pack using k=v\034k2=v2\034... */ |
765 return msim_msg_pack_dict((MsimMessage *)elem->data); | 732 return msim_msg_pack_dict((MsimMessage *)elem->data); |
766 | 733 |
767 case MSIM_TYPE_LIST: | 734 case MSIM_TYPE_LIST: |
768 /* Pack using a|b|c|d|... */ | 735 /* Pack using a|b|c|d|... */ |
769 { | 736 gs = g_string_new(""); |
770 GString *gs; | 737 |
771 GList *gl; | 738 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) { |
772 | 739 g_string_append_printf(gs, "%s", (gchar*)(gl->data)); |
773 gs = g_string_new(""); | |
774 | |
775 for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl)) | |
776 { | |
777 g_string_append_printf(gs, "%s", (gchar*)(gl->data)); | |
778 | |
779 /* All but last element is separated by a bar. */ | |
780 if (g_list_next(gl)) | |
781 g_string_append(gs, "|"); | |
782 } | |
783 | 740 |
784 return gs->str; | 741 /* All but last element is separated by a bar. */ |
742 if (g_list_next(gl)) | |
743 g_string_append(gs, "|"); | |
785 } | 744 } |
745 | |
746 return gs->str; | |
786 | 747 |
787 default: | 748 default: |
788 purple_debug_info("msim", "field %s, unknown type %d\n", | 749 purple_debug_info("msim", "field %s, unknown type %d\n", |
789 elem->name ? elem->name : "(NULL)", | 750 elem->name ? elem->name : "(NULL)", |
790 elem->type); | 751 elem->type); |
804 | 765 |
805 elem = (MsimMessageElement *)data; | 766 elem = (MsimMessageElement *)data; |
806 items = (gchar ***)user_data; | 767 items = (gchar ***)user_data; |
807 | 768 |
808 /* Exclude elements beginning with '_' from packed protocol messages. */ | 769 /* Exclude elements beginning with '_' from packed protocol messages. */ |
809 if (elem->name[0] == '_') | 770 if (elem->name[0] == '_') { |
810 { | |
811 return; | 771 return; |
812 } | 772 } |
813 | 773 |
814 data_string = msim_msg_pack_element_data(elem); | 774 data_string = msim_msg_pack_element_data(elem); |
815 | 775 |
816 g_return_if_fail(data_string != NULL); | 776 g_return_if_fail(data_string != NULL); |
817 | 777 |
818 switch (elem->type) | 778 switch (elem->type) { |
819 { | |
820 /* These types are represented by key name/value pairs (converted above). */ | 779 /* These types are represented by key name/value pairs (converted above). */ |
821 case MSIM_TYPE_INTEGER: | 780 case MSIM_TYPE_INTEGER: |
822 case MSIM_TYPE_RAW: | 781 case MSIM_TYPE_RAW: |
823 case MSIM_TYPE_STRING: | 782 case MSIM_TYPE_STRING: |
824 case MSIM_TYPE_BINARY: | 783 case MSIM_TYPE_BINARY: |
859 | 818 |
860 elem = (MsimMessageElement *)data; | 819 elem = (MsimMessageElement *)data; |
861 items = (gchar ***)user_data; | 820 items = (gchar ***)user_data; |
862 | 821 |
863 /* Exclude elements beginning with '_' from packed protocol messages. */ | 822 /* Exclude elements beginning with '_' from packed protocol messages. */ |
864 if (elem->name[0] == '_') | 823 if (elem->name[0] == '_') { |
865 { | |
866 return; | 824 return; |
867 } | 825 } |
868 | 826 |
869 data_string = msim_msg_pack_element_data(elem); | 827 data_string = msim_msg_pack_element_data(elem); |
870 | 828 |
871 switch (elem->type) | 829 switch (elem->type) { |
872 { | |
873 /* These types are represented by key name/value pairs (converted above). */ | 830 /* These types are represented by key name/value pairs (converted above). */ |
874 case MSIM_TYPE_INTEGER: | 831 case MSIM_TYPE_INTEGER: |
875 case MSIM_TYPE_RAW: | 832 case MSIM_TYPE_RAW: |
876 case MSIM_TYPE_STRING: | 833 case MSIM_TYPE_STRING: |
877 case MSIM_TYPE_BINARY: | 834 case MSIM_TYPE_BINARY: |
880 string = g_strconcat(elem->name, "\\", data_string, NULL); | 837 string = g_strconcat(elem->name, "\\", data_string, NULL); |
881 break; | 838 break; |
882 | 839 |
883 /* Boolean is represented by absence or presence of name. */ | 840 /* Boolean is represented by absence or presence of name. */ |
884 case MSIM_TYPE_BOOLEAN: | 841 case MSIM_TYPE_BOOLEAN: |
885 if (GPOINTER_TO_UINT(elem->data)) | 842 if (GPOINTER_TO_UINT(elem->data)) { |
886 { | |
887 /* True - leave in, with blank value. */ | 843 /* True - leave in, with blank value. */ |
888 string = g_strdup_printf("%s\\", elem->name); | 844 string = g_strdup_printf("%s\\", elem->name); |
889 } else { | 845 } else { |
890 /* False - leave out. */ | 846 /* False - leave out. */ |
891 string = g_strdup(""); | 847 string = g_strdup(""); |
951 purple_debug_info("msim", "msim_parse: got <%s>\n", raw); | 907 purple_debug_info("msim", "msim_parse: got <%s>\n", raw); |
952 | 908 |
953 key = NULL; | 909 key = NULL; |
954 | 910 |
955 /* All messages begin with a \. */ | 911 /* All messages begin with a \. */ |
956 if (raw[0] != '\\' || raw[1] == 0) | 912 if (raw[0] != '\\' || raw[1] == 0) { |
957 { | |
958 purple_debug_info("msim", "msim_parse: incomplete/bad string, " | 913 purple_debug_info("msim", "msim_parse: incomplete/bad string, " |
959 "missing initial backslash: <%s>\n", raw); | 914 "missing initial backslash: <%s>\n", raw); |
960 /* XXX: Should we try to recover, and read to first backslash? */ | 915 /* XXX: Should we try to recover, and read to first backslash? */ |
961 | 916 |
962 g_free(raw); | 917 g_free(raw); |
965 | 920 |
966 msg = msim_msg_new(FALSE); | 921 msg = msim_msg_new(FALSE); |
967 | 922 |
968 for (tokens = g_strsplit(raw + 1, "\\", 0), i = 0; | 923 for (tokens = g_strsplit(raw + 1, "\\", 0), i = 0; |
969 (token = tokens[i]); | 924 (token = tokens[i]); |
970 i++) | 925 i++) { |
971 { | |
972 #ifdef MSIM_DEBUG_PARSE | 926 #ifdef MSIM_DEBUG_PARSE |
973 purple_debug_info("msim", "tok=<%s>, i%2=%d\n", token, i % 2); | 927 purple_debug_info("msim", "tok=<%s>, i%2=%d\n", token, i % 2); |
974 #endif | 928 #endif |
975 if (i % 2) | 929 if (i % 2) { |
976 { | |
977 /* Odd-numbered ordinal is a value. */ | 930 /* Odd-numbered ordinal is a value. */ |
978 | 931 |
979 value = token; | 932 value = token; |
980 | 933 |
981 /* Incoming protocol messages get tagged as MSIM_TYPE_RAW, which | 934 /* Incoming protocol messages get tagged as MSIM_TYPE_RAW, which |
1019 | 972 |
1020 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); | 973 table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); |
1021 | 974 |
1022 for (items = g_strsplit(body_str, "\x1c", 0), i = 0; | 975 for (items = g_strsplit(body_str, "\x1c", 0), i = 0; |
1023 (item = items[i]); | 976 (item = items[i]); |
1024 i++) | 977 i++) { |
1025 { | |
1026 gchar *key, *value; | 978 gchar *key, *value; |
1027 | 979 |
1028 elements = g_strsplit(item, "=", 2); | 980 elements = g_strsplit(item, "=", 2); |
1029 | 981 |
1030 key = elements[0]; | 982 key = elements[0]; |
1031 if (!key) | 983 if (!key) { |
1032 { | |
1033 purple_debug_info("msim", "msim_parse_body(%s): null key\n", | 984 purple_debug_info("msim", "msim_parse_body(%s): null key\n", |
1034 body_str); | 985 body_str); |
1035 g_strfreev(elements); | 986 g_strfreev(elements); |
1036 break; | 987 break; |
1037 } | 988 } |
1038 | 989 |
1039 value = elements[1]; | 990 value = elements[1]; |
1040 if (!value) | 991 if (!value) { |
1041 { | |
1042 purple_debug_info("msim", "msim_parse_body(%s): null value\n", | 992 purple_debug_info("msim", "msim_parse_body(%s): null value\n", |
1043 body_str); | 993 body_str); |
1044 g_strfreev(elements); | 994 g_strfreev(elements); |
1045 break; | 995 break; |
1046 } | 996 } |
1078 static GList * | 1028 static GList * |
1079 msim_msg_get_node(MsimMessage *msg, const gchar *name) | 1029 msim_msg_get_node(MsimMessage *msg, const gchar *name) |
1080 { | 1030 { |
1081 GList *i; | 1031 GList *i; |
1082 | 1032 |
1083 if (!name) | 1033 if (!name) { |
1084 { | |
1085 return NULL; | 1034 return NULL; |
1086 } | 1035 } |
1087 | 1036 |
1088 /* Linear search for the given name. O(n) but n is small. */ | 1037 /* Linear search for the given name. O(n) but n is small. */ |
1089 for (i = g_list_first(msg); i != NULL; i = g_list_next(i)) | 1038 for (i = g_list_first(msg); i != NULL; i = g_list_next(i)) { |
1090 { | |
1091 MsimMessageElement *elem; | 1039 MsimMessageElement *elem; |
1092 | 1040 |
1093 elem = i->data; | 1041 elem = i->data; |
1094 g_return_val_if_fail(elem != NULL, NULL); | 1042 g_return_val_if_fail(elem != NULL, NULL); |
1095 | 1043 |
1096 if (strcmp(elem->name, name) == 0) | 1044 if (strcmp(elem->name, name) == 0) { |
1097 return i; | 1045 return i; |
1046 } | |
1098 } | 1047 } |
1099 return NULL; | 1048 return NULL; |
1100 } | 1049 } |
1101 | 1050 |
1102 /** Return the first MsimMessageElement * with given name in the MsimMessage *. | 1051 /** Return the first MsimMessageElement * with given name in the MsimMessage *. |
1113 msim_msg_get(MsimMessage *msg, const gchar *name) | 1062 msim_msg_get(MsimMessage *msg, const gchar *name) |
1114 { | 1063 { |
1115 GList *node; | 1064 GList *node; |
1116 | 1065 |
1117 node = msim_msg_get_node(msg, name); | 1066 node = msim_msg_get_node(msg, name); |
1118 if (node) | 1067 if (node) { |
1119 return (MsimMessageElement *)node->data; | 1068 return (MsimMessageElement *)node->data; |
1120 else | 1069 } else { |
1121 return NULL; | 1070 return NULL; |
1071 } | |
1122 } | 1072 } |
1123 | 1073 |
1124 /** Return the data of an element of a given name, as a string. | 1074 /** Return the data of an element of a given name, as a string. |
1125 * | 1075 * |
1126 * @param name Name of element. | 1076 * @param name Name of element. |
1137 MsimMessageElement *elem; | 1087 MsimMessageElement *elem; |
1138 | 1088 |
1139 elem = msim_msg_get(msg, name); | 1089 elem = msim_msg_get(msg, name); |
1140 g_return_val_if_fail(elem != NULL , NULL); | 1090 g_return_val_if_fail(elem != NULL , NULL); |
1141 | 1091 |
1142 switch (elem->type) | 1092 switch (elem->type) { |
1143 { | |
1144 case MSIM_TYPE_INTEGER: | 1093 case MSIM_TYPE_INTEGER: |
1145 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); | 1094 return g_strdup_printf("%d", GPOINTER_TO_UINT(elem->data)); |
1146 | 1095 |
1147 case MSIM_TYPE_RAW: | 1096 case MSIM_TYPE_RAW: |
1148 /* Raw element from incoming message - if its a string, it'll | 1097 /* Raw element from incoming message - if its a string, it'll |
1165 msim_msg_get_list(MsimMessage *msg, const gchar *name) | 1114 msim_msg_get_list(MsimMessage *msg, const gchar *name) |
1166 { | 1115 { |
1167 MsimMessageElement *elem; | 1116 MsimMessageElement *elem; |
1168 | 1117 |
1169 elem = msim_msg_get(msg, name); | 1118 elem = msim_msg_get(msg, name); |
1170 if (!elem) | 1119 if (!elem) { |
1171 return NULL; | 1120 return NULL; |
1172 | 1121 } |
1173 switch (elem->type) | 1122 |
1174 { | 1123 switch (elem->type) { |
1175 case MSIM_TYPE_LIST: | 1124 case MSIM_TYPE_LIST: |
1176 return msim_msg_list_copy((GList *)elem->data); | 1125 return msim_msg_list_copy((GList *)elem->data); |
1177 | 1126 |
1178 case MSIM_TYPE_RAW: | 1127 case MSIM_TYPE_RAW: |
1179 return msim_msg_list_parse((gchar *)elem->data); | 1128 return msim_msg_list_parse((gchar *)elem->data); |
1199 { | 1148 { |
1200 MsimMessageElement *elem; | 1149 MsimMessageElement *elem; |
1201 | 1150 |
1202 elem = msim_msg_get(msg, name); | 1151 elem = msim_msg_get(msg, name); |
1203 if (!elem) | 1152 if (!elem) |
1153 { | |
1204 return NULL; | 1154 return NULL; |
1205 | 1155 } |
1206 switch (elem->type) | 1156 |
1207 { | 1157 switch (elem->type) { |
1208 case MSIM_TYPE_DICTIONARY: | 1158 case MSIM_TYPE_DICTIONARY: |
1209 return msim_msg_clone((MsimMessage *)elem->data); | 1159 return msim_msg_clone((MsimMessage *)elem->data); |
1210 | 1160 |
1211 case MSIM_TYPE_RAW: | 1161 case MSIM_TYPE_RAW: |
1212 return msim_msg_dictionary_parse((gchar *)elem->data); | 1162 return msim_msg_dictionary_parse((gchar *)elem->data); |
1233 { | 1183 { |
1234 MsimMessageElement *elem; | 1184 MsimMessageElement *elem; |
1235 | 1185 |
1236 elem = msim_msg_get(msg, name); | 1186 elem = msim_msg_get(msg, name); |
1237 | 1187 |
1238 if (!elem) | 1188 if (!elem) { |
1239 return 0; | 1189 return 0; |
1240 | 1190 } |
1241 switch (elem->type) | 1191 |
1242 { | 1192 switch (elem->type) { |
1243 case MSIM_TYPE_INTEGER: | 1193 case MSIM_TYPE_INTEGER: |
1244 return GPOINTER_TO_UINT(elem->data); | 1194 return GPOINTER_TO_UINT(elem->data); |
1245 | 1195 |
1246 case MSIM_TYPE_RAW: | 1196 case MSIM_TYPE_RAW: |
1247 case MSIM_TYPE_STRING: | 1197 case MSIM_TYPE_STRING: |
1264 gboolean | 1214 gboolean |
1265 msim_msg_get_binary(MsimMessage *msg, const gchar *name, | 1215 msim_msg_get_binary(MsimMessage *msg, const gchar *name, |
1266 gchar **binary_data, gsize *binary_length) | 1216 gchar **binary_data, gsize *binary_length) |
1267 { | 1217 { |
1268 MsimMessageElement *elem; | 1218 MsimMessageElement *elem; |
1219 | |
1220 GString *gs; | |
1269 | 1221 |
1270 elem = msim_msg_get(msg, name); | 1222 elem = msim_msg_get(msg, name); |
1271 if (!elem) | 1223 if (!elem) { |
1272 return FALSE; | 1224 return FALSE; |
1273 | 1225 } |
1274 switch (elem->type) | 1226 |
1275 { | 1227 switch (elem->type) { |
1276 case MSIM_TYPE_RAW: | 1228 case MSIM_TYPE_RAW: |
1277 /* Incoming messages are tagged with MSIM_TYPE_RAW, and | 1229 /* Incoming messages are tagged with MSIM_TYPE_RAW, and |
1278 * converted appropriately. They can still be "strings", just they won't | 1230 * converted appropriately. They can still be "strings", just they won't |
1279 * be tagged as MSIM_TYPE_STRING (as MSIM_TYPE_STRING is intended to be used | 1231 * be tagged as MSIM_TYPE_STRING (as MSIM_TYPE_STRING is intended to be used |
1280 * by msimprpl code for things like instant messages - stuff that should be | 1232 * by msimprpl code for things like instant messages - stuff that should be |
1296 */ | 1248 */ |
1297 *binary_data = (gchar *)purple_base64_decode((const gchar *)elem->data, binary_length); | 1249 *binary_data = (gchar *)purple_base64_decode((const gchar *)elem->data, binary_length); |
1298 return TRUE; | 1250 return TRUE; |
1299 | 1251 |
1300 case MSIM_TYPE_BINARY: | 1252 case MSIM_TYPE_BINARY: |
1301 { | 1253 gs = (GString *)elem->data; |
1302 GString *gs; | 1254 |
1303 | 1255 /* Duplicate data, so caller can g_free() it. */ |
1304 gs = (GString *)elem->data; | 1256 *binary_data = g_new0(char, gs->len); |
1305 | 1257 memcpy(*binary_data, gs->str, gs->len); |
1306 /* Duplicate data, so caller can g_free() it. */ | 1258 |
1307 *binary_data = g_new0(char, gs->len); | 1259 *binary_length = gs->len; |
1308 memcpy(*binary_data, gs->str, gs->len); | 1260 |
1309 | 1261 return TRUE; |
1310 *binary_length = gs->len; | |
1311 | |
1312 return TRUE; | |
1313 } | |
1314 | 1262 |
1315 | 1263 |
1316 /* Rejected because if it isn't already a GString, have to g_new0 it and | 1264 /* Rejected because if it isn't already a GString, have to g_new0 it and |
1317 * then caller has to ALSO free the GString! | 1265 * then caller has to ALSO free the GString! |
1318 * | 1266 * |