PipeWire: builder.h Source File

PipeWire 0.3.66

Loading...
Searching...
No Matches
builder.h
Go to the documentation of this file.
1/* Simple Plugin API
2 *
3 * Copyright © 2018 Wim Taymans
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef SPA_POD_BUILDER_H
26#define SPA_POD_BUILDER_H
27
28#ifdef __cplusplus
29extern "C" {
30#endif
31
41#include <stdarg.h>
42
43#include <spa/utils/hook.h>
44#include <spa/pod/iter.h>
45#include <spa/pod/vararg.h>
46
47struct spa_pod_builder_state {
48 uint32_t offset;
49#define SPA_POD_BUILDER_FLAG_BODY (1<<0)
50#define SPA_POD_BUILDER_FLAG_FIRST (1<<1)
51 uint32_t flags;
52 struct spa_pod_frame *frame;
53};
54
55 struct spa_pod_builder;
56
57 struct spa_pod_builder_callbacks {
58#define SPA_VERSION_POD_BUILDER_CALLBACKS 0
59 uint32_t version;
60
61 int (*overflow) (void *data, uint32_t size);
62};
63
64struct spa_pod_builder {
65 void *data;
66 uint32_t size;
67 uint32_t _padding;
68 struct spa_pod_builder_state state;
69 struct spa_callbacks callbacks;
70};
71
72#define SPA_POD_BUILDER_INIT(buffer,size) ((struct spa_pod_builder){ (buffer), (size), 0, {}, {} })
73
74 static inline void
75 spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builder_state *state)
76{
77 *state = builder->state;
78}
79
80static inline void
81 spa_pod_builder_set_callbacks(struct spa_pod_builder *builder,
82 const struct spa_pod_builder_callbacks *callbacks, void *data)
83{
84 builder->callbacks = SPA_CALLBACKS_INIT(callbacks, data);
85}
86
87static inline void
88 spa_pod_builder_reset(struct spa_pod_builder *builder, struct spa_pod_builder_state *state)
89{
90 struct spa_pod_frame *f;
91 uint32_t size = builder->state.offset - state->offset;
92 builder->state = *state;
93 for (f = builder->state.frame; f ; f = f->parent)
94 f->pod.size -= size;
95}
96
97static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size)
98{
99 *builder = SPA_POD_BUILDER_INIT(data, size);
100}
101
102static inline struct spa_pod *
103 spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
104{
105 uint32_t size = builder->size;
106 if (offset + 8 <= size) {
107 struct spa_pod *pod = SPA_PTROFF(builder->data, offset, struct spa_pod);
108 if (offset + SPA_POD_SIZE(pod) <= size)
109 return pod;
110 }
111 return NULL;
112}
113
114static inline struct spa_pod *
115 spa_pod_builder_frame(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
116{
117 if (frame->offset + SPA_POD_SIZE(&frame->pod) <= builder->size)
118 return SPA_PTROFF(builder->data, frame->offset, struct spa_pod);
119 return NULL;
120}
121
122static inline void
123 spa_pod_builder_push(struct spa_pod_builder *builder,
124 struct spa_pod_frame *frame,
125 const struct spa_pod *pod,
126 uint32_t offset)
127{
128 frame->pod = *pod;
129 frame->offset = offset;
130 frame->parent = builder->state.frame;
131 frame->flags = builder->state.flags;
132 builder->state.frame = frame;
133
134 if (frame->pod.type == SPA_TYPE_Array || frame->pod.type == SPA_TYPE_Choice)
135 builder->state.flags = SPA_POD_BUILDER_FLAG_FIRST | SPA_POD_BUILDER_FLAG_BODY;
136}
137
138static inline int spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t size)
139{
140 int res = 0;
141 struct spa_pod_frame *f;
142 uint32_t offset = builder->state.offset;
143
144 if (offset + size > builder->size) {
145 res = -ENOSPC;
146 if (offset <= builder->size)
147 spa_callbacks_call_res(&builder->callbacks,
148 struct spa_pod_builder_callbacks, res,
149 overflow, 0, offset + size);
150 }
151 if (res == 0 && data)
152 memcpy(SPA_PTROFF(builder->data, offset, void), data, size);
153
154 builder->state.offset += size;
155
156 for (f = builder->state.frame; f ; f = f->parent)
157 f->pod.size += size;
158
159 return res;
160}
161
162static inline int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size)
163{
164 uint64_t zeroes = 0;
165 size = SPA_ROUND_UP_N(size, 8) - size;
166 return size ? spa_pod_builder_raw(builder, &zeroes, size) : 0;
167}
168
169static inline int
170 spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, uint32_t size)
171{
172 int r, res = spa_pod_builder_raw(builder, data, size);
173 if ((r = spa_pod_builder_pad(builder, size)) < 0)
174 res = r;
175 return res;
176}
177
178static inline void *spa_pod_builder_pop(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
179{
180 struct spa_pod *pod;
181
182 if (SPA_FLAG_IS_SET(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST)) {
183 const struct spa_pod p = { 0, SPA_TYPE_None };
184 spa_pod_builder_raw(builder, &p, sizeof(p));
185 }
186 if ((pod = (struct spa_pod*)spa_pod_builder_frame(builder, frame)) != NULL)
187 *pod = frame->pod;
188
189 builder->state.frame = frame->parent;
190 builder->state.flags = frame->flags;
191 spa_pod_builder_pad(builder, builder->state.offset);
192 return pod;
193}
194
195static inline int
196 spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod *p)
197{
198 const void *data;
199 uint32_t size;
200 int r, res;
201
202 if (builder->state.flags == SPA_POD_BUILDER_FLAG_BODY) {
203 data = SPA_POD_BODY_CONST(p);
204 size = SPA_POD_BODY_SIZE(p);
205 } else {
206 data = p;
207 size = SPA_POD_SIZE(p);
208 SPA_FLAG_CLEAR(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST);
209 }
210 res = spa_pod_builder_raw(builder, data, size);
211 if (builder->state.flags != SPA_POD_BUILDER_FLAG_BODY)
212 if ((r = spa_pod_builder_pad(builder, size)) < 0)
213 res = r;
214 return res;
215}
216
217#define SPA_POD_INIT(size,type) ((struct spa_pod) { (size), (type) })
218
219#define SPA_POD_INIT_None() SPA_POD_INIT(0, SPA_TYPE_None)
220
221static inline int spa_pod_builder_none(struct spa_pod_builder *builder)
222{
223 const struct spa_pod p = SPA_POD_INIT_None();
224 return spa_pod_builder_primitive(builder, &p);
225}
226
227static inline int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_t size, uint32_t type)
228{
229 const struct spa_pod p = SPA_POD_INIT(size,type);
230 SPA_FLAG_CLEAR(builder->state.flags, SPA_POD_BUILDER_FLAG_FIRST);
231 return spa_pod_builder_raw(builder, &p, sizeof(p));
232}
233
234#define SPA_POD_INIT_Bool(val) ((struct spa_pod_bool){ { sizeof(uint32_t), SPA_TYPE_Bool }, (val) ? 1 : 0, 0 })
235
236static inline int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val)
237{
238 const struct spa_pod_bool p = SPA_POD_INIT_Bool(val);
239 return spa_pod_builder_primitive(builder, &p.pod);
240}
241
242#define SPA_POD_INIT_Id(val) ((struct spa_pod_id){ { sizeof(uint32_t), SPA_TYPE_Id }, (val), 0 })
243
244static inline int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t val)
245{
246 const struct spa_pod_id p = SPA_POD_INIT_Id(val);
247 return spa_pod_builder_primitive(builder, &p.pod);
248}
249
250#define SPA_POD_INIT_Int(val) ((struct spa_pod_int){ { sizeof(int32_t), SPA_TYPE_Int }, (val), 0 })
251
252static inline int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val)
253{
254 const struct spa_pod_int p = SPA_POD_INIT_Int(val);
255 return spa_pod_builder_primitive(builder, &p.pod);
256}
257
258#define SPA_POD_INIT_Long(val) ((struct spa_pod_long){ { sizeof(int64_t), SPA_TYPE_Long }, (val) })
259
260static inline int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val)
261{
262 const struct spa_pod_long p = SPA_POD_INIT_Long(val);
263 return spa_pod_builder_primitive(builder, &p.pod);
264}
265
266#define SPA_POD_INIT_Float(val) ((struct spa_pod_float){ { sizeof(float), SPA_TYPE_Float }, (val), 0 })
267
268static inline int spa_pod_builder_float(struct spa_pod_builder *builder, float val)
269{
270 const struct spa_pod_float p = SPA_POD_INIT_Float(val);
271 return spa_pod_builder_primitive(builder, &p.pod);
272}
273
274#define SPA_POD_INIT_Double(val) ((struct spa_pod_double){ { sizeof(double), SPA_TYPE_Double }, (val) })
275
276 static inline int spa_pod_builder_double(struct spa_pod_builder *builder, double val)
277{
278 const struct spa_pod_double p = SPA_POD_INIT_Double(val);
279 return spa_pod_builder_primitive(builder, &p.pod);
280}
281
282#define SPA_POD_INIT_String(len) ((struct spa_pod_string){ { (len), SPA_TYPE_String } })
283
284static inline int
285 spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, uint32_t len)
286{
287 int r, res;
288 res = spa_pod_builder_raw(builder, str, len);
289 if ((r = spa_pod_builder_raw(builder, "", 1)) < 0)
290 res = r;
291 if ((r = spa_pod_builder_pad(builder, builder->state.offset)) < 0)
292 res = r;
293 return res;
294}
295
296static inline int
297 spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uint32_t len)
298{
299 const struct spa_pod_string p = SPA_POD_INIT_String(len+1);
300 int r, res = spa_pod_builder_raw(builder, &p, sizeof(p));
301 if ((r = spa_pod_builder_write_string(builder, str, len)) < 0)
302 res = r;
303 return res;
304}
305
306static inline int spa_pod_builder_string(struct spa_pod_builder *builder, const char *str)
307{
308 uint32_t len = str ? strlen(str) : 0;
309 return spa_pod_builder_string_len(builder, str ? str : "", len);
310}
311
312#define SPA_POD_INIT_Bytes(len) ((struct spa_pod_bytes){ { (len), SPA_TYPE_Bytes } })
313
314static inline int
315 spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32_t len)
316{
317 const struct spa_pod_bytes p = SPA_POD_INIT_Bytes(len);
318 int r, res = spa_pod_builder_raw(builder, &p, sizeof(p));
319 if ((r = spa_pod_builder_raw_padded(builder, bytes, len)) < 0)
320 res = r;
321 return res;
322}
323static inline void *
324 spa_pod_builder_reserve_bytes(struct spa_pod_builder *builder, uint32_t len)
325{
326 uint32_t offset = builder->state.offset;
327 if (spa_pod_builder_bytes(builder, NULL, len) < 0)
328 return NULL;
329 return SPA_POD_BODY(spa_pod_builder_deref(builder, offset));
330}
331
332#define SPA_POD_INIT_Pointer(type,value) ((struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { (type), 0, (value) } })
333
334static inline int
335 spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const void *val)
336{
337 const struct spa_pod_pointer p = SPA_POD_INIT_Pointer(type, val);
338 return spa_pod_builder_primitive(builder, &p.pod);
339}
340
341#define SPA_POD_INIT_Fd(fd) ((struct spa_pod_fd){ { sizeof(int64_t), SPA_TYPE_Fd }, (fd) })
342
343static inline int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd)
344{
345 const struct spa_pod_fd p = SPA_POD_INIT_Fd(fd);
346 return spa_pod_builder_primitive(builder, &p.pod);
347}
348
349#define SPA_POD_INIT_Rectangle(val) ((struct spa_pod_rectangle){ { sizeof(struct spa_rectangle), SPA_TYPE_Rectangle }, (val) })
350
351static inline int
352 spa_pod_builder_rectangle(struct spa_pod_builder *builder, uint32_t width, uint32_t height)
353{
354 const struct spa_pod_rectangle p = SPA_POD_INIT_Rectangle(SPA_RECTANGLE(width, height));
355 return spa_pod_builder_primitive(builder, &p.pod);
356}
357
358#define SPA_POD_INIT_Fraction(val) ((struct spa_pod_fraction){ { sizeof(struct spa_fraction), SPA_TYPE_Fraction }, (val) })
359
360static inline int
361 spa_pod_builder_fraction(struct spa_pod_builder *builder, uint32_t num, uint32_t denom)
362{
363 const struct spa_pod_fraction p = SPA_POD_INIT_Fraction(SPA_FRACTION(num, denom));
364 return spa_pod_builder_primitive(builder, &p.pod);
365}
366
367static inline int
368 spa_pod_builder_push_array(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
369{
370 const struct spa_pod_array p =
371 { {sizeof(struct spa_pod_array_body) - sizeof(struct spa_pod), SPA_TYPE_Array},
372 {{0, 0}} };
373 uint32_t offset = builder->state.offset;
374 int res = spa_pod_builder_raw(builder, &p, sizeof(p) - sizeof(struct spa_pod));
375 spa_pod_builder_push(builder, frame, &p.pod, offset);
376 return res;
377}
378
379static inline int
380 spa_pod_builder_array(struct spa_pod_builder *builder,
381 uint32_t child_size, uint32_t child_type, uint32_t n_elems, const void *elems)
382{
383 const struct spa_pod_array p = {
384 {(uint32_t)(sizeof(struct spa_pod_array_body) + n_elems * child_size), SPA_TYPE_Array},
385 {{child_size, child_type}}
386 };
387 int r, res = spa_pod_builder_raw(builder, &p, sizeof(p));
388 if ((r = spa_pod_builder_raw_padded(builder, elems, child_size * n_elems)) < 0)
389 res = r;
390 return res;
391}
392
393#define SPA_POD_INIT_CHOICE_BODY(type, flags, child_size, child_type) \
394 ((struct spa_pod_choice_body) { (type), (flags), { (child_size), (child_type) }})
395
396#define SPA_POD_INIT_Choice(type, ctype, child_type, n_vals, ...) \
397 ((struct { struct spa_pod_choice choice; ctype vals[(n_vals)];}) \
398 { { { (n_vals) * sizeof(ctype) + sizeof(struct spa_pod_choice_body), SPA_TYPE_Choice }, \
399 { (type), 0, { sizeof(ctype), (child_type) } } }, { __VA_ARGS__ } })
400
401static inline int
402 spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_frame *frame,
403 uint32_t type, uint32_t flags)
404{
405 const struct spa_pod_choice p =
406 { {sizeof(struct spa_pod_choice_body) - sizeof(struct spa_pod), SPA_TYPE_Choice},
407 { type, flags, {0, 0}} };
408 uint32_t offset = builder->state.offset;
409 int res = spa_pod_builder_raw(builder, &p, sizeof(p) - sizeof(struct spa_pod));
410 spa_pod_builder_push(builder, frame, &p.pod, offset);
411 return res;
412}
413
414#define SPA_POD_INIT_Struct(size) ((struct spa_pod_struct){ { (size), SPA_TYPE_Struct } })
415
416static inline int
417 spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
418{
419 const struct spa_pod_struct p = SPA_POD_INIT_Struct(0);
420 uint32_t offset = builder->state.offset;
421 int res = spa_pod_builder_raw(builder, &p, sizeof(p));
422 spa_pod_builder_push(builder, frame, &p.pod, offset);
423 return res;
424}
425
426#define SPA_POD_INIT_Object(size,type,id,...) ((struct spa_pod_object){ { (size), SPA_TYPE_Object }, { (type), (id) }, ##__VA_ARGS__ })
427
428static inline int
429 spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_frame *frame,
430 uint32_t type, uint32_t id)
431{
432 const struct spa_pod_object p =
433 SPA_POD_INIT_Object(sizeof(struct spa_pod_object_body), type, id);
434 uint32_t offset = builder->state.offset;
435 int res = spa_pod_builder_raw(builder, &p, sizeof(p));
436 spa_pod_builder_push(builder, frame, &p.pod, offset);
437 return res;
438}
439
440#define SPA_POD_INIT_Prop(key,flags,size,type) \
441 ((struct spa_pod_prop){ (key), (flags), { (size), (type) } })
442
443static inline int
444 spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t flags)
445{
446 const struct { uint32_t key; uint32_t flags; } p = { key, flags };
447 return spa_pod_builder_raw(builder, &p, sizeof(p));
448}
449
450#define SPA_POD_INIT_Sequence(size,unit) \
451 ((struct spa_pod_sequence){ { (size), SPA_TYPE_Sequence}, {(unit), 0 } })
452
453static inline int
454 spa_pod_builder_push_sequence(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t unit)
455{
456 const struct spa_pod_sequence p =
457 SPA_POD_INIT_Sequence(sizeof(struct spa_pod_sequence_body), unit);
458 uint32_t offset = builder->state.offset;
459 int res = spa_pod_builder_raw(builder, &p, sizeof(p));
460 spa_pod_builder_push(builder, frame, &p.pod, offset);
461 return res;
462}
463
464static inline uint32_t
465 spa_pod_builder_control(struct spa_pod_builder *builder, uint32_t offset, uint32_t type)
466{
467 const struct { uint32_t offset; uint32_t type; } p = { offset, type };
468 return spa_pod_builder_raw(builder, &p, sizeof(p));
469}
470
471static inline uint32_t spa_choice_from_id(char id)
472{
473 switch (id) {
474 case 'r':
475 return SPA_CHOICE_Range;
476 case 's':
477 return SPA_CHOICE_Step;
478 case 'e':
479 return SPA_CHOICE_Enum;
480 case 'f':
481 return SPA_CHOICE_Flags;
482 case 'n':
483 default:
484 return SPA_CHOICE_None;
485 }
486}
487
488#define SPA_POD_BUILDER_COLLECT(builder,type,args) \
489do { \
490 switch (type) { \
491 case 'b': \
492 spa_pod_builder_bool(builder, !!va_arg(args, int)); \
493 break; \
494 case 'I': \
495 spa_pod_builder_id(builder, va_arg(args, uint32_t)); \
496 break; \
497 case 'i': \
498 spa_pod_builder_int(builder, va_arg(args, int)); \
499 break; \
500 case 'l': \
501 spa_pod_builder_long(builder, va_arg(args, int64_t)); \
502 break; \
503 case 'f': \
504 spa_pod_builder_float(builder, va_arg(args, double)); \
505 break; \
506 case 'd': \
507 spa_pod_builder_double(builder, va_arg(args, double)); \
508 break; \
509 case 's': \
510 { \
511 char *strval = va_arg(args, char *); \
512 if (strval != NULL) { \
513 size_t len = strlen(strval); \
514 spa_pod_builder_string_len(builder, strval, len); \
515 } \
516 else \
517 spa_pod_builder_none(builder); \
518 break; \
519 } \
520 case 'S': \
521 { \
522 char *strval = va_arg(args, char *); \
523 size_t len = va_arg(args, int); \
524 spa_pod_builder_string_len(builder, strval, len); \
525 break; \
526 } \
527 case 'y': \
528 { \
529 void *ptr = va_arg(args, void *); \
530 int len = va_arg(args, int); \
531 spa_pod_builder_bytes(builder, ptr, len); \
532 break; \
533 } \
534 case 'R': \
535 { \
536 struct spa_rectangle *rectval = \
537 va_arg(args, struct spa_rectangle *); \
538 spa_pod_builder_rectangle(builder, \
539 rectval->width, rectval->height); \
540 break; \
541 } \
542 case 'F': \
543 { \
544 struct spa_fraction *fracval = \
545 va_arg(args, struct spa_fraction *); \
546 spa_pod_builder_fraction(builder, fracval->num, fracval->denom);\
547 break; \
548 } \
549 case 'a': \
550 { \
551 int child_size = va_arg(args, int); \
552 int child_type = va_arg(args, int); \
553 int n_elems = va_arg(args, int); \
554 void *elems = va_arg(args, void *); \
555 spa_pod_builder_array(builder, child_size, \
556 child_type, n_elems, elems); \
557 break; \
558 } \
559 case 'p': \
560 { \
561 int t = va_arg(args, uint32_t); \
562 spa_pod_builder_pointer(builder, t, va_arg(args, void *)); \
563 break; \
564 } \
565 case 'h': \
566 spa_pod_builder_fd(builder, va_arg(args, int)); \
567 break; \
568 case 'P': \
569 case 'O': \
570 case 'T': \
571 case 'V': \
572 { \
573 struct spa_pod *pod = va_arg(args, struct spa_pod *); \
574 if (pod == NULL) \
575 spa_pod_builder_none(builder); \
576 else \
577 spa_pod_builder_primitive(builder, pod); \
578 break; \
579 } \
580 } \
581} while(false)
582
583static inline int
584 spa_pod_builder_addv(struct spa_pod_builder *builder, va_list args)
585{
586 int res = 0;
587 struct spa_pod_frame *frame = builder->state.frame;
588 uint32_t ftype = frame ? frame->pod.type : (uint32_t)SPA_TYPE_None;
589
590 do {
591 const char *format;
592 int n_values = 1;
593 struct spa_pod_frame f;
594 bool choice;
595
596 switch (ftype) {
597 case SPA_TYPE_Object:
598 {
599 uint32_t key = va_arg(args, uint32_t);
600 if (key == 0)
601 goto exit;
602 spa_pod_builder_prop(builder, key, 0);
603 break;
604 }
605 case SPA_TYPE_Sequence:
606 {
607 uint32_t offset = va_arg(args, uint32_t);
608 uint32_t type = va_arg(args, uint32_t);
609 if (type == 0)
610 goto exit;
611 spa_pod_builder_control(builder, offset, type);
612 SPA_FALLTHROUGH
613 }
614 default:
615 break;
616 }
617 if ((format = va_arg(args, const char *)) == NULL)
618 break;
619
620 choice = *format == '?';
621 if (choice) {
622 uint32_t type = spa_choice_from_id(*++format);
623 if (*format != '\0')
624 format++;
625
626 spa_pod_builder_push_choice(builder, &f, type, 0);
627
628 n_values = va_arg(args, int);
629 }
630 while (n_values-- > 0)
631 SPA_POD_BUILDER_COLLECT(builder, *format, args);
632
633 if (choice)
634 spa_pod_builder_pop(builder, &f);
635 } while (true);
636
637 exit:
638 return res;
639}
640
641static inline int spa_pod_builder_add(struct spa_pod_builder *builder, ...)
642{
643 int res;
644 va_list args;
645
646 va_start(args, builder);
647 res = spa_pod_builder_addv(builder, args);
648 va_end(args);
649
650 return res;
651}
652
653#define spa_pod_builder_add_object(b,type,id,...) \
654({ \
655 struct spa_pod_builder *_b = (b); \
656 struct spa_pod_frame _f; \
657 spa_pod_builder_push_object(_b, &_f, type, id); \
658 spa_pod_builder_add(_b, ##__VA_ARGS__, 0); \
659 spa_pod_builder_pop(_b, &_f); \
660})
661
662#define spa_pod_builder_add_struct(b,...) \
663({ \
664 struct spa_pod_builder *_b = (b); \
665 struct spa_pod_frame _f; \
666 spa_pod_builder_push_struct(_b, &_f); \
667 spa_pod_builder_add(_b, ##__VA_ARGS__, NULL); \
668 spa_pod_builder_pop(_b, &_f); \
669})
670
671#define spa_pod_builder_add_sequence(b,unit,...) \
672({ \
673 struct spa_pod_builder *_b = (b); \
674 struct spa_pod_frame _f; \
675 spa_pod_builder_push_sequence(_b, &_f, unit); \
676 spa_pod_builder_add(_b, ##__VA_ARGS__, 0, 0); \
677 spa_pod_builder_pop(_b, &_f); \
678})
679
681static inline struct spa_pod *
682 spa_pod_copy(const struct spa_pod *pod)
683{
684 size_t size;
685 struct spa_pod *c;
686
687 size = SPA_POD_SIZE(pod);
688 if ((c = (struct spa_pod *) malloc(size)) == NULL)
689 return NULL;
690 return (struct spa_pod *) memcpy(c, pod, size);
691}
692
697#ifdef __cplusplus
698} /* extern "C" */
699#endif
700
701#endif /* SPA_POD_BUILDER_H */
SPA_CALLBACKS_INIT
#define SPA_CALLBACKS_INIT(_funcs, _data)
Initialize the set of functions funcs as a spa_callbacks, together with _data.
Definition: hook.h:154
spa_callbacks_call_res
#define spa_callbacks_call_res(callbacks, type, res, method, vers,...)
Invoke method named method in the callbacks.
Definition: hook.h:219
SPA_POD_INIT_Double
#define SPA_POD_INIT_Double(val)
Definition: builder.h:292
spa_pod_builder_reserve_bytes
static void * spa_pod_builder_reserve_bytes(struct spa_pod_builder *builder, uint32_t len)
Definition: builder.h:344
spa_pod_builder_prop
static int spa_pod_builder_prop(struct spa_pod_builder *builder, uint32_t key, uint32_t flags)
Definition: builder.h:470
SPA_POD_INIT_None
#define SPA_POD_INIT_None()
Definition: builder.h:231
SPA_POD_INIT
#define SPA_POD_INIT(size, type)
Definition: builder.h:228
spa_pod_builder_string
static int spa_pod_builder_string(struct spa_pod_builder *builder, const char *str)
Definition: builder.h:325
spa_pod_builder_child
static int spa_pod_builder_child(struct spa_pod_builder *builder, uint32_t size, uint32_t type)
Definition: builder.h:239
spa_pod_builder_fraction
static int spa_pod_builder_fraction(struct spa_pod_builder *builder, uint32_t num, uint32_t denom)
Definition: builder.h:385
spa_pod_builder_rectangle
static int spa_pod_builder_rectangle(struct spa_pod_builder *builder, uint32_t width, uint32_t height)
Definition: builder.h:375
spa_pod_builder_float
static int spa_pod_builder_float(struct spa_pod_builder *builder, float val)
Definition: builder.h:285
SPA_POD_BODY_CONST
#define SPA_POD_BODY_CONST(pod)
Definition: pod/pod.h:61
SPA_POD_INIT_Object
#define SPA_POD_INIT_Object(size, type, id,...)
Definition: builder.h:452
SPA_POD_BUILDER_FLAG_BODY
#define SPA_POD_BUILDER_FLAG_BODY
Definition: builder.h:55
spa_pod_builder_push
static void spa_pod_builder_push(struct spa_pod_builder *builder, struct spa_pod_frame *frame, const struct spa_pod *pod, uint32_t offset)
Definition: builder.h:133
spa_pod_builder_double
static int spa_pod_builder_double(struct spa_pod_builder *builder, double val)
Definition: builder.h:294
spa_pod_builder_write_string
static int spa_pod_builder_write_string(struct spa_pod_builder *builder, const char *str, uint32_t len)
Definition: builder.h:304
SPA_POD_INIT_Sequence
#define SPA_POD_INIT_Sequence(size, unit)
Definition: builder.h:476
SPA_POD_INIT_Rectangle
#define SPA_POD_INIT_Rectangle(val)
Definition: builder.h:372
spa_pod_builder_set_callbacks
static void spa_pod_builder_set_callbacks(struct spa_pod_builder *builder, const struct spa_pod_builder_callbacks *callbacks, void *data)
Definition: builder.h:91
SPA_POD_INIT_Bool
#define SPA_POD_INIT_Bool(val)
Definition: builder.h:247
spa_pod_builder_id
static int spa_pod_builder_id(struct spa_pod_builder *builder, uint32_t val)
Definition: builder.h:258
spa_pod_builder_add
static int spa_pod_builder_add(struct spa_pod_builder *builder,...)
Definition: builder.h:667
SPA_POD_INIT_String
#define SPA_POD_INIT_String(len)
Definition: builder.h:301
spa_pod_builder_fd
static int spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd)
Definition: builder.h:365
SPA_POD_BODY
#define SPA_POD_BODY(pod)
Definition: pod/pod.h:59
spa_pod_builder_frame
static struct spa_pod * spa_pod_builder_frame(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
Definition: builder.h:125
spa_pod_builder_reset
static void spa_pod_builder_reset(struct spa_pod_builder *builder, struct spa_pod_builder_state *state)
Definition: builder.h:98
spa_pod_builder_none
static int spa_pod_builder_none(struct spa_pod_builder *builder)
Definition: builder.h:233
SPA_POD_INIT_Id
#define SPA_POD_INIT_Id(val)
Definition: builder.h:256
spa_pod_builder_push_sequence
static int spa_pod_builder_push_sequence(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t unit)
Definition: builder.h:480
spa_pod_builder_raw_padded
static int spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, uint32_t size)
Definition: builder.h:180
SPA_POD_BODY_SIZE
#define SPA_POD_BODY_SIZE(pod)
Definition: pod/pod.h:46
SPA_POD_BUILDER_INIT
#define SPA_POD_BUILDER_INIT(buffer, size)
Definition: builder.h:82
spa_pod_builder_pop
static void * spa_pod_builder_pop(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
Definition: builder.h:188
spa_pod_builder_pad
static int spa_pod_builder_pad(struct spa_pod_builder *builder, uint32_t size)
Definition: builder.h:172
spa_pod_builder_string_len
static int spa_pod_builder_string_len(struct spa_pod_builder *builder, const char *str, uint32_t len)
Definition: builder.h:316
SPA_POD_INIT_Struct
#define SPA_POD_INIT_Struct(size)
Definition: builder.h:439
spa_pod_builder_push_array
static int spa_pod_builder_push_array(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
Definition: builder.h:392
spa_pod_builder_primitive
static int spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod *p)
Definition: builder.h:206
spa_choice_from_id
static uint32_t spa_choice_from_id(char id)
Definition: builder.h:497
spa_pod_builder_push_struct
static int spa_pod_builder_push_struct(struct spa_pod_builder *builder, struct spa_pod_frame *frame)
Definition: builder.h:442
spa_pod_builder_control
static uint32_t spa_pod_builder_control(struct spa_pod_builder *builder, uint32_t offset, uint32_t type)
Definition: builder.h:491
spa_pod_builder_get_state
static void spa_pod_builder_get_state(struct spa_pod_builder *builder, struct spa_pod_builder_state *state)
Definition: builder.h:85
spa_pod_builder_bool
static int spa_pod_builder_bool(struct spa_pod_builder *builder, bool val)
Definition: builder.h:249
SPA_POD_BUILDER_COLLECT
#define SPA_POD_BUILDER_COLLECT(builder, type, args)
Definition: builder.h:514
spa_pod_copy
static struct spa_pod * spa_pod_copy(const struct spa_pod *pod)
Copy a pod structure.
Definition: builder.h:708
spa_pod_builder_raw
static int spa_pod_builder_raw(struct spa_pod_builder *builder, const void *data, uint32_t size)
Definition: builder.h:148
SPA_POD_INIT_Int
#define SPA_POD_INIT_Int(val)
Definition: builder.h:265
spa_pod_builder_bytes
static int spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32_t len)
Definition: builder.h:335
spa_pod_builder_push_choice
static int spa_pod_builder_push_choice(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t type, uint32_t flags)
Definition: builder.h:426
spa_pod_builder_int
static int spa_pod_builder_int(struct spa_pod_builder *builder, int32_t val)
Definition: builder.h:267
spa_pod_builder_init
static void spa_pod_builder_init(struct spa_pod_builder *builder, void *data, uint32_t size)
Definition: builder.h:107
spa_pod_builder_push_object
static int spa_pod_builder_push_object(struct spa_pod_builder *builder, struct spa_pod_frame *frame, uint32_t type, uint32_t id)
Definition: builder.h:455
SPA_POD_INIT_Float
#define SPA_POD_INIT_Float(val)
Definition: builder.h:283
spa_pod_builder_long
static int spa_pod_builder_long(struct spa_pod_builder *builder, int64_t val)
Definition: builder.h:276
SPA_POD_INIT_Bytes
#define SPA_POD_INIT_Bytes(len)
Definition: builder.h:332
SPA_POD_INIT_Fd
#define SPA_POD_INIT_Fd(fd)
Definition: builder.h:363
spa_pod_builder_array
static int spa_pod_builder_array(struct spa_pod_builder *builder, uint32_t child_size, uint32_t child_type, uint32_t n_elems, const void *elems)
Definition: builder.h:404
SPA_POD_INIT_Long
#define SPA_POD_INIT_Long(val)
Definition: builder.h:274
SPA_POD_INIT_Pointer
#define SPA_POD_INIT_Pointer(type, value)
Definition: builder.h:353
SPA_POD_INIT_Fraction
#define SPA_POD_INIT_Fraction(val)
Definition: builder.h:382
SPA_POD_BUILDER_FLAG_FIRST
#define SPA_POD_BUILDER_FLAG_FIRST
Definition: builder.h:57
SPA_POD_SIZE
#define SPA_POD_SIZE(pod)
Definition: pod/pod.h:50
spa_pod_builder_addv
static int spa_pod_builder_addv(struct spa_pod_builder *builder, va_list args)
Definition: builder.h:610
spa_pod_builder_deref
static struct spa_pod * spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t offset)
Definition: builder.h:113
spa_pod_builder_pointer
static int spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const void *val)
Definition: builder.h:356
SPA_CHOICE_Step
@ SPA_CHOICE_Step
range with step: default, min, max, step
Definition: pod/pod.h:169
SPA_CHOICE_None
@ SPA_CHOICE_None
no choice, first value is current
Definition: pod/pod.h:167
SPA_CHOICE_Flags
@ SPA_CHOICE_Flags
flags: default, possible flags,...
Definition: pod/pod.h:171
SPA_CHOICE_Range
@ SPA_CHOICE_Range
range: default, min, max
Definition: pod/pod.h:168
SPA_CHOICE_Enum
@ SPA_CHOICE_Enum
list: default, alternative,...
Definition: pod/pod.h:170
SPA_TYPE_Object
@ SPA_TYPE_Object
Definition: spa/include/spa/utils/type.h:65
SPA_TYPE_None
@ SPA_TYPE_None
Definition: spa/include/spa/utils/type.h:51
SPA_TYPE_Sequence
@ SPA_TYPE_Sequence
Definition: spa/include/spa/utils/type.h:66
SPA_TYPE_Choice
@ SPA_TYPE_Choice
Definition: spa/include/spa/utils/type.h:69
SPA_TYPE_Array
@ SPA_TYPE_Array
Definition: spa/include/spa/utils/type.h:63
SPA_ROUND_UP_N
#define SPA_ROUND_UP_N(num, align)
Definition: defs.h:336
SPA_FRACTION
#define SPA_FRACTION(num, denom)
Definition: defs.h:138
SPA_FLAG_IS_SET
#define SPA_FLAG_IS_SET(field, flag)
Definition: defs.h:92
SPA_FALLTHROUGH
#define SPA_FALLTHROUGH
SPA_FALLTHROUGH is an annotation to suppress compiler warnings about switch cases that fall through w...
Definition: defs.h:86
SPA_FLAG_CLEAR
#define SPA_FLAG_CLEAR(field, flag)
Definition: defs.h:96
SPA_PTROFF
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition: defs.h:210
SPA_RECTANGLE
#define SPA_RECTANGLE(width, height)
Definition: defs.h:117
hook.h
spa/utils/hook.h
iter.h
spa/pod/iter.h
spa_callbacks
Callbacks, contains the structure with functions and the data passed to the functions.
Definition: hook.h:136
spa_callbacks::data
void * data
Definition: hook.h:138
spa_pod_array_body
Definition: pod/pod.h:141
spa_pod_array
Definition: pod/pod.h:146
spa_pod_array::pod
struct spa_pod pod
Definition: pod/pod.h:147
spa_pod_bool
Definition: pod/pod.h:71
spa_pod_bool::pod
struct spa_pod pod
Definition: pod/pod.h:72
spa_pod_builder_callbacks
Definition: builder.h:65
spa_pod_builder_callbacks::overflow
int(* overflow)(void *data, uint32_t size)
Definition: builder.h:70
spa_pod_builder_callbacks::version
uint32_t version
Definition: builder.h:68
spa_pod_builder_state
Definition: builder.h:52
spa_pod_builder_state::flags
uint32_t flags
Definition: builder.h:58
spa_pod_builder_state::offset
uint32_t offset
Definition: builder.h:53
spa_pod_builder_state::frame
struct spa_pod_frame * frame
Definition: builder.h:59
spa_pod_builder
Definition: builder.h:73
spa_pod_builder::_padding
uint32_t _padding
Definition: builder.h:76
spa_pod_builder::callbacks
struct spa_callbacks callbacks
Definition: builder.h:78
spa_pod_builder::data
void * data
Definition: builder.h:74
spa_pod_builder::state
struct spa_pod_builder_state state
Definition: builder.h:77
spa_pod_builder::size
uint32_t size
Definition: builder.h:75
spa_pod_bytes
Definition: pod/pod.h:110
spa_pod_choice_body
Definition: pod/pod.h:174
spa_pod_choice_body::type
uint32_t type
type of choice, one of enum spa_choice_type
Definition: pod/pod.h:175
spa_pod_choice_body::flags
uint32_t flags
extra flags
Definition: pod/pod.h:176
spa_pod_choice
Definition: pod/pod.h:182
spa_pod_choice::pod
struct spa_pod pod
Definition: pod/pod.h:183
spa_pod_double
Definition: pod/pod.h:100
spa_pod_double::pod
struct spa_pod pod
Definition: pod/pod.h:101
spa_pod_fd
Definition: pod/pod.h:219
spa_pod_fd::pod
struct spa_pod pod
Definition: pod/pod.h:220
spa_pod_float
Definition: pod/pod.h:94
spa_pod_float::pod
struct spa_pod pod
Definition: pod/pod.h:95
spa_pod_fraction
Definition: pod/pod.h:120
spa_pod_fraction::pod
struct spa_pod pod
Definition: pod/pod.h:121
spa_pod_frame
Definition: iter.h:47
spa_pod_frame::pod
struct spa_pod pod
Definition: iter.h:48
spa_pod_frame::offset
uint32_t offset
Definition: iter.h:50
spa_pod_frame::parent
struct spa_pod_frame * parent
Definition: iter.h:49
spa_pod_frame::flags
uint32_t flags
Definition: iter.h:51
spa_pod_id
Definition: pod/pod.h:77
spa_pod_id::pod
struct spa_pod pod
Definition: pod/pod.h:78
spa_pod_int
Definition: pod/pod.h:83
spa_pod_int::pod
struct spa_pod pod
Definition: pod/pod.h:84
spa_pod_long
Definition: pod/pod.h:89
spa_pod_long::pod
struct spa_pod pod
Definition: pod/pod.h:90
spa_pod_object_body
Definition: pod/pod.h:197
spa_pod_object
Definition: pod/pod.h:203
spa_pod_object::pod
struct spa_pod pod
Definition: pod/pod.h:204
spa_pod_pointer
Definition: pod/pod.h:214
spa_pod_pointer::pod
struct spa_pod pod
Definition: pod/pod.h:215
spa_pod_rectangle
Definition: pod/pod.h:115
spa_pod_rectangle::pod
struct spa_pod pod
Definition: pod/pod.h:116
spa_pod_sequence_body
Definition: pod/pod.h:261
spa_pod_sequence
a sequence of timed controls
Definition: pod/pod.h:268
spa_pod_sequence::pod
struct spa_pod pod
Definition: pod/pod.h:269
spa_pod_string
Definition: pod/pod.h:105
spa_pod_struct
Definition: pod/pod.h:187
spa_pod_struct::pod
struct spa_pod pod
Definition: pod/pod.h:188
spa_pod
Definition: pod/pod.h:63
spa_pod::type
uint32_t type
Definition: pod/pod.h:65
spa_pod::size
uint32_t size
Definition: pod/pod.h:64
vararg.h
spa/pod/vararg.h