PipeWire  1.6.4
json.h
Go to the documentation of this file.
1 /* Simple Plugin API */
2 /* SPDX-FileCopyrightText: Copyright © 2020 Wim Taymans */
3 /* SPDX-License-Identifier: MIT */
4 
5 #ifndef SPA_UTILS_JSON_UTILS_H
6 #define SPA_UTILS_JSON_UTILS_H
7 
8 #include <stddef.h>
9 #include <stdlib.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include <math.h>
13 #include <float.h>
14 
15 #include <spa/utils/json-core.h>
16 
17 #ifdef __cplusplus
18 extern "C" {
19 #else
20 #include <stdbool.h>
21 #endif
22 
23 #ifndef SPA_API_JSON_UTILS
24  #ifdef SPA_API_IMPL
25  #define SPA_API_JSON_UTILS SPA_API_IMPL
26  #else
27  #define SPA_API_JSON_UTILS static inline
28  #endif
29 #endif
30 
40 SPA_API_JSON_UTILS int spa_json_begin(struct spa_json * iter, const char *data, size_t size, const char **val)
41 {
42  spa_json_init(iter, data, size);
43  return spa_json_next(iter, val);
44 }
45 
46 /* float */
48 {
49  const char *value;
50  int len;
51  if ((len = spa_json_next(iter, &value)) <= 0)
52  return len;
53  return spa_json_parse_float(value, len, res);
54 }
55 
56 /* int */
57 SPA_API_JSON_UTILS int spa_json_get_int(struct spa_json *iter, int *res)
58 {
59  const char *value;
60  int len;
61  if ((len = spa_json_next(iter, &value)) <= 0)
62  return len;
63  return spa_json_parse_int(value, len, res);
64 }
65 
66 /* bool */
67 SPA_API_JSON_UTILS int spa_json_get_bool(struct spa_json *iter, bool *res)
68 {
69  const char *value;
70  int len;
71  if ((len = spa_json_next(iter, &value)) <= 0)
72  return len;
73  return spa_json_parse_bool(value, len, res);
74 }
75 
76 /* string */
77 SPA_API_JSON_UTILS int spa_json_get_string(struct spa_json *iter, char *res, int maxlen)
78 {
79  const char *value;
80  int len;
81  if ((len = spa_json_next(iter, &value)) <= 0)
82  return len;
83  return spa_json_parse_stringn(value, len, res, maxlen);
84 }
85 
86 
87 SPA_API_JSON_UTILS int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)
88 {
89  const char *value;
90  int len;
91  if ((len = spa_json_next(iter, &value)) <= 0)
92  return len;
93  if (!spa_json_is_container(value, len))
94  return -EPROTO;
95  if (*value != type)
96  return -EINVAL;
97  spa_json_enter(iter, sub);
98  return 1;
99 }
100 
102  const char *data, size_t size, char type, bool relax)
103 {
104  int res;
105  spa_json_init(iter, data, size);
106  res = spa_json_enter_container(iter, iter, type);
107  if (res == -EPROTO && relax)
108  spa_json_init_relax(iter, type, data, size);
109  else if (res <= 0)
110  return res;
111  return 1;
112 }
118 SPA_API_JSON_UTILS int spa_json_container_len(struct spa_json *iter, const char *value, int len SPA_UNUSED)
119 {
120  const char *val;
121  struct spa_json sub;
122  int res;
123  spa_json_enter(iter, &sub);
124  while ((res = spa_json_next(&sub, &val)) > 0);
125  if (res < 0)
126  return 0;
127  return sub.cur + 1 - value;
128 }
129 
130 /* object */
131 SPA_API_JSON_UTILS int spa_json_enter_object(struct spa_json *iter, struct spa_json *sub)
132 {
133  return spa_json_enter_container(iter, sub, '{');
134 }
135 SPA_API_JSON_UTILS int spa_json_begin_object_relax(struct spa_json * iter, const char *data, size_t size)
136 {
137  return spa_json_begin_container(iter, data, size, '{', true);
138 }
139 SPA_API_JSON_UTILS int spa_json_begin_object(struct spa_json * iter, const char *data, size_t size)
140 {
141  return spa_json_begin_container(iter, data, size, '{', false);
142 }
143 
144 SPA_API_JSON_UTILS int spa_json_object_next(struct spa_json *iter, char *key, int maxkeylen, const char **value)
145 {
146  int res1, res2;
147  while (true) {
148  res1 = spa_json_get_string(iter, key, maxkeylen);
149  if (res1 <= 0 && res1 != -ENOSPC)
150  return res1;
151  res2 = spa_json_next(iter, value);
152  if (res2 <= 0 || res1 != -ENOSPC)
153  return res2;
154  }
155 }
156 
157 SPA_API_JSON_UTILS int spa_json_object_find(struct spa_json *iter, const char *key, const char **value)
158 {
159  struct spa_json obj = SPA_JSON_SAVE(iter);
160  int res, len = strlen(key) + 3;
161  char k[len];
162 
163  while ((res = spa_json_object_next(&obj, k, len, value)) > 0)
164  if (spa_streq(k, key))
165  return res;
166  return -ENOENT;
167 }
168 
169 SPA_API_JSON_UTILS int spa_json_str_object_find(const char *obj, size_t obj_len,
170  const char *key, char *value, size_t maxlen)
171 {
172  struct spa_json iter;
173  int l;
174  const char *v;
175 
176  if (spa_json_begin_object(&iter, obj, obj_len) <= 0)
177  return -EINVAL;
178  if ((l = spa_json_object_find(&iter, key, &v)) <= 0)
179  return l;
180  return spa_json_parse_stringn(v, l, value, maxlen);
181 }
182 
183 /* array */
184 SPA_API_JSON_UTILS int spa_json_enter_array(struct spa_json *iter, struct spa_json *sub)
185 {
186  return spa_json_enter_container(iter, sub, '[');
187 }
188 SPA_API_JSON_UTILS int spa_json_begin_array_relax(struct spa_json * iter, const char *data, size_t size)
189 {
190  return spa_json_begin_container(iter, data, size, '[', true);
191 }
192 SPA_API_JSON_UTILS int spa_json_begin_array(struct spa_json * iter, const char *data, size_t size)
193 {
194  return spa_json_begin_container(iter, data, size, '[', false);
195 }
196 
197 #define spa_json_make_str_array_unpack(maxlen,type,conv) \
198 { \
199  struct spa_json iter; \
200  char v[maxlen]; \
201  uint32_t count = 0; \
202  if (spa_json_begin_array_relax(&iter, arr, arr_len) <= 0) \
203  return -EINVAL; \
204  while (spa_json_get_string(&iter, v, sizeof(v)) > 0 && count < max) \
205  values[count++] = conv(v); \
206  return count; \
207 }
208 
209 SPA_API_JSON_UTILS int spa_json_str_array_uint32(const char *arr, size_t arr_len,
210  uint32_t *values, size_t max)
211 {
212  spa_json_make_str_array_unpack(32,uint32_t, atoi);
213 }
214 
219 #ifdef __cplusplus
220 } /* extern "C" */
221 #endif
222 
223 #endif /* SPA_UTILS_JSON_UTILS_H */
uint32_t int int res
Definition: core.h:433
SPA_API_JSON_UTILS int spa_json_str_object_find(const char *obj, size_t obj_len, const char *key, char *value, size_t maxlen)
Definition: json.h:176
SPA_API_JSON_UTILS int spa_json_enter_array(struct spa_json *iter, struct spa_json *sub)
Definition: json.h:191
#define SPA_JSON_SAVE(iter)
Definition: json-core.h:84
SPA_API_JSON_UTILS int spa_json_begin_array(struct spa_json *iter, const char *data, size_t size)
Definition: json.h:199
SPA_API_JSON_UTILS int spa_json_object_next(struct spa_json *iter, char *key, int maxkeylen, const char **value)
Definition: json.h:151
SPA_API_JSON_UTILS int spa_json_begin_object_relax(struct spa_json *iter, const char *data, size_t size)
Definition: json.h:142
SPA_API_JSON void spa_json_init(struct spa_json *iter, const char *data, size_t size)
Definition: json-core.h:62
SPA_API_JSON_UTILS int spa_json_begin_object(struct spa_json *iter, const char *data, size_t size)
Definition: json.h:146
SPA_API_JSON_UTILS int spa_json_begin(struct spa_json *iter, const char *data, size_t size, const char **val)
Definition: json.h:47
SPA_API_JSON_UTILS int spa_json_enter_object(struct spa_json *iter, struct spa_json *sub)
Definition: json.h:138
SPA_API_JSON_UTILS int spa_json_begin_array_relax(struct spa_json *iter, const char *data, size_t size)
Definition: json.h:195
SPA_API_JSON int spa_json_next(struct spa_json *iter, const char **value)
Get the next token.
Definition: json-core.h:101
SPA_API_JSON int spa_json_parse_float(const char *val, int len, float *result)
Definition: json-core.h:434
SPA_API_JSON_UTILS int spa_json_get_int(struct spa_json *iter, int *res)
Definition: json.h:64
SPA_API_JSON int spa_json_parse_int(const char *val, int len, int *result)
Definition: json-core.h:475
SPA_API_JSON_UTILS int spa_json_container_len(struct spa_json *iter, const char *value, int len 1)
Return length of container at current position, starting at value.
Definition: json.h:125
SPA_API_JSON_UTILS int spa_json_get_bool(struct spa_json *iter, bool *res)
Definition: json.h:74
SPA_API_JSON_UTILS int spa_json_object_find(struct spa_json *iter, const char *key, const char **value)
Definition: json.h:164
SPA_API_JSON void spa_json_init_relax(struct spa_json *iter, char type, const char *data, size_t size)
Definition: json-core.h:70
SPA_API_JSON int spa_json_parse_bool(const char *val, int len, bool *result)
Definition: json-core.h:511
SPA_API_JSON_UTILS int spa_json_str_array_uint32(const char *arr, size_t arr_len, uint32_t *values, size_t max)
Definition: json.h:216
SPA_API_JSON int spa_json_parse_stringn(const char *val, int len, char *result, int maxlen)
Definition: json-core.h:545
SPA_API_JSON void spa_json_enter(struct spa_json *iter, struct spa_json *sub)
Definition: json-core.h:78
SPA_API_JSON_UTILS int spa_json_enter_container(struct spa_json *iter, struct spa_json *sub, char type)
Definition: json.h:94
#define spa_json_make_str_array_unpack(maxlen, type, conv)
Definition: json.h:204
SPA_API_JSON_UTILS int spa_json_begin_container(struct spa_json *iter, const char *data, size_t size, char type, bool relax)
Definition: json.h:108
SPA_API_JSON int spa_json_is_container(const char *val, int len)
Definition: json-core.h:410
SPA_API_JSON_UTILS int spa_json_get_string(struct spa_json *iter, char *res, int maxlen)
Definition: json.h:84
SPA_API_JSON_UTILS int spa_json_get_float(struct spa_json *iter, float *res)
Definition: json.h:54
SPA_API_STRING bool spa_streq(const char *s1, const char *s2)
Definition: string.h:52
#define SPA_UNUSED
Definition: defs.h:309
spa/utils/json-core.h
#define SPA_API_JSON_UTILS
Definition: json.h:34
spa/utils/string.h
Definition: json-core.h:49
const char * cur
Definition: json-core.h:50