root / tests / test-visitor-serialization.c @ a372823a
History | View | Annotate | Download (20.5 kB)
1 | 2d496105 | Michael Roth | /*
|
---|---|---|---|
2 | 2d496105 | Michael Roth | * Unit-tests for visitor-based serialization
|
3 | 2d496105 | Michael Roth | *
|
4 | 2d496105 | Michael Roth | * Copyright IBM, Corp. 2012
|
5 | 2d496105 | Michael Roth | *
|
6 | 2d496105 | Michael Roth | * Authors:
|
7 | 2d496105 | Michael Roth | * Michael Roth <mdroth@linux.vnet.ibm.com>
|
8 | 2d496105 | Michael Roth | *
|
9 | 2d496105 | Michael Roth | * This work is licensed under the terms of the GNU GPL, version 2 or later.
|
10 | 2d496105 | Michael Roth | * See the COPYING file in the top-level directory.
|
11 | 2d496105 | Michael Roth | */
|
12 | 2d496105 | Michael Roth | |
13 | 2d496105 | Michael Roth | #include <glib.h> |
14 | 2d496105 | Michael Roth | #include <stdlib.h> |
15 | 2d496105 | Michael Roth | #include <stdint.h> |
16 | 2d496105 | Michael Roth | #include <float.h> |
17 | 79ee7df8 | Paolo Bonzini | |
18 | 79ee7df8 | Paolo Bonzini | #include "qemu-common.h" |
19 | 2d496105 | Michael Roth | #include "test-qapi-types.h" |
20 | 2d496105 | Michael Roth | #include "test-qapi-visit.h" |
21 | 7b1b5d19 | Paolo Bonzini | #include "qapi/qmp/types.h" |
22 | 2d496105 | Michael Roth | #include "qapi/qmp-input-visitor.h" |
23 | 2d496105 | Michael Roth | #include "qapi/qmp-output-visitor.h" |
24 | 0d30b0a2 | Michael Roth | #include "qapi/string-input-visitor.h" |
25 | 0d30b0a2 | Michael Roth | #include "qapi/string-output-visitor.h" |
26 | 2d496105 | Michael Roth | |
27 | 2d496105 | Michael Roth | typedef struct PrimitiveType { |
28 | 2d496105 | Michael Roth | union {
|
29 | 2d496105 | Michael Roth | const char *string; |
30 | 2d496105 | Michael Roth | bool boolean;
|
31 | 2d496105 | Michael Roth | double number;
|
32 | 2d496105 | Michael Roth | int64_t integer; |
33 | 2d496105 | Michael Roth | uint8_t u8; |
34 | 2d496105 | Michael Roth | uint16_t u16; |
35 | 2d496105 | Michael Roth | uint32_t u32; |
36 | 2d496105 | Michael Roth | uint64_t u64; |
37 | 2d496105 | Michael Roth | int8_t s8; |
38 | 2d496105 | Michael Roth | int16_t s16; |
39 | 2d496105 | Michael Roth | int32_t s32; |
40 | 2d496105 | Michael Roth | int64_t s64; |
41 | 2d496105 | Michael Roth | intmax_t max; |
42 | 2d496105 | Michael Roth | } value; |
43 | 2d496105 | Michael Roth | enum {
|
44 | 2d496105 | Michael Roth | PTYPE_STRING = 0,
|
45 | 2d496105 | Michael Roth | PTYPE_BOOLEAN, |
46 | 2d496105 | Michael Roth | PTYPE_NUMBER, |
47 | 2d496105 | Michael Roth | PTYPE_INTEGER, |
48 | 2d496105 | Michael Roth | PTYPE_U8, |
49 | 2d496105 | Michael Roth | PTYPE_U16, |
50 | 2d496105 | Michael Roth | PTYPE_U32, |
51 | 2d496105 | Michael Roth | PTYPE_U64, |
52 | 2d496105 | Michael Roth | PTYPE_S8, |
53 | 2d496105 | Michael Roth | PTYPE_S16, |
54 | 2d496105 | Michael Roth | PTYPE_S32, |
55 | 2d496105 | Michael Roth | PTYPE_S64, |
56 | 2d496105 | Michael Roth | PTYPE_EOL, |
57 | 2d496105 | Michael Roth | } type; |
58 | 2d496105 | Michael Roth | const char *description; |
59 | 2d496105 | Michael Roth | } PrimitiveType; |
60 | 2d496105 | Michael Roth | |
61 | 2d496105 | Michael Roth | /* test helpers */
|
62 | 2d496105 | Michael Roth | |
63 | 2d496105 | Michael Roth | static void visit_primitive_type(Visitor *v, void **native, Error **errp) |
64 | 2d496105 | Michael Roth | { |
65 | 2d496105 | Michael Roth | PrimitiveType *pt = *native; |
66 | 2d496105 | Michael Roth | switch(pt->type) {
|
67 | 2d496105 | Michael Roth | case PTYPE_STRING:
|
68 | 2d496105 | Michael Roth | visit_type_str(v, (char **)&pt->value.string, NULL, errp); |
69 | 2d496105 | Michael Roth | break;
|
70 | 2d496105 | Michael Roth | case PTYPE_BOOLEAN:
|
71 | 2d496105 | Michael Roth | visit_type_bool(v, &pt->value.boolean, NULL, errp);
|
72 | 2d496105 | Michael Roth | break;
|
73 | 2d496105 | Michael Roth | case PTYPE_NUMBER:
|
74 | 2d496105 | Michael Roth | visit_type_number(v, &pt->value.number, NULL, errp);
|
75 | 2d496105 | Michael Roth | break;
|
76 | 2d496105 | Michael Roth | case PTYPE_INTEGER:
|
77 | 2d496105 | Michael Roth | visit_type_int(v, &pt->value.integer, NULL, errp);
|
78 | 2d496105 | Michael Roth | break;
|
79 | 2d496105 | Michael Roth | case PTYPE_U8:
|
80 | 2d496105 | Michael Roth | visit_type_uint8(v, &pt->value.u8, NULL, errp);
|
81 | 2d496105 | Michael Roth | break;
|
82 | 2d496105 | Michael Roth | case PTYPE_U16:
|
83 | 2d496105 | Michael Roth | visit_type_uint16(v, &pt->value.u16, NULL, errp);
|
84 | 2d496105 | Michael Roth | break;
|
85 | 2d496105 | Michael Roth | case PTYPE_U32:
|
86 | 2d496105 | Michael Roth | visit_type_uint32(v, &pt->value.u32, NULL, errp);
|
87 | 2d496105 | Michael Roth | break;
|
88 | 2d496105 | Michael Roth | case PTYPE_U64:
|
89 | 2d496105 | Michael Roth | visit_type_uint64(v, &pt->value.u64, NULL, errp);
|
90 | 2d496105 | Michael Roth | break;
|
91 | 2d496105 | Michael Roth | case PTYPE_S8:
|
92 | 2d496105 | Michael Roth | visit_type_int8(v, &pt->value.s8, NULL, errp);
|
93 | 2d496105 | Michael Roth | break;
|
94 | 2d496105 | Michael Roth | case PTYPE_S16:
|
95 | 2d496105 | Michael Roth | visit_type_int16(v, &pt->value.s16, NULL, errp);
|
96 | 2d496105 | Michael Roth | break;
|
97 | 2d496105 | Michael Roth | case PTYPE_S32:
|
98 | 2d496105 | Michael Roth | visit_type_int32(v, &pt->value.s32, NULL, errp);
|
99 | 2d496105 | Michael Roth | break;
|
100 | 2d496105 | Michael Roth | case PTYPE_S64:
|
101 | 2d496105 | Michael Roth | visit_type_int64(v, &pt->value.s64, NULL, errp);
|
102 | 2d496105 | Michael Roth | break;
|
103 | 2d496105 | Michael Roth | case PTYPE_EOL:
|
104 | 2d496105 | Michael Roth | g_assert(false);
|
105 | 2d496105 | Michael Roth | } |
106 | 2d496105 | Michael Roth | } |
107 | 2d496105 | Michael Roth | |
108 | 2d496105 | Michael Roth | typedef struct TestStruct |
109 | 2d496105 | Michael Roth | { |
110 | 2d496105 | Michael Roth | int64_t integer; |
111 | 2d496105 | Michael Roth | bool boolean;
|
112 | 2d496105 | Michael Roth | char *string;
|
113 | 2d496105 | Michael Roth | } TestStruct; |
114 | 2d496105 | Michael Roth | |
115 | 2d496105 | Michael Roth | static void visit_type_TestStruct(Visitor *v, TestStruct **obj, |
116 | 2d496105 | Michael Roth | const char *name, Error **errp) |
117 | 2d496105 | Michael Roth | { |
118 | 2d496105 | Michael Roth | visit_start_struct(v, (void **)obj, NULL, name, sizeof(TestStruct), errp); |
119 | 2d496105 | Michael Roth | |
120 | 2d496105 | Michael Roth | visit_type_int(v, &(*obj)->integer, "integer", errp);
|
121 | 2d496105 | Michael Roth | visit_type_bool(v, &(*obj)->boolean, "boolean", errp);
|
122 | 2d496105 | Michael Roth | visit_type_str(v, &(*obj)->string, "string", errp);
|
123 | 2d496105 | Michael Roth | |
124 | 2d496105 | Michael Roth | visit_end_struct(v, errp); |
125 | 2d496105 | Michael Roth | } |
126 | 2d496105 | Michael Roth | |
127 | 2d496105 | Michael Roth | static TestStruct *struct_create(void) |
128 | 2d496105 | Michael Roth | { |
129 | 2d496105 | Michael Roth | TestStruct *ts = g_malloc0(sizeof(*ts));
|
130 | 2d496105 | Michael Roth | ts->integer = -42;
|
131 | 2d496105 | Michael Roth | ts->boolean = true;
|
132 | 2d496105 | Michael Roth | ts->string = strdup("test string");
|
133 | 2d496105 | Michael Roth | return ts;
|
134 | 2d496105 | Michael Roth | } |
135 | 2d496105 | Michael Roth | |
136 | 2d496105 | Michael Roth | static void struct_compare(TestStruct *ts1, TestStruct *ts2) |
137 | 2d496105 | Michael Roth | { |
138 | 2d496105 | Michael Roth | g_assert(ts1); |
139 | 2d496105 | Michael Roth | g_assert(ts2); |
140 | 2d496105 | Michael Roth | g_assert_cmpint(ts1->integer, ==, ts2->integer); |
141 | 2d496105 | Michael Roth | g_assert(ts1->boolean == ts2->boolean); |
142 | 2d496105 | Michael Roth | g_assert_cmpstr(ts1->string, ==, ts2->string); |
143 | 2d496105 | Michael Roth | } |
144 | 2d496105 | Michael Roth | |
145 | 2d496105 | Michael Roth | static void struct_cleanup(TestStruct *ts) |
146 | 2d496105 | Michael Roth | { |
147 | 2d496105 | Michael Roth | g_free(ts->string); |
148 | 2d496105 | Michael Roth | g_free(ts); |
149 | 2d496105 | Michael Roth | } |
150 | 2d496105 | Michael Roth | |
151 | 2d496105 | Michael Roth | static void visit_struct(Visitor *v, void **native, Error **errp) |
152 | 2d496105 | Michael Roth | { |
153 | 2d496105 | Michael Roth | visit_type_TestStruct(v, (TestStruct **)native, NULL, errp);
|
154 | 2d496105 | Michael Roth | } |
155 | 2d496105 | Michael Roth | |
156 | 2d496105 | Michael Roth | static UserDefNested *nested_struct_create(void) |
157 | 2d496105 | Michael Roth | { |
158 | 2d496105 | Michael Roth | UserDefNested *udnp = g_malloc0(sizeof(*udnp));
|
159 | 2d496105 | Michael Roth | udnp->string0 = strdup("test_string0");
|
160 | 2d496105 | Michael Roth | udnp->dict1.string1 = strdup("test_string1");
|
161 | 2d496105 | Michael Roth | udnp->dict1.dict2.userdef1 = g_malloc0(sizeof(UserDefOne));
|
162 | 2d496105 | Michael Roth | udnp->dict1.dict2.userdef1->integer = 42;
|
163 | 2d496105 | Michael Roth | udnp->dict1.dict2.userdef1->string = strdup("test_string");
|
164 | 2d496105 | Michael Roth | udnp->dict1.dict2.string2 = strdup("test_string2");
|
165 | 2d496105 | Michael Roth | udnp->dict1.has_dict3 = true;
|
166 | 2d496105 | Michael Roth | udnp->dict1.dict3.userdef2 = g_malloc0(sizeof(UserDefOne));
|
167 | 2d496105 | Michael Roth | udnp->dict1.dict3.userdef2->integer = 43;
|
168 | 2d496105 | Michael Roth | udnp->dict1.dict3.userdef2->string = strdup("test_string");
|
169 | 2d496105 | Michael Roth | udnp->dict1.dict3.string3 = strdup("test_string3");
|
170 | 2d496105 | Michael Roth | return udnp;
|
171 | 2d496105 | Michael Roth | } |
172 | 2d496105 | Michael Roth | |
173 | 2d496105 | Michael Roth | static void nested_struct_compare(UserDefNested *udnp1, UserDefNested *udnp2) |
174 | 2d496105 | Michael Roth | { |
175 | 2d496105 | Michael Roth | g_assert(udnp1); |
176 | 2d496105 | Michael Roth | g_assert(udnp2); |
177 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->string0, ==, udnp2->string0); |
178 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.string1, ==, udnp2->dict1.string1); |
179 | 2d496105 | Michael Roth | g_assert_cmpint(udnp1->dict1.dict2.userdef1->integer, ==, |
180 | 2d496105 | Michael Roth | udnp2->dict1.dict2.userdef1->integer); |
181 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict2.userdef1->string, ==, |
182 | 2d496105 | Michael Roth | udnp2->dict1.dict2.userdef1->string); |
183 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict2.string2, ==, udnp2->dict1.dict2.string2); |
184 | 2d496105 | Michael Roth | g_assert(udnp1->dict1.has_dict3 == udnp2->dict1.has_dict3); |
185 | 2d496105 | Michael Roth | g_assert_cmpint(udnp1->dict1.dict3.userdef2->integer, ==, |
186 | 2d496105 | Michael Roth | udnp2->dict1.dict3.userdef2->integer); |
187 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict3.userdef2->string, ==, |
188 | 2d496105 | Michael Roth | udnp2->dict1.dict3.userdef2->string); |
189 | 2d496105 | Michael Roth | g_assert_cmpstr(udnp1->dict1.dict3.string3, ==, udnp2->dict1.dict3.string3); |
190 | 2d496105 | Michael Roth | } |
191 | 2d496105 | Michael Roth | |
192 | 2d496105 | Michael Roth | static void nested_struct_cleanup(UserDefNested *udnp) |
193 | 2d496105 | Michael Roth | { |
194 | 2d496105 | Michael Roth | qapi_free_UserDefNested(udnp); |
195 | 2d496105 | Michael Roth | } |
196 | 2d496105 | Michael Roth | |
197 | 2d496105 | Michael Roth | static void visit_nested_struct(Visitor *v, void **native, Error **errp) |
198 | 2d496105 | Michael Roth | { |
199 | 2d496105 | Michael Roth | visit_type_UserDefNested(v, (UserDefNested **)native, NULL, errp);
|
200 | 2d496105 | Michael Roth | } |
201 | 2d496105 | Michael Roth | |
202 | 2d496105 | Michael Roth | static void visit_nested_struct_list(Visitor *v, void **native, Error **errp) |
203 | 2d496105 | Michael Roth | { |
204 | 2d496105 | Michael Roth | visit_type_UserDefNestedList(v, (UserDefNestedList **)native, NULL, errp);
|
205 | 2d496105 | Michael Roth | } |
206 | 2d496105 | Michael Roth | |
207 | 2d496105 | Michael Roth | /* test cases */
|
208 | 2d496105 | Michael Roth | |
209 | 2d496105 | Michael Roth | typedef void (*VisitorFunc)(Visitor *v, void **native, Error **errp); |
210 | 2d496105 | Michael Roth | |
211 | 2d496105 | Michael Roth | typedef enum VisitorCapabilities { |
212 | 2d496105 | Michael Roth | VCAP_PRIMITIVES = 1,
|
213 | 2d496105 | Michael Roth | VCAP_STRUCTURES = 2,
|
214 | 2d496105 | Michael Roth | VCAP_LISTS = 4,
|
215 | 2d496105 | Michael Roth | } VisitorCapabilities; |
216 | 2d496105 | Michael Roth | |
217 | 2d496105 | Michael Roth | typedef struct SerializeOps { |
218 | 2d496105 | Michael Roth | void (*serialize)(void *native_in, void **datap, |
219 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp); |
220 | 2d496105 | Michael Roth | void (*deserialize)(void **native_out, void *datap, |
221 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp); |
222 | 2d496105 | Michael Roth | void (*cleanup)(void *datap); |
223 | 2d496105 | Michael Roth | const char *type; |
224 | 2d496105 | Michael Roth | VisitorCapabilities caps; |
225 | 2d496105 | Michael Roth | } SerializeOps; |
226 | 2d496105 | Michael Roth | |
227 | 2d496105 | Michael Roth | typedef struct TestArgs { |
228 | 2d496105 | Michael Roth | const SerializeOps *ops;
|
229 | 2d496105 | Michael Roth | void *test_data;
|
230 | 2d496105 | Michael Roth | } TestArgs; |
231 | 2d496105 | Michael Roth | |
232 | 2d496105 | Michael Roth | #define FLOAT_STRING_PRECISION 6 /* corresponding to n in %.nf formatting */ |
233 | 2d496105 | Michael Roth | static gsize calc_float_string_storage(double value) |
234 | 2d496105 | Michael Roth | { |
235 | 2d496105 | Michael Roth | int whole_value = value;
|
236 | 2d496105 | Michael Roth | gsize i = 0;
|
237 | 2d496105 | Michael Roth | do {
|
238 | 2d496105 | Michael Roth | i++; |
239 | 2d496105 | Michael Roth | } while (whole_value /= 10); |
240 | 2d496105 | Michael Roth | return i + 2 + FLOAT_STRING_PRECISION; |
241 | 2d496105 | Michael Roth | } |
242 | 2d496105 | Michael Roth | |
243 | 2d496105 | Michael Roth | static void test_primitives(gconstpointer opaque) |
244 | 2d496105 | Michael Roth | { |
245 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
246 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
247 | 2d496105 | Michael Roth | PrimitiveType *pt = args->test_data; |
248 | 2d496105 | Michael Roth | PrimitiveType *pt_copy = g_malloc0(sizeof(*pt_copy));
|
249 | 2d496105 | Michael Roth | Error *err = NULL;
|
250 | 2d496105 | Michael Roth | void *serialize_data;
|
251 | 2d496105 | Michael Roth | char *double1, *double2;
|
252 | 2d496105 | Michael Roth | |
253 | 2d496105 | Michael Roth | pt_copy->type = pt->type; |
254 | 2d496105 | Michael Roth | ops->serialize(pt, &serialize_data, visit_primitive_type, &err); |
255 | 2d496105 | Michael Roth | ops->deserialize((void **)&pt_copy, serialize_data, visit_primitive_type, &err);
|
256 | 2d496105 | Michael Roth | |
257 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
258 | 2d496105 | Michael Roth | g_assert(pt_copy != NULL);
|
259 | 2d496105 | Michael Roth | if (pt->type == PTYPE_STRING) {
|
260 | 2d496105 | Michael Roth | g_assert_cmpstr(pt->value.string, ==, pt_copy->value.string); |
261 | 2d496105 | Michael Roth | } else if (pt->type == PTYPE_NUMBER) { |
262 | 2d496105 | Michael Roth | /* we serialize with %f for our reference visitors, so rather than fuzzy
|
263 | 2d496105 | Michael Roth | * floating math to test "equality", just compare the formatted values
|
264 | 2d496105 | Michael Roth | */
|
265 | 2d496105 | Michael Roth | double1 = g_malloc0(calc_float_string_storage(pt->value.number)); |
266 | 2d496105 | Michael Roth | double2 = g_malloc0(calc_float_string_storage(pt_copy->value.number)); |
267 | 2d496105 | Michael Roth | g_assert_cmpstr(double1, ==, double2); |
268 | 2d496105 | Michael Roth | g_free(double1); |
269 | 2d496105 | Michael Roth | g_free(double2); |
270 | 2d496105 | Michael Roth | } else if (pt->type == PTYPE_BOOLEAN) { |
271 | 2d496105 | Michael Roth | g_assert_cmpint(!!pt->value.max, ==, !!pt->value.max); |
272 | 2d496105 | Michael Roth | } else {
|
273 | 2d496105 | Michael Roth | g_assert_cmpint(pt->value.max, ==, pt_copy->value.max); |
274 | 2d496105 | Michael Roth | } |
275 | 2d496105 | Michael Roth | |
276 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
277 | 2d496105 | Michael Roth | g_free(args); |
278 | 2d496105 | Michael Roth | } |
279 | 2d496105 | Michael Roth | |
280 | 2d496105 | Michael Roth | static void test_struct(gconstpointer opaque) |
281 | 2d496105 | Michael Roth | { |
282 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
283 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
284 | 2d496105 | Michael Roth | TestStruct *ts = struct_create(); |
285 | 2d496105 | Michael Roth | TestStruct *ts_copy = NULL;
|
286 | 2d496105 | Michael Roth | Error *err = NULL;
|
287 | 2d496105 | Michael Roth | void *serialize_data;
|
288 | 2d496105 | Michael Roth | |
289 | 2d496105 | Michael Roth | ops->serialize(ts, &serialize_data, visit_struct, &err); |
290 | 2d496105 | Michael Roth | ops->deserialize((void **)&ts_copy, serialize_data, visit_struct, &err);
|
291 | 2d496105 | Michael Roth | |
292 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
293 | 2d496105 | Michael Roth | struct_compare(ts, ts_copy); |
294 | 2d496105 | Michael Roth | |
295 | 2d496105 | Michael Roth | struct_cleanup(ts); |
296 | 2d496105 | Michael Roth | struct_cleanup(ts_copy); |
297 | 2d496105 | Michael Roth | |
298 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
299 | 2d496105 | Michael Roth | g_free(args); |
300 | 2d496105 | Michael Roth | } |
301 | 2d496105 | Michael Roth | |
302 | 2d496105 | Michael Roth | static void test_nested_struct(gconstpointer opaque) |
303 | 2d496105 | Michael Roth | { |
304 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
305 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
306 | 2d496105 | Michael Roth | UserDefNested *udnp = nested_struct_create(); |
307 | 2d496105 | Michael Roth | UserDefNested *udnp_copy = NULL;
|
308 | 2d496105 | Michael Roth | Error *err = NULL;
|
309 | 2d496105 | Michael Roth | void *serialize_data;
|
310 | 2d496105 | Michael Roth | |
311 | 2d496105 | Michael Roth | ops->serialize(udnp, &serialize_data, visit_nested_struct, &err); |
312 | 2d496105 | Michael Roth | ops->deserialize((void **)&udnp_copy, serialize_data, visit_nested_struct, &err);
|
313 | 2d496105 | Michael Roth | |
314 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
315 | 2d496105 | Michael Roth | nested_struct_compare(udnp, udnp_copy); |
316 | 2d496105 | Michael Roth | |
317 | 2d496105 | Michael Roth | nested_struct_cleanup(udnp); |
318 | 2d496105 | Michael Roth | nested_struct_cleanup(udnp_copy); |
319 | 2d496105 | Michael Roth | |
320 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
321 | 2d496105 | Michael Roth | g_free(args); |
322 | 2d496105 | Michael Roth | } |
323 | 2d496105 | Michael Roth | |
324 | 2d496105 | Michael Roth | static void test_nested_struct_list(gconstpointer opaque) |
325 | 2d496105 | Michael Roth | { |
326 | 2d496105 | Michael Roth | TestArgs *args = (TestArgs *) opaque; |
327 | 2d496105 | Michael Roth | const SerializeOps *ops = args->ops;
|
328 | 2d496105 | Michael Roth | UserDefNestedList *listp = NULL, *tmp, *tmp_copy, *listp_copy = NULL; |
329 | 2d496105 | Michael Roth | Error *err = NULL;
|
330 | 2d496105 | Michael Roth | void *serialize_data;
|
331 | 2d496105 | Michael Roth | int i = 0; |
332 | 2d496105 | Michael Roth | |
333 | 2d496105 | Michael Roth | for (i = 0; i < 8; i++) { |
334 | 2d496105 | Michael Roth | tmp = g_malloc0(sizeof(UserDefNestedList));
|
335 | 2d496105 | Michael Roth | tmp->value = nested_struct_create(); |
336 | 2d496105 | Michael Roth | tmp->next = listp; |
337 | 2d496105 | Michael Roth | listp = tmp; |
338 | 2d496105 | Michael Roth | } |
339 | 2d496105 | Michael Roth | |
340 | 2d496105 | Michael Roth | ops->serialize(listp, &serialize_data, visit_nested_struct_list, &err); |
341 | 2d496105 | Michael Roth | ops->deserialize((void **)&listp_copy, serialize_data,
|
342 | 2d496105 | Michael Roth | visit_nested_struct_list, &err); |
343 | 2d496105 | Michael Roth | |
344 | 2d496105 | Michael Roth | g_assert(err == NULL);
|
345 | 2d496105 | Michael Roth | |
346 | 2d496105 | Michael Roth | tmp = listp; |
347 | 2d496105 | Michael Roth | tmp_copy = listp_copy; |
348 | 2d496105 | Michael Roth | while (listp_copy) {
|
349 | 2d496105 | Michael Roth | g_assert(listp); |
350 | 2d496105 | Michael Roth | nested_struct_compare(listp->value, listp_copy->value); |
351 | 2d496105 | Michael Roth | listp = listp->next; |
352 | 2d496105 | Michael Roth | listp_copy = listp_copy->next; |
353 | 2d496105 | Michael Roth | } |
354 | 2d496105 | Michael Roth | |
355 | 2d496105 | Michael Roth | qapi_free_UserDefNestedList(tmp); |
356 | 2d496105 | Michael Roth | qapi_free_UserDefNestedList(tmp_copy); |
357 | 2d496105 | Michael Roth | |
358 | 2d496105 | Michael Roth | ops->cleanup(serialize_data); |
359 | 2d496105 | Michael Roth | g_free(args); |
360 | 2d496105 | Michael Roth | } |
361 | 2d496105 | Michael Roth | |
362 | 2d496105 | Michael Roth | PrimitiveType pt_values[] = { |
363 | 2d496105 | Michael Roth | /* string tests */
|
364 | 2d496105 | Michael Roth | { |
365 | 2d496105 | Michael Roth | .description = "string_empty",
|
366 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
367 | 2d496105 | Michael Roth | .value.string = "",
|
368 | 2d496105 | Michael Roth | }, |
369 | 2d496105 | Michael Roth | { |
370 | 2d496105 | Michael Roth | .description = "string_whitespace",
|
371 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
372 | 2d496105 | Michael Roth | .value.string = "a b c\td",
|
373 | 2d496105 | Michael Roth | }, |
374 | 2d496105 | Michael Roth | { |
375 | 2d496105 | Michael Roth | .description = "string_newlines",
|
376 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
377 | 2d496105 | Michael Roth | .value.string = "a\nb\n",
|
378 | 2d496105 | Michael Roth | }, |
379 | 2d496105 | Michael Roth | { |
380 | 2d496105 | Michael Roth | .description = "string_commas",
|
381 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
382 | 2d496105 | Michael Roth | .value.string = "a,b, c,d",
|
383 | 2d496105 | Michael Roth | }, |
384 | 2d496105 | Michael Roth | { |
385 | 2d496105 | Michael Roth | .description = "string_single_quoted",
|
386 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
387 | 2d496105 | Michael Roth | .value.string = "'a b',cd",
|
388 | 2d496105 | Michael Roth | }, |
389 | 2d496105 | Michael Roth | { |
390 | 2d496105 | Michael Roth | .description = "string_double_quoted",
|
391 | 2d496105 | Michael Roth | .type = PTYPE_STRING, |
392 | 2d496105 | Michael Roth | .value.string = "\"a b\",cd",
|
393 | 2d496105 | Michael Roth | }, |
394 | 2d496105 | Michael Roth | /* boolean tests */
|
395 | 2d496105 | Michael Roth | { |
396 | 2d496105 | Michael Roth | .description = "boolean_true1",
|
397 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
398 | 2d496105 | Michael Roth | .value.boolean = true,
|
399 | 2d496105 | Michael Roth | }, |
400 | 2d496105 | Michael Roth | { |
401 | 2d496105 | Michael Roth | .description = "boolean_true2",
|
402 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
403 | 2d496105 | Michael Roth | .value.boolean = 8,
|
404 | 2d496105 | Michael Roth | }, |
405 | 2d496105 | Michael Roth | { |
406 | 2d496105 | Michael Roth | .description = "boolean_true3",
|
407 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
408 | 2d496105 | Michael Roth | .value.boolean = -1,
|
409 | 2d496105 | Michael Roth | }, |
410 | 2d496105 | Michael Roth | { |
411 | 2d496105 | Michael Roth | .description = "boolean_false1",
|
412 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
413 | 2d496105 | Michael Roth | .value.boolean = false,
|
414 | 2d496105 | Michael Roth | }, |
415 | 2d496105 | Michael Roth | { |
416 | 2d496105 | Michael Roth | .description = "boolean_false2",
|
417 | 2d496105 | Michael Roth | .type = PTYPE_BOOLEAN, |
418 | 2d496105 | Michael Roth | .value.boolean = 0,
|
419 | 2d496105 | Michael Roth | }, |
420 | 2d496105 | Michael Roth | /* number tests (double) */
|
421 | 2d496105 | Michael Roth | /* note: we format these to %.6f before comparing, since that's how
|
422 | 2d496105 | Michael Roth | * we serialize them and it doesn't make sense to check precision
|
423 | 2d496105 | Michael Roth | * beyond that.
|
424 | 2d496105 | Michael Roth | */
|
425 | 2d496105 | Michael Roth | { |
426 | 2d496105 | Michael Roth | .description = "number_sanity1",
|
427 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
428 | 2d496105 | Michael Roth | .value.number = -1,
|
429 | 2d496105 | Michael Roth | }, |
430 | 2d496105 | Michael Roth | { |
431 | 2d496105 | Michael Roth | .description = "number_sanity2",
|
432 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
433 | 2d496105 | Michael Roth | .value.number = 3.14159265, |
434 | 2d496105 | Michael Roth | }, |
435 | 2d496105 | Michael Roth | { |
436 | 2d496105 | Michael Roth | .description = "number_min",
|
437 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
438 | 2d496105 | Michael Roth | .value.number = DBL_MIN, |
439 | 2d496105 | Michael Roth | }, |
440 | 2d496105 | Michael Roth | { |
441 | 2d496105 | Michael Roth | .description = "number_max",
|
442 | 2d496105 | Michael Roth | .type = PTYPE_NUMBER, |
443 | 2d496105 | Michael Roth | .value.number = DBL_MAX, |
444 | 2d496105 | Michael Roth | }, |
445 | 2d496105 | Michael Roth | /* integer tests (int64) */
|
446 | 2d496105 | Michael Roth | { |
447 | 2d496105 | Michael Roth | .description = "integer_sanity1",
|
448 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
449 | 2d496105 | Michael Roth | .value.integer = -1,
|
450 | 2d496105 | Michael Roth | }, |
451 | 2d496105 | Michael Roth | { |
452 | 2d496105 | Michael Roth | .description = "integer_sanity2",
|
453 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
454 | 2d496105 | Michael Roth | .value.integer = INT64_MAX / 2 + 1, |
455 | 2d496105 | Michael Roth | }, |
456 | 2d496105 | Michael Roth | { |
457 | 2d496105 | Michael Roth | .description = "integer_min",
|
458 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
459 | 2d496105 | Michael Roth | .value.integer = INT64_MIN, |
460 | 2d496105 | Michael Roth | }, |
461 | 2d496105 | Michael Roth | { |
462 | 2d496105 | Michael Roth | .description = "integer_max",
|
463 | 2d496105 | Michael Roth | .type = PTYPE_INTEGER, |
464 | 2d496105 | Michael Roth | .value.integer = INT64_MAX, |
465 | 2d496105 | Michael Roth | }, |
466 | 2d496105 | Michael Roth | /* uint8 tests */
|
467 | 2d496105 | Michael Roth | { |
468 | 2d496105 | Michael Roth | .description = "uint8_sanity1",
|
469 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
470 | 2d496105 | Michael Roth | .value.u8 = 1,
|
471 | 2d496105 | Michael Roth | }, |
472 | 2d496105 | Michael Roth | { |
473 | 2d496105 | Michael Roth | .description = "uint8_sanity2",
|
474 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
475 | 2d496105 | Michael Roth | .value.u8 = UINT8_MAX / 2 + 1, |
476 | 2d496105 | Michael Roth | }, |
477 | 2d496105 | Michael Roth | { |
478 | 2d496105 | Michael Roth | .description = "uint8_min",
|
479 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
480 | 2d496105 | Michael Roth | .value.u8 = 0,
|
481 | 2d496105 | Michael Roth | }, |
482 | 2d496105 | Michael Roth | { |
483 | 2d496105 | Michael Roth | .description = "uint8_max",
|
484 | 2d496105 | Michael Roth | .type = PTYPE_U8, |
485 | 2d496105 | Michael Roth | .value.u8 = UINT8_MAX, |
486 | 2d496105 | Michael Roth | }, |
487 | 2d496105 | Michael Roth | /* uint16 tests */
|
488 | 2d496105 | Michael Roth | { |
489 | 2d496105 | Michael Roth | .description = "uint16_sanity1",
|
490 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
491 | 2d496105 | Michael Roth | .value.u16 = 1,
|
492 | 2d496105 | Michael Roth | }, |
493 | 2d496105 | Michael Roth | { |
494 | 2d496105 | Michael Roth | .description = "uint16_sanity2",
|
495 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
496 | 2d496105 | Michael Roth | .value.u16 = UINT16_MAX / 2 + 1, |
497 | 2d496105 | Michael Roth | }, |
498 | 2d496105 | Michael Roth | { |
499 | 2d496105 | Michael Roth | .description = "uint16_min",
|
500 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
501 | 2d496105 | Michael Roth | .value.u16 = 0,
|
502 | 2d496105 | Michael Roth | }, |
503 | 2d496105 | Michael Roth | { |
504 | 2d496105 | Michael Roth | .description = "uint16_max",
|
505 | 2d496105 | Michael Roth | .type = PTYPE_U16, |
506 | 2d496105 | Michael Roth | .value.u16 = UINT16_MAX, |
507 | 2d496105 | Michael Roth | }, |
508 | 2d496105 | Michael Roth | /* uint32 tests */
|
509 | 2d496105 | Michael Roth | { |
510 | 2d496105 | Michael Roth | .description = "uint32_sanity1",
|
511 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
512 | 2d496105 | Michael Roth | .value.u32 = 1,
|
513 | 2d496105 | Michael Roth | }, |
514 | 2d496105 | Michael Roth | { |
515 | 2d496105 | Michael Roth | .description = "uint32_sanity2",
|
516 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
517 | 2d496105 | Michael Roth | .value.u32 = UINT32_MAX / 2 + 1, |
518 | 2d496105 | Michael Roth | }, |
519 | 2d496105 | Michael Roth | { |
520 | 2d496105 | Michael Roth | .description = "uint32_min",
|
521 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
522 | 2d496105 | Michael Roth | .value.u32 = 0,
|
523 | 2d496105 | Michael Roth | }, |
524 | 2d496105 | Michael Roth | { |
525 | 2d496105 | Michael Roth | .description = "uint32_max",
|
526 | 2d496105 | Michael Roth | .type = PTYPE_U32, |
527 | 2d496105 | Michael Roth | .value.u32 = UINT32_MAX, |
528 | 2d496105 | Michael Roth | }, |
529 | 2d496105 | Michael Roth | /* uint64 tests */
|
530 | 2d496105 | Michael Roth | { |
531 | 2d496105 | Michael Roth | .description = "uint64_sanity1",
|
532 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
533 | 2d496105 | Michael Roth | .value.u64 = 1,
|
534 | 2d496105 | Michael Roth | }, |
535 | 2d496105 | Michael Roth | { |
536 | 2d496105 | Michael Roth | .description = "uint64_sanity2",
|
537 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
538 | 2d496105 | Michael Roth | .value.u64 = UINT64_MAX / 2 + 1, |
539 | 2d496105 | Michael Roth | }, |
540 | 2d496105 | Michael Roth | { |
541 | 2d496105 | Michael Roth | .description = "uint64_min",
|
542 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
543 | 2d496105 | Michael Roth | .value.u64 = 0,
|
544 | 2d496105 | Michael Roth | }, |
545 | 2d496105 | Michael Roth | { |
546 | 2d496105 | Michael Roth | .description = "uint64_max",
|
547 | 2d496105 | Michael Roth | .type = PTYPE_U64, |
548 | 2d496105 | Michael Roth | .value.u64 = UINT64_MAX, |
549 | 2d496105 | Michael Roth | }, |
550 | 2d496105 | Michael Roth | /* int8 tests */
|
551 | 2d496105 | Michael Roth | { |
552 | 2d496105 | Michael Roth | .description = "int8_sanity1",
|
553 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
554 | 2d496105 | Michael Roth | .value.s8 = -1,
|
555 | 2d496105 | Michael Roth | }, |
556 | 2d496105 | Michael Roth | { |
557 | 2d496105 | Michael Roth | .description = "int8_sanity2",
|
558 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
559 | 2d496105 | Michael Roth | .value.s8 = INT8_MAX / 2 + 1, |
560 | 2d496105 | Michael Roth | }, |
561 | 2d496105 | Michael Roth | { |
562 | 2d496105 | Michael Roth | .description = "int8_min",
|
563 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
564 | 2d496105 | Michael Roth | .value.s8 = INT8_MIN, |
565 | 2d496105 | Michael Roth | }, |
566 | 2d496105 | Michael Roth | { |
567 | 2d496105 | Michael Roth | .description = "int8_max",
|
568 | 2d496105 | Michael Roth | .type = PTYPE_S8, |
569 | 2d496105 | Michael Roth | .value.s8 = INT8_MAX, |
570 | 2d496105 | Michael Roth | }, |
571 | 2d496105 | Michael Roth | /* int16 tests */
|
572 | 2d496105 | Michael Roth | { |
573 | 2d496105 | Michael Roth | .description = "int16_sanity1",
|
574 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
575 | 2d496105 | Michael Roth | .value.s16 = -1,
|
576 | 2d496105 | Michael Roth | }, |
577 | 2d496105 | Michael Roth | { |
578 | 2d496105 | Michael Roth | .description = "int16_sanity2",
|
579 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
580 | 2d496105 | Michael Roth | .value.s16 = INT16_MAX / 2 + 1, |
581 | 2d496105 | Michael Roth | }, |
582 | 2d496105 | Michael Roth | { |
583 | 2d496105 | Michael Roth | .description = "int16_min",
|
584 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
585 | 2d496105 | Michael Roth | .value.s16 = INT16_MIN, |
586 | 2d496105 | Michael Roth | }, |
587 | 2d496105 | Michael Roth | { |
588 | 2d496105 | Michael Roth | .description = "int16_max",
|
589 | 2d496105 | Michael Roth | .type = PTYPE_S16, |
590 | 2d496105 | Michael Roth | .value.s16 = INT16_MAX, |
591 | 2d496105 | Michael Roth | }, |
592 | 2d496105 | Michael Roth | /* int32 tests */
|
593 | 2d496105 | Michael Roth | { |
594 | 2d496105 | Michael Roth | .description = "int32_sanity1",
|
595 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
596 | 2d496105 | Michael Roth | .value.s32 = -1,
|
597 | 2d496105 | Michael Roth | }, |
598 | 2d496105 | Michael Roth | { |
599 | 2d496105 | Michael Roth | .description = "int32_sanity2",
|
600 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
601 | 2d496105 | Michael Roth | .value.s32 = INT32_MAX / 2 + 1, |
602 | 2d496105 | Michael Roth | }, |
603 | 2d496105 | Michael Roth | { |
604 | 2d496105 | Michael Roth | .description = "int32_min",
|
605 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
606 | 2d496105 | Michael Roth | .value.s32 = INT32_MIN, |
607 | 2d496105 | Michael Roth | }, |
608 | 2d496105 | Michael Roth | { |
609 | 2d496105 | Michael Roth | .description = "int32_max",
|
610 | 2d496105 | Michael Roth | .type = PTYPE_S32, |
611 | 2d496105 | Michael Roth | .value.s32 = INT32_MAX, |
612 | 2d496105 | Michael Roth | }, |
613 | 2d496105 | Michael Roth | /* int64 tests */
|
614 | 2d496105 | Michael Roth | { |
615 | 2d496105 | Michael Roth | .description = "int64_sanity1",
|
616 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
617 | 2d496105 | Michael Roth | .value.s64 = -1,
|
618 | 2d496105 | Michael Roth | }, |
619 | 2d496105 | Michael Roth | { |
620 | 2d496105 | Michael Roth | .description = "int64_sanity2",
|
621 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
622 | 2d496105 | Michael Roth | .value.s64 = INT64_MAX / 2 + 1, |
623 | 2d496105 | Michael Roth | }, |
624 | 2d496105 | Michael Roth | { |
625 | 2d496105 | Michael Roth | .description = "int64_min",
|
626 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
627 | 2d496105 | Michael Roth | .value.s64 = INT64_MIN, |
628 | 2d496105 | Michael Roth | }, |
629 | 2d496105 | Michael Roth | { |
630 | 2d496105 | Michael Roth | .description = "int64_max",
|
631 | 2d496105 | Michael Roth | .type = PTYPE_S64, |
632 | 2d496105 | Michael Roth | .value.s64 = INT64_MAX, |
633 | 2d496105 | Michael Roth | }, |
634 | 2d496105 | Michael Roth | { .type = PTYPE_EOL } |
635 | 2d496105 | Michael Roth | }; |
636 | 2d496105 | Michael Roth | |
637 | 2d496105 | Michael Roth | /* visitor-specific op implementations */
|
638 | 2d496105 | Michael Roth | |
639 | 2d496105 | Michael Roth | typedef struct QmpSerializeData { |
640 | 2d496105 | Michael Roth | QmpOutputVisitor *qov; |
641 | 2d496105 | Michael Roth | QmpInputVisitor *qiv; |
642 | 2d496105 | Michael Roth | } QmpSerializeData; |
643 | 2d496105 | Michael Roth | |
644 | 2d496105 | Michael Roth | static void qmp_serialize(void *native_in, void **datap, |
645 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp) |
646 | 2d496105 | Michael Roth | { |
647 | 2d496105 | Michael Roth | QmpSerializeData *d = g_malloc0(sizeof(*d));
|
648 | 2d496105 | Michael Roth | |
649 | 2d496105 | Michael Roth | d->qov = qmp_output_visitor_new(); |
650 | 2d496105 | Michael Roth | visit(qmp_output_get_visitor(d->qov), &native_in, errp); |
651 | 2d496105 | Michael Roth | *datap = d; |
652 | 2d496105 | Michael Roth | } |
653 | 2d496105 | Michael Roth | |
654 | 2d496105 | Michael Roth | static void qmp_deserialize(void **native_out, void *datap, |
655 | 2d496105 | Michael Roth | VisitorFunc visit, Error **errp) |
656 | 2d496105 | Michael Roth | { |
657 | 2d496105 | Michael Roth | QmpSerializeData *d = datap; |
658 | 2d496105 | Michael Roth | QString *output_json = qobject_to_json(qmp_output_get_qobject(d->qov)); |
659 | 2d496105 | Michael Roth | QObject *obj = qobject_from_json(qstring_get_str(output_json)); |
660 | 2d496105 | Michael Roth | |
661 | 2d496105 | Michael Roth | QDECREF(output_json); |
662 | 2d496105 | Michael Roth | d->qiv = qmp_input_visitor_new(obj); |
663 | 2d496105 | Michael Roth | visit(qmp_input_get_visitor(d->qiv), native_out, errp); |
664 | 2d496105 | Michael Roth | } |
665 | 2d496105 | Michael Roth | |
666 | 2d496105 | Michael Roth | static void qmp_cleanup(void *datap) |
667 | 2d496105 | Michael Roth | { |
668 | 2d496105 | Michael Roth | QmpSerializeData *d = datap; |
669 | 2d496105 | Michael Roth | qmp_output_visitor_cleanup(d->qov); |
670 | 2d496105 | Michael Roth | qmp_input_visitor_cleanup(d->qiv); |
671 | 2d496105 | Michael Roth | } |
672 | 2d496105 | Michael Roth | |
673 | 0d30b0a2 | Michael Roth | typedef struct StringSerializeData { |
674 | 0d30b0a2 | Michael Roth | StringOutputVisitor *sov; |
675 | 0d30b0a2 | Michael Roth | StringInputVisitor *siv; |
676 | 0d30b0a2 | Michael Roth | } StringSerializeData; |
677 | 0d30b0a2 | Michael Roth | |
678 | 0d30b0a2 | Michael Roth | static void string_serialize(void *native_in, void **datap, |
679 | 0d30b0a2 | Michael Roth | VisitorFunc visit, Error **errp) |
680 | 0d30b0a2 | Michael Roth | { |
681 | 0d30b0a2 | Michael Roth | StringSerializeData *d = g_malloc0(sizeof(*d));
|
682 | 0d30b0a2 | Michael Roth | |
683 | 0d30b0a2 | Michael Roth | d->sov = string_output_visitor_new(); |
684 | 0d30b0a2 | Michael Roth | visit(string_output_get_visitor(d->sov), &native_in, errp); |
685 | 0d30b0a2 | Michael Roth | *datap = d; |
686 | 0d30b0a2 | Michael Roth | } |
687 | 0d30b0a2 | Michael Roth | |
688 | 0d30b0a2 | Michael Roth | static void string_deserialize(void **native_out, void *datap, |
689 | 0d30b0a2 | Michael Roth | VisitorFunc visit, Error **errp) |
690 | 0d30b0a2 | Michael Roth | { |
691 | 0d30b0a2 | Michael Roth | StringSerializeData *d = datap; |
692 | 0d30b0a2 | Michael Roth | |
693 | 0d30b0a2 | Michael Roth | d->siv = string_input_visitor_new(string_output_get_string(d->sov)); |
694 | 0d30b0a2 | Michael Roth | visit(string_input_get_visitor(d->siv), native_out, errp); |
695 | 0d30b0a2 | Michael Roth | } |
696 | 0d30b0a2 | Michael Roth | |
697 | 0d30b0a2 | Michael Roth | static void string_cleanup(void *datap) |
698 | 0d30b0a2 | Michael Roth | { |
699 | 0d30b0a2 | Michael Roth | StringSerializeData *d = datap; |
700 | 0d30b0a2 | Michael Roth | string_output_visitor_cleanup(d->sov); |
701 | 0d30b0a2 | Michael Roth | string_input_visitor_cleanup(d->siv); |
702 | 0d30b0a2 | Michael Roth | } |
703 | 0d30b0a2 | Michael Roth | |
704 | 2d496105 | Michael Roth | /* visitor registration, test harness */
|
705 | 2d496105 | Michael Roth | |
706 | 2d496105 | Michael Roth | /* note: to function interchangeably as a serialization mechanism your
|
707 | 2d496105 | Michael Roth | * visitor test implementation should pass the test cases for all visitor
|
708 | 2d496105 | Michael Roth | * capabilities: primitives, structures, and lists
|
709 | 2d496105 | Michael Roth | */
|
710 | 2d496105 | Michael Roth | static const SerializeOps visitors[] = { |
711 | 2d496105 | Michael Roth | { |
712 | 2d496105 | Michael Roth | .type = "QMP",
|
713 | 2d496105 | Michael Roth | .serialize = qmp_serialize, |
714 | 2d496105 | Michael Roth | .deserialize = qmp_deserialize, |
715 | 2d496105 | Michael Roth | .cleanup = qmp_cleanup, |
716 | 2d496105 | Michael Roth | .caps = VCAP_PRIMITIVES | VCAP_STRUCTURES | VCAP_LISTS |
717 | 2d496105 | Michael Roth | }, |
718 | 0d30b0a2 | Michael Roth | { |
719 | 0d30b0a2 | Michael Roth | .type = "String",
|
720 | 0d30b0a2 | Michael Roth | .serialize = string_serialize, |
721 | 0d30b0a2 | Michael Roth | .deserialize = string_deserialize, |
722 | 0d30b0a2 | Michael Roth | .cleanup = string_cleanup, |
723 | 0d30b0a2 | Michael Roth | .caps = VCAP_PRIMITIVES |
724 | 0d30b0a2 | Michael Roth | }, |
725 | 2d496105 | Michael Roth | { NULL }
|
726 | 2d496105 | Michael Roth | }; |
727 | 2d496105 | Michael Roth | |
728 | 2d496105 | Michael Roth | static void add_visitor_type(const SerializeOps *ops) |
729 | 2d496105 | Michael Roth | { |
730 | 2d496105 | Michael Roth | char testname_prefix[128]; |
731 | 2d496105 | Michael Roth | char testname[128]; |
732 | 2d496105 | Michael Roth | TestArgs *args; |
733 | 2d496105 | Michael Roth | int i = 0; |
734 | 2d496105 | Michael Roth | |
735 | 2d496105 | Michael Roth | sprintf(testname_prefix, "/visitor/serialization/%s", ops->type);
|
736 | 2d496105 | Michael Roth | |
737 | 2d496105 | Michael Roth | if (ops->caps & VCAP_PRIMITIVES) {
|
738 | 2d496105 | Michael Roth | while (pt_values[i].type != PTYPE_EOL) {
|
739 | 2d496105 | Michael Roth | sprintf(testname, "%s/primitives/%s", testname_prefix,
|
740 | 2d496105 | Michael Roth | pt_values[i].description); |
741 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
742 | 2d496105 | Michael Roth | args->ops = ops; |
743 | 2d496105 | Michael Roth | args->test_data = &pt_values[i]; |
744 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_primitives); |
745 | 2d496105 | Michael Roth | i++; |
746 | 2d496105 | Michael Roth | } |
747 | 2d496105 | Michael Roth | } |
748 | 2d496105 | Michael Roth | |
749 | 2d496105 | Michael Roth | if (ops->caps & VCAP_STRUCTURES) {
|
750 | 2d496105 | Michael Roth | sprintf(testname, "%s/struct", testname_prefix);
|
751 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
752 | 2d496105 | Michael Roth | args->ops = ops; |
753 | 2d496105 | Michael Roth | args->test_data = NULL;
|
754 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_struct); |
755 | 2d496105 | Michael Roth | |
756 | 2d496105 | Michael Roth | sprintf(testname, "%s/nested_struct", testname_prefix);
|
757 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
758 | 2d496105 | Michael Roth | args->ops = ops; |
759 | 2d496105 | Michael Roth | args->test_data = NULL;
|
760 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_nested_struct); |
761 | 2d496105 | Michael Roth | } |
762 | 2d496105 | Michael Roth | |
763 | 2d496105 | Michael Roth | if (ops->caps & VCAP_LISTS) {
|
764 | 2d496105 | Michael Roth | sprintf(testname, "%s/nested_struct_list", testname_prefix);
|
765 | 2d496105 | Michael Roth | args = g_malloc0(sizeof(*args));
|
766 | 2d496105 | Michael Roth | args->ops = ops; |
767 | 2d496105 | Michael Roth | args->test_data = NULL;
|
768 | 2d496105 | Michael Roth | g_test_add_data_func(testname, args, test_nested_struct_list); |
769 | 2d496105 | Michael Roth | } |
770 | 2d496105 | Michael Roth | } |
771 | 2d496105 | Michael Roth | |
772 | 2d496105 | Michael Roth | int main(int argc, char **argv) |
773 | 2d496105 | Michael Roth | { |
774 | 2d496105 | Michael Roth | int i = 0; |
775 | 2d496105 | Michael Roth | |
776 | 2d496105 | Michael Roth | g_test_init(&argc, &argv, NULL);
|
777 | 2d496105 | Michael Roth | |
778 | 2d496105 | Michael Roth | while (visitors[i].type != NULL) { |
779 | 2d496105 | Michael Roth | add_visitor_type(&visitors[i]); |
780 | 2d496105 | Michael Roth | i++; |
781 | 2d496105 | Michael Roth | } |
782 | 2d496105 | Michael Roth | |
783 | 2d496105 | Michael Roth | g_test_run(); |
784 | 2d496105 | Michael Roth | |
785 | 2d496105 | Michael Roth | return 0; |
786 | 2d496105 | Michael Roth | } |