initial load of upstream version 1.06.32
[xmlrpc-c] / src / test / value.c
1 /* Copyright information is at the end of the file. */
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <string.h>
6 #include <errno.h>
7
8 #include "casprintf.h"
9
10 #include "xmlrpc_config.h"
11
12 #include "xmlrpc-c/base.h"
13
14 #include "test.h"
15 #include "value.h"
16
17
18
19 /*=========================================================================
20 **  Test Data
21 **=========================================================================
22 **  Some common test data which need to be allocated at a fixed address,
23 **  or which are inconvenient to allocate inline.
24 */
25 static char* test_string_1 = "foo";
26
27
28
29 static void
30 test_value_alloc_dealloc(void) {
31
32     xmlrpc_value * v;
33     xmlrpc_env env;
34
35     xmlrpc_env_init(&env);
36
37     /* Test allocation and deallocation (w/memprof). */
38     v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5);
39     TEST_NO_FAULT(&env);
40     TEST(v != NULL);
41     xmlrpc_INCREF(v);
42     xmlrpc_DECREF(v);
43     xmlrpc_DECREF(v);
44
45     xmlrpc_env_clean(&env);
46 }
47
48
49 static void
50 test_value_integer(void) { 
51
52     xmlrpc_value * v;
53     xmlrpc_env env;
54     xmlrpc_int32 i;
55
56     xmlrpc_env_init(&env);
57
58     v = xmlrpc_int_new(&env, (xmlrpc_int32) 25);
59     TEST_NO_FAULT(&env);
60     TEST(XMLRPC_TYPE_INT == xmlrpc_value_type(v));
61     xmlrpc_read_int(&env, v, &i);
62     TEST_NO_FAULT(&env);
63     TEST(i == 25);
64     xmlrpc_DECREF(v);
65
66     v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 10);
67     TEST_NO_FAULT(&env);
68     TEST(v != NULL);
69     TEST(XMLRPC_TYPE_INT == xmlrpc_value_type(v));
70     xmlrpc_decompose_value(&env, v, "i", &i);
71     xmlrpc_DECREF(v);
72     TEST_NO_FAULT(&env);
73     TEST(i == 10);
74
75     xmlrpc_env_clean(&env);
76 }
77
78
79
80 static void
81 test_value_bool(void) {
82
83     xmlrpc_value * v;
84     xmlrpc_env env;
85     xmlrpc_bool b;
86
87     /* Test booleans. */
88
89     xmlrpc_env_init(&env);
90
91     v = xmlrpc_bool_new(&env, (xmlrpc_bool) 1);
92     TEST_NO_FAULT(&env);
93     TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v));
94     xmlrpc_read_bool(&env, v, &b);
95     TEST_NO_FAULT(&env);
96     TEST(b);
97     xmlrpc_DECREF(v);
98
99     v = xmlrpc_build_value(&env, "b", (xmlrpc_bool) 0);
100     TEST_NO_FAULT(&env);
101     TEST(v != NULL);
102     TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v));
103     xmlrpc_decompose_value(&env, v, "b", &b);
104     xmlrpc_DECREF(v);
105     TEST_NO_FAULT(&env);
106     TEST(!b);
107
108     xmlrpc_env_clean(&env);
109 }
110
111
112
113 static void
114 test_value_double(void) {
115
116     xmlrpc_value * v;
117     xmlrpc_env env;
118     double d;
119
120     xmlrpc_env_init(&env);
121
122     v = xmlrpc_double_new(&env, -3.25);
123     TEST_NO_FAULT(&env);
124     TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v));
125     xmlrpc_read_double(&env, v, &d);
126     TEST_NO_FAULT(&env);
127     TEST(d == -3.25);
128     xmlrpc_DECREF(v);
129
130     v = xmlrpc_build_value(&env, "d", 1.0);
131     TEST_NO_FAULT(&env);
132     TEST(v != NULL);
133     TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v));
134     xmlrpc_decompose_value(&env, v, "d", &d);
135     xmlrpc_DECREF(v);
136     TEST_NO_FAULT(&env);
137     TEST(d == 1.0);
138
139     xmlrpc_env_clean(&env);
140 }
141
142
143
144 static void
145 test_value_datetime(void) {
146
147     const char * datestring = "19980717T14:08:55";
148     time_t const datetime = 900684535;
149
150     xmlrpc_value * v;
151     xmlrpc_env env;
152     const char * ds;
153     time_t dt;
154
155     xmlrpc_env_init(&env);
156
157     v = xmlrpc_datetime_new_str(&env, datestring);
158     TEST_NO_FAULT(&env);
159     TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
160
161     xmlrpc_read_datetime_str(&env, v, &ds);
162     TEST_NO_FAULT(&env);
163     TEST(strcmp(ds, datestring) == 0);
164     strfree(ds);
165
166     xmlrpc_read_datetime_sec(&env, v, &dt);
167     TEST_NO_FAULT(&env);
168     TEST(dt == datetime);
169
170     xmlrpc_DECREF(v);
171
172     v = xmlrpc_datetime_new_sec(&env, datetime);
173     TEST_NO_FAULT(&env);
174     TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
175
176     xmlrpc_read_datetime_str(&env, v, &ds);
177     TEST_NO_FAULT(&env);
178     TEST(strcmp(ds, datestring) == 0);
179     strfree(ds);
180
181     xmlrpc_read_datetime_sec(&env, v, &dt);
182     TEST_NO_FAULT(&env);
183     TEST(dt == datetime);
184
185     xmlrpc_DECREF(v);
186
187     v = xmlrpc_build_value(&env, "8", datestring);
188     TEST_NO_FAULT(&env);
189     TEST(v != NULL);
190     TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
191     xmlrpc_decompose_value(&env, v, "8", &ds);
192     xmlrpc_DECREF(v);
193     TEST_NO_FAULT(&env);
194     TEST(strcmp(ds, datestring) == 0);
195     strfree(ds);
196
197     xmlrpc_env_clean(&env);
198 }
199
200
201
202 static void
203 test_value_string_no_null(void) {
204
205     xmlrpc_value * v;
206     xmlrpc_env env;
207     const char * str;
208     size_t len;
209
210     /* Test strings (without '\0' bytes). */
211     xmlrpc_env_init(&env);
212
213     v = xmlrpc_string_new(&env, test_string_1);
214     TEST_NO_FAULT(&env);
215     TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
216     xmlrpc_read_string(&env, v, &str);
217     TEST_NO_FAULT(&env);
218     TEST(strcmp(str, test_string_1) == 0);
219     xmlrpc_DECREF(v);
220     strfree(str);
221
222     v = xmlrpc_build_value(&env, "s", test_string_1);
223
224     TEST_NO_FAULT(&env);
225     TEST(v != NULL);
226     TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
227
228     xmlrpc_decompose_value(&env, v, "s", &str);
229     TEST_NO_FAULT(&env);
230     TEST(strcmp(str, test_string_1) == 0);
231     strfree(str);
232
233     xmlrpc_decompose_value(&env, v, "s#", &str, &len);
234     TEST_NO_FAULT(&env);
235     TEST(memcmp(str, test_string_1, strlen(test_string_1)) == 0);
236     TEST(strlen(str) == strlen(test_string_1));
237     strfree(str);
238
239     xmlrpc_DECREF(v);
240
241     xmlrpc_env_clean(&env);
242 }
243
244
245
246 static void
247 test_value_string_null(void) {
248
249     xmlrpc_value * v;
250     xmlrpc_env env;
251     xmlrpc_env env2;
252     const char * str;
253     size_t len;
254
255     /* Test a string with a '\0' byte. */
256
257     xmlrpc_env_init(&env);
258
259     v = xmlrpc_string_new_lp(&env, 7, "foo\0bar");
260     TEST_NO_FAULT(&env);
261     TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
262     xmlrpc_read_string_lp(&env, v, &len, &str);
263     TEST_NO_FAULT(&env);
264     TEST(len == 7);
265     TEST(memcmp(str, "foo\0bar", 7) == 0);
266     xmlrpc_DECREF(v);
267     strfree(str);
268
269     v = xmlrpc_build_value(&env, "s#", "foo\0bar", (size_t) 7);
270     TEST_NO_FAULT(&env);
271     TEST(v != NULL);
272     TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
273
274     xmlrpc_decompose_value(&env, v, "s#", &str, &len);
275     TEST_NO_FAULT(&env);
276     TEST(memcmp(str, "foo\0bar", 7) == 0);
277     TEST(len == 7);
278     strfree(str);
279
280     /* Test for type error when decoding a string with a zero byte to a
281     ** regular C string. */
282     xmlrpc_env_init(&env2);
283     xmlrpc_decompose_value(&env2, v, "s", &str);
284     TEST_FAULT(&env2, XMLRPC_TYPE_ERROR);
285     xmlrpc_env_clean(&env2);
286     xmlrpc_DECREF(v);
287
288     xmlrpc_env_clean(&env);
289 }
290
291
292
293 #if HAVE_UNICODE_WCHAR
294
295 /* Here is a 3-character, NUL-terminated string, once in UTF-8 chars,
296    and once in UTF-16 wchar_ts.  Note that 2 of the UTF-16 characters
297    translate directly to UTF-8 bytes because only the lower 7 bits of
298    each is nonzero, but the middle UTF-16 character translates to two
299    UTF-8 bytes.  
300 */
301 static char utf8_data[] = "[\xC2\xA9]";
302 static wchar_t wcs_data[] = {'[', 0x00A9, ']', 0x0000};
303
304 static void
305 test_value_string_wide_build(void) {
306
307     xmlrpc_env env;
308     xmlrpc_value * valueP;
309     const wchar_t * wcs;
310     size_t len;
311
312     xmlrpc_env_init(&env);
313
314     /* Build with build_value w# */
315     valueP = xmlrpc_build_value(&env, "w#", wcs_data, 3);
316     TEST_NO_FAULT(&env);
317     TEST(valueP != NULL);
318
319     /* Verify it */
320     xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
321     TEST_NO_FAULT(&env);
322     TEST(wcs != NULL);
323     TEST(len == 3);
324     TEST(wcs[len] == '\0');
325     TEST(0 == wcsncmp(wcs, wcs_data, len));
326     free((void*)wcs);
327
328     xmlrpc_DECREF(valueP);
329
330     /* Build with build_value w */
331     valueP = xmlrpc_build_value(&env, "w", wcs_data);
332     TEST_NO_FAULT(&env);
333     TEST(valueP != NULL);
334
335     /* Verify it */
336     xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
337     TEST_NO_FAULT(&env);
338     TEST(wcs != NULL);
339     TEST(len == 3);
340     TEST(wcs[len] == '\0');
341     TEST(0 == wcsncmp(wcs, wcs_data, len));
342     free((void*)wcs);
343
344     xmlrpc_DECREF(valueP);
345 }
346 #endif /* HAVE_UNICODE_WCHAR */
347
348
349 static void 
350 test_value_string_wide(void) {
351
352 #if HAVE_UNICODE_WCHAR
353     xmlrpc_env env;
354     xmlrpc_value * valueP;
355     const wchar_t * wcs;
356     size_t len;
357
358     xmlrpc_env_init(&env);
359
360     /* Build a string from wchar_t data. */
361     valueP = xmlrpc_string_w_new_lp(&env, 3, wcs_data);
362     TEST_NO_FAULT(&env);
363     TEST(valueP != NULL);
364
365     /* Extract it as a wchar_t string. */
366     xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
367     TEST_NO_FAULT(&env);
368     TEST(wcs != NULL);
369     TEST(len == 3);
370     TEST(wcs[len] == '\0');
371     TEST(0 == wcsncmp(wcs, wcs_data, len));
372     free((void*)wcs);
373
374     xmlrpc_read_string_w(&env, valueP, &wcs);
375     TEST_NO_FAULT(&env);
376     TEST(wcs != NULL);
377     TEST(wcs[3] == '\0');
378     TEST(0 == wcsncmp(wcs, wcs_data, 3));
379     free((void*)wcs);
380
381     xmlrpc_decompose_value(&env, valueP, "w#", &wcs, &len);
382     TEST_NO_FAULT(&env);
383     TEST(wcs != NULL);
384     TEST(len == 3);
385     TEST(wcs[len] == '\0');
386     TEST(0 == wcsncmp(wcs, wcs_data, len));
387     free((void*)wcs);
388
389     {
390         /* Extract it as a UTF-8 string. */
391         const char * str;
392         size_t len;
393
394         xmlrpc_read_string_lp(&env, valueP, &len, &str);
395         TEST_NO_FAULT(&env);
396         TEST(str != NULL);
397         TEST(len == 4);
398         TEST(str[len] == '\0');
399         TEST(0 == strncmp(str, utf8_data, len));
400         free((void*)str);
401     }
402
403     xmlrpc_DECREF(valueP);
404
405     /* Build from null-terminated wchar_t string */
406     valueP = xmlrpc_string_w_new(&env, wcs_data);
407     TEST_NO_FAULT(&env);
408     TEST(valueP != NULL);
409
410     /* Verify it */
411     xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
412     TEST_NO_FAULT(&env);
413     TEST(wcs != NULL);
414     TEST(len == 3);
415     TEST(wcs[len] == '\0');
416     TEST(0 == wcsncmp(wcs, wcs_data, len));
417     free((void*)wcs);
418
419     xmlrpc_DECREF(valueP);
420
421     test_value_string_wide_build();
422
423     /* Build a string from UTF-8 data. */
424     valueP = xmlrpc_string_new(&env, utf8_data);
425     TEST_NO_FAULT(&env);
426     TEST(valueP != NULL);
427
428     /* Extract it as a wchar_t string. */
429     xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
430     TEST_NO_FAULT(&env);
431     TEST(wcs != NULL);
432     TEST(len == 3);
433     TEST(wcs[len] == 0x0000);
434     TEST(0 == wcsncmp(wcs, wcs_data, len));
435     free((void*)wcs);
436     xmlrpc_DECREF(valueP);
437
438     /* Test with embedded NUL.  We use a length of 4 so that the terminating
439        NUL actually becomes part of the string.
440     */
441     valueP = xmlrpc_string_w_new_lp(&env, 4, wcs_data);
442     TEST_NO_FAULT(&env);
443     TEST(valueP != NULL);
444
445     /* Extract it as a wchar_t string. */
446     xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
447     TEST_NO_FAULT(&env);
448     TEST(wcs != NULL);
449     TEST(len == 4);
450     TEST(wcs[len] == '\0');
451     TEST(0 == wcsncmp(wcs, wcs_data, len));
452     free((void*)wcs);
453
454     xmlrpc_read_string_w(&env, valueP, &wcs);
455     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
456
457     xmlrpc_DECREF(valueP);
458 #endif /* HAVE_UNICODE_WCHAR */
459 }
460
461
462
463 static void
464 test_value_base64(void) {
465
466     /* Test <base64> data. */
467
468     unsigned char const data1[5] = {'a', '\0', 'b', '\n', 'c'};
469     unsigned char const data2[3] = {'a', '\0', 'b'};
470
471     xmlrpc_value * v;
472     xmlrpc_env env;
473     const unsigned char * data;
474     size_t len;
475
476     xmlrpc_env_init(&env);
477
478     v = xmlrpc_base64_new(&env, sizeof(data1), data1);
479     TEST_NO_FAULT(&env);
480     TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v));
481     xmlrpc_read_base64(&env, v, &len, &data);
482     TEST_NO_FAULT(&env);
483     TEST(memcmp(data, data1, sizeof(data1)) == 0);
484     TEST(len == sizeof(data1));
485     xmlrpc_DECREF(v);
486     free((void*)data);
487
488     v = xmlrpc_build_value(&env, "6", data2, sizeof(data2));
489     TEST_NO_FAULT(&env);
490     TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v));
491     xmlrpc_decompose_value(&env, v, "6", &data, &len);
492     xmlrpc_DECREF(v);
493     TEST_NO_FAULT(&env);
494     TEST(len == sizeof(data2));
495     TEST(memcmp(data, data1, sizeof(data2)) == 0);
496     strfree(data);
497
498     xmlrpc_env_clean(&env);
499 }
500
501
502
503 static void
504 test_value_value(void) {
505
506     xmlrpc_value *v, *v2, *v3;
507     xmlrpc_env env;
508
509     /* Test 'V' with building and parsing. */
510
511     xmlrpc_env_init(&env);
512
513     v2 = xmlrpc_int_new(&env, (xmlrpc_int32) 5);
514     TEST_NO_FAULT(&env);
515     v = xmlrpc_build_value(&env, "V", v2);
516     TEST_NO_FAULT(&env);
517     TEST(v == v2);
518     xmlrpc_decompose_value(&env, v2, "V", &v3);
519     xmlrpc_DECREF(v);
520     TEST_NO_FAULT(&env);
521     TEST(v2 == v3);
522     xmlrpc_DECREF(v3);
523     xmlrpc_DECREF(v2);
524
525     xmlrpc_env_clean(&env);
526 }
527
528
529
530 static void
531 test_value_array(void) {
532
533     xmlrpc_value *v;
534     xmlrpc_env env;
535     size_t len;
536
537     /* Basic array-building test. */
538
539     xmlrpc_env_init(&env);
540
541     v = xmlrpc_array_new(&env);
542     TEST_NO_FAULT(&env);
543     TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v));
544     len = xmlrpc_array_size(&env, v);
545     TEST_NO_FAULT(&env);
546     TEST(len == 0);
547     xmlrpc_DECREF(v);
548
549     v = xmlrpc_build_value(&env, "()");
550     TEST_NO_FAULT(&env);
551     TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v));
552     len = xmlrpc_array_size(&env, v);
553     TEST_NO_FAULT(&env);
554     TEST(len == 0);
555     xmlrpc_DECREF(v);
556
557     xmlrpc_env_clean(&env);
558 }
559
560
561
562 static void
563 test_value_AS(void) {
564
565     xmlrpc_value *v;
566     xmlrpc_value *v2;
567     xmlrpc_value *v3;
568     xmlrpc_env env;
569     size_t len;
570
571     /* Test parsing of 'A' and 'S'. */
572
573     xmlrpc_env_init(&env);
574
575     v = xmlrpc_build_value(&env, "((){})");
576     TEST_NO_FAULT(&env);
577     xmlrpc_decompose_value(&env, v, "(AS)", &v2, &v3);
578     xmlrpc_DECREF(v);
579     TEST_NO_FAULT(&env);
580     TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v2));
581     TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(v3));
582     len = xmlrpc_array_size(&env, v2);
583     TEST_NO_FAULT(&env);
584     TEST(len == 0);
585     len = xmlrpc_struct_size(&env, v3);
586     TEST_NO_FAULT(&env);
587     TEST(len == 0);
588     xmlrpc_DECREF(v2);
589     xmlrpc_DECREF(v3);
590
591     xmlrpc_env_clean(&env);
592 }
593
594
595
596 static void
597 test_value_AS_typecheck(void) {
598
599     xmlrpc_env env;
600     xmlrpc_env env2;
601     xmlrpc_value *v;
602     xmlrpc_value *v2;
603
604     /* Test typechecks for 'A' and 'S'. */
605
606     xmlrpc_env_init(&env);
607
608     v = xmlrpc_build_value(&env, "s", "foo");
609     TEST_NO_FAULT(&env);
610     xmlrpc_env_init(&env2);
611     xmlrpc_decompose_value(&env2, v, "A", &v2);
612     TEST_FAULT(&env2, XMLRPC_TYPE_ERROR);
613     xmlrpc_env_clean(&env2);
614
615     xmlrpc_env_init(&env2);
616     xmlrpc_decompose_value(&env2, v, "S", &v2);
617     TEST_FAULT(&env2, XMLRPC_TYPE_ERROR);
618     xmlrpc_env_clean(&env2);
619     xmlrpc_DECREF(v);
620     xmlrpc_env_clean(&env);
621 }
622
623
624
625 static void
626 test_value_array2(void) {
627
628     xmlrpc_value * arrayP;
629     xmlrpc_env env;
630     xmlrpc_int32 i, i1, i2, i3, i4;
631     xmlrpc_value * itemP;
632     xmlrpc_value * subarrayP;
633     size_t len;
634
635     /* A more complex array. */
636
637     xmlrpc_env_init(&env);
638
639     arrayP = xmlrpc_build_value(&env, "(i(ii)i)",
640                                 (xmlrpc_int32) 10, (xmlrpc_int32) 20,
641                                 (xmlrpc_int32) 30, (xmlrpc_int32) 40);
642     TEST_NO_FAULT(&env);
643     TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP));
644
645     len = xmlrpc_array_size(&env, arrayP);
646     TEST_NO_FAULT(&env);
647     TEST(len == 3);
648
649     xmlrpc_array_read_item(&env, arrayP, 1, &subarrayP);
650     TEST_NO_FAULT(&env);
651
652     len = xmlrpc_array_size(&env, subarrayP);
653     TEST_NO_FAULT(&env);
654     TEST(len == 2);
655
656     xmlrpc_array_read_item(&env, subarrayP, 0, &itemP);
657     TEST_NO_FAULT(&env);
658     xmlrpc_decompose_value(&env, itemP, "i", &i);
659     xmlrpc_DECREF(itemP);
660     TEST_NO_FAULT(&env);
661     TEST(i == 20);
662
663     xmlrpc_DECREF(subarrayP);
664
665     itemP = xmlrpc_array_get_item(&env, arrayP, 0);
666     TEST_NO_FAULT(&env);
667     xmlrpc_decompose_value(&env, itemP, "i", &i);
668     TEST_NO_FAULT(&env);
669     TEST(i == 10);
670
671     xmlrpc_decompose_value(&env, arrayP, "(i(ii)i)", &i1, &i2, &i3, &i4);
672     TEST_NO_FAULT(&env);
673     TEST(i1 == 10 && i2 == 20 && i3 == 30 && i4 == 40);
674
675     xmlrpc_decompose_value(&env, arrayP, "(i(i*)i)", &i1, &i2, &i3);
676     TEST_NO_FAULT(&env);
677     TEST(i1 == 10 && i2 == 20 && i3 == 40);
678
679     xmlrpc_decompose_value(&env, arrayP, "(i(ii*)i)", &i1, &i2, &i3, &i4);
680     TEST_NO_FAULT(&env);
681
682
683     /* Test bounds check on xmlrpc_array_get_item. */
684     xmlrpc_array_read_item(&env, arrayP, 3, &itemP);
685     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
686     xmlrpc_env_clean(&env);
687     xmlrpc_env_init(&env);
688
689     xmlrpc_array_get_item(&env, arrayP, 3);
690     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
691     xmlrpc_env_clean(&env);
692     xmlrpc_env_init(&env);
693
694     xmlrpc_array_get_item(&env, arrayP, -1);
695     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
696     xmlrpc_env_clean(&env);
697     xmlrpc_env_init(&env);
698
699     xmlrpc_DECREF(arrayP);
700
701     xmlrpc_env_clean(&env);
702 }
703
704
705
706 static void
707 test_value_array_nil(void) {
708
709     xmlrpc_value * arrayP;
710     xmlrpc_env env;
711     xmlrpc_int32 i1, i2;
712     xmlrpc_value * itemP;
713     size_t len;
714
715     xmlrpc_env_init(&env);
716
717     arrayP = xmlrpc_build_value(&env, "(nini)",
718                                 (xmlrpc_int32) 10, (xmlrpc_int32) 20);
719     TEST_NO_FAULT(&env);
720     TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP));
721
722     len = xmlrpc_array_size(&env, arrayP);
723     TEST_NO_FAULT(&env);
724     TEST(len == 4);
725
726     itemP = xmlrpc_array_get_item(&env, arrayP, 0);
727     TEST_NO_FAULT(&env);
728     xmlrpc_decompose_value(&env, itemP, "n");
729     TEST_NO_FAULT(&env);
730
731     itemP = xmlrpc_array_get_item(&env, arrayP, 1);
732     TEST_NO_FAULT(&env);
733     {
734         int i;
735         xmlrpc_decompose_value(&env, itemP, "i", &i);
736         TEST_NO_FAULT(&env);
737         TEST(i == 10);
738     }
739     xmlrpc_decompose_value(&env, arrayP, "(nini)", &i1, &i2);
740     TEST_NO_FAULT(&env);
741     TEST(i1 == 10 && i2 == 20);
742
743     /* Test bounds check on xmlrpc_array_get_item. */
744     xmlrpc_array_read_item(&env, arrayP, 4, &itemP);
745     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
746     xmlrpc_env_clean(&env);
747     xmlrpc_env_init(&env);
748
749     xmlrpc_array_get_item(&env, arrayP, 4);
750     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
751     xmlrpc_env_clean(&env);
752     xmlrpc_env_init(&env);
753
754     xmlrpc_DECREF(arrayP);
755
756     xmlrpc_env_clean(&env);
757 }
758
759
760
761 static void
762 test_value_type_mismatch(void) {
763
764     xmlrpc_value * v;
765     xmlrpc_env env;
766     xmlrpc_env env2;
767     char * str;
768
769     /* Test for one, simple kind of type mismatch error. We assume that
770     ** if one of these typechecks works, the rest work fine. */
771
772     xmlrpc_env_init(&env);
773
774     v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5);
775     TEST_NO_FAULT(&env);
776     xmlrpc_env_init(&env2);
777     xmlrpc_decompose_value(&env2, v, "s", &str);
778     xmlrpc_DECREF(v);
779     TEST_FAULT(&env2, XMLRPC_TYPE_ERROR);
780     xmlrpc_env_clean(&env2);
781
782     xmlrpc_env_clean(&env);
783 }
784
785
786
787 static void
788 test_value_cptr(void) {
789
790     xmlrpc_value * v;
791     xmlrpc_env env;
792     void * ptr;
793
794     /* Test C pointer storage using 'p'.
795        We don't have cleanup functions (yet). 
796     */
797
798     xmlrpc_env_init(&env);
799
800     v = xmlrpc_build_value(&env, "p", (void*) 0x00000017);
801     TEST_NO_FAULT(&env);
802     TEST(XMLRPC_TYPE_C_PTR == xmlrpc_value_type(v));
803     xmlrpc_decompose_value(&env, v, "p", &ptr);
804     xmlrpc_DECREF(v);
805     TEST_NO_FAULT(&env);
806     TEST(ptr == (void*) 0x00000017);
807
808     xmlrpc_env_clean(&env);
809 }
810
811
812
813 static void
814 test_value_nil(void) {
815
816     xmlrpc_value * v;
817     xmlrpc_env env;
818
819     xmlrpc_env_init(&env);
820
821     v = xmlrpc_nil_new(&env);
822     TEST_NO_FAULT(&env);
823     TEST(XMLRPC_TYPE_NIL == xmlrpc_value_type(v));
824     xmlrpc_DECREF(v);
825
826     v = xmlrpc_build_value(&env, "n");
827     TEST_NO_FAULT(&env);
828     TEST(XMLRPC_TYPE_NIL == xmlrpc_value_type(v));
829     xmlrpc_decompose_value(&env, v, "n");
830     xmlrpc_DECREF(v);
831     TEST_NO_FAULT(&env);
832
833     xmlrpc_env_clean(&env);
834 }
835
836
837
838 static void
839 test_value_invalid_type(void) {
840
841     xmlrpc_value * v;
842     xmlrpc_env env;
843
844     /* Test invalid type specifier in format string */
845
846     xmlrpc_env_init(&env);
847
848     v = xmlrpc_build_value(&env, "Q");
849     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
850
851     xmlrpc_env_clean(&env);
852 }
853
854
855
856 static void
857 test_value_missing_array_delim(void) {
858
859     xmlrpc_value * v;
860     xmlrpc_env env;
861
862     /* Test missing close parenthesis on array */
863
864     xmlrpc_env_init(&env);
865     v = xmlrpc_build_value(&env, "(");
866     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
867     xmlrpc_env_clean(&env);
868
869     xmlrpc_env_init(&env);
870     v = xmlrpc_build_value(&env, "(i");
871     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
872     xmlrpc_env_clean(&env);
873 }
874
875
876
877 static void
878 test_value_missing_struct_delim(void) {
879
880     xmlrpc_value * v;
881     xmlrpc_env env;
882     
883     /* Test missing closing brace on struct */
884
885     xmlrpc_env_init(&env);
886     v = xmlrpc_build_value(&env, "{");
887     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
888     xmlrpc_env_clean(&env);
889
890     xmlrpc_env_init(&env);
891     v = xmlrpc_build_value(&env, "{s:i", "key1", 7);
892     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
893     xmlrpc_env_clean(&env);
894
895     xmlrpc_env_init(&env);
896     v = xmlrpc_build_value(&env, "{s:i,s:i", "key1", 9, "key2", -4);
897     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
898     xmlrpc_env_clean(&env);
899 }
900
901
902
903 static void
904 test_value_invalid_struct(void) {
905
906     xmlrpc_value * v;
907     xmlrpc_env env;
908
909     /* Note that even though the format strings are invalid, we have
910        to supply the variable arguments that xmlrpc_build_value() will
911        be looking for as it tries to parse it.  Otherwise, we get wild
912        memory references and consequent Valgrind flags.
913     */
914     
915     xmlrpc_env_init(&env);
916     v = xmlrpc_build_value(&env, "{s:ii", "key1", 9, 9);
917     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
918     xmlrpc_env_clean(&env);
919
920     xmlrpc_env_init(&env);
921     v = xmlrpc_build_value(&env, "{si:", "key1", 9);
922     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
923     xmlrpc_env_clean(&env);
924
925     xmlrpc_env_init(&env);
926     v = xmlrpc_build_value(&env, "{s", "key1");
927     TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
928     xmlrpc_env_clean(&env);
929 }
930
931
932
933 static void
934 test_value_parse_value(void) {
935
936     xmlrpc_env env;
937     xmlrpc_value * valueP;
938     const char * datestring = "19980717T14:08:55";
939
940     xmlrpc_env_init(&env);
941
942     valueP = xmlrpc_build_value(&env, "(idb8ss#6(i){s:i}np(i))",
943                                 7, 3.14, (xmlrpc_bool)1, datestring,
944                                 "hello world", "a\0b", 3, 
945                                 "base64 data", strlen("base64 data"),
946                                 15, "member9", 9, &valueP, -5);
947     
948     TEST_NO_FAULT(&env);
949
950     {
951         xmlrpc_int32 i;
952         xmlrpc_double d;
953         xmlrpc_bool b;
954         const char * dt_str;
955         const char * s1;
956         const char * s2;
957         size_t s2_len;
958         const unsigned char * b64;
959         size_t b64_len;
960         xmlrpc_value * arrayP;
961         xmlrpc_value * structP;
962         void * cptr;
963         xmlrpc_value * subvalP;
964
965         xmlrpc_parse_value(&env, valueP, "(idb8ss#6ASnpV)",
966                            &i, &d, &b, &dt_str, &s1, &s2, &s2_len,
967                            &b64, &b64_len,
968                            &arrayP, &structP, &cptr, &subvalP);
969         
970         TEST_NO_FAULT(&env);
971
972         TEST(i == 7);
973         TEST(d == 3.14);
974         TEST(b == (xmlrpc_bool)1);
975         TEST(strcmp(dt_str, datestring) == 0);
976         TEST(strcmp(s1, "hello world") == 0);
977         TEST(s2_len == 3);
978         TEST(memcmp(s2, "a\0b", 3) == 0);
979         TEST(b64_len == strlen("base64 data"));
980         TEST(memcmp(b64, "base64 data", b64_len) == 0);
981         TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP));
982         TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(structP));
983         TEST(cptr == &valueP);
984         TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(subvalP));
985
986         xmlrpc_DECREF(valueP);
987     }
988     xmlrpc_env_clean(&env);
989 }
990
991
992
993 static void
994 test_struct_get_element(xmlrpc_value * const structP,
995                         xmlrpc_value * const i1,
996                         xmlrpc_value * const i2,
997                         const char *   const weirdKey,
998                         unsigned int   const weirdKeyLen) {
999
1000     xmlrpc_env env;
1001     xmlrpc_value * valueP;
1002     xmlrpc_value * aasStringP;
1003     xmlrpc_value * bogusKeyStringP;
1004
1005     xmlrpc_env_init(&env);
1006
1007     /* build test tools */
1008
1009     aasStringP = xmlrpc_build_value(&env, "s", "aas");
1010     TEST_NO_FAULT(&env);
1011
1012     bogusKeyStringP = xmlrpc_build_value(&env, "s", "doesn't_exist");
1013     TEST_NO_FAULT(&env);
1014
1015     /* "find" interface */
1016
1017     xmlrpc_struct_find_value(&env, structP, "aas", &valueP);
1018     TEST_NO_FAULT(&env);
1019     TEST(valueP == i1);
1020     xmlrpc_DECREF(valueP);
1021             
1022     xmlrpc_struct_find_value(&env, structP, "doesn't_exist", &valueP);
1023     TEST_NO_FAULT(&env);
1024     TEST(valueP == NULL);
1025             
1026     xmlrpc_struct_find_value_v(&env, structP, aasStringP, &valueP);
1027     TEST_NO_FAULT(&env);
1028     TEST(valueP == i1);
1029     xmlrpc_DECREF(valueP);
1030             
1031     xmlrpc_struct_find_value_v(&env, structP, bogusKeyStringP, &valueP);
1032     TEST_NO_FAULT(&env);
1033     TEST(valueP == NULL);
1034
1035     xmlrpc_struct_find_value(&env, i1, "aas", &valueP);
1036     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1037             
1038     /* "read" interface */
1039             
1040     xmlrpc_struct_read_value(&env, structP, "aas", &valueP);
1041     TEST_NO_FAULT(&env);
1042     TEST(valueP == i1);
1043     xmlrpc_DECREF(valueP);
1044             
1045     xmlrpc_struct_read_value(&env, structP, "doesn't_exist", &valueP);
1046     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1047             
1048     xmlrpc_struct_read_value_v(&env, structP, aasStringP, &valueP);
1049     TEST_NO_FAULT(&env);
1050     TEST(valueP == i1);
1051     xmlrpc_DECREF(valueP);
1052             
1053     xmlrpc_struct_read_value_v(&env, structP, bogusKeyStringP, &valueP);
1054     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1055
1056     xmlrpc_struct_read_value(&env, i1, "aas", &valueP);
1057     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1058             
1059     /* obsolete "get" interface.  Note that it does not update the
1060        reference count of the xmlrpc_value it returns.
1061     */
1062             
1063     valueP = xmlrpc_struct_get_value(&env, structP, "aas");
1064     TEST_NO_FAULT(&env);
1065     TEST(valueP == i1);
1066
1067     valueP = xmlrpc_struct_get_value(&env, structP, "doesn't_exist");
1068     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1069
1070     valueP = xmlrpc_struct_get_value(&env, i1, "foo");
1071     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1072
1073     valueP = xmlrpc_struct_get_value_n(&env, structP, weirdKey, weirdKeyLen);
1074     TEST_NO_FAULT(&env);
1075     TEST(valueP == i2);
1076
1077     /* Clean up */
1078
1079     xmlrpc_DECREF(aasStringP);
1080     xmlrpc_DECREF(bogusKeyStringP);
1081
1082     xmlrpc_env_clean(&env);
1083 }
1084
1085
1086
1087 static void
1088 testStructReadout(xmlrpc_value * const structP,
1089                   size_t         const expectedSize) {
1090
1091     xmlrpc_env env;
1092     xmlrpc_value * keyP;
1093     xmlrpc_value * valueP;
1094
1095     unsigned int index;
1096
1097     xmlrpc_env_init(&env);
1098
1099     for (index = 0; index < expectedSize; ++index) {
1100         xmlrpc_struct_read_member(&env, structP, index, &keyP, &valueP);
1101         TEST_NO_FAULT(&env);
1102         xmlrpc_DECREF(keyP);
1103         xmlrpc_DECREF(valueP);
1104     }
1105
1106     xmlrpc_struct_read_member(&env, structP, expectedSize, &keyP, &valueP);
1107     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1108     xmlrpc_env_clean(&env);
1109     xmlrpc_env_init(&env);
1110
1111     for (index = 0; index < expectedSize; ++index) {
1112         xmlrpc_struct_get_key_and_value(&env, structP, index, &keyP, &valueP);
1113         TEST_NO_FAULT(&env);
1114     }
1115     xmlrpc_env_clean(&env);
1116 }
1117
1118
1119
1120 static void
1121 test_struct (void) {
1122
1123     xmlrpc_env env;
1124     xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value;
1125     size_t size;
1126     int present;
1127     xmlrpc_int32 ival;
1128     xmlrpc_bool bval;
1129     char *sval;
1130     char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'};
1131
1132     xmlrpc_env_init(&env);
1133
1134     /* Create a struct. */
1135     s = xmlrpc_struct_new(&env);
1136     TEST_NO_FAULT(&env);
1137     TEST(s != NULL);
1138     TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
1139     size = xmlrpc_struct_size(&env, s);
1140     TEST_NO_FAULT(&env);
1141     TEST(size == 0);
1142
1143     /* Create some elements to insert into our struct. */
1144     i1 = xmlrpc_build_value(&env, "s", "Item #1");
1145     TEST_NO_FAULT(&env);
1146     i2 = xmlrpc_build_value(&env, "s", "Item #2");
1147     TEST_NO_FAULT(&env);
1148     i3 = xmlrpc_build_value(&env, "s", "Item #3");
1149     TEST_NO_FAULT(&env);
1150
1151     /* Insert a single item. */
1152     xmlrpc_struct_set_value(&env, s, "foo", i1);
1153     TEST_NO_FAULT(&env);
1154     size = xmlrpc_struct_size(&env, s);
1155     TEST_NO_FAULT(&env);
1156     TEST(size == 1);
1157
1158     /* Insert two more items with conflicting hash codes. (We assume that
1159     ** nobody has changed the hash function.) */
1160     xmlrpc_struct_set_value(&env, s, "bar", i2);
1161     TEST_NO_FAULT(&env);
1162     xmlrpc_struct_set_value(&env, s, "aas", i3);
1163     TEST_NO_FAULT(&env);
1164     size = xmlrpc_struct_size(&env, s);
1165     TEST_NO_FAULT(&env);
1166     TEST(size == 3);
1167
1168     /* Replace an existing element with a different element. */
1169     xmlrpc_struct_set_value(&env, s, "aas", i1);
1170     TEST_NO_FAULT(&env);
1171     size = xmlrpc_struct_size(&env, s);
1172     TEST_NO_FAULT(&env);
1173     TEST(size == 3);
1174
1175     /* Insert an item with a NUL in the key */
1176     xmlrpc_struct_set_value_n(&env, s, weirdKey, sizeof(weirdKey), i2);
1177     TEST_NO_FAULT(&env);
1178     size = xmlrpc_struct_size(&env, s);
1179     TEST_NO_FAULT(&env);
1180     TEST(size == 4);
1181
1182     test_struct_get_element(s, i1, i2, weirdKey, sizeof(weirdKey));
1183
1184     /* Replace an existing element with the same element (tricky). */
1185     xmlrpc_struct_set_value(&env, s, "aas", i1);
1186     TEST_NO_FAULT(&env);
1187     size = xmlrpc_struct_size(&env, s);
1188     TEST_NO_FAULT(&env);
1189     TEST(size == 4);
1190     i = xmlrpc_struct_get_value(&env, s, "aas");
1191     TEST_NO_FAULT(&env);
1192     TEST(i == i1);
1193
1194     /* Test for the presence and absence of elements. */
1195     present = xmlrpc_struct_has_key(&env, s, "aas");
1196     TEST_NO_FAULT(&env);
1197     TEST(present);
1198     present = xmlrpc_struct_has_key(&env, s, "bogus");
1199     TEST_NO_FAULT(&env);
1200     TEST(!present);
1201
1202     /* Make sure our typechecks work correctly. */
1203     xmlrpc_struct_size(&env, i1);
1204     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1205
1206     xmlrpc_struct_has_key(&env, i1, "foo");
1207     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1208
1209     xmlrpc_struct_set_value(&env, i1, "foo", i2);
1210     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1211
1212     xmlrpc_struct_set_value_v(&env, s, s, i2);
1213     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1214
1215     /* Test cleanup code (w/memprof). */
1216     xmlrpc_DECREF(s);
1217
1218     /* Build a struct using our automagic struct builder. */
1219     s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}",
1220                            "foo", "Hello!",
1221                            "bar", (xmlrpc_int32) 1,
1222                            "baz", (xmlrpc_bool) 0);
1223     TEST_NO_FAULT(&env);
1224     TEST(s != NULL);
1225     TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
1226     size = xmlrpc_struct_size(&env, s);
1227     TEST_NO_FAULT(&env);
1228     TEST(size == 3);
1229     present = xmlrpc_struct_has_key(&env, s, "foo");
1230     TEST_NO_FAULT(&env);
1231     TEST(present);
1232     present = xmlrpc_struct_has_key(&env, s, "bar");
1233     TEST_NO_FAULT(&env);
1234     TEST(present);
1235     present = xmlrpc_struct_has_key(&env, s, "baz");
1236     TEST_NO_FAULT(&env);
1237     TEST(present);
1238     i = xmlrpc_struct_get_value(&env, s, "baz");
1239     TEST_NO_FAULT(&env);
1240     xmlrpc_decompose_value(&env, i, "b", &bval);
1241     TEST_NO_FAULT(&env);
1242     TEST(!bval);
1243
1244     testStructReadout(s, 3);
1245
1246     /* Test our automagic struct parser. */
1247     xmlrpc_decompose_value(&env, s, "{s:b,s:s,s:i,*}",
1248                            "baz", &bval,
1249                            "foo", &sval,
1250                            "bar", &ival);
1251     TEST_NO_FAULT(&env);
1252     TEST(ival == 1);
1253     TEST(!bval);
1254     TEST(strcmp(sval, "Hello!") == 0);
1255     free(sval);
1256
1257     /* Test automagic struct parser with value of wrong type. */
1258     xmlrpc_decompose_value(&env, s, "{s:b,s:i,*}",
1259                            "baz", &bval,
1260                            "foo", &sval);
1261     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1262
1263     /* Test automagic struct parser with bad key. */
1264     xmlrpc_decompose_value(&env, s, "{s:b,s:i,*}",
1265                            "baz", &bval,
1266                            "nosuch", &sval);
1267     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1268
1269     /* Test type check. */
1270     xmlrpc_struct_get_key_and_value(&env, i1, 0, &key, &value);
1271     TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1272     TEST(key == NULL && value == NULL);
1273     
1274     /* Test bounds checks. */
1275     xmlrpc_struct_get_key_and_value(&env, s, -1, &key, &value);
1276     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1277     TEST(key == NULL && value == NULL);
1278
1279     xmlrpc_struct_get_key_and_value(&env, s, 3, &key, &value);
1280     TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1281     TEST(key == NULL && value == NULL);
1282     
1283     /* Test cleanup code (w/memprof). */
1284     xmlrpc_DECREF(s);
1285
1286     xmlrpc_DECREF(i1);
1287     xmlrpc_DECREF(i2);
1288     xmlrpc_DECREF(i3);
1289     xmlrpc_env_clean(&env);
1290 }
1291
1292
1293
1294 void 
1295 test_value(void) {
1296
1297     printf("Running value tests.");
1298
1299     test_value_alloc_dealloc();
1300     test_value_integer();
1301     test_value_bool();
1302     test_value_double();
1303     test_value_datetime();
1304     test_value_string_no_null();
1305     test_value_string_null();
1306     test_value_string_wide();
1307     test_value_base64();
1308     test_value_array();
1309     test_value_array2();
1310     test_value_array_nil();
1311     test_value_value();
1312     test_value_AS();
1313     test_value_AS_typecheck();
1314     test_value_cptr();
1315     test_value_nil();
1316     test_value_type_mismatch();
1317     test_value_invalid_type();
1318     test_value_missing_array_delim();
1319     test_value_missing_struct_delim();
1320     test_value_invalid_struct();
1321     test_value_parse_value();
1322     test_struct();
1323
1324     printf("\n");
1325     printf("Value tests done.\n");
1326 }