1 /* Copyright information is at the end of the file. */
10 #include "xmlrpc_config.h"
12 #include "xmlrpc-c/base.h"
19 /*=========================================================================
21 **=========================================================================
22 ** Some common test data which need to be allocated at a fixed address,
23 ** or which are inconvenient to allocate inline.
25 static char* test_string_1 = "foo";
30 test_value_alloc_dealloc(void) {
35 xmlrpc_env_init(&env);
37 /* Test allocation and deallocation (w/memprof). */
38 v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5);
45 xmlrpc_env_clean(&env);
50 test_value_integer(void) {
56 xmlrpc_env_init(&env);
58 v = xmlrpc_int_new(&env, (xmlrpc_int32) 25);
60 TEST(XMLRPC_TYPE_INT == xmlrpc_value_type(v));
61 xmlrpc_read_int(&env, v, &i);
66 v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 10);
69 TEST(XMLRPC_TYPE_INT == xmlrpc_value_type(v));
70 xmlrpc_decompose_value(&env, v, "i", &i);
75 xmlrpc_env_clean(&env);
81 test_value_bool(void) {
89 xmlrpc_env_init(&env);
91 v = xmlrpc_bool_new(&env, (xmlrpc_bool) 1);
93 TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v));
94 xmlrpc_read_bool(&env, v, &b);
99 v = xmlrpc_build_value(&env, "b", (xmlrpc_bool) 0);
102 TEST(XMLRPC_TYPE_BOOL == xmlrpc_value_type(v));
103 xmlrpc_decompose_value(&env, v, "b", &b);
108 xmlrpc_env_clean(&env);
114 test_value_double(void) {
120 xmlrpc_env_init(&env);
122 v = xmlrpc_double_new(&env, -3.25);
124 TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v));
125 xmlrpc_read_double(&env, v, &d);
130 v = xmlrpc_build_value(&env, "d", 1.0);
133 TEST(XMLRPC_TYPE_DOUBLE == xmlrpc_value_type(v));
134 xmlrpc_decompose_value(&env, v, "d", &d);
139 xmlrpc_env_clean(&env);
145 test_value_datetime(void) {
147 const char * datestring = "19980717T14:08:55";
148 time_t const datetime = 900684535;
155 xmlrpc_env_init(&env);
157 v = xmlrpc_datetime_new_str(&env, datestring);
159 TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
161 xmlrpc_read_datetime_str(&env, v, &ds);
163 TEST(strcmp(ds, datestring) == 0);
166 xmlrpc_read_datetime_sec(&env, v, &dt);
168 TEST(dt == datetime);
172 v = xmlrpc_datetime_new_sec(&env, datetime);
174 TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
176 xmlrpc_read_datetime_str(&env, v, &ds);
178 TEST(strcmp(ds, datestring) == 0);
181 xmlrpc_read_datetime_sec(&env, v, &dt);
183 TEST(dt == datetime);
187 v = xmlrpc_build_value(&env, "8", datestring);
190 TEST(XMLRPC_TYPE_DATETIME == xmlrpc_value_type(v));
191 xmlrpc_decompose_value(&env, v, "8", &ds);
194 TEST(strcmp(ds, datestring) == 0);
197 xmlrpc_env_clean(&env);
203 test_value_string_no_null(void) {
210 /* Test strings (without '\0' bytes). */
211 xmlrpc_env_init(&env);
213 v = xmlrpc_string_new(&env, test_string_1);
215 TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
216 xmlrpc_read_string(&env, v, &str);
218 TEST(strcmp(str, test_string_1) == 0);
222 v = xmlrpc_build_value(&env, "s", test_string_1);
226 TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
228 xmlrpc_decompose_value(&env, v, "s", &str);
230 TEST(strcmp(str, test_string_1) == 0);
233 xmlrpc_decompose_value(&env, v, "s#", &str, &len);
235 TEST(memcmp(str, test_string_1, strlen(test_string_1)) == 0);
236 TEST(strlen(str) == strlen(test_string_1));
241 xmlrpc_env_clean(&env);
247 test_value_string_null(void) {
255 /* Test a string with a '\0' byte. */
257 xmlrpc_env_init(&env);
259 v = xmlrpc_string_new_lp(&env, 7, "foo\0bar");
261 TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
262 xmlrpc_read_string_lp(&env, v, &len, &str);
265 TEST(memcmp(str, "foo\0bar", 7) == 0);
269 v = xmlrpc_build_value(&env, "s#", "foo\0bar", (size_t) 7);
272 TEST(XMLRPC_TYPE_STRING == xmlrpc_value_type(v));
274 xmlrpc_decompose_value(&env, v, "s#", &str, &len);
276 TEST(memcmp(str, "foo\0bar", 7) == 0);
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);
288 xmlrpc_env_clean(&env);
293 #if HAVE_UNICODE_WCHAR
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
301 static char utf8_data[] = "[\xC2\xA9]";
302 static wchar_t wcs_data[] = {'[', 0x00A9, ']', 0x0000};
305 test_value_string_wide_build(void) {
308 xmlrpc_value * valueP;
312 xmlrpc_env_init(&env);
314 /* Build with build_value w# */
315 valueP = xmlrpc_build_value(&env, "w#", wcs_data, 3);
317 TEST(valueP != NULL);
320 xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
324 TEST(wcs[len] == '\0');
325 TEST(0 == wcsncmp(wcs, wcs_data, len));
328 xmlrpc_DECREF(valueP);
330 /* Build with build_value w */
331 valueP = xmlrpc_build_value(&env, "w", wcs_data);
333 TEST(valueP != NULL);
336 xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
340 TEST(wcs[len] == '\0');
341 TEST(0 == wcsncmp(wcs, wcs_data, len));
344 xmlrpc_DECREF(valueP);
346 #endif /* HAVE_UNICODE_WCHAR */
350 test_value_string_wide(void) {
352 #if HAVE_UNICODE_WCHAR
354 xmlrpc_value * valueP;
358 xmlrpc_env_init(&env);
360 /* Build a string from wchar_t data. */
361 valueP = xmlrpc_string_w_new_lp(&env, 3, wcs_data);
363 TEST(valueP != NULL);
365 /* Extract it as a wchar_t string. */
366 xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
370 TEST(wcs[len] == '\0');
371 TEST(0 == wcsncmp(wcs, wcs_data, len));
374 xmlrpc_read_string_w(&env, valueP, &wcs);
377 TEST(wcs[3] == '\0');
378 TEST(0 == wcsncmp(wcs, wcs_data, 3));
381 xmlrpc_decompose_value(&env, valueP, "w#", &wcs, &len);
385 TEST(wcs[len] == '\0');
386 TEST(0 == wcsncmp(wcs, wcs_data, len));
390 /* Extract it as a UTF-8 string. */
394 xmlrpc_read_string_lp(&env, valueP, &len, &str);
398 TEST(str[len] == '\0');
399 TEST(0 == strncmp(str, utf8_data, len));
403 xmlrpc_DECREF(valueP);
405 /* Build from null-terminated wchar_t string */
406 valueP = xmlrpc_string_w_new(&env, wcs_data);
408 TEST(valueP != NULL);
411 xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
415 TEST(wcs[len] == '\0');
416 TEST(0 == wcsncmp(wcs, wcs_data, len));
419 xmlrpc_DECREF(valueP);
421 test_value_string_wide_build();
423 /* Build a string from UTF-8 data. */
424 valueP = xmlrpc_string_new(&env, utf8_data);
426 TEST(valueP != NULL);
428 /* Extract it as a wchar_t string. */
429 xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
433 TEST(wcs[len] == 0x0000);
434 TEST(0 == wcsncmp(wcs, wcs_data, len));
436 xmlrpc_DECREF(valueP);
438 /* Test with embedded NUL. We use a length of 4 so that the terminating
439 NUL actually becomes part of the string.
441 valueP = xmlrpc_string_w_new_lp(&env, 4, wcs_data);
443 TEST(valueP != NULL);
445 /* Extract it as a wchar_t string. */
446 xmlrpc_read_string_w_lp(&env, valueP, &len, &wcs);
450 TEST(wcs[len] == '\0');
451 TEST(0 == wcsncmp(wcs, wcs_data, len));
454 xmlrpc_read_string_w(&env, valueP, &wcs);
455 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
457 xmlrpc_DECREF(valueP);
458 #endif /* HAVE_UNICODE_WCHAR */
464 test_value_base64(void) {
466 /* Test <base64> data. */
468 unsigned char const data1[5] = {'a', '\0', 'b', '\n', 'c'};
469 unsigned char const data2[3] = {'a', '\0', 'b'};
473 const unsigned char * data;
476 xmlrpc_env_init(&env);
478 v = xmlrpc_base64_new(&env, sizeof(data1), data1);
480 TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v));
481 xmlrpc_read_base64(&env, v, &len, &data);
483 TEST(memcmp(data, data1, sizeof(data1)) == 0);
484 TEST(len == sizeof(data1));
488 v = xmlrpc_build_value(&env, "6", data2, sizeof(data2));
490 TEST(XMLRPC_TYPE_BASE64 == xmlrpc_value_type(v));
491 xmlrpc_decompose_value(&env, v, "6", &data, &len);
494 TEST(len == sizeof(data2));
495 TEST(memcmp(data, data1, sizeof(data2)) == 0);
498 xmlrpc_env_clean(&env);
504 test_value_value(void) {
506 xmlrpc_value *v, *v2, *v3;
509 /* Test 'V' with building and parsing. */
511 xmlrpc_env_init(&env);
513 v2 = xmlrpc_int_new(&env, (xmlrpc_int32) 5);
515 v = xmlrpc_build_value(&env, "V", v2);
518 xmlrpc_decompose_value(&env, v2, "V", &v3);
525 xmlrpc_env_clean(&env);
531 test_value_array(void) {
537 /* Basic array-building test. */
539 xmlrpc_env_init(&env);
541 v = xmlrpc_array_new(&env);
543 TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v));
544 len = xmlrpc_array_size(&env, v);
549 v = xmlrpc_build_value(&env, "()");
551 TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(v));
552 len = xmlrpc_array_size(&env, v);
557 xmlrpc_env_clean(&env);
563 test_value_AS(void) {
571 /* Test parsing of 'A' and 'S'. */
573 xmlrpc_env_init(&env);
575 v = xmlrpc_build_value(&env, "((){})");
577 xmlrpc_decompose_value(&env, v, "(AS)", &v2, &v3);
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);
585 len = xmlrpc_struct_size(&env, v3);
591 xmlrpc_env_clean(&env);
597 test_value_AS_typecheck(void) {
604 /* Test typechecks for 'A' and 'S'. */
606 xmlrpc_env_init(&env);
608 v = xmlrpc_build_value(&env, "s", "foo");
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);
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);
620 xmlrpc_env_clean(&env);
626 test_value_array2(void) {
628 xmlrpc_value * arrayP;
630 xmlrpc_int32 i, i1, i2, i3, i4;
631 xmlrpc_value * itemP;
632 xmlrpc_value * subarrayP;
635 /* A more complex array. */
637 xmlrpc_env_init(&env);
639 arrayP = xmlrpc_build_value(&env, "(i(ii)i)",
640 (xmlrpc_int32) 10, (xmlrpc_int32) 20,
641 (xmlrpc_int32) 30, (xmlrpc_int32) 40);
643 TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP));
645 len = xmlrpc_array_size(&env, arrayP);
649 xmlrpc_array_read_item(&env, arrayP, 1, &subarrayP);
652 len = xmlrpc_array_size(&env, subarrayP);
656 xmlrpc_array_read_item(&env, subarrayP, 0, &itemP);
658 xmlrpc_decompose_value(&env, itemP, "i", &i);
659 xmlrpc_DECREF(itemP);
663 xmlrpc_DECREF(subarrayP);
665 itemP = xmlrpc_array_get_item(&env, arrayP, 0);
667 xmlrpc_decompose_value(&env, itemP, "i", &i);
671 xmlrpc_decompose_value(&env, arrayP, "(i(ii)i)", &i1, &i2, &i3, &i4);
673 TEST(i1 == 10 && i2 == 20 && i3 == 30 && i4 == 40);
675 xmlrpc_decompose_value(&env, arrayP, "(i(i*)i)", &i1, &i2, &i3);
677 TEST(i1 == 10 && i2 == 20 && i3 == 40);
679 xmlrpc_decompose_value(&env, arrayP, "(i(ii*)i)", &i1, &i2, &i3, &i4);
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);
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);
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);
699 xmlrpc_DECREF(arrayP);
701 xmlrpc_env_clean(&env);
707 test_value_array_nil(void) {
709 xmlrpc_value * arrayP;
712 xmlrpc_value * itemP;
715 xmlrpc_env_init(&env);
717 arrayP = xmlrpc_build_value(&env, "(nini)",
718 (xmlrpc_int32) 10, (xmlrpc_int32) 20);
720 TEST(XMLRPC_TYPE_ARRAY == xmlrpc_value_type(arrayP));
722 len = xmlrpc_array_size(&env, arrayP);
726 itemP = xmlrpc_array_get_item(&env, arrayP, 0);
728 xmlrpc_decompose_value(&env, itemP, "n");
731 itemP = xmlrpc_array_get_item(&env, arrayP, 1);
735 xmlrpc_decompose_value(&env, itemP, "i", &i);
739 xmlrpc_decompose_value(&env, arrayP, "(nini)", &i1, &i2);
741 TEST(i1 == 10 && i2 == 20);
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);
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);
754 xmlrpc_DECREF(arrayP);
756 xmlrpc_env_clean(&env);
762 test_value_type_mismatch(void) {
769 /* Test for one, simple kind of type mismatch error. We assume that
770 ** if one of these typechecks works, the rest work fine. */
772 xmlrpc_env_init(&env);
774 v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 5);
776 xmlrpc_env_init(&env2);
777 xmlrpc_decompose_value(&env2, v, "s", &str);
779 TEST_FAULT(&env2, XMLRPC_TYPE_ERROR);
780 xmlrpc_env_clean(&env2);
782 xmlrpc_env_clean(&env);
788 test_value_cptr(void) {
794 /* Test C pointer storage using 'p'.
795 We don't have cleanup functions (yet).
798 xmlrpc_env_init(&env);
800 v = xmlrpc_build_value(&env, "p", (void*) 0x00000017);
802 TEST(XMLRPC_TYPE_C_PTR == xmlrpc_value_type(v));
803 xmlrpc_decompose_value(&env, v, "p", &ptr);
806 TEST(ptr == (void*) 0x00000017);
808 xmlrpc_env_clean(&env);
814 test_value_nil(void) {
819 xmlrpc_env_init(&env);
821 v = xmlrpc_nil_new(&env);
823 TEST(XMLRPC_TYPE_NIL == xmlrpc_value_type(v));
826 v = xmlrpc_build_value(&env, "n");
828 TEST(XMLRPC_TYPE_NIL == xmlrpc_value_type(v));
829 xmlrpc_decompose_value(&env, v, "n");
833 xmlrpc_env_clean(&env);
839 test_value_invalid_type(void) {
844 /* Test invalid type specifier in format string */
846 xmlrpc_env_init(&env);
848 v = xmlrpc_build_value(&env, "Q");
849 TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
851 xmlrpc_env_clean(&env);
857 test_value_missing_array_delim(void) {
862 /* Test missing close parenthesis on array */
864 xmlrpc_env_init(&env);
865 v = xmlrpc_build_value(&env, "(");
866 TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
867 xmlrpc_env_clean(&env);
869 xmlrpc_env_init(&env);
870 v = xmlrpc_build_value(&env, "(i");
871 TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
872 xmlrpc_env_clean(&env);
878 test_value_missing_struct_delim(void) {
883 /* Test missing closing brace on struct */
885 xmlrpc_env_init(&env);
886 v = xmlrpc_build_value(&env, "{");
887 TEST_FAULT(&env, XMLRPC_INTERNAL_ERROR);
888 xmlrpc_env_clean(&env);
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);
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);
904 test_value_invalid_struct(void) {
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.
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);
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);
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);
934 test_value_parse_value(void) {
937 xmlrpc_value * valueP;
938 const char * datestring = "19980717T14:08:55";
940 xmlrpc_env_init(&env);
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);
958 const unsigned char * b64;
960 xmlrpc_value * arrayP;
961 xmlrpc_value * structP;
963 xmlrpc_value * subvalP;
965 xmlrpc_parse_value(&env, valueP, "(idb8ss#6ASnpV)",
966 &i, &d, &b, &dt_str, &s1, &s2, &s2_len,
968 &arrayP, &structP, &cptr, &subvalP);
974 TEST(b == (xmlrpc_bool)1);
975 TEST(strcmp(dt_str, datestring) == 0);
976 TEST(strcmp(s1, "hello world") == 0);
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));
986 xmlrpc_DECREF(valueP);
988 xmlrpc_env_clean(&env);
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) {
1001 xmlrpc_value * valueP;
1002 xmlrpc_value * aasStringP;
1003 xmlrpc_value * bogusKeyStringP;
1005 xmlrpc_env_init(&env);
1007 /* build test tools */
1009 aasStringP = xmlrpc_build_value(&env, "s", "aas");
1010 TEST_NO_FAULT(&env);
1012 bogusKeyStringP = xmlrpc_build_value(&env, "s", "doesn't_exist");
1013 TEST_NO_FAULT(&env);
1015 /* "find" interface */
1017 xmlrpc_struct_find_value(&env, structP, "aas", &valueP);
1018 TEST_NO_FAULT(&env);
1020 xmlrpc_DECREF(valueP);
1022 xmlrpc_struct_find_value(&env, structP, "doesn't_exist", &valueP);
1023 TEST_NO_FAULT(&env);
1024 TEST(valueP == NULL);
1026 xmlrpc_struct_find_value_v(&env, structP, aasStringP, &valueP);
1027 TEST_NO_FAULT(&env);
1029 xmlrpc_DECREF(valueP);
1031 xmlrpc_struct_find_value_v(&env, structP, bogusKeyStringP, &valueP);
1032 TEST_NO_FAULT(&env);
1033 TEST(valueP == NULL);
1035 xmlrpc_struct_find_value(&env, i1, "aas", &valueP);
1036 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1038 /* "read" interface */
1040 xmlrpc_struct_read_value(&env, structP, "aas", &valueP);
1041 TEST_NO_FAULT(&env);
1043 xmlrpc_DECREF(valueP);
1045 xmlrpc_struct_read_value(&env, structP, "doesn't_exist", &valueP);
1046 TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1048 xmlrpc_struct_read_value_v(&env, structP, aasStringP, &valueP);
1049 TEST_NO_FAULT(&env);
1051 xmlrpc_DECREF(valueP);
1053 xmlrpc_struct_read_value_v(&env, structP, bogusKeyStringP, &valueP);
1054 TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1056 xmlrpc_struct_read_value(&env, i1, "aas", &valueP);
1057 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1059 /* obsolete "get" interface. Note that it does not update the
1060 reference count of the xmlrpc_value it returns.
1063 valueP = xmlrpc_struct_get_value(&env, structP, "aas");
1064 TEST_NO_FAULT(&env);
1067 valueP = xmlrpc_struct_get_value(&env, structP, "doesn't_exist");
1068 TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
1070 valueP = xmlrpc_struct_get_value(&env, i1, "foo");
1071 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1073 valueP = xmlrpc_struct_get_value_n(&env, structP, weirdKey, weirdKeyLen);
1074 TEST_NO_FAULT(&env);
1079 xmlrpc_DECREF(aasStringP);
1080 xmlrpc_DECREF(bogusKeyStringP);
1082 xmlrpc_env_clean(&env);
1088 testStructReadout(xmlrpc_value * const structP,
1089 size_t const expectedSize) {
1092 xmlrpc_value * keyP;
1093 xmlrpc_value * valueP;
1097 xmlrpc_env_init(&env);
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);
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);
1111 for (index = 0; index < expectedSize; ++index) {
1112 xmlrpc_struct_get_key_and_value(&env, structP, index, &keyP, &valueP);
1113 TEST_NO_FAULT(&env);
1115 xmlrpc_env_clean(&env);
1121 test_struct (void) {
1124 xmlrpc_value *s, *i, *i1, *i2, *i3, *key, *value;
1130 char const weirdKey[] = {'f', 'o', 'o', '\0', 'b', 'a', 'r'};
1132 xmlrpc_env_init(&env);
1134 /* Create a struct. */
1135 s = xmlrpc_struct_new(&env);
1136 TEST_NO_FAULT(&env);
1138 TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
1139 size = xmlrpc_struct_size(&env, s);
1140 TEST_NO_FAULT(&env);
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);
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);
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);
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);
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);
1182 test_struct_get_element(s, i1, i2, weirdKey, sizeof(weirdKey));
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);
1190 i = xmlrpc_struct_get_value(&env, s, "aas");
1191 TEST_NO_FAULT(&env);
1194 /* Test for the presence and absence of elements. */
1195 present = xmlrpc_struct_has_key(&env, s, "aas");
1196 TEST_NO_FAULT(&env);
1198 present = xmlrpc_struct_has_key(&env, s, "bogus");
1199 TEST_NO_FAULT(&env);
1202 /* Make sure our typechecks work correctly. */
1203 xmlrpc_struct_size(&env, i1);
1204 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1206 xmlrpc_struct_has_key(&env, i1, "foo");
1207 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1209 xmlrpc_struct_set_value(&env, i1, "foo", i2);
1210 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1212 xmlrpc_struct_set_value_v(&env, s, s, i2);
1213 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1215 /* Test cleanup code (w/memprof). */
1218 /* Build a struct using our automagic struct builder. */
1219 s = xmlrpc_build_value(&env, "{s:s,s:i,s:b}",
1221 "bar", (xmlrpc_int32) 1,
1222 "baz", (xmlrpc_bool) 0);
1223 TEST_NO_FAULT(&env);
1225 TEST(XMLRPC_TYPE_STRUCT == xmlrpc_value_type(s));
1226 size = xmlrpc_struct_size(&env, s);
1227 TEST_NO_FAULT(&env);
1229 present = xmlrpc_struct_has_key(&env, s, "foo");
1230 TEST_NO_FAULT(&env);
1232 present = xmlrpc_struct_has_key(&env, s, "bar");
1233 TEST_NO_FAULT(&env);
1235 present = xmlrpc_struct_has_key(&env, s, "baz");
1236 TEST_NO_FAULT(&env);
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);
1244 testStructReadout(s, 3);
1246 /* Test our automagic struct parser. */
1247 xmlrpc_decompose_value(&env, s, "{s:b,s:s,s:i,*}",
1251 TEST_NO_FAULT(&env);
1254 TEST(strcmp(sval, "Hello!") == 0);
1257 /* Test automagic struct parser with value of wrong type. */
1258 xmlrpc_decompose_value(&env, s, "{s:b,s:i,*}",
1261 TEST_FAULT(&env, XMLRPC_TYPE_ERROR);
1263 /* Test automagic struct parser with bad key. */
1264 xmlrpc_decompose_value(&env, s, "{s:b,s:i,*}",
1267 TEST_FAULT(&env, XMLRPC_INDEX_ERROR);
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);
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);
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);
1283 /* Test cleanup code (w/memprof). */
1289 xmlrpc_env_clean(&env);
1297 printf("Running value tests.");
1299 test_value_alloc_dealloc();
1300 test_value_integer();
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();
1309 test_value_array2();
1310 test_value_array_nil();
1313 test_value_AS_typecheck();
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();
1325 printf("Value tests done.\n");