PipeWire 1.4.1
All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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
9extern "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
39SPA_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);
54
55/* int */
56SPA_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);
64
65/* bool */
66SPA_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);
74
75/* string */
76SPA_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);
84
85
86SPA_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}
117SPA_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 */
130SPA_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}
134SPA_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);
138SPA_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);
142
143SPA_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
156SPA_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
168SPA_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 */
183SPA_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}
187SPA_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);
191SPA_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);
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
208SPA_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