aboutsummaryrefslogtreecommitdiff
path: root/src/json
diff options
context:
space:
mode:
authorChristian Grothoff <grothoff@gnunet.org>2021-07-26 16:32:34 +0200
committerChristian Grothoff <grothoff@gnunet.org>2021-07-26 16:32:34 +0200
commit90095d19b4da40e79dce43a31af398a8925bcc4a (patch)
treecd8b5eaf6073963fae7c428d4ce0797253e88fd5 /src/json
parent089fe579a913bda293d2c1579972a64657242660 (diff)
downloadgnunet-90095d19b4da40e79dce43a31af398a8925bcc4a.tar.gz
gnunet-90095d19b4da40e79dce43a31af398a8925bcc4a.zip
implement typed JSON packer
Diffstat (limited to 'src/json')
-rw-r--r--src/json/Makefile.am5
-rw-r--r--src/json/json.c34
-rw-r--r--src/json/json_pack.c291
3 files changed, 294 insertions, 36 deletions
diff --git a/src/json/Makefile.am b/src/json/Makefile.am
index d4ea38adf..3c19f96bf 100644
--- a/src/json/Makefile.am
+++ b/src/json/Makefile.am
@@ -16,9 +16,10 @@ libgnunetjson_la_LDFLAGS = \
16libgnunetjson_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS) 16libgnunetjson_la_CFLAGS = $(MHD_CFLAGS) $(AM_CFLAGS)
17libgnunetjson_la_SOURCES = \ 17libgnunetjson_la_SOURCES = \
18 json.c \ 18 json.c \
19 json_mhd.c \
20 json_generator.c \ 19 json_generator.c \
21 json_helper.c 20 json_helper.c \
21 json_mhd.c \
22 json_pack.c
22libgnunetjson_la_LIBADD = \ 23libgnunetjson_la_LIBADD = \
23 $(top_builddir)/src/util/libgnunetutil.la \ 24 $(top_builddir)/src/util/libgnunetutil.la \
24 -ljansson \ 25 -ljansson \
diff --git a/src/json/json.c b/src/json/json.c
index d55189804..4dabd4d22 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,12 +82,6 @@ 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{
@@ -151,15 +126,6 @@ set_json (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
151} 126}
152 127
153 128
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 129struct GNUNET_GETOPT_CommandLineOption
164GNUNET_JSON_getopt (char shortName, 130GNUNET_JSON_getopt (char shortName,
165 const char *name, 131 const char *name,
diff --git a/src/json/json_pack.c b/src/json/json_pack.c
new file mode 100644
index 000000000..88edaca5f
--- /dev/null
+++ b/src/json/json_pack.c
@@ -0,0 +1,291 @@
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 <= LONG_LONG_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 <= LONG_LONG_MAX);
131 GNUNET_assert (num >= LONG_LONG_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 GNUNET_assert (json_is_object (o));
152 return ps;
153}
154
155
156struct GNUNET_JSON_PackSpec
157GNUNET_JSON_pack_object_incref (const char *name,
158 json_t *o)
159{
160 struct GNUNET_JSON_PackSpec ps = {
161 .field_name = name,
162 .object = o
163 };
164
165 if (NULL == o)
166 return ps;
167 (void) json_incref (o);
168 GNUNET_assert (json_is_object (o));
169 return ps;
170}
171
172
173struct GNUNET_JSON_PackSpec
174GNUNET_JSON_pack_array_steal (const char *name,
175 json_t *a)
176{
177 struct GNUNET_JSON_PackSpec ps = {
178 .field_name = name,
179 .object = a
180 };
181
182 if (NULL == a)
183 return ps;
184 GNUNET_assert (json_is_array (a));
185 return ps;
186}
187
188
189struct GNUNET_JSON_PackSpec
190GNUNET_JSON_pack_array_incref (const char *name,
191 json_t *a)
192{
193 struct GNUNET_JSON_PackSpec ps = {
194 .field_name = name,
195 .object = a
196 };
197
198 if (NULL == a)
199 return ps;
200 (void) json_incref (a);
201 GNUNET_assert (json_is_array (a));
202 return ps;
203}
204
205
206struct GNUNET_JSON_PackSpec
207GNUNET_JSON_pack_data_varsize (const char *name,
208 const void *blob,
209 size_t blob_size)
210{
211 json_t *json;
212
213 json = GNUNET_JSON_from_data (blob,
214 blob_size);
215 GNUNET_assert (NULL != json);
216 return GNUNET_JSON_pack_object_steal (name,
217 json);
218}
219
220
221struct GNUNET_JSON_PackSpec
222GNUNET_JSON_pack_time_abs (const char *name,
223 struct GNUNET_TIME_Absolute at)
224{
225 json_t *json;
226
227 json = GNUNET_JSON_from_time_abs (at);
228 GNUNET_assert (NULL != json);
229 return GNUNET_JSON_pack_object_steal (name,
230 json);
231}
232
233
234struct GNUNET_JSON_PackSpec
235GNUNET_JSON_pack_time_abs_nbo (const char *name,
236 struct GNUNET_TIME_AbsoluteNBO at)
237{
238 return GNUNET_JSON_pack_time_abs (name,
239 GNUNET_TIME_absolute_ntoh (at));
240}
241
242
243struct GNUNET_JSON_PackSpec
244GNUNET_JSON_pack_time_rel (const char *name,
245 struct GNUNET_TIME_Relative rt)
246{
247 json_t *json;
248
249 json = GNUNET_JSON_from_time_rel (rt);
250 GNUNET_assert (NULL != json);
251 return GNUNET_JSON_pack_object_steal (name,
252 json);
253}
254
255
256struct GNUNET_JSON_PackSpec
257GNUNET_JSON_pack_time_rel_nbo (const char *name,
258 struct GNUNET_TIME_RelativeNBO rt)
259{
260 return GNUNET_JSON_pack_time_rel (name,
261 GNUNET_TIME_relative_ntoh (rt));
262}
263
264
265struct GNUNET_JSON_PackSpec
266GNUNET_JSON_pack_rsa_public_key (const char *name,
267 const struct GNUNET_CRYPTO_RsaPublicKey *pk)
268{
269 json_t *json;
270
271 json = GNUNET_JSON_from_rsa_public_key (pk);
272 GNUNET_assert (NULL != json);
273 return GNUNET_JSON_pack_object_steal (name,
274 json);
275}
276
277
278struct GNUNET_JSON_PackSpec
279GNUNET_JSON_pack_rsa_signature (const char *name,
280 const struct GNUNET_CRYPTO_RsaSignature *sig)
281{
282 json_t *json;
283
284 json = GNUNET_JSON_from_rsa_signature (sig);
285 GNUNET_assert (NULL != json);
286 return GNUNET_JSON_pack_object_steal (name,
287 json);
288}
289
290
291/* end of json_pack.c */