Revert "pod: remove checks from spa_pod_body_get_*()"

This partially reverts commit f7ae61cb1e.

We do want to do the checks in spa_pod_body_get_*() for extra safety.
The reason they were removed is because then we do the checks twice in
the parser. It should however be possible to fuse the can_collect and
COLLECT and SKIP calls together in the future.
This commit is contained in:
Wim Taymans 2025-08-01 10:08:06 +02:00
parent 00dbe9cb2a
commit bef0706238
3 changed files with 162 additions and 146 deletions

View file

@ -105,9 +105,12 @@ SPA_API_POD_BODY int spa_pod_is_bool(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Bool, sizeof(int32_t)); return SPA_POD_CHECK(pod, SPA_TYPE_Bool, sizeof(int32_t));
} }
SPA_API_POD_BODY void spa_pod_body_get_bool(const struct spa_pod *pod, const void *body, bool *value) SPA_API_POD_BODY int spa_pod_body_get_bool(const struct spa_pod *pod, const void *body, bool *value)
{ {
if (!spa_pod_is_bool(pod))
return -EINVAL;
*value = !!*((int32_t*)body); *value = !!*((int32_t*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_id(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_id(const struct spa_pod *pod)
@ -115,9 +118,12 @@ SPA_API_POD_BODY int spa_pod_is_id(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Id, sizeof(uint32_t)); return SPA_POD_CHECK(pod, SPA_TYPE_Id, sizeof(uint32_t));
} }
SPA_API_POD_BODY void spa_pod_body_get_id(const struct spa_pod *pod, const void *body, uint32_t *value) SPA_API_POD_BODY int spa_pod_body_get_id(const struct spa_pod *pod, const void *body, uint32_t *value)
{ {
if (!spa_pod_is_id(pod))
return -EINVAL;
*value = *((uint32_t*)body); *value = *((uint32_t*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_int(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_int(const struct spa_pod *pod)
@ -125,9 +131,12 @@ SPA_API_POD_BODY int spa_pod_is_int(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Int, sizeof(int32_t)); return SPA_POD_CHECK(pod, SPA_TYPE_Int, sizeof(int32_t));
} }
SPA_API_POD_BODY void spa_pod_body_get_int(const struct spa_pod *pod, const void *body, int32_t *value) SPA_API_POD_BODY int spa_pod_body_get_int(const struct spa_pod *pod, const void *body, int32_t *value)
{ {
if (!spa_pod_is_int(pod))
return -EINVAL;
*value = *((int32_t*)body); *value = *((int32_t*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_long(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_long(const struct spa_pod *pod)
@ -135,9 +144,12 @@ SPA_API_POD_BODY int spa_pod_is_long(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Long, sizeof(int64_t)); return SPA_POD_CHECK(pod, SPA_TYPE_Long, sizeof(int64_t));
} }
SPA_API_POD_BODY void spa_pod_body_get_long(const struct spa_pod *pod, const void *body, int64_t *value) SPA_API_POD_BODY int spa_pod_body_get_long(const struct spa_pod *pod, const void *body, int64_t *value)
{ {
if (!spa_pod_is_long(pod))
return -EINVAL;
*value = *((int64_t*)body); *value = *((int64_t*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_float(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_float(const struct spa_pod *pod)
@ -145,9 +157,12 @@ SPA_API_POD_BODY int spa_pod_is_float(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Float, sizeof(float)); return SPA_POD_CHECK(pod, SPA_TYPE_Float, sizeof(float));
} }
SPA_API_POD_BODY void spa_pod_body_get_float(const struct spa_pod *pod, const void *body, float *value) SPA_API_POD_BODY int spa_pod_body_get_float(const struct spa_pod *pod, const void *body, float *value)
{ {
if (!spa_pod_is_float(pod))
return -EINVAL;
*value = *((float*)body); *value = *((float*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_double(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_double(const struct spa_pod *pod)
@ -155,9 +170,12 @@ SPA_API_POD_BODY int spa_pod_is_double(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Double, sizeof(double)); return SPA_POD_CHECK(pod, SPA_TYPE_Double, sizeof(double));
} }
SPA_API_POD_BODY void spa_pod_body_get_double(const struct spa_pod *pod, const void *body, double *value) SPA_API_POD_BODY int spa_pod_body_get_double(const struct spa_pod *pod, const void *body, double *value)
{ {
if (!spa_pod_is_double(pod))
return -EINVAL;
*value = *((double*)body); *value = *((double*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_string(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_string(const struct spa_pod *pod)
@ -165,21 +183,24 @@ SPA_API_POD_BODY int spa_pod_is_string(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_String, 1); return SPA_POD_CHECK(pod, SPA_TYPE_String, 1);
} }
SPA_API_POD_BODY void spa_pod_body_get_string(const struct spa_pod *pod, SPA_API_POD_BODY int spa_pod_body_get_string(const struct spa_pod *pod,
const void *body, const char **value) const void *body, const char **value)
{ {
const char *s = (const char *)body; const char *s;
if (!spa_pod_is_string(pod))
return -EINVAL;
s = (const char *)body;
if (s[pod->size-1] != '\0') if (s[pod->size-1] != '\0')
s = NULL; return -EINVAL;
*value = s; *value = s;
return 0;
} }
SPA_API_POD_BODY int spa_pod_body_copy_string(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_copy_string(const struct spa_pod *pod, const void *body,
char *dest, size_t maxlen) char *dest, size_t maxlen)
{ {
const char *s; const char *s;
spa_pod_body_get_string(pod, body, &s); if (spa_pod_body_get_string(pod, body, &s) < 0 || maxlen < 1)
if (s == NULL || maxlen < 1)
return -EINVAL; return -EINVAL;
strncpy(dest, s, maxlen-1); strncpy(dest, s, maxlen-1);
dest[maxlen-1]= '\0'; dest[maxlen-1]= '\0';
@ -191,11 +212,14 @@ SPA_API_POD_BODY int spa_pod_is_bytes(const struct spa_pod *pod)
return SPA_POD_CHECK_TYPE(pod, SPA_TYPE_Bytes); return SPA_POD_CHECK_TYPE(pod, SPA_TYPE_Bytes);
} }
SPA_API_POD_BODY void spa_pod_body_get_bytes(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_get_bytes(const struct spa_pod *pod, const void *body,
const void **value, uint32_t *len) const void **value, uint32_t *len)
{ {
if (!spa_pod_is_bytes(pod))
return -EINVAL;
*value = (const void *)body; *value = (const void *)body;
*len = pod->size; *len = pod->size;
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_pointer(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_pointer(const struct spa_pod *pod)
@ -203,11 +227,14 @@ SPA_API_POD_BODY int spa_pod_is_pointer(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Pointer, sizeof(struct spa_pod_pointer_body)); return SPA_POD_CHECK(pod, SPA_TYPE_Pointer, sizeof(struct spa_pod_pointer_body));
} }
SPA_API_POD_BODY void spa_pod_body_get_pointer(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_get_pointer(const struct spa_pod *pod, const void *body,
uint32_t *type, const void **value) uint32_t *type, const void **value)
{ {
if (!spa_pod_is_pointer(pod))
return -EINVAL;
*type = ((struct spa_pod_pointer_body*)body)->type; *type = ((struct spa_pod_pointer_body*)body)->type;
*value = ((struct spa_pod_pointer_body*)body)->value; *value = ((struct spa_pod_pointer_body*)body)->value;
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_fd(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_fd(const struct spa_pod *pod)
@ -215,10 +242,13 @@ SPA_API_POD_BODY int spa_pod_is_fd(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Fd, sizeof(int64_t)); return SPA_POD_CHECK(pod, SPA_TYPE_Fd, sizeof(int64_t));
} }
SPA_API_POD_BODY void spa_pod_body_get_fd(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_get_fd(const struct spa_pod *pod, const void *body,
int64_t *value) int64_t *value)
{ {
if (!spa_pod_is_fd(pod))
return -EINVAL;
*value = *((int64_t*)body); *value = *((int64_t*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_rectangle(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_rectangle(const struct spa_pod *pod)
@ -226,42 +256,54 @@ SPA_API_POD_BODY int spa_pod_is_rectangle(const struct spa_pod *pod)
return SPA_POD_CHECK(pod, SPA_TYPE_Rectangle, sizeof(struct spa_rectangle)); return SPA_POD_CHECK(pod, SPA_TYPE_Rectangle, sizeof(struct spa_rectangle));
} }
SPA_API_POD_BODY void spa_pod_body_get_rectangle(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_get_rectangle(const struct spa_pod *pod, const void *body,
struct spa_rectangle *value) struct spa_rectangle *value)
{ {
if (!spa_pod_is_rectangle(pod))
return -EINVAL;
*value = *((struct spa_rectangle*)body); *value = *((struct spa_rectangle*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_fraction(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_fraction(const struct spa_pod *pod)
{ {
return SPA_POD_CHECK(pod, SPA_TYPE_Fraction, sizeof(struct spa_fraction)); return SPA_POD_CHECK(pod, SPA_TYPE_Fraction, sizeof(struct spa_fraction));
} }
SPA_API_POD_BODY void spa_pod_body_get_fraction(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_get_fraction(const struct spa_pod *pod, const void *body,
struct spa_fraction *value) struct spa_fraction *value)
{ {
if (!spa_pod_is_fraction(pod))
return -EINVAL;
*value = *((struct spa_fraction*)body); *value = *((struct spa_fraction*)body);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_bitmap(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_bitmap(const struct spa_pod *pod)
{ {
return SPA_POD_CHECK(pod, SPA_TYPE_Bitmap, sizeof(uint8_t)); return SPA_POD_CHECK(pod, SPA_TYPE_Bitmap, sizeof(uint8_t));
} }
SPA_API_POD_BODY void spa_pod_body_get_bitmap(const struct spa_pod *pod, const void *body, SPA_API_POD_BODY int spa_pod_body_get_bitmap(const struct spa_pod *pod, const void *body,
const uint8_t **value) const uint8_t **value)
{ {
if (!spa_pod_is_bitmap(pod))
return -EINVAL;
*value = (const uint8_t *)body; *value = (const uint8_t *)body;
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_array(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_array(const struct spa_pod *pod)
{ {
return SPA_POD_CHECK(pod, SPA_TYPE_Array, sizeof(struct spa_pod_array_body)); return SPA_POD_CHECK(pod, SPA_TYPE_Array, sizeof(struct spa_pod_array_body));
} }
SPA_API_POD_BODY void spa_pod_body_get_array(const struct spa_pod *pod, const void *body, 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) struct spa_pod_array *arr, const void **arr_body)
{ {
if (!spa_pod_is_array(pod))
return -EINVAL;
arr->pod = *pod; arr->pod = *pod;
memcpy(&arr->body, body, sizeof(struct spa_pod_array_body)); memcpy(&arr->body, body, sizeof(struct spa_pod_array_body));
*arr_body = SPA_PTROFF(body, sizeof(struct spa_pod_array_body), void); *arr_body = SPA_PTROFF(body, sizeof(struct spa_pod_array_body), void);
return 0;
} }
SPA_API_POD_BODY const void *spa_pod_array_body_get_values(const struct spa_pod_array *arr, 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) const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
@ -277,7 +319,8 @@ SPA_API_POD_BODY const void *spa_pod_body_get_array_values(const struct spa_pod
const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type) const void *body, uint32_t *n_values, uint32_t *val_size, uint32_t *val_type)
{ {
struct spa_pod_array arr; struct spa_pod_array arr;
spa_pod_body_get_array(pod, body, &arr, &body); if (spa_pod_body_get_array(pod, body, &arr, &body) < 0)
return NULL;
return spa_pod_array_body_get_values(&arr, body, n_values, val_size, val_type); return spa_pod_array_body_get_values(&arr, body, n_values, val_size, val_type);
} }
@ -285,12 +328,15 @@ SPA_API_POD_BODY int spa_pod_is_choice(const struct spa_pod *pod)
{ {
return SPA_POD_CHECK(pod, SPA_TYPE_Choice, sizeof(struct spa_pod_choice_body)); return SPA_POD_CHECK(pod, SPA_TYPE_Choice, sizeof(struct spa_pod_choice_body));
} }
SPA_API_POD_BODY void spa_pod_body_get_choice(const struct spa_pod *pod, const void *body, 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) struct spa_pod_choice *choice, const void **choice_body)
{ {
if (!spa_pod_is_choice(pod))
return -EINVAL;
choice->pod = *pod; choice->pod = *pod;
memcpy(&choice->body, body, sizeof(struct spa_pod_choice_body)); memcpy(&choice->body, body, sizeof(struct spa_pod_choice_body));
*choice_body = SPA_PTROFF(body, sizeof(struct spa_pod_choice_body), void); *choice_body = SPA_PTROFF(body, sizeof(struct spa_pod_choice_body), void);
return 0;
} }
SPA_API_POD_BODY const void *spa_pod_choice_body_get_values(const struct spa_pod_choice *pod, 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, const void *body, uint32_t *n_values, uint32_t *choice,
@ -315,24 +361,30 @@ SPA_API_POD_BODY int spa_pod_is_object(const struct spa_pod *pod)
{ {
return SPA_POD_CHECK(pod, SPA_TYPE_Object, sizeof(struct spa_pod_object_body)); return SPA_POD_CHECK(pod, SPA_TYPE_Object, sizeof(struct spa_pod_object_body));
} }
SPA_API_POD_BODY void spa_pod_body_get_object(const struct spa_pod *pod, const void *body, 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) struct spa_pod_object *object, const void **object_body)
{ {
if (!spa_pod_is_object(pod))
return -EINVAL;
object->pod = *pod; object->pod = *pod;
memcpy(&object->body, body, sizeof(struct spa_pod_object_body)); memcpy(&object->body, body, sizeof(struct spa_pod_object_body));
*object_body = SPA_PTROFF(body, sizeof(struct spa_pod_object_body), void); *object_body = SPA_PTROFF(body, sizeof(struct spa_pod_object_body), void);
return 0;
} }
SPA_API_POD_BODY int spa_pod_is_sequence(const struct spa_pod *pod) SPA_API_POD_BODY int spa_pod_is_sequence(const struct spa_pod *pod)
{ {
return SPA_POD_CHECK(pod, SPA_TYPE_Sequence, sizeof(struct spa_pod_sequence_body)); return SPA_POD_CHECK(pod, SPA_TYPE_Sequence, sizeof(struct spa_pod_sequence_body));
} }
SPA_API_POD_BODY void spa_pod_body_get_sequence(const struct spa_pod *pod, const void *body, 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) struct spa_pod_sequence *seq, const void **seq_body)
{ {
if (!spa_pod_is_sequence(pod))
return -EINVAL;
seq->pod = *pod; seq->pod = *pod;
memcpy(&seq->body, body, sizeof(struct spa_pod_sequence_body)); memcpy(&seq->body, body, sizeof(struct spa_pod_sequence_body));
*seq_body = SPA_PTROFF(body, sizeof(struct spa_pod_sequence_body), void); *seq_body = SPA_PTROFF(body, sizeof(struct spa_pod_sequence_body), void);
return 0;
} }
/** /**

View file

@ -130,112 +130,72 @@ SPA_API_POD_ITER void *spa_pod_from_data(void *data, size_t maxsize, off_t offse
SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value) SPA_API_POD_ITER int spa_pod_get_bool(const struct spa_pod *pod, bool *value)
{ {
if (!spa_pod_is_bool(pod)) return spa_pod_body_get_bool(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_bool(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value) SPA_API_POD_ITER int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value)
{ {
if (!spa_pod_is_id(pod)) return spa_pod_body_get_id(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_id(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value) SPA_API_POD_ITER int spa_pod_get_int(const struct spa_pod *pod, int32_t *value)
{ {
if (!spa_pod_is_int(pod)) return spa_pod_body_get_int(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_int(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value) SPA_API_POD_ITER int spa_pod_get_long(const struct spa_pod *pod, int64_t *value)
{ {
if (!spa_pod_is_long(pod)) return spa_pod_body_get_long(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_long(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value) SPA_API_POD_ITER int spa_pod_get_float(const struct spa_pod *pod, float *value)
{ {
if (!spa_pod_is_float(pod)) return spa_pod_body_get_float(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_float(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value) SPA_API_POD_ITER int spa_pod_get_double(const struct spa_pod *pod, double *value)
{ {
if (!spa_pod_is_double(pod)) return spa_pod_body_get_double(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_double(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_string(const struct spa_pod *pod, const char **value) SPA_API_POD_ITER int spa_pod_get_string(const struct spa_pod *pod, const char **value)
{ {
if (!spa_pod_is_string(pod)) return spa_pod_body_get_string(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_string(pod, SPA_POD_BODY_CONST(pod), value);
return *value ? 0 : -EINVAL;
} }
SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest) SPA_API_POD_ITER int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest)
{ {
if (!spa_pod_is_string(pod))
return -EINVAL;
return spa_pod_body_copy_string(pod, SPA_POD_BODY_CONST(pod), dest, maxlen); return spa_pod_body_copy_string(pod, SPA_POD_BODY_CONST(pod), dest, maxlen);
} }
SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len) SPA_API_POD_ITER int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len)
{ {
if (!spa_pod_is_bytes(pod)) return spa_pod_body_get_bytes(pod, SPA_POD_BODY_CONST(pod), value, len);
return -EINVAL;
spa_pod_body_get_bytes(pod, SPA_POD_BODY_CONST(pod), value, len);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value) SPA_API_POD_ITER int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value)
{ {
if (!spa_pod_is_pointer(pod)) return spa_pod_body_get_pointer(pod, SPA_POD_BODY_CONST(pod), type, value);
return -EINVAL;
spa_pod_body_get_pointer(pod, SPA_POD_BODY_CONST(pod), type, value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value) SPA_API_POD_ITER int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value)
{ {
if (!spa_pod_is_fd(pod)) return spa_pod_body_get_fd(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_fd(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value) SPA_API_POD_ITER int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value)
{ {
if (!spa_pod_is_rectangle(pod)) return spa_pod_body_get_rectangle(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_rectangle(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value) SPA_API_POD_ITER int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value)
{ {
if (!spa_pod_is_fraction(pod)) return spa_pod_body_get_fraction(pod, SPA_POD_BODY_CONST(pod), value);
return -EINVAL;
spa_pod_body_get_fraction(pod, SPA_POD_BODY_CONST(pod), value);
return 0;
} }
SPA_API_POD_ITER void *spa_pod_get_array_full(const struct spa_pod *pod, uint32_t *n_values, 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) uint32_t *val_size, uint32_t *val_type)
{ {
if (!spa_pod_is_array(pod))
return NULL;
return (void*)spa_pod_body_get_array_values(pod, SPA_POD_BODY(pod), n_values, val_size, val_type); return (void*)spa_pod_body_get_array_values(pod, SPA_POD_BODY(pod), n_values, val_size, val_type);
} }
SPA_API_POD_ITER void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values) SPA_API_POD_ITER void *spa_pod_get_array(const struct spa_pod *pod, uint32_t *n_values)

View file

@ -206,10 +206,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_bool(struct spa_pod_parser *parser, bo
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_bool(&pod)) if ((res = spa_pod_body_get_bool(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_bool(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -220,10 +218,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_id(struct spa_pod_parser *parser, uint
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_id(&pod)) if ((res = spa_pod_body_get_id(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_id(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -234,10 +230,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_int(struct spa_pod_parser *parser, int
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_int(&pod)) if ((res = spa_pod_body_get_int(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_int(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -248,10 +242,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_long(struct spa_pod_parser *parser, in
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_long(&pod)) if ((res = spa_pod_body_get_long(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_long(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -262,10 +254,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_float(struct spa_pod_parser *parser, f
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_float(&pod)) if ((res = spa_pod_body_get_float(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_float(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -276,10 +266,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_double(struct spa_pod_parser *parser,
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_double(&pod)) if ((res = spa_pod_body_get_double(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_double(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -290,10 +278,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_string(struct spa_pod_parser *parser,
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_string(&pod)) if ((res = spa_pod_body_get_string(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_string(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -304,10 +290,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_bytes(struct spa_pod_parser *parser, c
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_bytes(&pod)) if ((res = spa_pod_body_get_bytes(&pod, body, value, len)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_bytes(&pod, body, value, len);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -318,10 +302,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_pointer(struct spa_pod_parser *parser,
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_pointer(&pod)) if ((res = spa_pod_body_get_pointer(&pod, body, type, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_pointer(&pod, body, type, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -332,10 +314,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_fd(struct spa_pod_parser *parser, int6
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_fd(&pod)) if ((res = spa_pod_body_get_fd(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_fd(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -346,10 +326,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_rectangle(struct spa_pod_parser *parse
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_rectangle(&pod)) if ((res = spa_pod_body_get_rectangle(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_rectangle(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -360,10 +338,8 @@ SPA_API_POD_PARSER int spa_pod_parser_get_fraction(struct spa_pod_parser *parser
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_fraction(&pod)) if ((res = spa_pod_body_get_fraction(&pod, body, value)) >= 0)
return -EINVAL; spa_pod_parser_advance(parser, &pod);
spa_pod_body_get_fraction(&pod, body, value);
spa_pod_parser_advance(parser, &pod);
return res; return res;
} }
@ -423,10 +399,12 @@ SPA_API_POD_PARSER int spa_pod_parser_init_object_body(struct spa_pod_parser *pa
struct spa_pod_frame *frame, const struct spa_pod *pod, const void *body, struct spa_pod_frame *frame, const struct spa_pod *pod, const void *body,
struct spa_pod_object *object, const void **object_body) struct spa_pod_object *object, const void **object_body)
{ {
int res;
if (!spa_pod_is_object(pod)) if (!spa_pod_is_object(pod))
return -EINVAL; return -EINVAL;
spa_pod_parser_init_pod_body(parser, pod, body); spa_pod_parser_init_pod_body(parser, pod, body);
spa_pod_body_get_object(pod, body, object, object_body); if ((res = spa_pod_body_get_object(pod, body, object, object_body)) < 0)
return res;
spa_pod_parser_push(parser, frame, pod, parser->state.offset); spa_pod_parser_push(parser, frame, pod, parser->state.offset);
parser->state.offset += sizeof(struct spa_pod_object); parser->state.offset += sizeof(struct spa_pod_object);
return 0; return 0;
@ -440,9 +418,8 @@ SPA_API_POD_PARSER int spa_pod_parser_push_object_body(struct spa_pod_parser *pa
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_object(&pod)) if ((res = spa_pod_body_get_object(&pod, body, object, object_body)) < 0)
return -EINVAL; return res;
spa_pod_body_get_object(&pod, body, object, object_body);
spa_pod_parser_push(parser, frame, &pod, parser->state.offset); spa_pod_parser_push(parser, frame, &pod, parser->state.offset);
parser->state.offset += sizeof(struct spa_pod_object); parser->state.offset += sizeof(struct spa_pod_object);
return 0; return 0;
@ -482,9 +459,8 @@ SPA_API_POD_PARSER int spa_pod_parser_push_sequence_body(struct spa_pod_parser *
const void *body; const void *body;
if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0) if ((res = spa_pod_parser_current_body(parser, &pod, &body)) < 0)
return res; return res;
if (!spa_pod_is_sequence(&pod)) if ((res = spa_pod_body_get_sequence(&pod, body, seq, seq_body)) < 0)
return -EINVAL; return res;
spa_pod_body_get_sequence(&pod, body, seq, seq_body);
spa_pod_parser_push(parser, frame, &pod, parser->state.offset); spa_pod_parser_push(parser, frame, &pod, parser->state.offset);
parser->state.offset += sizeof(struct spa_pod_sequence); parser->state.offset += sizeof(struct spa_pod_sequence);
return 0; return 0;
@ -537,7 +513,8 @@ SPA_API_POD_PARSER bool spa_pod_parser_body_can_collect(const struct spa_pod *po
return false; return false;
if (type == 'V' || type == 'W') if (type == 'V' || type == 'W')
return true; return true;
spa_pod_body_get_choice(pod, body, &choice, &body); if (spa_pod_body_get_choice(pod, body, &choice, &body) < 0)
return false;
if (choice.body.type != SPA_CHOICE_None) if (choice.body.type != SPA_CHOICE_None)
return false; return false;
pod = &choice.body.child; pod = &choice.body.child;
@ -598,23 +575,41 @@ SPA_API_POD_PARSER bool spa_pod_parser_can_collect(const struct spa_pod *pod, ch
do { \ do { \
switch (_type) { \ switch (_type) { \
case 'b': \ case 'b': \
spa_pod_body_get_bool(pod, body, va_arg(args, bool*)); \ { \
bool *val = va_arg(args, bool*); \
spa_pod_body_get_bool(pod, body, val); \
break; \ break; \
} \
case 'I': \ case 'I': \
spa_pod_body_get_id(pod, body, va_arg(args, uint32_t*)); \ { \
uint32_t *val = va_arg(args, uint32_t*); \
spa_pod_body_get_id(pod, body, val); \
break; \ break; \
} \
case 'i': \ case 'i': \
spa_pod_body_get_int(pod, body, va_arg(args, int32_t*)); \ { \
int32_t *val = va_arg(args, int32_t*); \
spa_pod_body_get_int(pod, body, val); \
break; \ break; \
} \
case 'l': \ case 'l': \
spa_pod_body_get_long(pod, body, va_arg(args, int64_t*)); \ { \
int64_t *val = va_arg(args, int64_t*); \
spa_pod_body_get_long(pod, body, val); \
break; \ break; \
} \
case 'f': \ case 'f': \
spa_pod_body_get_float(pod, body, va_arg(args, float*)); \ { \
float *val = va_arg(args, float*); \
spa_pod_body_get_float(pod, body, val); \
break; \ break; \
} \
case 'd': \ case 'd': \
spa_pod_body_get_double(pod, body, va_arg(args, double*)); \ { \
double *val = va_arg(args, double*); \
spa_pod_body_get_double(pod, body, val); \
break; \ break; \
} \
case 's': \ case 's': \
{ \ { \
const char **dest = va_arg(args, const char**); \ const char **dest = va_arg(args, const char**); \
@ -639,25 +634,30 @@ do { \
break; \ break; \
} \ } \
case 'R': \ case 'R': \
spa_pod_body_get_rectangle(pod, body, \ { \
va_arg(args, struct spa_rectangle*)); \ struct spa_rectangle *val = va_arg(args, struct spa_rectangle*); \
spa_pod_body_get_rectangle(pod, body, val); \
break; \ break; \
} \
case 'F': \ case 'F': \
spa_pod_body_get_fraction(pod, body, \ { \
va_arg(args, struct spa_fraction*)); \ struct spa_fraction *val = va_arg(args, struct spa_fraction*); \
spa_pod_body_get_fraction(pod, body, val); \
break; \ break; \
} \
case 'B': \ case 'B': \
spa_pod_body_get_bitmap(pod, body, va_arg(args, const uint8_t**)); \ { \
const uint8_t **val = va_arg(args, const uint8_t**); \
spa_pod_body_get_bitmap(pod, body, val); \
break; \ break; \
} \
case 'a': \ case 'a': \
{ \ { \
struct spa_pod_array arr; \
uint32_t *val_size = va_arg(args, uint32_t*); \ uint32_t *val_size = va_arg(args, uint32_t*); \
uint32_t *val_type = va_arg(args, uint32_t*); \ uint32_t *val_type = va_arg(args, uint32_t*); \
uint32_t *n_values = va_arg(args, uint32_t*); \ uint32_t *n_values = va_arg(args, uint32_t*); \
const void **arr_body = va_arg(args, const void**); \ const void **arr_body = va_arg(args, const void**); \
spa_pod_body_get_array(pod, body, &arr, arr_body); \ *arr_body = spa_pod_body_get_array_values(pod, body, \
spa_pod_array_body_get_values(&arr, *arr_body, \
n_values, val_size, val_type); \ n_values, val_size, val_type); \
break; \ break; \
} \ } \
@ -669,8 +669,11 @@ do { \
break; \ break; \
} \ } \
case 'h': \ case 'h': \
spa_pod_body_get_fd(pod, body, va_arg(args, int64_t*)); \ { \
int64_t *val = va_arg(args, int64_t*); \
spa_pod_body_get_fd(pod, body, val); \
break; \ break; \
} \
case 'P': \ case 'P': \
case 'T': \ case 'T': \
case 'O': \ case 'O': \
@ -789,7 +792,8 @@ SPA_API_POD_PARSER int spa_pod_parser_getv(struct spa_pod_parser *parser, va_lis
struct spa_pod_choice choice; struct spa_pod_choice choice;
if (pod.type == SPA_TYPE_Choice && *format != 'V') { if (pod.type == SPA_TYPE_Choice && *format != 'V') {
spa_pod_body_get_choice(&pod, body, &choice, &body); if (spa_pod_body_get_choice(&pod, body, &choice, &body) < 0)
return -EINVAL;
pod = choice.body.child; pod = choice.body.child;
} }