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