PipeWire  0.3.66
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
9 extern "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 
28 static 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);
48  case SPA_TYPE_Rectangle:
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  }
59  case SPA_TYPE_Fraction:
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 
79 static 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 struct spa_pod * spa_pod_get_values(const struct spa_pod *pod, uint32_t *n_vals, uint32_t *choice)
Definition: iter.h:347
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/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
#define SPA_POD_OBJECT_FOREACH(obj, iter)
Definition: iter.h:108
#define SPA_POD_BODY(pod)
Definition: pod/pod.h:39
#define SPA_POD_TYPE(pod)
Definition: pod/pod.h:28
#define SPA_POD_BODY_SIZE(pod)
Definition: pod/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 void * spa_pod_next(const void *iter)
Definition: iter.h:40
@ SPA_TYPE_Int
Definition: spa/include/spa/utils/type.h:34
@ SPA_TYPE_Rectangle
Definition: spa/include/spa/utils/type.h:40
@ SPA_TYPE_Long
Definition: spa/include/spa/utils/type.h:35
@ SPA_TYPE_Bool
Definition: spa/include/spa/utils/type.h:32
@ SPA_TYPE_Bytes
Definition: spa/include/spa/utils/type.h:39
@ SPA_TYPE_Object
Definition: spa/include/spa/utils/type.h:45
@ SPA_TYPE_Float
Definition: spa/include/spa/utils/type.h:36
@ SPA_TYPE_Fraction
Definition: spa/include/spa/utils/type.h:41
@ SPA_TYPE_None
Definition: spa/include/spa/utils/type.h:31
@ SPA_TYPE_Double
Definition: spa/include/spa/utils/type.h:37
@ SPA_TYPE_Id
Definition: spa/include/spa/utils/type.h:33
@ SPA_TYPE_Array
Definition: spa/include/spa/utils/type.h:43
@ SPA_TYPE_String
Definition: spa/include/spa/utils/type.h:38
@ SPA_TYPE_Struct
Definition: spa/include/spa/utils/type.h:44
#define spa_return_val_if_fail(expr, val)
Definition: defs.h:361
spa/pod/iter.h
spa/utils/string.h
Definition: defs.h:119
uint32_t num
Definition: defs.h:120
uint32_t denom
Definition: defs.h:121
Definition: pod/pod.h:183
Definition: pod/pod.h:208
uint32_t key
key of property, list of valid keys depends on the object type
Definition: pod/pod.h:209
struct spa_pod value
Definition: pod/pod.h:226
Definition: pod/pod.h:43
Definition: defs.h:98
uint32_t width
Definition: defs.h:99
uint32_t height
Definition: defs.h:100