initial load of upstream version 1.06.32
[xmlrpc-c] / src / test / serialize.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <limits.h>
4
5 #include "xmlrpc_config.h"
6
7 #include "xmlrpc-c/base.h"
8
9 #include "test.h"
10 #include "xml_data.h"
11 #include "serialize.h"
12
13
14
15 static void
16 test_serialize_basic(void) {
17
18     xmlrpc_env env;
19     xmlrpc_value * v;
20     xmlrpc_mem_block *output;
21     size_t size;
22     
23     xmlrpc_env_init(&env);
24
25     /* Build a nice, messy value to serialize. We should attempt to use
26     ** use every data type except double (which doesn't serialize in a
27     ** portable manner. */
28     v = xmlrpc_build_value(&env, "(iibbs68())",
29                            (xmlrpc_int32) INT_MAX, (xmlrpc_int32) INT_MIN,
30                            (xmlrpc_bool) 0, (xmlrpc_bool) 1,
31                            "Hello, world! <&>",
32                            "base64 data", (size_t) 11,
33                            "19980717T14:08:55");
34     TEST_NO_FAULT(&env);
35     
36     /* Serialize the value. */
37     output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
38     TEST_NO_FAULT(&env);
39     xmlrpc_serialize_value(&env, output, v);
40     TEST_NO_FAULT(&env);
41
42     /* Make sure we serialized the correct value. */
43     size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
44     TEST(size == strlen(serialized_data));
45     TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
46                 serialized_data, size) == 0);
47     
48     /* (Debugging code to display the value.) */
49     /* XMLRPC_TYPED_MEM_BLOCK_APPEND(char, &env, output, "\0", 1);
50     ** TEST_NO_FAULT(&env);
51     ** printf("%s\n", XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output)); */
52
53     /* Clean up our value. */
54     XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
55     xmlrpc_DECREF(v);
56
57     xmlrpc_env_clean(&env);
58 }
59
60
61
62 static void
63 test_serialize_double(void) {
64
65     /* Test serialize of a double.  */
66
67     xmlrpc_env env;
68     xmlrpc_value * v;
69     xmlrpc_mem_block *output;
70     char * result;
71         /* serialized result, as asciiz string */
72     size_t resultLength;
73         /* Length in characters of the serialized result */
74     float serializedValue;
75     char nextChar;
76     int itemsMatched;
77     
78     xmlrpc_env_init(&env);
79
80     /* Build a double to serialize */
81     v = xmlrpc_build_value(&env, "d", 3.14159);
82     TEST_NO_FAULT(&env);
83     
84     /* Serialize the value. */
85     output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
86     TEST_NO_FAULT(&env);
87     xmlrpc_serialize_value(&env, output, v);
88     TEST_NO_FAULT(&env);
89
90     /* Make sure we serialized the correct value.  Note that because
91        doubles aren't precise, this might serialize as 3.1415899999
92        or something like that.  So we check it arithmetically.
93     */
94     resultLength = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
95     result = malloc(resultLength + 1);
96
97     memcpy(result, XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output), 
98            resultLength);
99     result[resultLength] = '\0';
100     
101     itemsMatched = sscanf(result, 
102                           "<value><double>%f</double></value>\r\n%c",
103                           &serializedValue, &nextChar);
104
105     TEST(itemsMatched == 1);
106     TEST(serializedValue - 3.14159 < .000001);
107     /* We'd like to test more precision, but sscanf doesn't do doubles */
108
109     free(result);
110     
111     /* Clean up our value. */
112     XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
113     xmlrpc_DECREF(v);
114
115     xmlrpc_env_clean(&env);
116 }
117
118
119
120 static void
121 test_serialize_struct(void) {
122
123     /* Serialize a simple struct. */
124
125     char const serialized_struct[] = 
126         "<value><struct>\r\n" \
127         "<member><name>&lt;&amp;&gt;</name>\r\n" \
128         "<value><i4>10</i4></value></member>\r\n" \
129         "</struct></value>";
130     
131     xmlrpc_env env;
132     xmlrpc_value * v;
133     xmlrpc_mem_block *output;
134     size_t size;
135     
136     xmlrpc_env_init(&env);
137
138     v = xmlrpc_build_value(&env, "{s:i}", "<&>", (xmlrpc_int32) 10);
139     TEST_NO_FAULT(&env);
140     output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
141     TEST_NO_FAULT(&env);
142     xmlrpc_serialize_value(&env, output, v);
143     TEST_NO_FAULT(&env);
144
145     /* Make sure we serialized the correct value. */
146     size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
147     TEST(size == strlen(serialized_struct));
148     TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
149                 serialized_struct, size) == 0);
150     
151     /* Clean up our struct. */
152     XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
153     xmlrpc_DECREF(v);
154
155     xmlrpc_env_clean(&env);
156 }
157
158
159
160 static void
161 test_serialize_methodResponse(void) {
162
163     /* Serialize a methodResponse. */
164
165     char const serialized_response[] =
166         XML_PROLOGUE
167         "<methodResponse>\r\n"
168         "<params>\r\n"
169         "<param><value><i4>30</i4></value></param>\r\n"
170         "</params>\r\n"
171         "</methodResponse>\r\n";
172
173     xmlrpc_env env;
174     xmlrpc_value * v;
175     xmlrpc_mem_block *output;
176     size_t size;
177     
178     xmlrpc_env_init(&env);
179
180     output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
181     TEST_NO_FAULT(&env);
182     v = xmlrpc_build_value(&env, "i", (xmlrpc_int32) 30);
183     TEST_NO_FAULT(&env);
184     xmlrpc_serialize_response(&env, output, v);
185     TEST_NO_FAULT(&env);
186
187     /* Make sure we serialized the correct value. */
188     size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
189     TEST(size == strlen(serialized_response));
190     TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
191                 serialized_response, size) == 0);
192
193     /* Clean up our methodResponse. */
194     xmlrpc_DECREF(v);
195     XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
196
197     xmlrpc_env_clean(&env);
198 }
199
200
201
202 static void
203 test_serialize_methodCall(void) {
204
205     /* Serialize a methodCall. */
206
207     xmlrpc_env env;
208     xmlrpc_value * v;
209     xmlrpc_mem_block *output;
210     size_t size;
211     
212     xmlrpc_env_init(&env);
213
214     output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
215     TEST_NO_FAULT(&env);
216     v = xmlrpc_build_value(&env, "(ii)", (xmlrpc_int32) 10, (xmlrpc_int32) 20);
217     TEST_NO_FAULT(&env);
218     xmlrpc_serialize_call(&env, output, "gloom&doom", v);
219     TEST_NO_FAULT(&env);
220
221     /* Make sure we serialized the correct value. */
222     size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
223     TEST(size == strlen(serialized_call));
224     TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
225                 serialized_call, size) == 0);
226
227     /* Clean up our methodCall. */
228     xmlrpc_DECREF(v);
229     XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
230
231     xmlrpc_env_clean(&env);
232 }
233
234
235
236 static void
237 test_serialize_fault(void) {
238     /* Serialize a fault. */
239
240     xmlrpc_env env;
241     xmlrpc_env fault;
242     xmlrpc_mem_block *output;
243     size_t size;
244     
245     xmlrpc_env_init(&env);
246
247     output = XMLRPC_TYPED_MEM_BLOCK_NEW(char, &env, 0);
248     TEST_NO_FAULT(&env);
249     xmlrpc_env_init(&fault);
250     xmlrpc_env_set_fault(&fault, 6, "A fault occurred");
251     xmlrpc_serialize_fault(&env, output, &fault);
252     TEST_NO_FAULT(&env);
253
254     /* Make sure we serialized the correct value. */
255     size = XMLRPC_TYPED_MEM_BLOCK_SIZE(char, output);
256     TEST(size == strlen(serialized_fault));
257     TEST(memcmp(XMLRPC_TYPED_MEM_BLOCK_CONTENTS(char, output),
258                 serialized_fault, size) == 0);
259
260     /* Clean up our fault. */
261     xmlrpc_env_clean(&fault);
262     XMLRPC_TYPED_MEM_BLOCK_FREE(char, output);
263
264     xmlrpc_env_clean(&env);
265 }
266
267
268
269 void 
270 test_serialize(void) {
271
272     printf("Running serialize tests.");
273
274     test_serialize_basic();
275     test_serialize_double();
276     test_serialize_struct();
277     test_serialize_methodResponse();
278     test_serialize_methodCall();
279     test_serialize_fault();
280
281     printf("\n");
282     printf("Serialize tests done.\n");
283 }