PipeWire 1.5.0
Loading...
Searching...
No Matches
body.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_BODY_H
6#define SPA_POD_BODY_H
7
8#include <errno.h>
9#include <sys/types.h>
10
11#include <spa/pod/pod.h>
12#include <spa/utils/atomic.h>
13
14#ifdef __cplusplus
15extern "C" {
16#endif
17
18#ifndef SPA_API_POD_BODY
19 #ifdef SPA_API_IMPL
20 #define SPA_API_POD_BODY SPA_API_IMPL
21 #else
22 #define SPA_API_POD_BODY static inline
23 #endif
24#endif
25
31struct spa_pod_frame {
32 struct spa_pod pod;
33 struct spa_pod_frame *parent;
34 uint32_t offset;
35 uint32_t flags;
36};
37
38SPA_API_POD_BODY uint32_t spa_pod_type_size(uint32_t type)
40 switch (type) {
43 case SPA_TYPE_Struct:
44 case SPA_TYPE_Pod:
45 return 0;
46 case SPA_TYPE_String:
47 return 1;
48 case SPA_TYPE_Bool:
49 case SPA_TYPE_Int:
50 return sizeof(int32_t);
51 case SPA_TYPE_Id:
52 return sizeof(uint32_t);
53 case SPA_TYPE_Long:
54 return sizeof(int64_t);
55 case SPA_TYPE_Float:
56 return sizeof(float);
57 case SPA_TYPE_Double:
58 return sizeof(double);
60 return sizeof(struct spa_rectangle);
62 return sizeof(struct spa_fraction);
63 case SPA_TYPE_Bitmap:
64 return sizeof(uint8_t);
65 case SPA_TYPE_Array:
66 return sizeof(struct spa_pod_array_body);
67 case SPA_TYPE_Object:
68 return sizeof(struct spa_pod_object_body);
70 return sizeof(struct spa_pod_sequence_body);
72 return sizeof(struct spa_pod_pointer_body);
73 case SPA_TYPE_Fd:
74 return sizeof(int64_t);
75 case SPA_TYPE_Choice:
76 return sizeof(struct spa_pod_choice_body);
77 }
78 return 0;
79}
80
81SPA_API_POD_BODY int spa_pod_body_from_data(void *data, size_t maxsize, off_t offset, size_t size,
82 struct spa_pod *pod, const void **body)
83{
84 if (offset < 0 || offset > (int64_t)UINT32_MAX)
85 return -EINVAL;
86 if (size < sizeof(struct spa_pod) ||
87 size > maxsize ||
88 maxsize - size < (uint32_t)offset)
89 return -EINVAL;
90 memcpy(pod, SPA_PTROFF(data, offset, void), sizeof(struct spa_pod));
91 if (!SPA_POD_IS_VALID(pod))
92 return -EINVAL;
93 if (pod->size > size - sizeof(struct spa_pod))
94 return -EINVAL;
95 *body = SPA_PTROFF(data, offset + sizeof(struct spa_pod), void);
96 return 0;
97}
98
99SPA_API_POD_BODY int spa_pod_is_none(const struct spa_pod *pod)
100{
102}
103
104SPA_API_POD_BODY int spa_pod_is_bool(const struct spa_pod *pod)
105{
106 return SPA_POD_CHECK(pod, SPA_TYPE_Bool, sizeof(int32_t));
107}
108
109#define SPA_POD_BODY_LOAD_ONCE(a, b) (*(a) = SPA_LOAD_ONCE((__typeof__(a))(b)))
110#define SPA_POD_BODY_LOAD_FIELD_ONCE(a, b, field) ((a)->field = SPA_LOAD_ONCE(&((__typeof__(a))(b))->field))
112SPA_API_POD_BODY int spa_pod_body_get_bool(const struct spa_pod *pod, const void *body, bool *value)
113{
114 if (!spa_pod_is_bool(pod))
115 return -EINVAL;
116 *value = !!__atomic_load_n((const int32_t *)body, __ATOMIC_RELAXED);
117 return 0;
118}
120SPA_API_POD_BODY int spa_pod_is_id(const struct spa_pod *pod)
122 return SPA_POD_CHECK(pod, SPA_TYPE_Id, sizeof(uint32_t));
123}
124
125SPA_API_POD_BODY int spa_pod_body_get_id(const struct spa_pod *pod, const void *body, uint32_t *value)
126{
127 if (!spa_pod_is_id(pod))
128 return -EINVAL;
130 return 0;
131}
132
133SPA_API_POD_BODY int spa_pod_is_int(const struct spa_pod *pod)
135 return SPA_POD_CHECK(pod, SPA_TYPE_Int, sizeof(int32_t));
136}
137
138SPA_API_POD_BODY int spa_pod_body_get_int(const struct spa_pod *pod, const void *body, int32_t *value)
139{
140 if (!spa_pod_is_int(pod))
141 return -EINVAL;
143 return 0;
144}
145
146SPA_API_POD_BODY int spa_pod_is_long(const struct spa_pod *pod)
148 return SPA_POD_CHECK(pod, SPA_TYPE_Long, sizeof(int64_t));
149}
150
151SPA_API_POD_BODY int spa_pod_body_get_long(const struct spa_pod *pod, const void *body, int64_t *value)
152{
153 if (!spa_pod_is_long(pod))
154 return -EINVAL;
155 /* TODO this is wrong per C standard, but if it breaks so does the Linux kernel. */
157 memcpy(value, body, sizeof *value);
159 return 0;
161
162SPA_API_POD_BODY int spa_pod_is_float(const struct spa_pod *pod)
163{
164 return SPA_POD_CHECK(pod, SPA_TYPE_Float, sizeof(float));
165}
166
167SPA_API_POD_BODY int spa_pod_body_get_float(const struct spa_pod *pod, const void *body, float *value)
168{
169 if (!spa_pod_is_float(pod))
170 return -EINVAL;
172 memcpy(value, body, sizeof *value);
174 return 0;
175}
177SPA_API_POD_BODY int spa_pod_is_double(const struct spa_pod *pod)
178{
179 return SPA_POD_CHECK(pod, SPA_TYPE_Double, sizeof(double));
180}
181
182SPA_API_POD_BODY int spa_pod_body_get_double(const struct spa_pod *pod, const void *body, double *value)
183{
184 if (!spa_pod_is_double(pod))
185 return -EINVAL;
187 memcpy(value, body, sizeof *value);
189 return 0;
190}
192SPA_API_POD_BODY int spa_pod_is_string(const struct spa_pod *pod)
193{
194 return SPA_POD_CHECK(pod, SPA_TYPE_String, 1);
195}
196
198 const void *body, const char **value)
199{
200 const char *s;
202 return -EINVAL;
203 s = (const char *)body;
204 if (((const volatile char *)s)[pod->size-1] != '\0')
205 return -EINVAL;
206 *value = s;
207 return 0;
208}
209
210SPA_API_POD_BODY int spa_pod_body_copy_string(const struct spa_pod *pod, const void *body,
211 char *dest, size_t maxlen)
212{
213 const char *s;
214 if (spa_pod_body_get_string(pod, body, &s) < 0 || maxlen < 1)
215 return -EINVAL;
217 strncpy(dest, s, maxlen-1);
219 dest[maxlen-1]= '\0';
220 return 0;
221}
222
223SPA_API_POD_BODY int spa_pod_is_bytes(const struct spa_pod *pod)
224{
226}
227
228SPA_API_POD_BODY int spa_pod_body_get_bytes(const struct spa_pod *pod, const void *body,
229 const void **value, uint32_t *len)
230{
231 if (!spa_pod_is_bytes(pod))
232 return -EINVAL;
233 *value = (const void *)body;
234 *len = pod->size;
235 return 0;
236}
238SPA_API_POD_BODY int spa_pod_is_pointer(const struct spa_pod *pod)
239{
240 return SPA_POD_CHECK(pod, SPA_TYPE_Pointer, sizeof(struct spa_pod_pointer_body));
241}
242
243SPA_API_POD_BODY int spa_pod_body_get_pointer(const struct spa_pod *pod, const void *body,
244 uint32_t *type, const void **value)
245{
246 if (!spa_pod_is_pointer(pod))
247 return -EINVAL;
248 struct spa_pod_pointer_body b;
251 *type = b.type;
252 *value = b.value;
253 return 0;
254}
255
256SPA_API_POD_BODY int spa_pod_is_fd(const struct spa_pod *pod)
257{
258 return SPA_POD_CHECK(pod, SPA_TYPE_Fd, sizeof(int64_t));
259}
260
261SPA_API_POD_BODY int spa_pod_body_get_fd(const struct spa_pod *pod, const void *body,
262 int64_t *value)
263{
264 if (!spa_pod_is_fd(pod))
265 return -EINVAL;
267 memcpy(value, body, sizeof *value);
269 return 0;
271
272SPA_API_POD_BODY int spa_pod_is_rectangle(const struct spa_pod *pod)
273{
274 return SPA_POD_CHECK(pod, SPA_TYPE_Rectangle, sizeof(struct spa_rectangle));
275}
276
277SPA_API_POD_BODY int spa_pod_body_get_rectangle(const struct spa_pod *pod, const void *body,
278 struct spa_rectangle *value)
279{
280 if (!spa_pod_is_rectangle(pod))
281 return -EINVAL;
283 SPA_POD_BODY_LOAD_FIELD_ONCE(value, body, height);
284 return 0;
285}
287SPA_API_POD_BODY int spa_pod_is_fraction(const struct spa_pod *pod)
288{
289 return SPA_POD_CHECK(pod, SPA_TYPE_Fraction, sizeof(struct spa_fraction));
290}
291SPA_API_POD_BODY int spa_pod_body_get_fraction(const struct spa_pod *pod, const void *body,
292 struct spa_fraction *value)
293{
294 if (!spa_pod_is_fraction(pod))
295 return -EINVAL;
298 return 0;
299}
301SPA_API_POD_BODY int spa_pod_is_bitmap(const struct spa_pod *pod)
302{
303 return SPA_POD_CHECK(pod, SPA_TYPE_Bitmap, sizeof(uint8_t));
304}
305SPA_API_POD_BODY int spa_pod_body_get_bitmap(const struct spa_pod *pod, const void *body,
306 const uint8_t **value)
307{
308 if (!spa_pod_is_bitmap(pod))
309 return -EINVAL;
310 *value = (const uint8_t *)body;
311 return 0;
312}
313
315{
316 return SPA_POD_CHECK(pod, SPA_TYPE_Array, sizeof(struct spa_pod_array_body));
317}
318SPA_API_POD_BODY int spa_pod_body_get_array(const struct spa_pod *pod, const void *body,
319 struct spa_pod_array *arr, const void **arr_body)
320{
321 if (!spa_pod_is_array(pod))
322 return -EINVAL;
323 arr->pod = *pod;
325 SPA_POD_BODY_LOAD_FIELD_ONCE(&arr->body.child, body, size);
326 *arr_body = SPA_PTROFF(body, sizeof(struct spa_pod_array_body), void);
327 return 0;
328}
330 const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
331{
332 uint32_t child_size = arr->body.child.size;
333 *n_values = child_size ? (arr->pod.size - sizeof(arr->body)) / child_size : 0;
334 *val_size = child_size;
335 *val_type = arr->body.child.type;
336 return body;
337}
339SPA_API_POD_BODY const void *spa_pod_body_get_array_values(const struct spa_pod *pod,
340 const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
341{
342 struct spa_pod_array arr;
343 if (spa_pod_body_get_array(pod, body, &arr, &body) < 0)
344 return NULL;
345 return spa_pod_array_body_get_values(&arr, body, n_values, val_size, val_type);
346}
347
349{
350 return SPA_POD_CHECK(pod, SPA_TYPE_Choice, sizeof(struct spa_pod_choice_body));
351}
352SPA_API_POD_BODY int spa_pod_body_get_choice(const struct spa_pod *pod, const void *body,
353 struct spa_pod_choice *choice, const void **choice_body)
354{
356 return -EINVAL;
357 choice->pod = *pod;
358 SPA_POD_BODY_LOAD_FIELD_ONCE(&choice->body, body, type);
359 SPA_POD_BODY_LOAD_FIELD_ONCE(&choice->body, body, flags);
360 SPA_POD_BODY_LOAD_FIELD_ONCE(&choice->body, body, child.size);
361 SPA_POD_BODY_LOAD_FIELD_ONCE(&choice->body, body, child.type);
362 *choice_body = SPA_PTROFF(body, sizeof(struct spa_pod_choice_body), void);
363 return 0;
364}
366 const void *body, uint32_t *n_values, uint32_t *choice,
367 uint32_t *val_size, uint32_t *val_type)
368{
369 uint32_t child_size = pod->body.child.size;
370 *val_size = child_size;
371 *val_type = pod->body.child.type;
372 *n_values = child_size ? (pod->pod.size - sizeof(pod->body)) / child_size : 0;
373 *choice = pod->body.type;
374 if (*choice == SPA_CHOICE_None)
375 *n_values = SPA_MIN(1u, *n_values);
376 return body;
377}
378
380{
382}
383
385{
386 return SPA_POD_CHECK(pod, SPA_TYPE_Object, sizeof(struct spa_pod_object_body));
387}
389 struct spa_pod_object *object, const void **object_body)
390{
392 return -EINVAL;
393 object->pod = *pod;
394 SPA_POD_BODY_LOAD_FIELD_ONCE(&object->body, body, type);
395 SPA_POD_BODY_LOAD_FIELD_ONCE(&object->body, body, id);
396 *object_body = SPA_PTROFF(body, sizeof(struct spa_pod_object_body), void);
397 return 0;
398}
399
401{
403}
404SPA_API_POD_BODY int spa_pod_body_get_sequence(const struct spa_pod *pod, const void *body,
405 struct spa_pod_sequence *seq, const void **seq_body)
406{
408 return -EINVAL;
409 seq->pod = *pod;
412 *seq_body = SPA_PTROFF(body, sizeof(struct spa_pod_sequence_body), void);
413 return 0;
414}
415
420#ifdef __cplusplus
421} /* extern "C" */
422#endif
423
424#endif /* SPA_POD_BODY_H */
#define SPA_API_POD_BODY
Definition body.h:29
uint32_t int seq
Definition core.h:432
SPA_API_POD_BODY int spa_pod_is_sequence(const struct spa_pod *pod)
Definition body.h:409
SPA_API_POD_BODY int spa_pod_is_pointer(const struct spa_pod *pod)
Definition body.h:247
SPA_API_POD_BODY int spa_pod_is_bitmap(const struct spa_pod *pod)
Definition body.h:310
#define SPA_POD_IS_VALID(pod)
Definition pod.h:48
SPA_API_POD_BODY int spa_pod_is_fraction(const struct spa_pod *pod)
Definition body.h:296
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:252
SPA_API_POD_BODY int spa_pod_is_double(const struct spa_pod *pod)
Definition body.h:186
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:348
SPA_API_POD_BODY int spa_pod_body_get_sequence(const struct spa_pod *pod, const void *body, struct spa_pod_sequence *seq, const void **seq_body)
Definition body.h:413
SPA_API_POD_BODY int spa_pod_body_get_string(const struct spa_pod *pod, const void *body, const char **value)
Definition body.h:206
SPA_API_POD_BODY int spa_pod_is_array(const struct spa_pod *pod)
Definition body.h:323
SPA_API_POD_BODY int spa_pod_is_rectangle(const struct spa_pod *pod)
Definition body.h:281
SPA_API_POD_BODY int spa_pod_is_struct(const struct spa_pod *pod)
Definition body.h:388
SPA_API_POD_BODY int spa_pod_is_int(const struct spa_pod *pod)
Definition body.h:142
SPA_API_POD_BODY int spa_pod_is_fd(const struct spa_pod *pod)
Definition body.h:265
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:300
SPA_API_POD_BODY int spa_pod_is_none(const struct spa_pod *pod)
Definition body.h:106
SPA_API_POD_BODY int spa_pod_is_object(const struct spa_pod *pod)
Definition body.h:393
SPA_API_POD_BODY const void * spa_pod_array_body_get_values(const struct spa_pod_array *arr, const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
Definition body.h:338
SPA_API_POD_BODY int spa_pod_is_bool(const struct spa_pod *pod)
Definition body.h:111
#define SPA_POD_CHECK_TYPE(pod, _type)
Definition pod.h:50
SPA_API_POD_BODY int spa_pod_is_id(const struct spa_pod *pod)
Definition body.h:129
SPA_API_POD_BODY uint32_t spa_pod_type_size(uint32_t type)
Definition body.h:45
#define SPA_POD_BODY_LOAD_FIELD_ONCE(a, b, field)
Definition body.h:119
SPA_API_POD_BODY int spa_pod_body_get_array(const struct spa_pod *pod, const void *body, struct spa_pod_array *arr, const void **arr_body)
Definition body.h:327
SPA_API_POD_BODY int spa_pod_body_get_double(const struct spa_pod *pod, const void *body, double *value)
Definition body.h:191
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:219
SPA_API_POD_BODY int spa_pod_body_get_long(const struct spa_pod *pod, const void *body, int64_t *value)
Definition body.h:160
SPA_API_POD_BODY int spa_pod_body_get_object(const struct spa_pod *pod, const void *body, struct spa_pod_object *object, const void **object_body)
Definition body.h:397
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:374
SPA_API_POD_BODY int spa_pod_is_bytes(const struct spa_pod *pod)
Definition body.h:232
SPA_API_POD_BODY int spa_pod_body_get_int(const struct spa_pod *pod, const void *body, int32_t *value)
Definition body.h:147
SPA_API_POD_BODY int spa_pod_is_string(const struct spa_pod *pod)
Definition body.h:201
#define SPA_POD_BODY_LOAD_ONCE(a, b)
Definition body.h:117
SPA_API_POD_BODY int spa_pod_body_get_float(const struct spa_pod *pod, const void *body, float *value)
Definition body.h:176
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:286
SPA_API_POD_BODY int spa_pod_body_get_bool(const struct spa_pod *pod, const void *body, bool *value)
Definition body.h:121
SPA_API_POD_BODY int spa_pod_body_get_bitmap(const struct spa_pod *pod, const void *body, const uint8_t **value)
Definition body.h:314
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:88
SPA_API_POD_BODY int spa_pod_body_get_choice(const struct spa_pod *pod, const void *body, struct spa_pod_choice *choice, const void **choice_body)
Definition body.h:361
SPA_API_POD_BODY int spa_pod_body_get_fd(const struct spa_pod *pod, const void *body, int64_t *value)
Definition body.h:270
SPA_API_POD_BODY int spa_pod_is_choice(const struct spa_pod *pod)
Definition body.h:357
SPA_API_POD_BODY int spa_pod_body_get_id(const struct spa_pod *pod, const void *body, uint32_t *value)
Definition body.h:134
SPA_API_POD_BODY int spa_pod_is_float(const struct spa_pod *pod)
Definition body.h:171
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:237
#define SPA_POD_CHECK(pod, _type, _size)
Definition pod.h:53
SPA_API_POD_BODY int spa_pod_is_long(const struct spa_pod *pod)
Definition body.h:155
@ SPA_CHOICE_None
no choice, first value is current
Definition pod.h:161
@ SPA_TYPE_Int
Definition type.h:45
@ SPA_TYPE_Rectangle
Definition type.h:51
@ SPA_TYPE_Long
Definition type.h:46
@ SPA_TYPE_Bool
Definition type.h:43
@ SPA_TYPE_Bytes
Definition type.h:50
@ SPA_TYPE_Pod
Definition type.h:61
@ SPA_TYPE_Bitmap
Definition type.h:53
@ SPA_TYPE_Object
Definition type.h:56
@ SPA_TYPE_Float
Definition type.h:47
@ SPA_TYPE_Fraction
Definition type.h:52
@ SPA_TYPE_None
Definition type.h:42
@ SPA_TYPE_Sequence
Definition type.h:57
@ SPA_TYPE_Double
Definition type.h:48
@ SPA_TYPE_Id
Definition type.h:44
@ SPA_TYPE_Choice
Definition type.h:60
@ SPA_TYPE_Pointer
Definition type.h:58
@ SPA_TYPE_Array
Definition type.h:54
@ SPA_TYPE_String
Definition type.h:49
@ SPA_TYPE_Fd
Definition type.h:59
@ SPA_TYPE_Struct
Definition type.h:55
#define SPA_MIN(a, b)
Definition defs.h:165
#define SPA_BARRIER
Definition defs.h:315
#define SPA_PTROFF(ptr_, offset_, type_)
Return the address (buffer + offset) as pointer of type.
Definition defs.h:222
spa/pod/pod.h
Definition defs.h:137
Definition pod.h:135
struct spa_pod child
Definition pod.h:136
Definition pod.h:140
struct spa_pod pod
Definition pod.h:141
struct spa_pod_array_body body
Definition pod.h:142
Definition pod.h:168
uint32_t type
type of choice, one of enum spa_choice_type
Definition pod.h:169
Definition pod.h:176
struct spa_pod_choice_body body
Definition pod.h:178
struct spa_pod pod
Definition pod.h:177
Definition body.h:38
struct spa_pod pod
Definition body.h:39
uint32_t offset
Definition body.h:41
struct spa_pod_frame * parent
Definition body.h:40
uint32_t flags
Definition body.h:42
Definition pod.h:196
Definition pod.h:202
Definition pod.h:207
const void * value
Definition pod.h:210
uint32_t type
pointer id, one of enum spa_type
Definition pod.h:208
Definition pod.h:264
a sequence of timed controls
Definition pod.h:271
Definition pod.h:57
uint32_t type
Definition pod.h:59
uint32_t size
Definition pod.h:58
Definition defs.h:116