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