pod: add more helpers

Implement more unit-tests
This commit is contained in:
Wim Taymans 2019-01-17 17:23:47 +01:00
parent 767e7efc0e
commit 2622e085a9
12 changed files with 745 additions and 182 deletions

View file

@ -49,8 +49,8 @@ spa_format_audio_raw_parse(const struct spa_pod *format, struct spa_audio_info_r
SPA_FORMAT_AUDIO_channels, SPA_POD_Int(&info->channels),
SPA_FORMAT_AUDIO_flags, SPA_POD_OPT_Int(&info->flags),
SPA_FORMAT_AUDIO_position, SPA_POD_OPT_Pod(&position));
if (position && position->type == SPA_TYPE_Array &&
SPA_POD_ARRAY_TYPE(position) == SPA_TYPE_Id) {
if (position && spa_pod_is_array(position) &&
SPA_POD_ARRAY_VALUE_TYPE(position) == SPA_TYPE_Id) {
uint32_t *values = (uint32_t*)SPA_POD_ARRAY_VALUES(position);
uint32_t n_values = SPA_MIN(SPA_POD_ARRAY_N_VALUES(position), SPA_AUDIO_MAX_CHANNELS);
memcpy(info->position, values, n_values * sizeof(uint32_t));

View file

@ -327,15 +327,15 @@ spa_pod_builder_bytes(struct spa_pod_builder *builder, const void *bytes, uint32
#define SPA_POD_INIT_Pointer(type,value) (struct spa_pod_pointer){ { sizeof(struct spa_pod_pointer_body), SPA_TYPE_Pointer }, { type, 0, value } }
static inline uint32_t
spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, void *val)
spa_pod_builder_pointer(struct spa_pod_builder *builder, uint32_t type, const void *val)
{
const struct spa_pod_pointer p = SPA_POD_INIT_Pointer(type, val);
return spa_pod_builder_primitive(builder, &p.pod);
}
#define SPA_POD_INIT_Fd(fd) (struct spa_pod_fd){ { sizeof(int), SPA_TYPE_Fd }, fd }
#define SPA_POD_INIT_Fd(fd) (struct spa_pod_fd){ { sizeof(int64_t), SPA_TYPE_Fd }, fd }
static inline uint32_t spa_pod_builder_fd(struct spa_pod_builder *builder, int fd)
static inline uint32_t spa_pod_builder_fd(struct spa_pod_builder *builder, int64_t fd)
{
const struct spa_pod_fd p = SPA_POD_INIT_Fd(fd);
return spa_pod_builder_primitive(builder, &p.pod);

View file

@ -137,15 +137,19 @@ static inline int spa_pod_compare(const struct spa_pod *pod1,
case SPA_TYPE_Object:
{
const struct spa_pod_prop *p1, *p2;
const struct spa_pod_object *o1, *o2;
SPA_POD_OBJECT_FOREACH((const struct spa_pod_object*)pod1, p1) {
if ((p2 = spa_pod_find_prop(pod2, p1->key)) == NULL)
o1 = (const struct spa_pod_object*)pod1;
o2 = (const struct spa_pod_object*)pod2;
SPA_POD_OBJECT_FOREACH(o1, p1) {
if ((p2 = spa_pod_object_find_prop(o2, p1->key)) == NULL)
return 1;
if ((res = spa_pod_compare(&p1->value, &p2->value)) != 0)
return res;
}
SPA_POD_OBJECT_FOREACH((const struct spa_pod_object*)pod2, p2) {
if ((p1 = spa_pod_find_prop(pod1, p2->key)) == NULL)
SPA_POD_OBJECT_FOREACH(o2, p2) {
if ((p1 = spa_pod_object_find_prop(o1, p2->key)) == NULL)
return -1;
}
break;

View file

@ -263,15 +263,16 @@ static inline int spa_pod_filter_part(struct spa_pod_builder *b,
switch (SPA_POD_TYPE(pp)) {
case SPA_TYPE_Object:
if (pf != NULL) {
struct spa_pod_object *obj = (struct spa_pod_object *) pp;
struct spa_pod_object *op = (struct spa_pod_object *) pp;
struct spa_pod_object *of = (struct spa_pod_object *) pf;
struct spa_pod_prop *p1, *p2;
if (SPA_POD_TYPE(pf) != SPA_POD_TYPE(pp))
return -EINVAL;
spa_pod_builder_push_object(b, obj->body.type, obj->body.id);
SPA_POD_OBJECT_FOREACH(obj, p1) {
p2 = spa_pod_find_prop(pf, p1->key);
spa_pod_builder_push_object(b, op->body.type, op->body.id);
SPA_POD_OBJECT_FOREACH(op, p1) {
p2 = spa_pod_object_find_prop(of, p1->key);
if (p2 != NULL)
res = spa_pod_filter_prop(b, p1, p2);
else
@ -280,9 +281,8 @@ static inline int spa_pod_filter_part(struct spa_pod_builder *b,
break;
}
if (res >= 0) {
obj = (struct spa_pod_object *) pf;
SPA_POD_OBJECT_FOREACH(obj, p2) {
p1 = spa_pod_find_prop(pp, p2->key);
SPA_POD_OBJECT_FOREACH(of, p2) {
p1 = spa_pod_object_find_prop(op, p2->key);
if (p1 != NULL)
continue;

View file

@ -112,11 +112,17 @@ static inline struct spa_pod_control *spa_pod_control_next(const struct spa_pod_
(iter) < (__typeof__(iter))SPA_MEMBER((body), (_size), void); \
(iter) = (__typeof__(iter))SPA_MEMBER((iter), (body)->child.size, void))
#define SPA_POD_ARRAY_FOREACH(obj, iter) \
SPA_POD_ARRAY_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter)
#define SPA_POD_CHOICE_BODY_FOREACH(body, _size, iter) \
for ((iter) = (__typeof__(iter))SPA_MEMBER((body), sizeof(struct spa_pod_choice_body), void); \
(iter) < (__typeof__(iter))SPA_MEMBER((body), (_size), void); \
(iter) = (__typeof__(iter))SPA_MEMBER((iter), (body)->child.size, void))
#define SPA_POD_CHOICE_FOREACH(obj, iter) \
SPA_POD_CHOICE_BODY_FOREACH(&(obj)->body, SPA_POD_BODY_SIZE(obj), iter)
#define SPA_POD_FOREACH(pod, size, iter) \
for ((iter) = (pod); \
spa_pod_is_inside(pod, size, iter); \
@ -141,34 +147,274 @@ static inline struct spa_pod_control *spa_pod_control_next(const struct spa_pod_
#define SPA_POD_SEQUENCE_FOREACH(seq, iter) \
SPA_POD_SEQUENCE_BODY_FOREACH(&(seq)->body, SPA_POD_BODY_SIZE(seq), iter)
static inline struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod *pod, uint32_t key)
static inline int spa_pod_is_none(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_None);
}
static inline int spa_pod_is_bool(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Bool && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t));
}
static inline int spa_pod_get_bool(const struct spa_pod *pod, bool *value)
{
if (!spa_pod_is_bool(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_bool, pod);
return 0;
}
static inline int spa_pod_is_id(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Id && SPA_POD_BODY_SIZE(pod) >= sizeof(uint32_t));
}
static inline int spa_pod_get_id(const struct spa_pod *pod, uint32_t *value)
{
if (!spa_pod_is_id(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_id, pod);
return 0;
}
static inline int spa_pod_is_int(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Int && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t));
}
static inline int spa_pod_get_int(const struct spa_pod *pod, int32_t *value)
{
if (!spa_pod_is_int(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_int, pod);
return 0;
}
static inline int spa_pod_is_long(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Long && SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t));
}
static inline int spa_pod_get_long(const struct spa_pod *pod, int64_t *value)
{
if (!spa_pod_is_long(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_long, pod);
return 0;
}
static inline int spa_pod_is_float(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Float && SPA_POD_BODY_SIZE(pod) >= sizeof(float));
}
static inline int spa_pod_get_float(const struct spa_pod *pod, float *value)
{
if (!spa_pod_is_float(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_float, pod);
return 0;
}
static inline int spa_pod_is_double(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Double && SPA_POD_BODY_SIZE(pod) >= sizeof(double));
}
static inline int spa_pod_get_double(const struct spa_pod *pod, double *value)
{
if (!spa_pod_is_double(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_double, pod);
return 0;
}
static inline int spa_pod_is_string(const struct spa_pod *pod)
{
const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod);
return (SPA_POD_TYPE(pod) == SPA_TYPE_String &&
SPA_POD_BODY_SIZE(pod) > 0 &&
s[SPA_POD_BODY_SIZE(pod)-1] == '\0');
}
static inline int spa_pod_get_string(const struct spa_pod *pod, const char **value)
{
if (!spa_pod_is_string(pod))
return -EINVAL;
*value = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod);
return 0;
}
static inline int spa_pod_copy_string(const struct spa_pod *pod, size_t maxlen, char *dest)
{
const char *s = (const char *)SPA_POD_CONTENTS(struct spa_pod_string, pod);
if (!spa_pod_is_string(pod) || maxlen < 1)
return -EINVAL;
strncpy(dest, s, maxlen-1);
dest[maxlen-1]= '\0';
return 0;
}
static inline int spa_pod_is_bytes(const struct spa_pod *pod)
{
return SPA_POD_TYPE(pod) == SPA_TYPE_Bytes;
}
static inline int spa_pod_get_bytes(const struct spa_pod *pod, const void **value, uint32_t *len)
{
if (!spa_pod_is_bytes(pod))
return -EINVAL;
*value = (const void *)SPA_POD_CONTENTS(struct spa_pod_bytes, pod);
*len = SPA_POD_BODY_SIZE(pod);
return 0;
}
static inline int spa_pod_is_pointer(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Pointer &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_pointer_body));
}
static inline int spa_pod_get_pointer(const struct spa_pod *pod, uint32_t *type, const void **value)
{
if (!spa_pod_is_pointer(pod))
return -EINVAL;
*type = ((struct spa_pod_pointer*)pod)->body.type;
*value = ((struct spa_pod_pointer*)pod)->body.value;
return 0;
}
static inline int spa_pod_is_fd(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Fd &&
SPA_POD_BODY_SIZE(pod) >= sizeof(int64_t));
}
static inline int spa_pod_get_fd(const struct spa_pod *pod, int64_t *value)
{
if (!spa_pod_is_fd(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_fd, pod);
return 0;
}
static inline int spa_pod_is_rectangle(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Rectangle &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_rectangle));
}
static inline int spa_pod_get_rectangle(const struct spa_pod *pod, struct spa_rectangle *value)
{
if (!spa_pod_is_rectangle(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_rectangle, pod);
return 0;
}
static inline int spa_pod_is_fraction(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Fraction &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_fraction));
}
static inline int spa_pod_get_fraction(const struct spa_pod *pod, struct spa_fraction *value)
{
spa_return_val_if_fail(spa_pod_is_fraction(pod), -EINVAL);
*value = SPA_POD_VALUE(struct spa_pod_fraction, pod);
return 0;
}
static inline int spa_pod_is_array(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Array &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_array_body));
}
static inline int spa_pod_is_choice(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Choice &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_choice_body));
}
static inline struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
{
if (pod->type == SPA_TYPE_Choice) {
*choice = SPA_POD_CHOICE_TYPE(pod);
*n_vals = *choice == SPA_CHOICE_None ? 1 : SPA_POD_CHOICE_N_VALUES(pod);
return (struct spa_pod*)SPA_POD_CHOICE_CHILD(pod);
} else {
*n_vals = 1;
*choice = SPA_CHOICE_None;
return (struct spa_pod*)pod;
}
}
static inline int spa_pod_is_struct(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Struct);
}
static inline int spa_pod_is_object(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Object &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_object_body));
}
static inline bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type)
{
return (pod && spa_pod_is_object(pod) &&
((const struct spa_pod_object *) pod)->body.type == type);
}
static inline bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id)
{
return (pod && spa_pod_is_object(pod) &&
((const struct spa_pod_object *) pod)->body.id == id);
}
static inline int spa_pod_is_sequence(const struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Sequence &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_pod_sequence_body));
}
static inline struct spa_pod_prop *spa_pod_object_find_prop(const struct spa_pod_object *pod, uint32_t key)
{
struct spa_pod_prop *res;
if (pod->type != SPA_TYPE_Object)
return NULL;
SPA_POD_OBJECT_FOREACH((struct spa_pod_object*)pod, res) {
SPA_POD_OBJECT_FOREACH(pod, res) {
if (res->key == key)
return res;
}
return NULL;
}
static inline int spa_pod_fixate(struct spa_pod *pod)
static inline struct spa_pod_prop *spa_pod_find_prop(const struct spa_pod *pod, uint32_t key)
{
if (!spa_pod_is_object(pod))
return NULL;
return spa_pod_object_find_prop((const struct spa_pod_object *)pod, key);
}
static inline int spa_pod_object_fixate(struct spa_pod_object *pod)
{
struct spa_pod_prop *res;
if (pod->type != SPA_TYPE_Object)
return -EINVAL;
SPA_POD_OBJECT_FOREACH((struct spa_pod_object*)pod, res) {
SPA_POD_OBJECT_FOREACH(pod, res) {
if (res->value.type == SPA_TYPE_Choice)
((struct spa_pod_choice*)&res->value)->body.type = SPA_CHOICE_None;
}
return 0;
}
static inline int spa_pod_fixate(struct spa_pod *pod)
{
if (!spa_pod_is_object(pod))
return -EINVAL;
return spa_pod_object_fixate((struct spa_pod_object *)pod);
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -262,14 +262,14 @@ static inline int spa_pod_parser_getv(struct spa_pod_parser *parser, va_list arg
goto read_pod;
case '\0':
if (parser->flags & SPA_POD_PARSER_FLAG_OBJECT) {
const struct spa_pod *obj = (const struct spa_pod *) it->data;
uint32_t key = va_arg(args, uint32_t);
if (key == 0) {
format = NULL;
continue;
}
if (key != SPA_ID_INVALID) {
prop = spa_pod_find_prop(obj, key);
prop = spa_pod_object_find_prop(
(const struct spa_pod_object *) it->data, key);
if (prop != NULL)
pod = &prop->value;
else
@ -358,113 +358,6 @@ static inline int spa_pod_parser_get(struct spa_pod_parser *parser, ...)
spa_pod_parser_get_struct(&_p,##__VA_ARGS__); \
})
static inline int spa_pod_is_bool(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Bool && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t));
}
static inline int spa_pod_get_bool(struct spa_pod *pod, bool *value)
{
if (!spa_pod_is_bool(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_bool, pod);
return 0;
}
static inline int spa_pod_is_float(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Float && SPA_POD_BODY_SIZE(pod) >= sizeof(float));
}
static inline int spa_pod_get_float(struct spa_pod *pod, float *value)
{
if (!spa_pod_is_float(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_float, pod);
return 0;
}
static inline int spa_pod_is_double(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Double && SPA_POD_BODY_SIZE(pod) >= sizeof(double));
}
static inline int spa_pod_get_double(struct spa_pod *pod, double *value)
{
if (!spa_pod_is_double(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_double, pod);
return 0;
}
static inline int spa_pod_is_id(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Id && SPA_POD_BODY_SIZE(pod) >= sizeof(uint32_t));
}
static inline int spa_pod_get_id(struct spa_pod *pod, uint32_t *value)
{
if (!spa_pod_is_id(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_id, pod);
return 0;
}
static inline int spa_pod_is_int(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Int && SPA_POD_BODY_SIZE(pod) >= sizeof(int32_t));
}
static inline int spa_pod_get_int(struct spa_pod *pod, int32_t *value)
{
if (!spa_pod_is_int(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_int, pod);
return 0;
}
static inline int spa_pod_is_string(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_String && SPA_POD_BODY_SIZE(pod) >= sizeof(1));
}
static inline int spa_pod_dup_string(struct spa_pod *pod, size_t maxlen, char *dest)
{
if (!spa_pod_is_string(pod) || maxlen < 1)
return -EINVAL;
strncpy(dest, (char *)SPA_POD_CONTENTS(struct spa_pod_string, pod), maxlen-1);
dest[maxlen-1]= '\0';
return 0;
}
static inline int spa_pod_is_rectangle(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Rectangle &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_rectangle));
}
static inline int spa_pod_get_rectangle(struct spa_pod *pod, struct spa_rectangle *value)
{
if (!spa_pod_is_rectangle(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_rectangle, pod);
return 0;
}
static inline int spa_pod_is_fraction(struct spa_pod *pod)
{
return (SPA_POD_TYPE(pod) == SPA_TYPE_Fraction &&
SPA_POD_BODY_SIZE(pod) >= sizeof(struct spa_fraction));
}
static inline int spa_pod_get_fraction(struct spa_pod *pod, struct spa_fraction *value)
{
if (!spa_pod_is_fraction(pod))
return -EINVAL;
*value = SPA_POD_VALUE(struct spa_pod_fraction, pod);
return 0;
}
#ifdef __cplusplus
} /* extern "C" */
#endif

View file

@ -115,9 +115,9 @@ struct spa_pod_bitmap {
};
#define SPA_POD_ARRAY_CHILD(arr) (&((struct spa_pod_array*)(arr))->body.child)
#define SPA_POD_ARRAY_TYPE(arr) (SPA_POD_TYPE(SPA_POD_ARRAY_CHILD(arr)))
#define SPA_POD_ARRAY_SIZE(arr) (SPA_POD_BODY_SIZE(SPA_POD_ARRAY_CHILD(arr)))
#define SPA_POD_ARRAY_N_VALUES(arr) ((SPA_POD_BODY_SIZE(arr) - sizeof(struct spa_pod_array_body)) / SPA_POD_ARRAY_SIZE(arr))
#define SPA_POD_ARRAY_VALUE_TYPE(arr) (SPA_POD_TYPE(SPA_POD_ARRAY_CHILD(arr)))
#define SPA_POD_ARRAY_VALUE_SIZE(arr) (SPA_POD_BODY_SIZE(SPA_POD_ARRAY_CHILD(arr)))
#define SPA_POD_ARRAY_N_VALUES(arr) ((SPA_POD_BODY_SIZE(arr) - sizeof(struct spa_pod_array_body)) / SPA_POD_ARRAY_VALUE_SIZE(arr))
#define SPA_POD_ARRAY_VALUES(arr) SPA_POD_CONTENTS(struct spa_pod_array, arr)
struct spa_pod_array_body {
@ -132,6 +132,7 @@ struct spa_pod_array {
#define SPA_POD_CHOICE_CHILD(choice) (&((struct spa_pod_choice*)(choice))->body.child)
#define SPA_POD_CHOICE_TYPE(choice) (((struct spa_pod_choice*)(choice))->body.type)
#define SPA_POD_CHOICE_FLAGS(choice) (((struct spa_pod_choice*)(choice))->body.flags)
#define SPA_POD_CHOICE_VALUE_TYPE(choice) (SPA_POD_TYPE(SPA_POD_CHOICE_CHILD(choice)))
#define SPA_POD_CHOICE_VALUE_SIZE(choice) (SPA_POD_BODY_SIZE(SPA_POD_CHOICE_CHILD(choice)))
#define SPA_POD_CHOICE_N_VALUES(choice) ((SPA_POD_BODY_SIZE(choice) - sizeof(struct spa_pod_choice_body)) / SPA_POD_CHOICE_VALUE_SIZE(choice))
@ -179,18 +180,6 @@ struct spa_pod_object {
struct spa_pod_object_body body;
};
static inline bool spa_pod_is_object_type(const struct spa_pod *pod, uint32_t type)
{
return (pod && pod->type == SPA_TYPE_Object
&& ((struct spa_pod_object *) pod)->body.type == type);
}
static inline bool spa_pod_is_object_id(const struct spa_pod *pod, uint32_t id)
{
return (pod && pod->type == SPA_TYPE_Object
&& ((struct spa_pod_object *) pod)->body.id == id);
}
struct spa_pod_pointer_body {
uint32_t type; /**< pointer id, one of enum spa_type */
uint32_t _padding;
@ -207,19 +196,6 @@ struct spa_pod_fd {
int64_t value;
};
static inline struct spa_pod *spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
{
if (pod->type == SPA_TYPE_Choice) {
*choice = SPA_POD_CHOICE_TYPE(pod);
*n_vals = *choice == SPA_CHOICE_None ? 1 : SPA_POD_CHOICE_N_VALUES(pod);
return (struct spa_pod*)SPA_POD_CHOICE_CHILD(pod);
} else {
*n_vals = 1;
*choice = SPA_CHOICE_None;
return (struct spa_pod*)pod;
}
}
#define SPA_POD_PROP_SIZE(prop) (sizeof(struct spa_pod_prop) + (prop)->value.size)
/* props can be inside an object */

View file

@ -90,17 +90,25 @@ static void test_init(void)
{
{
struct spa_pod pod = SPA_POD_INIT(sizeof(int64_t), SPA_TYPE_Long);
int32_t val;
spa_assert(SPA_POD_SIZE(&pod) == sizeof(int64_t) + 8);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Long);
spa_assert(SPA_POD_BODY_SIZE(&pod) == sizeof(int64_t));
spa_assert(SPA_POD_CONTENTS_SIZE(struct spa_pod, &pod) == sizeof(int64_t));
spa_assert(spa_pod_is_long(&pod));
pod = SPA_POD_INIT(sizeof(int32_t), SPA_TYPE_Int);
spa_assert(SPA_POD_SIZE(&pod) == sizeof(int32_t) + 8);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Int);
spa_assert(SPA_POD_BODY_SIZE(&pod) == sizeof(int32_t));
spa_assert(SPA_POD_CONTENTS_SIZE(struct spa_pod, &pod) == sizeof(int32_t));
spa_assert(spa_pod_is_int(&pod));
/** too small */
pod = SPA_POD_INIT(0, SPA_TYPE_Int);
spa_assert(!spa_pod_is_int(&pod));
spa_assert(spa_pod_get_int(&pod, &val) < 0);
}
{
struct spa_pod pod = SPA_POD_INIT_None();
@ -109,90 +117,523 @@ static void test_init(void)
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_None);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 0);
spa_assert(SPA_POD_CONTENTS_SIZE(struct spa_pod, &pod) == 0);
spa_assert(spa_pod_is_none(&pod));
}
{
struct spa_pod_bool pod = SPA_POD_INIT_Bool(true);
bool val;
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Bool);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_bool, &pod) == true);
spa_assert(spa_pod_is_bool(&pod.pod));
spa_assert(spa_pod_get_bool(&pod.pod, &val) == 0);
spa_assert(val == true);
pod = SPA_POD_INIT_Bool(false);
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Bool);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_bool, &pod) == false);
spa_assert(spa_pod_is_bool(&pod.pod));
spa_assert(spa_pod_get_bool(&pod.pod, &val) == 0);
spa_assert(val == false);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Bool);
spa_assert(!spa_pod_is_bool(&pod.pod));
spa_assert(spa_pod_get_bool(&pod.pod, &val) < 0);
}
{
struct spa_pod_id pod = SPA_POD_INIT_Id(SPA_TYPE_Int);
uint32_t val;
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Id);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_id, &pod) == SPA_TYPE_Int);
spa_assert(spa_pod_is_id(&pod.pod));
spa_assert(spa_pod_get_id(&pod.pod, &val) == 0);
spa_assert(val == SPA_TYPE_Int);
pod = SPA_POD_INIT_Id(SPA_TYPE_Long);
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Id);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_id, &pod) == SPA_TYPE_Long);
spa_assert(spa_pod_is_id(&pod.pod));
spa_assert(spa_pod_get_id(&pod.pod, &val) == 0);
spa_assert(val == SPA_TYPE_Long);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Id);
spa_assert(!spa_pod_is_id(&pod.pod));
spa_assert(spa_pod_get_id(&pod.pod, &val) < 0);
}
{
struct spa_pod_int pod = SPA_POD_INIT_Int(23);
int32_t val;
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Int);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_int, &pod) == 23);
spa_assert(spa_pod_is_int(&pod.pod));
spa_assert(spa_pod_get_int(&pod.pod, &val) == 0);
spa_assert(val == 23);
pod = SPA_POD_INIT_Int(-123);
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Int);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_int, &pod) == -123);
spa_assert(spa_pod_is_int(&pod.pod));
spa_assert(spa_pod_get_int(&pod.pod, &val) == 0);
spa_assert(val == -123);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Int);
spa_assert(!spa_pod_is_int(&pod.pod));
spa_assert(spa_pod_get_int(&pod.pod, &val) < 0);
}
{
struct spa_pod_long pod = SPA_POD_INIT_Long(-23);
int64_t val;
spa_assert(SPA_POD_SIZE(&pod) == 16);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Long);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 8);
spa_assert(SPA_POD_VALUE(struct spa_pod_long, &pod) == -23);
spa_assert(spa_pod_is_long(&pod.pod));
spa_assert(spa_pod_get_long(&pod.pod, &val) == 0);
spa_assert(val == -23);
pod = SPA_POD_INIT_Long(123);
spa_assert(SPA_POD_SIZE(&pod) == 16);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Long);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 8);
spa_assert(SPA_POD_VALUE(struct spa_pod_long, &pod) == 123);
spa_assert(spa_pod_is_long(&pod.pod));
spa_assert(spa_pod_get_long(&pod.pod, &val) == 0);
spa_assert(val == 123);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Long);
spa_assert(!spa_pod_is_long(&pod.pod));
spa_assert(spa_pod_get_long(&pod.pod, &val) < 0);
}
{
struct spa_pod_float pod = SPA_POD_INIT_Float(0.67f);
float val;
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Float);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_float, &pod) == 0.67f);
spa_assert(spa_pod_is_float(&pod.pod));
spa_assert(spa_pod_get_float(&pod.pod, &val) == 0);
spa_assert(val == 0.67f);
pod = SPA_POD_INIT_Float(134.8f);
pod = SPA_POD_INIT_Float(-134.8f);
spa_assert(SPA_POD_SIZE(&pod) == 12);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Float);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 4);
spa_assert(SPA_POD_VALUE(struct spa_pod_float, &pod) == 134.8f);
spa_assert(SPA_POD_VALUE(struct spa_pod_float, &pod) == -134.8f);
spa_assert(spa_pod_is_float(&pod.pod));
spa_assert(spa_pod_get_float(&pod.pod, &val) == 0);
spa_assert(val == -134.8f);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Float);
spa_assert(!spa_pod_is_float(&pod.pod));
spa_assert(spa_pod_get_float(&pod.pod, &val) < 0);
}
{
struct spa_pod_double pod = SPA_POD_INIT_Double(0.67);
double val;
spa_assert(SPA_POD_SIZE(&pod) == 16);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Double);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 8);
spa_assert(SPA_POD_VALUE(struct spa_pod_double, &pod) == 0.67);
spa_assert(spa_pod_is_double(&pod.pod));
spa_assert(spa_pod_get_double(&pod.pod, &val) == 0);
spa_assert(val == 0.67);
pod = SPA_POD_INIT_Double(134.8);
pod = SPA_POD_INIT_Double(-134.8);
spa_assert(SPA_POD_SIZE(&pod) == 16);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Double);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 8);
spa_assert(SPA_POD_VALUE(struct spa_pod_double, &pod) == 134.8);
spa_assert(SPA_POD_VALUE(struct spa_pod_double, &pod) == -134.8);
spa_assert(spa_pod_is_double(&pod.pod));
spa_assert(spa_pod_get_double(&pod.pod, &val) == 0);
spa_assert(val == -134.8);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Double);
spa_assert(!spa_pod_is_double(&pod.pod));
spa_assert(spa_pod_get_double(&pod.pod, &val) < 0);
}
{
struct {
struct spa_pod_string pod;
char str[9];
} pod;
char val[12];
pod.pod = SPA_POD_INIT_String(9);
strncpy(pod.str, "test", 9);
spa_assert(SPA_POD_SIZE(&pod) == 17);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_String);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 9);
spa_assert(spa_pod_is_string(&pod.pod.pod));
spa_assert(spa_pod_copy_string(&pod.pod.pod, sizeof(val), val) == 0);
spa_assert(strcmp(pod.str, val) == 0);
pod.pod = SPA_POD_INIT_String(6);
memcpy(pod.str, "test123456789", 9);
spa_assert(SPA_POD_SIZE(&pod) == 14);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_String);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 6);
spa_assert(!spa_pod_is_string(&pod.pod.pod));
spa_assert(spa_pod_copy_string(&pod.pod.pod, sizeof(val), val) < 0);
}
{
struct spa_pod_rectangle pod = SPA_POD_INIT_Rectangle(SPA_RECTANGLE(320,240));
struct spa_rectangle val;
spa_assert(SPA_POD_SIZE(&pod) == 16);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Rectangle);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 8);
spa_assert(memcmp(&SPA_POD_VALUE(struct spa_pod_rectangle, &pod),
&SPA_RECTANGLE(320,240), sizeof(struct spa_rectangle)) == 0);
spa_assert(spa_pod_is_rectangle(&pod.pod));
spa_assert(spa_pod_get_rectangle(&pod.pod, &val) == 0);
spa_assert(memcmp(&val, &SPA_RECTANGLE(320,240), sizeof(struct spa_rectangle)) == 0);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Rectangle);
spa_assert(!spa_pod_is_rectangle(&pod.pod));
spa_assert(spa_pod_get_rectangle(&pod.pod, &val) < 0);
}
{
struct spa_pod_fraction pod = SPA_POD_INIT_Fraction(SPA_FRACTION(25,1));
struct spa_fraction val;
spa_assert(SPA_POD_SIZE(&pod) == 16);
spa_assert(SPA_POD_TYPE(&pod) == SPA_TYPE_Fraction);
spa_assert(SPA_POD_BODY_SIZE(&pod) == 8);
spa_assert(memcmp(&SPA_POD_VALUE(struct spa_pod_fraction, &pod),
&SPA_FRACTION(25,1), sizeof(struct spa_fraction)) == 0);
spa_assert(spa_pod_is_fraction(&pod.pod));
spa_assert(spa_pod_get_fraction(&pod.pod, &val) == 0);
spa_assert(memcmp(&val, &SPA_FRACTION(25,1), sizeof(struct spa_fraction)) == 0);
pod.pod = SPA_POD_INIT(0, SPA_TYPE_Fraction);
spa_assert(!spa_pod_is_fraction(&pod.pod));
spa_assert(spa_pod_get_fraction(&pod.pod, &val) < 0);
}
}
static void test_build(void)
{
uint8_t buffer[4096];
struct spa_pod_builder b;
struct spa_pod *array, *choice, *head, *pod, *it;
struct spa_pod_prop *prop;
struct spa_pod_control *control;
int64_t longs[] = { 5, 7, 11, 13, 17 }, *al;
uint32_t i, len, zl, *ai;
union {
bool b;
uint32_t I;
int32_t i;
int64_t l;
float f;
double d;
const char *s;
const void *z;
const void *p;
int64_t h;
struct spa_rectangle R;
struct spa_fraction F;
} val;
spa_pod_builder_init(&b, buffer, sizeof(buffer));
spa_assert(b.data == buffer);
spa_assert(b.size == sizeof(buffer));
spa_assert(b.state.offset == 0);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 0);
spa_assert(spa_pod_builder_none(&b) == 0);
spa_assert(spa_pod_builder_bool(&b, true) == 8);
spa_assert(spa_pod_builder_id(&b, SPA_TYPE_Object) == 24);
spa_assert(spa_pod_builder_int(&b, 21) == 40);
spa_assert(spa_pod_builder_float(&b, 0.8f) == 56);
spa_assert(spa_pod_builder_double(&b, -1.56) == 72);
spa_assert(spa_pod_builder_string(&b, "test") == 88);
spa_assert(spa_pod_builder_bytes(&b, "PipeWire", 8) == 104);
spa_assert(spa_pod_builder_pointer(&b, SPA_TYPE_Object, &b) == 120);
spa_assert(spa_pod_builder_fd(&b, 4) == 144);
spa_assert(spa_pod_builder_rectangle(&b, 320, 240) == 160);
spa_assert(spa_pod_builder_fraction(&b, 25, 1) == 176);
spa_assert(spa_pod_builder_push_array(&b) == 192);
spa_assert(b.state.flags == (SPA_POD_BUILDER_FLAG_BODY | SPA_POD_BUILDER_FLAG_FIRST));
spa_assert(b.state.depth == 1);
spa_assert(spa_pod_builder_int(&b, 1) == 200);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_BODY);
spa_assert(spa_pod_builder_int(&b, 2) == 212);
spa_assert(spa_pod_builder_int(&b, 3) == 216);
array = spa_pod_builder_pop(&b);
spa_assert(array != NULL);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 0);
spa_assert(spa_pod_builder_array(&b,
sizeof(int64_t), SPA_TYPE_Long,
SPA_N_ELEMENTS(longs), longs) == 224);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 0);
spa_assert(spa_pod_builder_push_choice(&b, SPA_CHOICE_Enum, 0) == 280);
spa_assert(b.state.flags == (SPA_POD_BUILDER_FLAG_BODY | SPA_POD_BUILDER_FLAG_FIRST));
spa_assert(b.state.depth == 1);
spa_assert(spa_pod_builder_long(&b, 1) == 296);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_BODY);
spa_assert(spa_pod_builder_long(&b, 2) == 312);
spa_assert(spa_pod_builder_long(&b, 3) == 320);
choice = spa_pod_builder_pop(&b);
spa_assert(choice != NULL);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 0);
spa_assert(spa_pod_builder_push_struct(&b) == 328);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 1);
spa_assert(spa_pod_builder_int(&b, 21) == 336);
spa_assert(spa_pod_builder_float(&b, 0.8f) == 352);
spa_assert(spa_pod_builder_double(&b, -1.56) == 368);
spa_assert(spa_pod_builder_pop(&b) != NULL);
spa_assert(b.state.depth == 0);
spa_assert(spa_pod_builder_push_object(&b, SPA_TYPE_OBJECT_Props, 0) == 384);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_OBJECT);
spa_assert(b.state.depth == 1);
spa_assert(spa_pod_builder_prop(&b, 1, 0) == 400);
spa_assert(b.state.flags == (SPA_POD_BUILDER_FLAG_OBJECT | SPA_POD_BUILDER_FLAG_HEADER));
spa_assert(spa_pod_builder_int(&b, 21) == 408);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_OBJECT);
spa_assert(spa_pod_builder_prop(&b, 2, 0) == 424);
spa_assert(b.state.flags == (SPA_POD_BUILDER_FLAG_OBJECT | SPA_POD_BUILDER_FLAG_HEADER));
spa_assert(spa_pod_builder_long(&b, 42) == 432);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_OBJECT);
spa_assert(spa_pod_builder_prop(&b, 3, 0) == 448);
spa_assert(spa_pod_builder_string(&b, "test123") == 456);
spa_assert(spa_pod_builder_pop(&b) != NULL);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 0);
spa_assert(spa_pod_builder_push_sequence(&b, 0) == 472);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_SEQUENCE);
spa_assert(b.state.depth == 1);
spa_assert(spa_pod_builder_control(&b, 0, 0) == 488);
spa_assert(b.state.flags == (SPA_POD_BUILDER_FLAG_SEQUENCE | SPA_POD_BUILDER_FLAG_HEADER));
spa_assert(spa_pod_builder_float(&b, 0.667f) == 496);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_SEQUENCE);
spa_assert(spa_pod_builder_control(&b, 12, 0) == 512);
spa_assert(b.state.flags == (SPA_POD_BUILDER_FLAG_SEQUENCE | SPA_POD_BUILDER_FLAG_HEADER));
spa_assert(spa_pod_builder_double(&b, 1.22) == 520);
spa_assert(b.state.flags == SPA_POD_BUILDER_FLAG_SEQUENCE);
spa_assert(spa_pod_builder_pop(&b) != NULL);
spa_assert(b.state.flags == 0);
spa_assert(b.state.depth == 0);
spa_assert(b.state.offset == 536);
len = b.state.offset;
pod = head = (struct spa_pod *)buffer;
spa_assert(spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_none(pod));
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_bool(pod));
spa_assert(spa_pod_get_bool(pod, &val.b) == 0);
spa_assert(val.b == true);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_id(pod));
spa_assert(spa_pod_get_id(pod, &val.I) == 0);
spa_assert(val.I == SPA_TYPE_Object);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_int(pod));
spa_assert(spa_pod_get_int(pod, &val.i) == 0);
spa_assert(val.i == 21);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_float(pod));
spa_assert(spa_pod_get_float(pod, &val.f) == 0);
spa_assert(val.f == 0.8f);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_double(pod));
spa_assert(spa_pod_get_double(pod, &val.d) == 0);
spa_assert(val.d == -1.56);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_string(pod));
spa_assert(spa_pod_get_string(pod, &val.s) == 0);
spa_assert(strcmp(val.s, "test") == 0);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_bytes(pod));
spa_assert(spa_pod_get_bytes(pod, &val.z, &zl) == 0);
spa_assert(zl == 8);
spa_assert(memcmp(val.z, "PipeWire", zl) == 0);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_pointer(pod));
spa_assert(spa_pod_get_pointer(pod, &zl, &val.p) == 0);
spa_assert(zl == SPA_TYPE_Object);
spa_assert(val.p == &b);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_fd(pod));
spa_assert(spa_pod_get_fd(pod, &val.l) == 0);
spa_assert(val.l == 4);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_rectangle(pod));
spa_assert(spa_pod_get_rectangle(pod, &val.R) == 0);
spa_assert(memcmp(&val.R, &SPA_RECTANGLE(320,240), sizeof(struct spa_rectangle)) == 0);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_fraction(pod));
spa_assert(spa_pod_get_fraction(pod, &val.F) == 0);
spa_assert(memcmp(&val.F, &SPA_FRACTION(25,1), sizeof(struct spa_fraction)) == 0);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_array(pod));
spa_assert(SPA_POD_ARRAY_VALUE_TYPE(pod) == SPA_TYPE_Int);
spa_assert(SPA_POD_ARRAY_VALUE_SIZE(pod) == sizeof(int32_t));
spa_assert(SPA_POD_ARRAY_N_VALUES(pod) == 3);
spa_assert((ai = SPA_POD_ARRAY_VALUES(pod)) != NULL);
spa_assert(SPA_POD_ARRAY_CHILD(pod)->type == SPA_TYPE_Int);
spa_assert(SPA_POD_ARRAY_CHILD(pod)->size == sizeof(int32_t));
spa_assert(ai[0] == 1);
spa_assert(ai[1] == 2);
spa_assert(ai[2] == 3);
i = 1;
SPA_POD_ARRAY_FOREACH((struct spa_pod_array*)pod, ai) {
spa_assert(*ai == i);
i++;
}
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_array(pod));
spa_assert(SPA_POD_ARRAY_VALUE_TYPE(pod) == SPA_TYPE_Long);
spa_assert(SPA_POD_ARRAY_VALUE_SIZE(pod) == sizeof(int64_t));
spa_assert(SPA_POD_ARRAY_N_VALUES(pod) == SPA_N_ELEMENTS(longs));
spa_assert((al = SPA_POD_ARRAY_VALUES(pod)) != NULL);
spa_assert(SPA_POD_ARRAY_CHILD(pod)->type == SPA_TYPE_Long);
spa_assert(SPA_POD_ARRAY_CHILD(pod)->size == sizeof(int64_t));
for (i = 0; i < SPA_N_ELEMENTS(longs); i++)
spa_assert(al[i] == longs[i]);
i = 0;
SPA_POD_ARRAY_FOREACH((struct spa_pod_array*)pod, al) {
spa_assert(*al == longs[i++]);
}
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_choice(pod));
spa_assert(SPA_POD_CHOICE_TYPE(pod) == SPA_CHOICE_Enum);
spa_assert(SPA_POD_CHOICE_FLAGS(pod) == 0);
spa_assert(SPA_POD_CHOICE_VALUE_TYPE(pod) == SPA_TYPE_Long);
spa_assert(SPA_POD_CHOICE_VALUE_SIZE(pod) == sizeof(int64_t));
spa_assert(SPA_POD_CHOICE_N_VALUES(pod) == 3);
spa_assert((al = SPA_POD_CHOICE_VALUES(pod)) != NULL);
spa_assert(SPA_POD_CHOICE_CHILD(pod)->type == SPA_TYPE_Long);
spa_assert(SPA_POD_CHOICE_CHILD(pod)->size == sizeof(int64_t));
spa_assert(al[0] == 1);
spa_assert(al[1] == 2);
spa_assert(al[2] == 3);
i = 1;
SPA_POD_CHOICE_FOREACH((struct spa_pod_choice*)pod, al) {
spa_assert(*al == i);
i++;
}
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_struct(pod));
i = 0;
SPA_POD_STRUCT_FOREACH(pod, it) {
switch (i++) {
case 0:
spa_assert(spa_pod_is_int(it));
spa_assert(spa_pod_get_int(it, &val.i) == 0 && val.i == 21);
break;
case 1:
spa_assert(spa_pod_is_float(it));
spa_assert(spa_pod_get_float(it, &val.f) == 0 && val.f == 0.8f);
break;
case 2:
spa_assert(spa_pod_is_double(it));
spa_assert(spa_pod_get_double(it, &val.d) == 0 && val.d == -1.56);
break;
default:
spa_assert_not_reached();
break;
}
}
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_object(pod));
spa_assert(spa_pod_is_object_type(pod, SPA_TYPE_OBJECT_Props));
spa_assert(spa_pod_is_object_id(pod, 0));
i = 0;
SPA_POD_OBJECT_FOREACH((const struct spa_pod_object*)pod, prop) {
switch (i++) {
case 0:
spa_assert(prop->key == 1);
spa_assert(SPA_POD_PROP_SIZE(prop) == 20);
spa_assert(spa_pod_get_int(&prop->value, &val.i) == 0 && val.i == 21);
break;
case 1:
spa_assert(prop->key == 2);
spa_assert(SPA_POD_PROP_SIZE(prop) == 24);
spa_assert(spa_pod_get_long(&prop->value, &val.l) == 0 && val.l == 42);
break;
case 2:
spa_assert(prop->key == 3);
spa_assert(SPA_POD_PROP_SIZE(prop) == 24);
spa_assert(spa_pod_get_string(&prop->value, &val.s) == 0 &&
strcmp(val.s, "test123") == 0);
break;
default:
spa_assert_not_reached();
break;
}
}
spa_assert((prop = spa_pod_find_prop(pod, 3)) != NULL);
spa_assert(prop->key == 3);
spa_assert(spa_pod_get_string(&prop->value, &val.s) == 0 &&
strcmp(val.s, "test123") == 0);
spa_assert((prop = spa_pod_find_prop(pod, 1)) != NULL);
spa_assert(prop->key == 1);
spa_assert(spa_pod_get_int(&prop->value, &val.i) == 0 && val.i == 21);
spa_assert((prop = spa_pod_find_prop(pod, 2)) != NULL);
spa_assert(prop->key == 2);
spa_assert(spa_pod_get_long(&prop->value, &val.l) == 0 && val.l == 42);
spa_assert((prop = spa_pod_find_prop(pod, 5)) == NULL);
spa_assert((pod = spa_pod_next(pod)) != NULL && spa_pod_is_inside(head, len, pod));
spa_assert(spa_pod_is_sequence(pod));
i = 0;
SPA_POD_SEQUENCE_FOREACH((const struct spa_pod_sequence*)pod, control) {
switch (i++) {
case 0:
spa_assert(control->offset == 0);
spa_assert(SPA_POD_CONTROL_SIZE(control) == 20);
spa_assert(spa_pod_get_float(&control->value, &val.f) == 0 && val.f == 0.667f);
break;
case 1:
spa_assert(control->offset == 12);
spa_assert(SPA_POD_CONTROL_SIZE(control) == 24);
spa_assert(spa_pod_get_double(&control->value, &val.d) == 0 && val.d == 1.22);
break;
default:
spa_assert_not_reached();
break;
}
}
}
@ -201,5 +642,6 @@ int main(int argc, char *argv[])
{
test_abi();
test_init();
test_build();
return 0;
}

View file

@ -374,7 +374,7 @@ static void node_event_param(void *object,
n->media_subtype != SPA_MEDIA_SUBTYPE_raw)
return;
spa_pod_fixate((struct spa_pod*)param);
spa_pod_object_fixate((struct spa_pod_object*)param);
if (spa_format_audio_raw_parse(param, &info) < 0)
goto error;

View file

@ -816,6 +816,7 @@ gst_caps_from_format (const struct spa_pod *format)
GstCaps *res = NULL;
uint32_t media_type, media_subtype;
struct spa_pod_prop *prop;
const struct spa_pod_object *obj = (const struct spa_pod_object *) format;
if (spa_format_parse(format, &media_type, &media_subtype) < 0)
return res;
@ -823,7 +824,7 @@ gst_caps_from_format (const struct spa_pod *format)
if (media_type == SPA_MEDIA_TYPE_video) {
if (media_subtype == SPA_MEDIA_SUBTYPE_raw) {
res = gst_caps_new_empty_simple ("video/x-raw");
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_VIDEO_format))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_format))) {
handle_id_prop (prop, "format", video_id_to_string, res);
}
}
@ -836,13 +837,13 @@ gst_caps_from_format (const struct spa_pod *format)
"alignment", G_TYPE_STRING, "au",
NULL);
}
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_VIDEO_size))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_size))) {
handle_rect_prop (prop, "width", "height", res);
}
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_VIDEO_framerate))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_framerate))) {
handle_fraction_prop (prop, "framerate", res);
}
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_VIDEO_maxFramerate))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_VIDEO_maxFramerate))) {
handle_fraction_prop (prop, "max-framerate", res);
}
} else if (media_type == SPA_MEDIA_TYPE_audio) {
@ -850,13 +851,13 @@ gst_caps_from_format (const struct spa_pod *format)
res = gst_caps_new_simple ("audio/x-raw",
"layout", G_TYPE_STRING, "interleaved",
NULL);
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_AUDIO_format))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_AUDIO_format))) {
handle_id_prop (prop, "format", audio_id_to_string, res);
}
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_AUDIO_rate))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_AUDIO_rate))) {
handle_int_prop (prop, "rate", res);
}
if ((prop = spa_pod_find_prop (format, SPA_FORMAT_AUDIO_channels))) {
if ((prop = spa_pod_object_find_prop (obj, SPA_FORMAT_AUDIO_channels))) {
handle_int_prop (prop, "channels", res);
}
}

View file

@ -35,6 +35,7 @@
#include <spa/node/node.h>
#include <spa/pod/filter.h>
#include <spa/pod/parser.h>
#include <spa/debug/types.h>
#include <pipewire/pipewire.h>
@ -372,7 +373,7 @@ static int impl_node_enum_params(struct spa_node *node,
param = this->params[(*index)++];
if (!spa_pod_is_object_type(param, id))
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
@ -523,7 +524,7 @@ do_update_port(struct node *this,
for (i = 0; i < port->n_params; i++) {
port->params[i] = params[i] ? pw_spa_pod_copy(params[i]) : NULL;
if (spa_pod_is_object_id(port->params[i], SPA_PARAM_Format))
if (port->params[i] && spa_pod_is_object_id(port->params[i], SPA_PARAM_Format))
port->have_format = true;
}
}
@ -664,7 +665,7 @@ impl_node_port_enum_params(struct spa_node *node,
param = port->params[(*index)++];
if (!spa_pod_is_object_id(param, id))
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)

View file

@ -436,7 +436,7 @@ static int impl_port_enum_params(struct spa_node *node,
break;
}
} else {
if (!spa_pod_is_object_id(param, id))
if (param == NULL || !spa_pod_is_object_id(param, id))
continue;
if (spa_pod_filter(builder, result, param, filter) == 0)
@ -460,7 +460,7 @@ static int port_set_format(struct spa_node *node,
spa_debug_format(2, NULL, format);
clear_params(stream, PARAM_TYPE_FORMAT);
if (spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) {
if (format && spa_pod_is_object_type(format, SPA_TYPE_OBJECT_Format)) {
p = add_param(stream, PARAM_TYPE_FORMAT, format);
if (p == NULL)
goto no_mem;