PipeWire  0.3.59
parser.h
Go to the documentation of this file.
1 /* Spa
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_PARSER_H
26 #define SPA_POD_PARSER_H
27 
28 #ifdef __cplusplus
29 extern "C" {
30 #endif
31 
32 #include <errno.h>
33 #include <stdarg.h>
34 
35 #include <spa/pod/iter.h>
36 #include <spa/pod/vararg.h>
37 
43 struct spa_pod_parser_state {
44  uint32_t offset;
45  uint32_t flags;
46  struct spa_pod_frame *frame;
47 };
48 
50  const void *data;
51  uint32_t size;
52  uint32_t _padding;
54 };
55 
56 #define SPA_POD_PARSER_INIT(buffer,size) ((struct spa_pod_parser){ (buffer), (size), 0, {} })
57 
58 static inline void spa_pod_parser_init(struct spa_pod_parser *parser,
59  const void *data, uint32_t size)
60 {
61  *parser = SPA_POD_PARSER_INIT(data, size);
62 }
63 
64 static inline void spa_pod_parser_pod(struct spa_pod_parser *parser,
65  const struct spa_pod *pod)
66 {
67  spa_pod_parser_init(parser, pod, SPA_POD_SIZE(pod));
68 }
69 
70 static inline void
72 {
73  *state = parser->state;
74 }
75 
76 static inline void
78 {
79  parser->state = *state;
80 }
81 
82 static inline struct spa_pod *
83 spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t size)
84 {
85  /* Cast to uint64_t to avoid wraparound. Add 8 for the pod itself. */
86  const uint64_t long_offset = (uint64_t)offset + 8;
87  if (long_offset <= size && (offset & 7) == 0) {
88  /* Use void* because creating a misaligned pointer is undefined. */
89  void *pod = SPA_PTROFF(parser->data, offset, void);
90  /*
91  * Check that the pointer is aligned and that the size (rounded
92  * to the next multiple of 8) is in bounds.
93  */
94  if (SPA_IS_ALIGNED(pod, __alignof__(struct spa_pod)) &&
95  long_offset + SPA_ROUND_UP_N((uint64_t)SPA_POD_BODY_SIZE(pod), 8) <= size)
96  return (struct spa_pod *)pod;
97  }
98  return NULL;
99 }
100 
101 static inline struct spa_pod *spa_pod_parser_frame(struct spa_pod_parser *parser, struct spa_pod_frame *frame)
102 {
103  return SPA_PTROFF(parser->data, frame->offset, struct spa_pod);
104 }
105 
106 static inline void spa_pod_parser_push(struct spa_pod_parser *parser,
107  struct spa_pod_frame *frame, const struct spa_pod *pod, uint32_t offset)
108 {
109  frame->pod = *pod;
110  frame->offset = offset;
111  frame->parent = parser->state.frame;
112  frame->flags = parser->state.flags;
113  parser->state.frame = frame;
114 }
115 
116 static inline struct spa_pod *spa_pod_parser_current(struct spa_pod_parser *parser)
117 {
118  struct spa_pod_frame *f = parser->state.frame;
119  uint32_t size = f ? f->offset + SPA_POD_SIZE(&f->pod) : parser->size;
120  return spa_pod_parser_deref(parser, parser->state.offset, size);
121 }
122 
123 static inline void spa_pod_parser_advance(struct spa_pod_parser *parser, const struct spa_pod *pod)
124 {
125  parser->state.offset += SPA_ROUND_UP_N(SPA_POD_SIZE(pod), 8);
126 }
127 
128 static inline struct spa_pod *spa_pod_parser_next(struct spa_pod_parser *parser)
129 {
130  struct spa_pod *pod = spa_pod_parser_current(parser);
131  if (pod)
132  spa_pod_parser_advance(parser, pod);
133  return pod;
134 }
135 
136 static inline int spa_pod_parser_pop(struct spa_pod_parser *parser,
137  struct spa_pod_frame *frame)
138 {
139  parser->state.frame = frame->parent;
140  parser->state.offset = frame->offset + SPA_ROUND_UP_N(SPA_POD_SIZE(&frame->pod), 8);
141  return 0;
142 }
143 
144 static inline int spa_pod_parser_get_bool(struct spa_pod_parser *parser, bool *value)
145 {
146  int res = -EPIPE;
147  const struct spa_pod *pod = spa_pod_parser_current(parser);
148  if (pod != NULL && (res = spa_pod_get_bool(pod, value)) >= 0)
149  spa_pod_parser_advance(parser, pod);
150  return res;
151 }
152 
153 static inline int spa_pod_parser_get_id(struct spa_pod_parser *parser, uint32_t *value)
154 {
155  int res = -EPIPE;
156  const struct spa_pod *pod = spa_pod_parser_current(parser);
157  if (pod != NULL && (res = spa_pod_get_id(pod, value)) >= 0)
158  spa_pod_parser_advance(parser, pod);
159  return res;
160 }
161 
162 static inline int spa_pod_parser_get_int(struct spa_pod_parser *parser, int32_t *value)
163 {
164  int res = -EPIPE;
165  const struct spa_pod *pod = spa_pod_parser_current(parser);
166  if (pod != NULL && (res = spa_pod_get_int(pod, value)) >= 0)
167  spa_pod_parser_advance(parser, pod);
168  return res;
169 }
170 
171 static inline int spa_pod_parser_get_long(struct spa_pod_parser *parser, int64_t *value)
172 {
173  int res = -EPIPE;
174  const struct spa_pod *pod = spa_pod_parser_current(parser);
175  if (pod != NULL && (res = spa_pod_get_long(pod, value)) >= 0)
176  spa_pod_parser_advance(parser, pod);
177  return res;
178 }
179 
180 static inline int spa_pod_parser_get_float(struct spa_pod_parser *parser, float *value)
181 {
182  int res = -EPIPE;
183  const struct spa_pod *pod = spa_pod_parser_current(parser);
184  if (pod != NULL && (res = spa_pod_get_float(pod, value)) >= 0)
185  spa_pod_parser_advance(parser, pod);
186  return res;
187 }
188 
189 static inline int spa_pod_parser_get_double(struct spa_pod_parser *parser, double *value)
190 {
191  int res = -EPIPE;
192  const struct spa_pod *pod = spa_pod_parser_current(parser);
193  if (pod != NULL && (res = spa_pod_get_double(pod, value)) >= 0)
194  spa_pod_parser_advance(parser, pod);
195  return res;
196 }
197 
198 static inline int spa_pod_parser_get_string(struct spa_pod_parser *parser, const char **value)
199 {
200  int res = -EPIPE;
201  const struct spa_pod *pod = spa_pod_parser_current(parser);
202  if (pod != NULL && (res = spa_pod_get_string(pod, value)) >= 0)
203  spa_pod_parser_advance(parser, pod);
204  return res;
205 }
206 
207 static inline int spa_pod_parser_get_bytes(struct spa_pod_parser *parser, const void **value, uint32_t *len)
208 {
209  int res = -EPIPE;
210  const struct spa_pod *pod = spa_pod_parser_current(parser);
211  if (pod != NULL && (res = spa_pod_get_bytes(pod, value, len)) >= 0)
212  spa_pod_parser_advance(parser, pod);
213  return res;
214 }
215 
216 static inline int spa_pod_parser_get_pointer(struct spa_pod_parser *parser, uint32_t *type, const void **value)
217 {
218  int res = -EPIPE;
219  const struct spa_pod *pod = spa_pod_parser_current(parser);
220  if (pod != NULL && (res = spa_pod_get_pointer(pod, type, value)) >= 0)
221  spa_pod_parser_advance(parser, pod);
222  return res;
223 }
224 
225 static inline int spa_pod_parser_get_fd(struct spa_pod_parser *parser, int64_t *value)
226 {
227  int res = -EPIPE;
228  const struct spa_pod *pod = spa_pod_parser_current(parser);
229  if (pod != NULL && (res = spa_pod_get_fd(pod, value)) >= 0)
230  spa_pod_parser_advance(parser, pod);
231  return res;
232 }
233 
234 static inline int spa_pod_parser_get_rectangle(struct spa_pod_parser *parser, struct spa_rectangle *value)
235 {
236  int res = -EPIPE;
237  const struct spa_pod *pod = spa_pod_parser_current(parser);
238  if (pod != NULL && (res = spa_pod_get_rectangle(pod, value)) >= 0)
239  spa_pod_parser_advance(parser, pod);
240  return res;
241 }
242 
243 static inline int spa_pod_parser_get_fraction(struct spa_pod_parser *parser, struct spa_fraction *value)
244 {
245  int res = -EPIPE;
246  const struct spa_pod *pod = spa_pod_parser_current(parser);
247  if (pod != NULL && (res = spa_pod_get_fraction(pod, value)) >= 0)
248  spa_pod_parser_advance(parser, pod);
249  return res;
250 }
251 
252 static inline int spa_pod_parser_get_pod(struct spa_pod_parser *parser, struct spa_pod **value)
253 {
254  struct spa_pod *pod = spa_pod_parser_current(parser);
255  if (pod == NULL)
256  return -EPIPE;
257  *value = pod;
259  return 0;
260 }
261 static inline int spa_pod_parser_push_struct(struct spa_pod_parser *parser,
262  struct spa_pod_frame *frame)
263 {
264  const struct spa_pod *pod = spa_pod_parser_current(parser);
265  if (pod == NULL)
266  return -EPIPE;
267  if (!spa_pod_is_struct(pod))
268  return -EINVAL;
269  spa_pod_parser_push(parser, frame, pod, parser->state.offset);
270  parser->state.offset += sizeof(struct spa_pod_struct);
271  return 0;
272 }
273 
274 static inline int spa_pod_parser_push_object(struct spa_pod_parser *parser,
275  struct spa_pod_frame *frame, uint32_t type, uint32_t *id)
276 {
277  const struct spa_pod *pod = spa_pod_parser_current(parser);
278  if (pod == NULL)
279  return -EPIPE;
280  if (!spa_pod_is_object(pod))
281  return -EINVAL;
282  if (type != SPA_POD_OBJECT_TYPE(pod))
283  return -EPROTO;
284  if (id != NULL)
285  *id = SPA_POD_OBJECT_ID(pod);
286  spa_pod_parser_push(parser, frame, pod, parser->state.offset);
287  parser->state.offset = parser->size;
288  return 0;
289 }
290 
291 static inline bool spa_pod_parser_can_collect(const struct spa_pod *pod, char type)
292 {
293  if (pod == NULL)
294  return false;
295 
296  if (SPA_POD_TYPE(pod) == SPA_TYPE_Choice) {
297  if (!spa_pod_is_choice(pod))
298  return false;
299  if (type == 'V')
300  return true;
302  return false;
303  pod = SPA_POD_CHOICE_CHILD(pod);
304  }
305 
306  switch (type) {
307  case 'P':
308  return true;
309  case 'b':
310  return spa_pod_is_bool(pod);
311  case 'I':
312  return spa_pod_is_id(pod);
313  case 'i':
314  return spa_pod_is_int(pod);
315  case 'l':
316  return spa_pod_is_long(pod);
317  case 'f':
318  return spa_pod_is_float(pod);
319  case 'd':
320  return spa_pod_is_double(pod);
321  case 's':
322  return spa_pod_is_string(pod) || spa_pod_is_none(pod);
323  case 'S':
324  return spa_pod_is_string(pod);
325  case 'y':
326  return spa_pod_is_bytes(pod);
327  case 'R':
328  return spa_pod_is_rectangle(pod);
329  case 'F':
330  return spa_pod_is_fraction(pod);
331  case 'B':
332  return spa_pod_is_bitmap(pod);
333  case 'a':
334  return spa_pod_is_array(pod);
335  case 'p':
336  return spa_pod_is_pointer(pod);
337  case 'h':
338  return spa_pod_is_fd(pod);
339  case 'T':
340  return spa_pod_is_struct(pod) || spa_pod_is_none(pod);
341  case 'O':
342  return spa_pod_is_object(pod) || spa_pod_is_none(pod);
343  case 'V':
344  default:
345  return false;
346  }
347 }
348 
349 #define SPA_POD_PARSER_COLLECT(pod,_type,args) \
350 do { \
351  switch (_type) { \
352  case 'b': \
353  *va_arg(args, bool*) = SPA_POD_VALUE(struct spa_pod_bool, pod); \
354  break; \
355  case 'I': \
356  case 'i': \
357  *va_arg(args, int32_t*) = SPA_POD_VALUE(struct spa_pod_int, pod); \
358  break; \
359  case 'l': \
360  *va_arg(args, int64_t*) = SPA_POD_VALUE(struct spa_pod_long, pod); \
361  break; \
362  case 'f': \
363  *va_arg(args, float*) = SPA_POD_VALUE(struct spa_pod_float, pod); \
364  break; \
365  case 'd': \
366  *va_arg(args, double*) = SPA_POD_VALUE(struct spa_pod_double, pod); \
367  break; \
368  case 's': \
369  *va_arg(args, char**) = \
370  ((pod) == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \
371  ? NULL \
372  : (char *)SPA_POD_CONTENTS(struct spa_pod_string, pod)); \
373  break; \
374  case 'S': \
375  { \
376  char *dest = va_arg(args, char*); \
377  uint32_t maxlen = va_arg(args, uint32_t); \
378  strncpy(dest, (char *)SPA_POD_CONTENTS(struct spa_pod_string, pod), maxlen-1); \
379  dest[maxlen-1] = '\0'; \
380  break; \
381  } \
382  case 'y': \
383  *(va_arg(args, void **)) = SPA_POD_CONTENTS(struct spa_pod_bytes, pod); \
384  *(va_arg(args, uint32_t *)) = SPA_POD_BODY_SIZE(pod); \
385  break; \
386  case 'R': \
387  *va_arg(args, struct spa_rectangle*) = \
388  SPA_POD_VALUE(struct spa_pod_rectangle, pod); \
389  break; \
390  case 'F': \
391  *va_arg(args, struct spa_fraction*) = \
392  SPA_POD_VALUE(struct spa_pod_fraction, pod); \
393  break; \
394  case 'B': \
395  *va_arg(args, uint32_t **) = \
396  (uint32_t *) SPA_POD_CONTENTS(struct spa_pod_bitmap, pod); \
397  break; \
398  case 'a': \
399  *va_arg(args, uint32_t*) = SPA_POD_ARRAY_VALUE_SIZE(pod); \
400  *va_arg(args, uint32_t*) = SPA_POD_ARRAY_VALUE_TYPE(pod); \
401  *va_arg(args, uint32_t*) = SPA_POD_ARRAY_N_VALUES(pod); \
402  *va_arg(args, void**) = SPA_POD_ARRAY_VALUES(pod); \
403  break; \
404  case 'p': \
405  { \
406  struct spa_pod_pointer_body *b = \
407  (struct spa_pod_pointer_body *) SPA_POD_BODY(pod); \
408  *(va_arg(args, uint32_t *)) = b->type; \
409  *(va_arg(args, const void **)) = b->value; \
410  break; \
411  } \
412  case 'h': \
413  *va_arg(args, int64_t*) = SPA_POD_VALUE(struct spa_pod_fd, pod); \
414  break; \
415  case 'P': \
416  case 'T': \
417  case 'O': \
418  case 'V': \
419  { \
420  const struct spa_pod **d = va_arg(args, const struct spa_pod**); \
421  if (d) \
422  *d = ((pod) == NULL || (SPA_POD_TYPE(pod) == SPA_TYPE_None) \
423  ? NULL : (pod)); \
424  break; \
425  } \
426  default: \
427  break; \
428  } \
429 } while(false)
430 
431 #define SPA_POD_PARSER_SKIP(_type,args) \
432 do { \
433  switch (_type) { \
434  case 'S': \
435  va_arg(args, char*); \
436  va_arg(args, uint32_t); \
437  break; \
438  case 'a': \
439  va_arg(args, void*); \
440  va_arg(args, void*); \
441  SPA_FALLTHROUGH \
442  case 'p': \
443  case 'y': \
444  va_arg(args, void*); \
445  SPA_FALLTHROUGH \
446  case 'b': \
447  case 'I': \
448  case 'i': \
449  case 'l': \
450  case 'f': \
451  case 'd': \
452  case 's': \
453  case 'R': \
454  case 'F': \
455  case 'B': \
456  case 'h': \
457  case 'V': \
458  case 'P': \
459  case 'T': \
460  case 'O': \
461  va_arg(args, void*); \
462  break; \
463  } \
464 } while(false)
465 
466 static inline int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list args)
467 {
468  struct spa_pod_frame *f = parser->state.frame;
469  uint32_t ftype = f ? f->pod.type : (uint32_t)SPA_TYPE_Struct;
470  const struct spa_pod_prop *prop = NULL;
471  int count = 0;
472 
473  do {
474  bool optional;
475  const struct spa_pod *pod = NULL;
476  const char *format;
477 
478  if (ftype == SPA_TYPE_Object) {
479  uint32_t key = va_arg(args, uint32_t);
480  const struct spa_pod_object *object;
481 
482  if (key == 0)
483  break;
484 
485  object = (const struct spa_pod_object *)spa_pod_parser_frame(parser, f);
486  prop = spa_pod_object_find_prop(object, prop, key);
487  pod = prop ? &prop->value : NULL;
488  }
489 
490  if ((format = va_arg(args, char *)) == NULL)
491  break;
492 
493  if (ftype == SPA_TYPE_Struct)
494  pod = spa_pod_parser_next(parser);
495 
496  if ((optional = (*format == '?')))
497  format++;
498 
499  if (!spa_pod_parser_can_collect(pod, *format)) {
500  if (!optional) {
501  if (pod == NULL)
502  return -ESRCH;
503  else
504  return -EPROTO;
505  }
506  SPA_POD_PARSER_SKIP(*format, args);
507  } else {
508  if (pod->type == SPA_TYPE_Choice && *format != 'V')
510 
511  SPA_POD_PARSER_COLLECT(pod, *format, args);
512  count++;
513  }
514  } while (true);
515 
516  return count;
517 }
518 
519 static inline int spa_pod_parser_get(struct spa_pod_parser *parser, ...)
520 {
521  int res;
522  va_list args;
523 
524  va_start(args, parser);
525  res = spa_pod_parser_getv(parser, args);
526  va_end(args);
527 
528  return res;
529 }
530 
531 #define SPA_POD_OPT_Bool(val) "?" SPA_POD_Bool(val)
532 #define SPA_POD_OPT_Id(val) "?" SPA_POD_Id(val)
533 #define SPA_POD_OPT_Int(val) "?" SPA_POD_Int(val)
534 #define SPA_POD_OPT_Long(val) "?" SPA_POD_Long(val)
535 #define SPA_POD_OPT_Float(val) "?" SPA_POD_Float(val)
536 #define SPA_POD_OPT_Double(val) "?" SPA_POD_Double(val)
537 #define SPA_POD_OPT_String(val) "?" SPA_POD_String(val)
538 #define SPA_POD_OPT_Stringn(val,len) "?" SPA_POD_Stringn(val,len)
539 #define SPA_POD_OPT_Bytes(val,len) "?" SPA_POD_Bytes(val,len)
540 #define SPA_POD_OPT_Rectangle(val) "?" SPA_POD_Rectangle(val)
541 #define SPA_POD_OPT_Fraction(val) "?" SPA_POD_Fraction(val)
542 #define SPA_POD_OPT_Array(csize,ctype,n_vals,vals) "?" SPA_POD_Array(csize,ctype,n_vals,vals)
543 #define SPA_POD_OPT_Pointer(type,val) "?" SPA_POD_Pointer(type,val)
544 #define SPA_POD_OPT_Fd(val) "?" SPA_POD_Fd(val)
545 #define SPA_POD_OPT_Pod(val) "?" SPA_POD_Pod(val)
546 #define SPA_POD_OPT_PodObject(val) "?" SPA_POD_PodObject(val)
547 #define SPA_POD_OPT_PodStruct(val) "?" SPA_POD_PodStruct(val)
548 #define SPA_POD_OPT_PodChoice(val) "?" SPA_POD_PodChoice(val)
549 
550 #define spa_pod_parser_get_object(p,type,id,...) \
551 ({ \
552  struct spa_pod_frame _f; \
553  int _res; \
554  if ((_res = spa_pod_parser_push_object(p, &_f, type, id)) == 0) { \
555  _res = spa_pod_parser_get(p,##__VA_ARGS__, 0); \
556  spa_pod_parser_pop(p, &_f); \
557  } \
558  _res; \
559 })
560 
561 #define spa_pod_parser_get_struct(p,...) \
562 ({ \
563  struct spa_pod_frame _f; \
564  int _res; \
565  if ((_res = spa_pod_parser_push_struct(p, &_f)) == 0) { \
566  _res = spa_pod_parser_get(p,##__VA_ARGS__, NULL); \
567  spa_pod_parser_pop(p, &_f); \
568  } \
569  _res; \
570 })
571 
572 #define spa_pod_parse_object(pod,type,id,...) \
573 ({ \
574  struct spa_pod_parser _p; \
575  spa_pod_parser_pod(&_p, pod); \
576  spa_pod_parser_get_object(&_p,type,id,##__VA_ARGS__); \
577 })
578 
579 #define spa_pod_parse_struct(pod,...) \
580 ({ \
581  struct spa_pod_parser _p; \
582  spa_pod_parser_pod(&_p, pod); \
583  spa_pod_parser_get_struct(&_p,##__VA_ARGS__); \
584 })
585 
590 #ifdef __cplusplus
591 } /* extern "C" */
592 #endif
593 
594 #endif /* SPA_POD_PARSER_H */
static int spa_pod_is_bitmap(const struct spa_pod *pod)
Definition: iter.h:330
static void spa_pod_parser_pod(struct spa_pod_parser *parser, const struct spa_pod *pod)
Definition: parser.h:70
static int spa_pod_get_int(const struct spa_pod *pod, int32_t *value)
Definition: iter.h:187
static int spa_pod_parser_get_double(struct spa_pod_parser *parser, double *value)
Definition: parser.h:195
static int spa_pod_is_long(const struct spa_pod *pod)
Definition: iter.h:195
static int spa_pod_is_bytes(const struct spa_pod *pod)
Definition: iter.h:260
static int spa_pod_parser_get_float(struct spa_pod_parser *parser, float *value)
Definition: parser.h:186
static const struct spa_pod_prop * spa_pod_object_find_prop(const struct spa_pod_object *pod, const struct spa_pod_prop *start, uint32_t key)
Definition: iter.h:408
static int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value)
Definition: iter.h:280
static int spa_pod_parser_get_bytes(struct spa_pod_parser *parser, const void **value, uint32_t *len)
Definition: parser.h:213
static int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value)
Definition: iter.h:323
static struct spa_pod * spa_pod_parser_deref(struct spa_pod_parser *parser, uint32_t offset, uint32_t size)
Definition: parser.h:89
static int spa_pod_parser_get(struct spa_pod_parser *parser,...)
Definition: parser.h:525
static int spa_pod_is_rectangle(const struct spa_pod *pod)
Definition: iter.h:303
static int spa_pod_is_fd(const struct spa_pod *pod)
Definition: iter.h:289
static int spa_pod_is_pointer(const struct spa_pod *pod)
Definition: iter.h:274
#define SPA_POD_TYPE(pod)
Definition: pod.h:48
static int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value)
Definition: iter.h:174
static int spa_pod_parser_get_long(struct spa_pod_parser *parser, int64_t *value)
Definition: parser.h:177
static struct spa_pod * spa_pod_parser_next(struct spa_pod_parser *parser)
Definition: parser.h:134
#define SPA_POD_BODY_SIZE(pod)
Definition: pod.h:46
static int spa_pod_get_float(const struct spa_pod *pod, float *value)
Definition: iter.h:213
static int spa_pod_parser_get_int(struct spa_pod_parser *parser, int32_t *value)
Definition: parser.h:168
static int spa_pod_parser_get_pod(struct spa_pod_parser *parser, struct spa_pod **value)
Definition: parser.h:258
static int spa_pod_parser_push_struct(struct spa_pod_parser *parser, struct spa_pod_frame *frame)
Definition: parser.h:267
static void spa_pod_parser_get_state(struct spa_pod_parser *parser, struct spa_pod_parser_state *state)
Definition: parser.h:77
#define SPA_POD_PARSER_COLLECT(pod, _type, args)
Definition: parser.h:355
static int spa_pod_parser_get_string(struct spa_pod_parser *parser, const char **value)
Definition: parser.h:204
static int spa_pod_parser_get_rectangle(struct spa_pod_parser *parser, struct spa_rectangle *value)
Definition: parser.h:240
static int spa_pod_parser_push_object(struct spa_pod_parser *parser, struct spa_pod_frame *frame, uint32_t type, uint32_t *id)
Definition: parser.h:280
static int spa_pod_is_object(const struct spa_pod *pod)
Definition: iter.h:386
static int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value)
Definition: iter.h:309
static int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value)
Definition: iter.h:295
static int spa_pod_is_struct(const struct spa_pod *pod)
Definition: iter.h:381
static struct spa_pod * spa_pod_parser_current(struct spa_pod_parser *parser)
Definition: parser.h:122
#define SPA_POD_PARSER_SKIP(_type, args)
Definition: parser.h:437
static int spa_pod_get_long(const struct spa_pod *pod, int64_t *value)
Definition: iter.h:200
static void spa_pod_parser_advance(struct spa_pod_parser *parser, const struct spa_pod *pod)
Definition: parser.h:129
static void spa_pod_parser_push(struct spa_pod_parser *parser, struct spa_pod_frame *frame, const struct spa_pod *pod, uint32_t offset)
Definition: parser.h:112
static int spa_pod_is_string(const struct spa_pod *pod)
Definition: iter.h:234
static void spa_pod_parser_init(struct spa_pod_parser *parser, const void *data, uint32_t size)
Definition: parser.h:64
static int spa_pod_parser_get_bool(struct spa_pod_parser *parser, bool *value)
Definition: parser.h:150
static int spa_pod_is_choice(const struct spa_pod *pod)
Definition: iter.h:361
static int spa_pod_get_string(const struct spa_pod *pod, const char **value)
Definition: iter.h:242
static int spa_pod_get_double(const struct spa_pod *pod, double *value)
Definition: iter.h:226
static int spa_pod_parser_get_fd(struct spa_pod_parser *parser, int64_t *value)
Definition: parser.h:231
#define SPA_POD_PARSER_INIT(buffer, size)
Definition: parser.h:62
static int spa_pod_get_bool(const struct spa_pod *pod, bool *value)
Definition: iter.h:161
static int spa_pod_parser_get_pointer(struct spa_pod_parser *parser, uint32_t *type, const void **value)
Definition: parser.h:222
#define SPA_POD_OBJECT_TYPE(obj)
Definition: pod.h:193
#define SPA_POD_OBJECT_ID(obj)
Definition: pod.h:195
static int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list args)
Definition: parser.h:472
static int spa_pod_is_array(const struct spa_pod *pod)
Definition: iter.h:336
static int spa_pod_parser_get_id(struct spa_pod_parser *parser, uint32_t *value)
Definition: parser.h:159
static int spa_pod_is_id(const struct spa_pod *pod)
Definition: iter.h:169
static int spa_pod_is_double(const struct spa_pod *pod)
Definition: iter.h:221
static int spa_pod_is_int(const struct spa_pod *pod)
Definition: iter.h:182
static struct spa_pod * spa_pod_parser_frame(struct spa_pod_parser *parser, struct spa_pod_frame *frame)
Definition: parser.h:107
static void spa_pod_parser_reset(struct spa_pod_parser *parser, struct spa_pod_parser_state *state)
Definition: parser.h:83
static bool spa_pod_parser_can_collect(const struct spa_pod *pod, char type)
Definition: parser.h:297
static int spa_pod_is_none(const struct spa_pod *pod)
Definition: iter.h:151
static int spa_pod_is_fraction(const struct spa_pod *pod)
Definition: iter.h:317
#define SPA_POD_SIZE(pod)
Definition: pod.h:50
static int spa_pod_parser_get_fraction(struct spa_pod_parser *parser, struct spa_fraction *value)
Definition: parser.h:249
static int spa_pod_parser_pop(struct spa_pod_parser *parser, struct spa_pod_frame *frame)
Definition: parser.h:142
static int spa_pod_is_float(const struct spa_pod *pod)
Definition: iter.h:208
#define SPA_POD_CHOICE_CHILD(choice)
Definition: pod.h:152
#define SPA_POD_CHOICE_TYPE(choice)
Definition: pod.h:154
static int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len)
Definition: iter.h:265
static int spa_pod_is_bool(const struct spa_pod *pod)
Definition: iter.h:156
@ SPA_CHOICE_None
no choice, first value is current
Definition: pod.h:167
@ SPA_TYPE_Object
Definition: type.h:65
@ SPA_TYPE_Choice
Definition: type.h:69
@ SPA_TYPE_Struct
Definition: type.h:64
#define SPA_ROUND_UP_N(num, align)
Definition: defs.h:336
#define SPA_IS_ALIGNED(p, align)
Definition: defs.h:341
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition: defs.h:210
spa/pod/iter.h
Definition: defs.h:139
Definition: iter.h:47
struct spa_pod pod
Definition: iter.h:48
uint32_t offset
Definition: iter.h:50
struct spa_pod_frame * parent
Definition: iter.h:49
uint32_t flags
Definition: iter.h:51
Definition: pod.h:203
struct spa_pod pod
Definition: pod.h:204
Definition: parser.h:48
uint32_t offset
Definition: parser.h:49
uint32_t flags
Definition: parser.h:50
struct spa_pod_frame * frame
Definition: parser.h:51
Definition: parser.h:54
uint32_t size
Definition: parser.h:56
struct spa_pod_parser_state state
Definition: parser.h:58
const void * data
Definition: parser.h:55
uint32_t _padding
Definition: parser.h:57
Definition: pod.h:228
struct spa_pod value
Definition: pod.h:246
Definition: pod.h:187
Definition: pod.h:63
uint32_t type
Definition: pod.h:65
uint32_t size
Definition: pod.h:64
Definition: defs.h:118
spa/pod/vararg.h