PipeWire  1.6.4
iter.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_ITER_H
6 #define SPA_POD_ITER_H
7 
8 #include <errno.h>
9 #include <sys/types.h>
10 
11 #include <spa/pod/pod.h>
12 #include <spa/pod/body.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 #ifndef SPA_API_POD_ITER
19  #ifdef SPA_API_IMPL
20  #define SPA_API_POD_ITER SPA_API_IMPL
21  #else
22  #define SPA_API_POD_ITER static inline
23  #endif
24 #endif
25 
31 SPA_API_POD_ITER bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter)
32 {
33  size_t remaining;
34 
35  return spa_ptr_type_inside(pod, size, iter, struct spa_pod, &remaining) &&
36  remaining >= SPA_POD_BODY_SIZE(iter);
37 }
38 
39 SPA_API_POD_ITER void *spa_pod_next(const void *iter)
40 {
41  return SPA_PTROFF(iter, SPA_ROUND_UP_N(SPA_POD_SIZE(iter), SPA_POD_ALIGN), void);
42 }
43 
45 {
46  return SPA_PTROFF(body, sizeof(struct spa_pod_object_body), struct spa_pod_prop);
47 }
48 
50  uint32_t size, const struct spa_pod_prop *iter)
51 {
52  size_t remaining;
53 
54  return spa_ptr_type_inside(body, size, iter, struct spa_pod_prop, &remaining) &&
55  remaining >= iter->value.size;
56 }
57 
59 {
61 }
62 
64 {
65  return SPA_PTROFF(body, sizeof(struct spa_pod_sequence_body), struct spa_pod_control);
66 }
67 
69  uint32_t size, const struct spa_pod_control *iter)
70 {
71  size_t remaining;
72 
73  return spa_ptr_type_inside(body, size, iter, struct spa_pod_control, &remaining) &&
74  remaining >= iter->value.size;
75 }
76 
78 {
80 }
81 
82 #define SPA_POD_ARRAY_BODY_FOREACH(body, _size, iter) \
83  for ((iter) = (__typeof__(iter))SPA_PTROFF((body), sizeof(struct spa_pod_array_body), void); \
84  (body)->child.size > 0 && spa_ptrinside(body, _size, iter, (body)->child.size, NULL); \
85  (iter) = (__typeof__(iter))SPA_PTROFF((iter), (body)->child.size, void))
86 
87 #define SPA_POD_ARRAY_FOREACH(obj, iter) \
88  SPA_POD_ARRAY_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter)
89 
90 #define SPA_POD_CHOICE_BODY_FOREACH(body, _size, iter) \
91  for ((iter) = (__typeof__(iter))SPA_PTROFF((body), sizeof(struct spa_pod_choice_body), void); \
92  (body)->child.size > 0 && spa_ptrinside(body, _size, iter, (body)->child.size, NULL); \
93  (iter) = (__typeof__(iter))SPA_PTROFF((iter), (body)->child.size, void))
94 
95 #define SPA_POD_CHOICE_FOREACH(obj, iter) \
96  SPA_POD_CHOICE_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter)
97 
98 #define SPA_POD_FOREACH(pod, size, iter) \
99  for ((iter) = (pod); \
100  spa_pod_is_inside(pod, size, iter); \
101  (iter) = (__typeof__(iter))spa_pod_next(iter))
102 
103 #define SPA_POD_STRUCT_FOREACH(obj, iter) \
104  SPA_POD_FOREACH(SPA_POD_STRUCT_BODY(obj), SPA_POD_BODY_SIZE(obj), iter)
105 
106 #define SPA_POD_OBJECT_BODY_FOREACH(body, size, iter) \
107  for ((iter) = spa_pod_prop_first(body); \
108  spa_pod_prop_is_inside(body, size, iter); \
109  (iter) = spa_pod_prop_next(iter))
110 
111 #define SPA_POD_OBJECT_FOREACH(obj, iter) \
112  SPA_POD_OBJECT_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter)
113 
114 #define SPA_POD_SEQUENCE_BODY_FOREACH(body, size, iter) \
115  for ((iter) = spa_pod_control_first(body); \
116  spa_pod_control_is_inside(body, size, iter); \
117  (iter) = spa_pod_control_next(iter))
118 
119 #define SPA_POD_SEQUENCE_FOREACH(seq, iter) \
120  SPA_POD_SEQUENCE_BODY_FOREACH(&(seq)->body, SPA_POD_BODY_SIZE(seq), iter)
121 
122 SPA_API_POD_ITER void *spa_pod_from_data(void *data, size_t maxsize, off_t offset, size_t size)
123 {
124  struct spa_pod pod;
125  const void *body;
126  if (spa_pod_body_from_data(data, maxsize, offset, size, &pod, &body) < 0)
127  return NULL;
128  return SPA_PTROFF(data, offset, void);
129 }
130 
131 SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value)
132 {
133  return spa_pod_body_get_bool(pod, SPA_POD_BODY_CONST(pod), value);
134 }
135 
136 SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value)
137 {
138  return spa_pod_body_get_id(pod, SPA_POD_BODY_CONST(pod), value);
139 }
140 
141 SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value)
142 {
143  return spa_pod_body_get_int(pod, SPA_POD_BODY_CONST(pod), value);
144 }
145 
146 SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value)
147 {
148  return spa_pod_body_get_long(pod, SPA_POD_BODY_CONST(pod), value);
149 }
150 
151 SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value)
152 {
153  return spa_pod_body_get_float(pod, SPA_POD_BODY_CONST(pod), value);
154 }
155 
156 SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value)
157 {
158  return spa_pod_body_get_double(pod, SPA_POD_BODY_CONST(pod), value);
159 }
160 
161 SPA_API_POD_ITER int spa_pod_get_string(const struct spa_pod *pod, const char **value)
162 {
163  return spa_pod_body_get_string(pod, SPA_POD_BODY_CONST(pod), value);
164 }
165 
166 SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest)
167 {
168  return spa_pod_body_copy_string(pod, SPA_POD_BODY_CONST(pod), dest, maxlen);
169 }
170 
171 SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len)
172 {
173  return spa_pod_body_get_bytes(pod, SPA_POD_BODY_CONST(pod), value, len);
174 }
175 
176 SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value)
177 {
179 }
180 
181 SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value)
182 {
183  return spa_pod_body_get_fd(pod, SPA_POD_BODY_CONST(pod), value);
184 }
185 
186 SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value)
187 {
189 }
190 
191 SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value)
192 {
194 }
195 
196 SPA_API_POD_ITER void *spa_pod_get_array_full(const struct spa_pod *pod, uint32_t *n_values,
197  uint32_t *val_size, uint32_t *val_type)
198 {
199  return (void*)spa_pod_body_get_array_values(pod, SPA_POD_BODY(pod), n_values, val_size, val_type);
200 }
201 SPA_API_POD_ITER void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values)
202 {
203  uint32_t size, type;
204  return spa_pod_get_array_full(pod, n_values, &size, &type);
205 }
206 
207 SPA_API_POD_ITER uint32_t spa_pod_copy_array_full(const struct spa_pod *pod, uint32_t type,
208  uint32_t size, void *values, uint32_t max_values)
209 {
210  uint32_t n_values, val_size, val_type;
211  const void *v = spa_pod_get_array_full(pod, &n_values, &val_size, &val_type);
212  if (v == NULL || max_values == 0 || val_type != type || val_size != size)
213  return 0;
214  n_values = SPA_MIN(n_values, max_values);
215  memcpy(values, v, val_size * n_values);
216  return n_values;
217 }
218 
219 #define spa_pod_copy_array(pod,type,values,max_values) \
220  spa_pod_copy_array_full(pod,type,sizeof(values[0]),values,max_values)
221 
222 SPA_API_POD_ITER struct spa_pod *spa_pod_get_values(const struct spa_pod *pod,
223  uint32_t *n_vals, uint32_t *choice)
224 {
225  if (spa_pod_is_choice(pod)) {
226  const struct spa_pod_choice *p = (const struct spa_pod_choice*)pod;
227  uint32_t type, size;
228  spa_pod_choice_body_get_values(p, SPA_POD_BODY_CONST(p), n_vals, choice, &size, &type);
229  return (struct spa_pod*)&p->body.child;
230  } else {
231  *n_vals = pod->size < spa_pod_type_size(pod->type) ? 0 : 1;
232  *choice = SPA_CHOICE_None;
233  return (struct spa_pod*)pod;
234  }
235 }
236 
237 SPA_API_POD_ITER bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type)
238 {
239  return (pod && spa_pod_is_object(pod) && SPA_POD_OBJECT_TYPE(pod) == type);
240 }
241 
242 SPA_API_POD_ITER bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id)
243 {
245 }
246 
248  const struct spa_pod_prop *start, uint32_t key)
249 {
250  const struct spa_pod_prop *first, *res;
251 
252  first = spa_pod_prop_first(&pod->body);
253  start = start ? spa_pod_prop_next(start) : first;
254 
255  for (res = start; spa_pod_prop_is_inside(&pod->body, pod->pod.size, res);
257  if (res->key == key)
258  return res;
259  }
260  for (res = first; res != start; res = spa_pod_prop_next(res)) {
261  if (res->key == key)
262  return res;
263  }
264  return NULL;
265 }
266 
267 SPA_API_POD_ITER const struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod *pod,
268  const struct spa_pod_prop *start, uint32_t key)
269 {
270  if (!spa_pod_is_object(pod))
271  return NULL;
272  return spa_pod_object_find_prop((const struct spa_pod_object *)pod, start, key);
273 }
274 
276 {
277  struct spa_pod_prop *res;
279  return 1;
280  return 0;
281 }
282 
284 {
285  struct spa_pod_prop *res;
287  if (spa_pod_is_choice(&res->value) &&
289  ((struct spa_pod_choice*)&res->value)->body.type = SPA_CHOICE_None;
290  }
291  return 0;
292 }
294 {
295  struct spa_pod_prop *res;
297  if (spa_pod_is_choice(&res->value) &&
298  ((struct spa_pod_choice*)&res->value)->body.type != SPA_CHOICE_None)
299  return 0;
300  }
301  return 1;
302 }
303 
304 SPA_API_POD_ITER int spa_pod_fixate(struct spa_pod *pod)
305 {
306  if (!spa_pod_is_object(pod))
307  return -EINVAL;
308  return spa_pod_object_fixate((struct spa_pod_object *)pod);
309 }
310 
312 {
313  if (!spa_pod_is_object(pod))
314  return -EINVAL;
315  return spa_pod_object_is_fixated((const struct spa_pod_object *)pod);
316 }
317 
322 #ifdef __cplusplus
323 } /* extern "C" */
324 #endif
325 
326 #endif /* SPA_POD_ITER_H */
spa/pod/body.h
uint32_t int int res
Definition: core.h:433
SPA_API_POD_ITER bool spa_pod_control_is_inside(const struct spa_pod_sequence_body *body, uint32_t size, const struct spa_pod_control *iter)
Definition: iter.h:75
SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value)
Definition: iter.h:148
SPA_API_POD_ITER struct spa_pod_control * spa_pod_control_next(const struct spa_pod_control *iter)
Definition: iter.h:84
SPA_API_POD_BODY int spa_pod_body_get_pointer(const struct spa_pod *pod, const void *body, uint32_t *type, const void **value)
Definition: body.h:282
SPA_API_POD_ITER void * spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values)
Definition: iter.h:208
#define SPA_POD_BODY_CONST(pod)
Definition: pod.h:46
SPA_API_POD_ITER void * spa_pod_from_data(void *data, size_t maxsize, off_t offset, size_t size)
Definition: iter.h:129
SPA_API_POD_ITER void * spa_pod_next(const void *iter)
Definition: iter.h:46
SPA_API_POD_ITER bool spa_pod_prop_is_inside(const struct spa_pod_object_body *body, uint32_t size, const struct spa_pod_prop *iter)
Definition: iter.h:56
SPA_API_POD_BODY int spa_pod_body_get_string(const struct spa_pod *pod, const void *body, const char **value)
Definition: body.h:236
SPA_API_POD_BODY const void * spa_pod_choice_body_get_values(const struct spa_pod_choice *pod, const void *body, uint32_t *n_values, uint32_t *choice, uint32_t *val_size, uint32_t *val_type)
Definition: body.h:406
SPA_API_POD_ITER struct spa_pod * spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
Definition: iter.h:229
SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value)
Definition: iter.h:183
SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value)
Definition: iter.h:143
SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len)
Definition: iter.h:178
SPA_API_POD_BODY int spa_pod_body_get_fraction(const struct spa_pod *pod, const void *body, struct spa_fraction *value)
Definition: body.h:330
SPA_API_POD_ITER int spa_pod_object_fixate(struct spa_pod_object *pod)
Definition: iter.h:290
#define SPA_POD_OBJECT_FOREACH(obj, iter)
Definition: iter.h:118
#define SPA_POD_BODY(pod)
Definition: pod.h:44
SPA_API_POD_ITER void * spa_pod_get_array_full(const struct spa_pod *pod, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
Definition: iter.h:203
SPA_API_POD_BODY const void * spa_pod_body_get_array_values(const struct spa_pod *pod, const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
Definition: body.h:380
SPA_API_POD_BODY int spa_pod_is_object(const struct spa_pod *pod)
Definition: body.h:428
SPA_API_POD_ITER 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:254
SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value)
Definition: iter.h:188
#define SPA_POD_BODY_SIZE(pod)
Definition: pod.h:31
SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value)
Definition: iter.h:153
SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value)
Definition: iter.h:158
SPA_API_POD_BODY uint32_t spa_pod_type_size(uint32_t type)
Definition: body.h:45
SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value)
Definition: iter.h:138
#define SPA_POD_PROP_FLAG_DONT_FIXATE
choices need no fixation
Definition: pod.h:244
SPA_API_POD_BODY int spa_pod_body_get_double(const struct spa_pod *pod, const void *body, double *value)
Definition: body.h:221
SPA_API_POD_ITER int spa_pod_is_fixated(const struct spa_pod *pod)
Definition: iter.h:318
SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value)
Definition: iter.h:193
SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value)
Definition: iter.h:163
#define SPA_POD_CONTROL_SIZE(ev)
Definition: pod.h:254
SPA_API_POD_BODY int spa_pod_body_copy_string(const struct spa_pod *pod, const void *body, char *dest, size_t maxlen)
Definition: body.h:249
SPA_API_POD_ITER int spa_pod_fixate(struct spa_pod *pod)
Definition: iter.h:311
#define SPA_POD_PROP_SIZE(prop)
Definition: pod.h:224
SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest)
Definition: iter.h:173
SPA_API_POD_BODY int spa_pod_body_get_long(const struct spa_pod *pod, const void *body, int64_t *value)
Definition: body.h:190
SPA_API_POD_BODY int spa_pod_body_get_int(const struct spa_pod *pod, const void *body, int32_t *value)
Definition: body.h:177
SPA_API_POD_ITER const struct spa_pod_prop * spa_pod_find_prop(const struct spa_pod *pod, const struct spa_pod_prop *start, uint32_t key)
Definition: iter.h:274
SPA_API_POD_ITER bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id)
Definition: iter.h:249
SPA_API_POD_ITER struct spa_pod_prop * spa_pod_prop_first(const struct spa_pod_object_body *body)
Definition: iter.h:51
SPA_API_POD_ITER bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter)
Definition: iter.h:38
SPA_API_POD_BODY int spa_pod_body_get_float(const struct spa_pod *pod, const void *body, float *value)
Definition: body.h:206
#define SPA_POD_OBJECT_TYPE(obj)
Definition: pod.h:192
#define SPA_POD_OBJECT_ID(obj)
Definition: pod.h:194
SPA_API_POD_ITER struct spa_pod_prop * spa_pod_prop_next(const struct spa_pod_prop *iter)
Definition: iter.h:65
SPA_API_POD_BODY int spa_pod_body_get_rectangle(const struct spa_pod *pod, const void *body, struct spa_rectangle *value)
Definition: body.h:316
SPA_API_POD_BODY int spa_pod_body_get_bool(const struct spa_pod *pod, const void *body, bool *value)
Definition: body.h:151
SPA_API_POD_ITER uint32_t spa_pod_copy_array_full(const struct spa_pod *pod, uint32_t type, uint32_t size, void *values, uint32_t max_values)
Definition: iter.h:214
SPA_API_POD_ITER bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type)
Definition: iter.h:244
SPA_API_POD_ITER int spa_pod_object_is_fixated(const struct spa_pod_object *pod)
Definition: iter.h:300
SPA_API_POD_ITER int spa_pod_get_string(const struct spa_pod *pod, const char **value)
Definition: iter.h:168
SPA_API_POD_BODY int spa_pod_body_from_data(void *data, size_t maxsize, off_t offset, size_t size, struct spa_pod *pod, const void **body)
Definition: body.h:118
#define SPA_POD_SIZE(pod)
Definition: pod.h:35
#define SPA_POD_ALIGN
Definition: pod.h:26
SPA_API_POD_ITER struct spa_pod_control * spa_pod_control_first(const struct spa_pod_sequence_body *body)
Definition: iter.h:70
SPA_API_POD_BODY int spa_pod_body_get_fd(const struct spa_pod *pod, const void *body, int64_t *value)
Definition: body.h:300
SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value)
Definition: iter.h:198
SPA_API_POD_BODY int spa_pod_is_choice(const struct spa_pod *pod)
Definition: body.h:389
SPA_API_POD_BODY int spa_pod_body_get_id(const struct spa_pod *pod, const void *body, uint32_t *value)
Definition: body.h:164
SPA_API_POD_ITER int spa_pod_object_has_props(const struct spa_pod_object *pod)
Definition: iter.h:282
SPA_API_POD_BODY int spa_pod_body_get_bytes(const struct spa_pod *pod, const void *body, const void **value, uint32_t *len)
Definition: body.h:267
@ SPA_CHOICE_None
no choice, first value is current
Definition: pod.h:161
#define SPA_MIN(a, b)
Definition: defs.h:165
#define SPA_ROUND_UP_N(num, align)
Definition: defs.h:364
#define SPA_FLAG_IS_SET(field, flag)
Definition: defs.h:90
#define spa_ptr_type_inside(p1, s1, p2, type, remaining)
Definition: defs.h:430
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition: defs.h:222
#define SPA_API_POD_ITER
Definition: iter.h:29
spa/pod/pod.h
Definition: defs.h:137
struct spa_pod child
Definition: pod.h:171
Definition: pod.h:176
struct spa_pod_choice_body body
Definition: pod.h:178
struct spa_pod pod
Definition: pod.h:177
Definition: pod.h:257
struct spa_pod value
control value, depends on type
Definition: pod.h:260
uint32_t offset
media offset
Definition: pod.h:258
Definition: pod.h:196
Definition: pod.h:202
struct spa_pod pod
Definition: pod.h:203
struct spa_pod_object_body body
Definition: pod.h:204
Definition: pod.h:227
uint32_t key
key of property, list of valid keys depends on the object type
Definition: pod.h:228
struct spa_pod value
Definition: pod.h:249
Definition: pod.h:264
Definition: pod.h:57
uint32_t type
Definition: pod.h:59
uint32_t size
Definition: pod.h:58
Definition: defs.h:116