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 *