PipeWire 1.0.5
Loading...
Searching...
No Matches
compare.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_COMPARE_H
6#define SPA_POD_COMPARE_H
7
8#ifdef __cplusplus
9extern "C" {
10#endif
11
12#include <stdarg.h>
13#include <errno.h>
14#include <stdint.h>
15#include <stddef.h>
16#include <stdio.h>
17#include <string.h>
18
19#include <spa/param/props.h>
20#include <spa/pod/iter.h>
21#include <spa/pod/builder.h>
22
28static inline int spa_pod_compare_value(uint32_t type, const void *r1, const void *r2, uint32_t size)
29{
30 switch (type) {
31 case SPA_TYPE_None:
32 return 0;
34 case SPA_TYPE_Id:
35 return *(uint32_t *) r1 == *(uint32_t *) r2 ? 0 : 1;
36 case SPA_TYPE_Int:
37 return *(int32_t *) r1 - *(int32_t *) r2;
38 case SPA_TYPE_Long:
39 return *(int64_t *) r1 - *(int64_t *) r2;
40 case SPA_TYPE_Float:
41 return *(float *) r1 - *(float *) r2;
42 case SPA_TYPE_Double:
43 return *(double *) r1 - *(double *) r2;
44 case SPA_TYPE_String:
45 return strcmp((char *)r1, (char *)r2);
46 case SPA_TYPE_Bytes:
47 return memcmp((char *)r1, (char *)r2, size);
49 {
50 const struct spa_rectangle *rec1 = (struct spa_rectangle *) r1,
51 *rec2 = (struct spa_rectangle *) r2;
52 if (rec1->width == rec2->width && rec1->height == rec2->height)
53 return 0;
54 else if (rec1->width < rec2->width || rec1->height < rec2->height)
55 return -1;
56 else
57 return 1;
58 }
60 {
61 const struct spa_fraction *f1 = (struct spa_fraction *) r1,
62 *f2 = (struct spa_fraction *) r2;
63 int64_t n1, n2;
64 n1 = ((int64_t) f1->num) * f2->denom;
65 n2 = ((int64_t) f2->num) * f1->denom;
66 if (n1 < n2)
67 return -1;
68 else if (n1 > n2)
69 return 1;
70 else
71 return 0;
72 }
73 default:
74 break;
75 }
76 return 0;
77}
78
79static inline int spa_pod_compare(const struct spa_pod *pod1,
80 const struct spa_pod *pod2)
81{
82 int res = 0;
83 uint32_t n_vals1, n_vals2;
84 uint32_t choice1, choice2;
85
86 spa_return_val_if_fail(pod1 != NULL, -EINVAL);
87 spa_return_val_if_fail(pod2 != NULL, -EINVAL);
88
89 pod1 = spa_pod_get_values(pod1, &n_vals1, &choice1);
90 pod2 = spa_pod_get_values(pod2, &n_vals2, &choice2);
91
92 if (n_vals1 != n_vals2)
93 return -EINVAL;
94
95 if (SPA_POD_TYPE(pod1) != SPA_POD_TYPE(pod2))
96 return -EINVAL;
97
98 switch (SPA_POD_TYPE(pod1)) {
99 case SPA_TYPE_Struct:
100 {
101 const struct spa_pod *p1, *p2;
102 size_t p1s, p2s;
103
104 p1 = (const struct spa_pod*)SPA_POD_BODY_CONST(pod1);
105 p1s = SPA_POD_BODY_SIZE(pod1);
106 p2 = (const struct spa_pod*)SPA_POD_BODY_CONST(pod2);
107 p2s = SPA_POD_BODY_SIZE(pod2);
108
109 while (true) {
110 if (!spa_pod_is_inside(pod1, p1s, p1) ||
111 !spa_pod_is_inside(pod2, p2s, p2))
112 return -EINVAL;
113
114 if ((res = spa_pod_compare(p1, p2)) != 0)
115 return res;
116
117 p1 = (const struct spa_pod*)spa_pod_next(p1);
118 p2 = (const struct spa_pod*)spa_pod_next(p2);
119 }
120 break;
121 }
122 case SPA_TYPE_Object:
123 {
124 const struct spa_pod_prop *p1, *p2;
125 const struct spa_pod_object *o1, *o2;
126
127 o1 = (const struct spa_pod_object*)pod1;
128 o2 = (const struct spa_pod_object*)pod2;
129
130 p2 = NULL;
131 SPA_POD_OBJECT_FOREACH(o1, p1) {
132 if ((p2 = spa_pod_object_find_prop(o2, p2, p1->key)) == NULL)
133 return 1;
134 if ((res = spa_pod_compare(&p1->value, &p2->value)) != 0)
135 return res;
136 }
137 p1 = NULL;
138 SPA_POD_OBJECT_FOREACH(o2, p2) {
139 if ((p1 = spa_pod_object_find_prop(o1, p1, p2->key)) == NULL)
140 return -1;
141 }
142 break;
143 }
144 case SPA_TYPE_Array:
145 {
146 if (SPA_POD_BODY_SIZE(pod1) != SPA_POD_BODY_SIZE(pod2))
147 return -EINVAL;
148 res = memcmp(SPA_POD_BODY(pod1), SPA_POD_BODY(pod2), SPA_POD_BODY_SIZE(pod2));
149 break;
150 }
151 default:
152 if (SPA_POD_BODY_SIZE(pod1) != SPA_POD_BODY_SIZE(pod2))
153 return -EINVAL;
155 SPA_POD_BODY(pod1), SPA_POD_BODY(pod2),
156 SPA_POD_BODY_SIZE(pod1));
157 break;
158 }
159 return res;
160}
161
166#ifdef __cplusplus
167}
168#endif
169
170#endif
spa/pod/builder.h
static const struct spa_pod_prop * spa_pod_object_find_prop(const struct spa_pod_object *pod, const struct spa_pod_prop *start, uint32_t key)
Definition iter.h:388
#define SPA_POD_BODY_CONST(pod)
Definition pod.h:41
static int spa_pod_compare_value(uint32_t type, const void *r1, const void *r2, uint32_t size)
Definition compare.h:33
static void * spa_pod_next(const void *iter)
Definition iter.h:40
#define SPA_POD_OBJECT_FOREACH(obj, iter)
Definition iter.h:108
#define SPA_POD_BODY(pod)
Definition pod.h:39
#define SPA_POD_TYPE(pod)
Definition pod.h:28
#define SPA_POD_BODY_SIZE(pod)
Definition pod.h:26
static bool spa_pod_is_inside(const void *pod, uint32_t size, const void *iter)
Definition iter.h:34
static int spa_pod_compare(const struct spa_pod *pod1, const struct spa_pod *pod2)
Definition compare.h:84
static struct spa_pod * spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
Definition iter.h:347
@ SPA_TYPE_Int
Definition type.h:34
@ SPA_TYPE_Rectangle
Definition type.h:40
@ SPA_TYPE_Long
Definition type.h:35
@ SPA_TYPE_Bool
Definition type.h:32
@ SPA_TYPE_Bytes
Definition type.h:39
@ SPA_TYPE_Object
Definition type.h:45
@ SPA_TYPE_Float
Definition type.h:36
@ SPA_TYPE_Fraction
Definition type.h:41
@ SPA_TYPE_None
Definition type.h:31
@ SPA_TYPE_Double
Definition type.h:37
@ SPA_TYPE_Id
Definition type.h:33
@ SPA_TYPE_Array
Definition type.h:43
@ SPA_TYPE_String
Definition type.h:38
@ SPA_TYPE_Struct
Definition type.h:44
#define spa_return_val_if_fail(expr, val)
Definition defs.h:369
spa/pod/iter.h
spa/utils/string.h
Definition defs.h:123
uint32_t num
Definition defs.h:124
uint32_t denom
Definition defs.h:125
Definition pod.h:183
Definition pod.h:208
uint32_t key
key of property, list of valid keys depends on the object type
Definition pod.h:209
struct spa_pod value
Definition pod.h:226
Definition pod.h:43
Definition defs.h:102
uint32_t width
Definition defs.h:103
uint32_t height
Definition defs.h:104