Branch data Line data Source code
1 : : /*
2 : : Copyright 2012-2015 David Robillard <http://drobilla.net>
3 : :
4 : : Permission to use, copy, modify, and/or distribute this software for any
5 : : purpose with or without fee is hereby granted, provided that the above
6 : : copyright notice and this permission notice appear in all copies.
7 : :
8 : : THIS SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 : : WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 : : MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 : : ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 : : WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 : : ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 : : OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 : : */
16 : :
17 : : #include "lv2/atom/atom-test-utils.c"
18 : : #include "lv2/atom/atom.h"
19 : : #include "lv2/atom/forge.h"
20 : : #include "lv2/atom/util.h"
21 : : #include "lv2/urid/urid.h"
22 : :
23 : : #include <stdint.h>
24 : : #include <stdlib.h>
25 : :
26 : : int
27 : 1 : main(void)
28 : : {
29 : 1 : LV2_URID_Map map = { NULL, urid_map };
30 : : LV2_Atom_Forge forge;
31 : 1 : lv2_atom_forge_init(&forge, &map);
32 : :
33 : 1 : LV2_URID eg_Object = urid_map(NULL, "http://example.org/Object");
34 : 1 : LV2_URID eg_one = urid_map(NULL, "http://example.org/one");
35 : 1 : LV2_URID eg_two = urid_map(NULL, "http://example.org/two");
36 : 1 : LV2_URID eg_three = urid_map(NULL, "http://example.org/three");
37 : 1 : LV2_URID eg_four = urid_map(NULL, "http://example.org/four");
38 : 1 : LV2_URID eg_true = urid_map(NULL, "http://example.org/true");
39 : 1 : LV2_URID eg_false = urid_map(NULL, "http://example.org/false");
40 : 1 : LV2_URID eg_path = urid_map(NULL, "http://example.org/path");
41 : 1 : LV2_URID eg_uri = urid_map(NULL, "http://example.org/uri");
42 : 1 : LV2_URID eg_urid = urid_map(NULL, "http://example.org/urid");
43 : 1 : LV2_URID eg_string = urid_map(NULL, "http://example.org/string");
44 : 1 : LV2_URID eg_literal = urid_map(NULL, "http://example.org/literal");
45 : 1 : LV2_URID eg_tuple = urid_map(NULL, "http://example.org/tuple");
46 : 1 : LV2_URID eg_vector = urid_map(NULL, "http://example.org/vector");
47 : 1 : LV2_URID eg_vector2 = urid_map(NULL, "http://example.org/vector2");
48 : 1 : LV2_URID eg_seq = urid_map(NULL, "http://example.org/seq");
49 : :
50 : : #define BUF_SIZE 1024
51 : : #define NUM_PROPS 15
52 : :
53 : : uint8_t buf[BUF_SIZE];
54 : 1 : lv2_atom_forge_set_buffer(&forge, buf, BUF_SIZE);
55 : :
56 : : LV2_Atom_Forge_Frame obj_frame;
57 : 1 : LV2_Atom* obj = lv2_atom_forge_deref(
58 : : &forge, lv2_atom_forge_object(&forge, &obj_frame, 0, eg_Object));
59 : :
60 : : // eg_one = (Int)1
61 : 1 : lv2_atom_forge_key(&forge, eg_one);
62 : 1 : LV2_Atom_Int* one = (LV2_Atom_Int*)lv2_atom_forge_deref(
63 : : &forge, lv2_atom_forge_int(&forge, 1));
64 [ - + ]: 1 : if (one->body != 1) {
65 : 0 : return test_fail("%d != 1\n", one->body);
66 : : }
67 : :
68 : : // eg_two = (Long)2
69 : 1 : lv2_atom_forge_key(&forge, eg_two);
70 : 1 : LV2_Atom_Long* two = (LV2_Atom_Long*)lv2_atom_forge_deref(
71 : : &forge, lv2_atom_forge_long(&forge, 2));
72 [ - + ]: 1 : if (two->body != 2) {
73 : 0 : return test_fail("%ld != 2\n", two->body);
74 : : }
75 : :
76 : : // eg_three = (Float)3.0
77 : 1 : lv2_atom_forge_key(&forge, eg_three);
78 : 1 : LV2_Atom_Float* three = (LV2_Atom_Float*)lv2_atom_forge_deref(
79 : : &forge, lv2_atom_forge_float(&forge, 3.0f));
80 [ - + ]: 1 : if (three->body != 3) {
81 : 0 : return test_fail("%f != 3\n", three->body);
82 : : }
83 : :
84 : : // eg_four = (Double)4.0
85 : 1 : lv2_atom_forge_key(&forge, eg_four);
86 : 1 : LV2_Atom_Double* four = (LV2_Atom_Double*)lv2_atom_forge_deref(
87 : : &forge, lv2_atom_forge_double(&forge, 4.0));
88 [ - + ]: 1 : if (four->body != 4) {
89 : 0 : return test_fail("%ld != 4\n", four->body);
90 : : }
91 : :
92 : : // eg_true = (Bool)1
93 : 1 : lv2_atom_forge_key(&forge, eg_true);
94 : 1 : LV2_Atom_Bool* t = (LV2_Atom_Bool*)lv2_atom_forge_deref(
95 : : &forge, lv2_atom_forge_bool(&forge, true));
96 [ - + ]: 1 : if (t->body != 1) {
97 : 0 : return test_fail("%ld != 1 (true)\n", t->body);
98 : : }
99 : :
100 : : // eg_false = (Bool)0
101 : 1 : lv2_atom_forge_key(&forge, eg_false);
102 : 1 : LV2_Atom_Bool* f = (LV2_Atom_Bool*)lv2_atom_forge_deref(
103 : : &forge, lv2_atom_forge_bool(&forge, false));
104 [ - + ]: 1 : if (f->body != 0) {
105 : 0 : return test_fail("%ld != 0 (false)\n", f->body);
106 : : }
107 : :
108 : : // eg_path = (Path)"/foo/bar"
109 : 1 : const char* pstr = "/foo/bar";
110 : 1 : const uint32_t pstr_len = (uint32_t)strlen(pstr);
111 : 1 : lv2_atom_forge_key(&forge, eg_path);
112 : 1 : LV2_Atom_String* path = (LV2_Atom_String*)lv2_atom_forge_deref(
113 : : &forge, lv2_atom_forge_uri(&forge, pstr, pstr_len));
114 : 1 : char* pbody = (char*)LV2_ATOM_BODY(path);
115 [ - + ]: 1 : if (strcmp(pbody, pstr)) {
116 : 0 : return test_fail("%s != \"%s\"\n", pbody, pstr);
117 : : }
118 : :
119 : : // eg_uri = (URI)"http://example.org/value"
120 : 1 : const char* ustr = "http://example.org/value";
121 : 1 : const uint32_t ustr_len = (uint32_t)strlen(ustr);
122 : 1 : lv2_atom_forge_key(&forge, eg_uri);
123 : 1 : LV2_Atom_String* uri = (LV2_Atom_String*)lv2_atom_forge_deref(
124 : : &forge, lv2_atom_forge_uri(&forge, ustr, ustr_len));
125 : 1 : char* ubody = (char*)LV2_ATOM_BODY(uri);
126 [ - + ]: 1 : if (strcmp(ubody, ustr)) {
127 : 0 : return test_fail("%s != \"%s\"\n", ubody, ustr);
128 : : }
129 : :
130 : : // eg_urid = (URID)"http://example.org/value"
131 : 1 : LV2_URID eg_value = urid_map(NULL, "http://example.org/value");
132 : 1 : lv2_atom_forge_key(&forge, eg_urid);
133 : 1 : LV2_Atom_URID* urid = (LV2_Atom_URID*)lv2_atom_forge_deref(
134 : : &forge, lv2_atom_forge_urid(&forge, eg_value));
135 [ - + ]: 1 : if (urid->body != eg_value) {
136 : 0 : return test_fail("%u != %u\n", urid->body, eg_value);
137 : : }
138 : :
139 : : // eg_string = (String)"hello"
140 : 1 : lv2_atom_forge_key(&forge, eg_string);
141 : 1 : LV2_Atom_String* string = (LV2_Atom_String*)lv2_atom_forge_deref(
142 : : &forge, lv2_atom_forge_string(
143 : : &forge, "hello", strlen("hello")));
144 : 1 : char* sbody = (char*)LV2_ATOM_BODY(string);
145 [ - + ]: 1 : if (strcmp(sbody, "hello")) {
146 : 0 : return test_fail("%s != \"hello\"\n", sbody);
147 : : }
148 : :
149 : : // eg_literal = (Literal)"hello"@fr
150 : 1 : lv2_atom_forge_key(&forge, eg_literal);
151 : 1 : LV2_Atom_Literal* literal = (LV2_Atom_Literal*)lv2_atom_forge_deref(
152 : : &forge, lv2_atom_forge_literal(
153 : : &forge, "bonjour", strlen("bonjour"),
154 : : 0, urid_map(NULL, "http://lexvo.org/id/term/fr")));
155 : 1 : char* lbody = (char*)LV2_ATOM_CONTENTS(LV2_Atom_Literal, literal);
156 [ - + ]: 1 : if (strcmp(lbody, "bonjour")) {
157 : 0 : return test_fail("%s != \"bonjour\"\n", lbody);
158 : : }
159 : :
160 : : // eg_tuple = "foo",true
161 : 1 : lv2_atom_forge_key(&forge, eg_tuple);
162 : : LV2_Atom_Forge_Frame tuple_frame;
163 : 1 : LV2_Atom_Tuple* tuple = (LV2_Atom_Tuple*)lv2_atom_forge_deref(
164 : : &forge, lv2_atom_forge_tuple(&forge, &tuple_frame));
165 : 1 : LV2_Atom_String* tup0 = (LV2_Atom_String*)lv2_atom_forge_deref(
166 : : &forge, lv2_atom_forge_string(
167 : : &forge, "foo", strlen("foo")));
168 : 1 : LV2_Atom_Bool* tup1 = (LV2_Atom_Bool*)lv2_atom_forge_deref(
169 : : &forge, lv2_atom_forge_bool(&forge, true));
170 : 1 : lv2_atom_forge_pop(&forge, &tuple_frame);
171 : 1 : LV2_Atom* i = lv2_atom_tuple_begin(tuple);
172 [ - + ]: 1 : if (lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), tuple->atom.size, i)) {
173 : 0 : return test_fail("Tuple iterator is empty\n");
174 : : }
175 : 1 : LV2_Atom* tup0i = i;
176 [ - + ]: 1 : if (!lv2_atom_equals((LV2_Atom*)tup0, tup0i)) {
177 : 0 : return test_fail("Corrupt tuple element 0\n");
178 : : }
179 : 1 : i = lv2_atom_tuple_next(i);
180 [ - + ]: 1 : if (lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), tuple->atom.size, i)) {
181 : 0 : return test_fail("Premature end of tuple iterator\n");
182 : : }
183 : 1 : LV2_Atom* tup1i = i;
184 [ - + ]: 1 : if (!lv2_atom_equals((LV2_Atom*)tup1, tup1i)) {
185 : 0 : return test_fail("Corrupt tuple element 1\n");
186 : : }
187 : 1 : i = lv2_atom_tuple_next(i);
188 [ - + ]: 1 : if (!lv2_atom_tuple_is_end(LV2_ATOM_BODY(tuple), tuple->atom.size, i)) {
189 : 0 : return test_fail("Tuple iter is not at end\n");
190 : : }
191 : :
192 : : // eg_vector = (Vector<Int>)1,2,3,4
193 : 1 : lv2_atom_forge_key(&forge, eg_vector);
194 : 1 : int32_t elems[] = { 1, 2, 3, 4 };
195 : 1 : LV2_Atom_Vector* vector = (LV2_Atom_Vector*)lv2_atom_forge_deref(
196 : : &forge, lv2_atom_forge_vector(
197 : : &forge, sizeof(int32_t), forge.Int, 4, elems));
198 : 1 : void* vec_body = LV2_ATOM_CONTENTS(LV2_Atom_Vector, vector);
199 [ - + ]: 1 : if (memcmp(elems, vec_body, sizeof(elems))) {
200 : 0 : return test_fail("Corrupt vector\n");
201 : : }
202 : :
203 : : // eg_vector2 = (Vector<Int>)1,2,3,4
204 : 1 : lv2_atom_forge_key(&forge, eg_vector2);
205 : : LV2_Atom_Forge_Frame vec_frame;
206 : 1 : LV2_Atom_Vector* vector2 = (LV2_Atom_Vector*)lv2_atom_forge_deref(
207 : : &forge, lv2_atom_forge_vector_head(
208 : : &forge, &vec_frame, sizeof(int32_t), forge.Int));
209 [ + + ]: 5 : for (unsigned e = 0; e < sizeof(elems) / sizeof(int32_t); ++e) {
210 : 4 : lv2_atom_forge_int(&forge, elems[e]);
211 : : }
212 : 1 : lv2_atom_forge_pop(&forge, &vec_frame);
213 [ - + ]: 1 : if (!lv2_atom_equals(&vector->atom, &vector2->atom)) {
214 : 0 : return test_fail("Vector != Vector2\n");
215 : : }
216 : :
217 : : // eg_seq = (Sequence)1, 2
218 : 1 : lv2_atom_forge_key(&forge, eg_seq);
219 : : LV2_Atom_Forge_Frame seq_frame;
220 : 1 : LV2_Atom_Sequence* seq = (LV2_Atom_Sequence*)lv2_atom_forge_deref(
221 : : &forge, lv2_atom_forge_sequence_head(&forge, &seq_frame, 0));
222 : 1 : lv2_atom_forge_frame_time(&forge, 0);
223 : 1 : lv2_atom_forge_int(&forge, 1);
224 : 1 : lv2_atom_forge_frame_time(&forge, 1);
225 : 1 : lv2_atom_forge_int(&forge, 2);
226 : 1 : lv2_atom_forge_pop(&forge, &seq_frame);
227 : :
228 : 1 : lv2_atom_forge_pop(&forge, &obj_frame);
229 : :
230 : : // Test equality
231 : 1 : LV2_Atom_Int itwo = { { forge.Int, sizeof(int32_t) }, 2 };
232 [ - + ]: 1 : if (lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)two)) {
233 : 0 : return test_fail("1 == 2.0\n");
234 [ - + ]: 1 : } else if (lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)&itwo)) {
235 : 0 : return test_fail("1 == 2\n");
236 [ - + ]: 1 : } else if (!lv2_atom_equals((LV2_Atom*)one, (LV2_Atom*)one)) {
237 : 0 : return test_fail("1 != 1\n");
238 : : }
239 : :
240 : 1 : unsigned n_events = 0;
241 [ + + ]: 3 : LV2_ATOM_SEQUENCE_FOREACH(seq, ev) {
242 [ - + ]: 2 : if (ev->time.frames != n_events) {
243 : 0 : return test_fail("Corrupt event %u has bad time\n", n_events);
244 [ - + ]: 2 : } else if (ev->body.type != forge.Int) {
245 : 0 : return test_fail("Corrupt event %u has bad type\n", n_events);
246 [ - + ]: 2 : } else if (((LV2_Atom_Int*)&ev->body)->body != (int)n_events + 1) {
247 : 0 : return test_fail("Event %u != %d\n", n_events, n_events + 1);
248 : : }
249 : 2 : ++n_events;
250 : : }
251 : :
252 : 1 : int n_props = 0;
253 [ + + ]: 16 : LV2_ATOM_OBJECT_FOREACH((LV2_Atom_Object*)obj, prop) {
254 [ - + ]: 15 : if (!prop->key) {
255 : 0 : return test_fail("Corrupt property %u has no key\n", n_props);
256 [ - + ]: 15 : } else if (prop->context) {
257 : 0 : return test_fail("Corrupt property %u has context\n", n_props);
258 : : }
259 : 15 : ++n_props;
260 : : }
261 : :
262 [ - + ]: 1 : if (n_props != NUM_PROPS) {
263 : 0 : return test_fail("Corrupt object has %u properties != %u\n",
264 : : n_props, NUM_PROPS);
265 : : }
266 : :
267 : : struct {
268 : : const LV2_Atom* one;
269 : : const LV2_Atom* two;
270 : : const LV2_Atom* three;
271 : : const LV2_Atom* four;
272 : : const LV2_Atom* affirmative;
273 : : const LV2_Atom* negative;
274 : : const LV2_Atom* path;
275 : : const LV2_Atom* uri;
276 : : const LV2_Atom* urid;
277 : : const LV2_Atom* string;
278 : : const LV2_Atom* literal;
279 : : const LV2_Atom* tuple;
280 : : const LV2_Atom* vector;
281 : : const LV2_Atom* vector2;
282 : : const LV2_Atom* seq;
283 : : } matches;
284 : :
285 : 1 : memset(&matches, 0, sizeof(matches));
286 : :
287 : 1 : LV2_Atom_Object_Query q[] = {
288 : : { eg_one, &matches.one },
289 : : { eg_two, &matches.two },
290 : : { eg_three, &matches.three },
291 : : { eg_four, &matches.four },
292 : : { eg_true, &matches.affirmative },
293 : : { eg_false, &matches.negative },
294 : : { eg_path, &matches.path },
295 : : { eg_uri, &matches.uri },
296 : : { eg_urid, &matches.urid },
297 : : { eg_string, &matches.string },
298 : : { eg_literal, &matches.literal },
299 : : { eg_tuple, &matches.tuple },
300 : : { eg_vector, &matches.vector },
301 : : { eg_vector2, &matches.vector2 },
302 : : { eg_seq, &matches.seq },
303 : : LV2_ATOM_OBJECT_QUERY_END
304 : : };
305 : :
306 : 1 : int n_matches = lv2_atom_object_query((LV2_Atom_Object*)obj, q);
307 [ + + ]: 3 : for (int n = 0; n < 2; ++n) {
308 [ - + ]: 2 : if (n_matches != n_props) {
309 : 0 : return test_fail("Query failed, %u matches != %u\n",
310 : : n_matches, n_props);
311 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)one, matches.one)) {
312 : 0 : return test_fail("Bad match one\n");
313 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)two, matches.two)) {
314 : 0 : return test_fail("Bad match two\n");
315 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)three, matches.three)) {
316 : 0 : return test_fail("Bad match three\n");
317 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)four, matches.four)) {
318 : 0 : return test_fail("Bad match four\n");
319 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)t, matches.affirmative)) {
320 : 0 : return test_fail("Bad match true\n");
321 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)f, matches.negative)) {
322 : 0 : return test_fail("Bad match false\n");
323 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)path, matches.path)) {
324 : 0 : return test_fail("Bad match path\n");
325 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)uri, matches.uri)) {
326 : 0 : return test_fail("Bad match URI\n");
327 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)string, matches.string)) {
328 : 0 : return test_fail("Bad match string\n");
329 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)literal, matches.literal)) {
330 : 0 : return test_fail("Bad match literal\n");
331 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)tuple, matches.tuple)) {
332 : 0 : return test_fail("Bad match tuple\n");
333 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)vector, matches.vector)) {
334 : 0 : return test_fail("Bad match vector\n");
335 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)vector, matches.vector2)) {
336 : 0 : return test_fail("Bad match vector2\n");
337 [ - + ]: 2 : } else if (!lv2_atom_equals((LV2_Atom*)seq, matches.seq)) {
338 : 0 : return test_fail("Bad match sequence\n");
339 : : }
340 : 2 : memset(&matches, 0, sizeof(matches));
341 : 2 : n_matches = lv2_atom_object_get((LV2_Atom_Object*)obj,
342 : : eg_one, &matches.one,
343 : : eg_two, &matches.two,
344 : : eg_three, &matches.three,
345 : : eg_four, &matches.four,
346 : : eg_true, &matches.affirmative,
347 : : eg_false, &matches.negative,
348 : : eg_path, &matches.path,
349 : : eg_uri, &matches.uri,
350 : : eg_urid, &matches.urid,
351 : : eg_string, &matches.string,
352 : : eg_literal, &matches.literal,
353 : : eg_tuple, &matches.tuple,
354 : : eg_vector, &matches.vector,
355 : : eg_vector2, &matches.vector2,
356 : : eg_seq, &matches.seq,
357 : : 0);
358 : : }
359 : :
360 : 1 : free_urid_map();
361 : :
362 : 1 : return 0;
363 : : }
|