aboutsummaryrefslogtreecommitdiff
path: root/src/json
diff options
context:
space:
mode:
Diffstat (limited to 'src/json')
-rw-r--r--src/json/Makefile.am12
-rw-r--r--src/json/json.c37
-rw-r--r--src/json/json_pack.c325
3 files changed, 333 insertions, 41 deletions
diff --git a/src/json/Makefile.am b/src/json/Makefile.am
index d4ea38adf..2e97cecb9 100644
--- a/src/json/Makefile.am
+++ b/src/json/Makefile.am
@@ -13,21 +13,21 @@ libgnunetjson_la_LDFLAGS = \
13 $(GN_LIBINTL) \ 13 $(GN_LIBINTL) \
14 -version-info 0:0:0 \ 14 -version-info 0:0:0 \
15 -no-undefined 15 -no-undefined
16libgnunetjson_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 16libgnunetjson_la_CFLAGS = \
17 $(MHD_CFLAGS) \
18 $(AM_CFLAGS)
17libgnunetjson_la_SOURCES = \ 19libgnunetjson_la_SOURCES = \
18 json.c \ 20 json.c \
19 json_mhd.c \
20 json_generator.c \ 21 json_generator.c \
21 json_helper.c 22 json_helper.c \
23 json_mhd.c \
24 json_pack.c
22libgnunetjson_la_LIBADD = \ 25libgnunetjson_la_LIBADD = \
23 $(top_builddir)/src/util/libgnunetutil.la \ 26 $(top_builddir)/src/util/libgnunetutil.la \
24 -ljansson \ 27 -ljansson \
25 $(MHD_LIBS) \ 28 $(MHD_LIBS) \
26 $(XLIB) \ 29 $(XLIB) \
27 $(Z_LIBS) 30 $(Z_LIBS)
28libgnunetjson_la_DEPENDENCIES = \
29 $(top_builddir)/src/util/libgnunetutil.la
30
31 31
32check_PROGRAMS = \ 32check_PROGRAMS = \
33 test_json \ 33 test_json \
diff --git a/src/json/json.c b/src/json/json.c
index d55189804..51d5c0c72 100644
--- a/src/json/json.c
+++ b/src/json/json.c
@@ -28,19 +28,6 @@
28#include "gnunet_json_lib.h" 28#include "gnunet_json_lib.h"
29 29
30 30
31/**
32 * Navigate and parse data in a JSON tree. Tries to parse the @a root
33 * to find all of the values given in the @a spec. If one of the
34 * entries in @a spec cannot be found or parsed, the name of the JSON
35 * field is returned in @a error_json_name, and the offset of the
36 * entry in @a spec is returned in @a error_line.
37 *
38 * @param root the JSON node to start the navigation at.
39 * @param spec parse specification array
40 * @param[out] error_json_name which JSON field was problematic
41 * @param[out] which index into @a spec did we encounter an error
42 * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
43 */
44enum GNUNET_GenericReturnValue 31enum GNUNET_GenericReturnValue
45GNUNET_JSON_parse (const json_t *root, 32GNUNET_JSON_parse (const json_t *root,
46 struct GNUNET_JSON_Specification *spec, 33 struct GNUNET_JSON_Specification *spec,
@@ -85,12 +72,6 @@ GNUNET_JSON_parse (const json_t *root,
85} 72}
86 73
87 74
88/**
89 * Set the "optional" flag for a parser specification entry.
90 *
91 * @param spec specification to modify
92 * @return spec copy of @a spec with optional bit set
93 */
94struct GNUNET_JSON_Specification 75struct GNUNET_JSON_Specification
95GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec) 76GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec)
96{ 77{
@@ -101,18 +82,13 @@ GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec)
101} 82}
102 83
103 84
104/**
105 * Frees all elements allocated during a #GNUNET_JSON_parse()
106 * operation.
107 *
108 * @param spec specification of the parse operation
109 */
110void 85void
111GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec) 86GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec)
112{ 87{
113 for (unsigned int i = 0; NULL != spec[i].parser; i++) 88 for (unsigned int i = 0; NULL != spec[i].parser; i++)
114 if (NULL != spec[i].cleaner) 89 if (NULL != spec[i].cleaner)
115 spec[i].cleaner (spec[i].cls, &spec[i]); 90 spec[i].cleaner (spec[i].cls,
91 &spec[i]);
116} 92}
117 93
118 94
@@ -151,15 +127,6 @@ set_json (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
151} 127}
152 128
153 129
154/**
155 * Allow user to specify a JSON input value.
156 *
157 * @param shortName short name of the option
158 * @param name long name of the option
159 * @param argumentHelp help text for the option argument
160 * @param description long help text for the option
161 * @param[out] val set to the JSON specified at the command line
162 */
163struct GNUNET_GETOPT_CommandLineOption 130struct GNUNET_GETOPT_CommandLineOption
164GNUNET_JSON_getopt (char shortName, 131GNUNET_JSON_getopt (char shortName,
165 const char *name, 132 const char *name,
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
new file mode 100644
index 000000000..92f8b4535
--- /dev/null
+++ b/src/json/json_pack.c
@@ -0,0 +1,325 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2021 GNUnet e.V.
4
5 GNUnet is free software: you can redistribute it and/or modify it
6 under the terms of the GNU Affero General Public License as published
7 by the Free Software Foundation, either version 3 of the License,
8 or (at your option) any later version.
9
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Affero General Public License for more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file json/json_pack.c
22 * @brief functions to pack JSON objects
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "gnunet_json_lib.h"
27
28
29json_t *
30GNUNET_JSON_pack_ (struct GNUNET_JSON_PackSpec spec[])
31{
32 json_t *ret;
33
34 ret = json_object ();
35 GNUNET_assert (NULL != ret);
36 for (unsigned int i = 0;
37 NULL != spec[i].field_name;
38 i++)
39 {
40 if (NULL == spec[i].object)
41 {
42 GNUNET_assert (spec[i].allow_null);
43 }
44 else
45 {
46 GNUNET_assert (0 ==
47 json_object_set_new (ret,
48 spec[i].field_name,
49 spec[i].object));
50 spec[i].object = NULL;
51 }
52 }
53 return ret;
54}
55
56
57struct GNUNET_JSON_PackSpec
58GNUNET_JSON_pack_end_ (void)
59{
60 struct GNUNET_JSON_PackSpec ps = {
61 .field_name = NULL
62 };
63
64 return ps;
65}
66
67
68struct GNUNET_JSON_PackSpec
69GNUNET_JSON_pack_allow_null (struct GNUNET_JSON_PackSpec in)
70{
71 in.allow_null = true;
72 return in;
73}
74
75
76struct GNUNET_JSON_PackSpec
77GNUNET_JSON_pack_bool (const char *name,
78 bool b)
79{
80 struct GNUNET_JSON_PackSpec ps = {
81 .field_name = name,
82 .object = json_boolean (b)
83 };
84
85 return ps;
86}
87
88
89struct GNUNET_JSON_PackSpec
90GNUNET_JSON_pack_string (const char *name,
91 const char *s)
92{
93 struct GNUNET_JSON_PackSpec ps = {
94 .field_name = name,
95 .object = json_string (s)
96 };
97
98 return ps;
99}
100
101
102struct GNUNET_JSON_PackSpec
103GNUNET_JSON_pack_uint64 (const char *name,
104 uint64_t num)
105{
106 struct GNUNET_JSON_PackSpec ps = {
107 .field_name = name,
108 .object = json_integer ((json_int_t) num)
109 };
110
111#if JSON_INTEGER_IS_LONG_LONG
112 GNUNET_assert (num <= LLONG_MAX);
113#else
114 GNUNET_assert (num <= LONG_MAX);
115#endif
116 return ps;
117}
118
119
120struct GNUNET_JSON_PackSpec
121GNUNET_JSON_pack_int64 (const char *name,
122 int64_t num)
123{
124 struct GNUNET_JSON_PackSpec ps = {
125 .field_name = name,
126 .object = json_integer ((json_int_t) num)
127 };
128
129#if JSON_INTEGER_IS_LONG_LONG
130 GNUNET_assert (num <= LLONG_MAX);
131 GNUNET_assert (num >= LLONG_MIN);
132#else
133 GNUNET_assert (num <= LONG_MAX);
134 GNUNET_assert (num >= LONG_MIN);
135#endif
136 return ps;
137}
138
139
140struct GNUNET_JSON_PackSpec
141GNUNET_JSON_pack_object_steal (const char *name,
142 json_t *o)
143{
144 struct GNUNET_JSON_PackSpec ps = {
145 .field_name = name,
146 .object = o
147 };
148
149 if (NULL == o)
150 return ps;
151 if (! json_is_object (o))
152 {
153 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
154 "Expected JSON object for field `%s'\n",
155 name);
156 GNUNET_assert (0);
157 }
158 return ps;
159}
160
161
162struct GNUNET_JSON_PackSpec
163GNUNET_JSON_pack_object_incref (const char *name,
164 json_t *o)
165{
166 struct GNUNET_JSON_PackSpec ps = {
167 .field_name = name,
168 .object = o
169 };
170
171 if (NULL == o)
172 return ps;
173 (void) json_incref (o);
174 if (! json_is_object (o))
175 {
176 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
177 "Expected JSON object for field `%s'\n",
178 name);
179 GNUNET_assert (0);
180 }
181 return ps;
182}
183
184
185struct GNUNET_JSON_PackSpec
186GNUNET_JSON_pack_array_steal (const char *name,
187 json_t *a)
188{
189 struct GNUNET_JSON_PackSpec ps = {
190 .field_name = name,
191 .object = a
192 };
193
194 if (NULL == a)
195 return ps;
196 if (! json_is_array (a))
197 {
198 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
199 "Expected JSON array for field `%s'\n",
200 name);
201 GNUNET_assert (0);
202 }
203 return ps;
204}
205
206
207struct GNUNET_JSON_PackSpec
208GNUNET_JSON_pack_array_incref (const char *name,
209 json_t *a)
210{
211 struct GNUNET_JSON_PackSpec ps = {
212 .field_name = name,
213 .object = a
214 };
215
216 if (NULL == a)
217 return ps;
218 (void) json_incref (a);
219 if (! json_is_array (a))
220 {
221 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
222 "Expected JSON array for field `%s'\n",
223 name);
224 GNUNET_assert (0);
225 }
226 return ps;
227}
228
229
230struct GNUNET_JSON_PackSpec
231GNUNET_JSON_pack_data_varsize (const char *name,
232 const void *blob,
233 size_t blob_size)
234{
235 struct GNUNET_JSON_PackSpec ps = {
236 .field_name = name,
237 .object = (NULL != blob)
238 ? GNUNET_JSON_from_data (blob,
239 blob_size)
240 : NULL
241 };
242
243 return ps;
244}
245
246
247struct GNUNET_JSON_PackSpec
248GNUNET_JSON_pack_time_abs (const char *name,
249 struct GNUNET_TIME_Absolute at)
250{
251 struct GNUNET_JSON_PackSpec ps = {
252 .field_name = name
253 };
254
255 if (0 != at.abs_value_us)
256 {
257 ps.object = GNUNET_JSON_from_time_abs (at);
258 GNUNET_assert (NULL != ps.object);
259 }
260 else
261 {
262 ps.object = NULL;
263 }
264 return ps;
265}
266
267
268struct GNUNET_JSON_PackSpec
269GNUNET_JSON_pack_time_abs_nbo (const char *name,
270 struct GNUNET_TIME_AbsoluteNBO at)
271{
272 return GNUNET_JSON_pack_time_abs (name,
273 GNUNET_TIME_absolute_ntoh (at));
274}
275
276
277struct GNUNET_JSON_PackSpec
278GNUNET_JSON_pack_time_rel (const char *name,
279 struct GNUNET_TIME_Relative rt)
280{
281 json_t *json;
282
283 json = GNUNET_JSON_from_time_rel (rt);
284 GNUNET_assert (NULL != json);
285 return GNUNET_JSON_pack_object_steal (name,
286 json);
287}
288
289
290struct GNUNET_JSON_PackSpec
291GNUNET_JSON_pack_time_rel_nbo (const char *name,
292 struct GNUNET_TIME_RelativeNBO rt)
293{
294 return GNUNET_JSON_pack_time_rel (name,
295 GNUNET_TIME_relative_ntoh (rt));
296}
297
298
299struct GNUNET_JSON_PackSpec
300GNUNET_JSON_pack_rsa_public_key (const char *name,
301 const struct GNUNET_CRYPTO_RsaPublicKey *pk)
302{
303 struct GNUNET_JSON_PackSpec ps = {
304 .field_name = name,
305 .object = GNUNET_JSON_from_rsa_public_key (pk)
306 };
307
308 return ps;
309}
310
311
312struct GNUNET_JSON_PackSpec
313GNUNET_JSON_pack_rsa_signature (const char *name,
314 const struct GNUNET_CRYPTO_RsaSignature *sig)
315{
316 struct GNUNET_JSON_PackSpec ps = {
317 .field_name = name,
318 .object = GNUNET_JSON_from_rsa_signature (sig)
319 };
320
321 return ps;
322}
323
324
325/* end of json_pack.c */