aboutsummaryrefslogtreecommitdiff
path: root/src/lib/json/json.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/json/json.c')
-rw-r--r--src/lib/json/json.c161
1 files changed, 161 insertions, 0 deletions
diff --git a/src/lib/json/json.c b/src/lib/json/json.c
new file mode 100644
index 000000000..07ec158be
--- /dev/null
+++ b/src/lib/json/json.c
@@ -0,0 +1,161 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014-2017, 2021, 2022 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.c
22 * @brief functions to parse JSON snippets
23 * @author Florian Dold
24 * @author Benedikt Mueller
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_json_lib.h"
29
30
31enum GNUNET_GenericReturnValue
32GNUNET_JSON_parse (const json_t *root,
33 struct GNUNET_JSON_Specification *spec,
34 const char **error_json_name,
35 unsigned int *error_line)
36{
37 if (NULL == root)
38 return GNUNET_SYSERR;
39 for (unsigned int i = 0; NULL != spec[i].parser; i++)
40 {
41 json_t *pos;
42
43 if (NULL == spec[i].field)
44 pos = (json_t *) root;
45 else
46 pos = json_object_get (root,
47 spec[i].field);
48 if ( ( (NULL == pos) ||
49 (json_is_null (pos) ) ) &&
50 (spec[i].is_optional) )
51 {
52 if (NULL != spec[i].missing)
53 *spec[i].missing = true;
54 continue;
55 }
56 if ( (NULL == pos) ||
57 (GNUNET_OK !=
58 spec[i].parser (spec[i].cls,
59 pos,
60 &spec[i])) )
61 {
62 if (NULL != error_json_name)
63 *error_json_name = spec[i].field;
64 else
65 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
66 "Parsing failed for field `%s:%u`\n",
67 spec[i].field,
68 i);
69 if (NULL != error_line)
70 *error_line = i;
71 GNUNET_JSON_parse_free (spec);
72 return GNUNET_SYSERR;
73 }
74 if (NULL != spec[i].missing)
75 *spec[i].missing = false;
76 }
77 return GNUNET_OK; /* all OK! */
78}
79
80
81struct GNUNET_JSON_Specification
82GNUNET_JSON_spec_mark_optional (struct GNUNET_JSON_Specification spec,
83 bool *missing)
84{
85 struct GNUNET_JSON_Specification ret = spec;
86
87 ret.is_optional = true;
88 ret.missing = missing;
89 return ret;
90}
91
92
93void
94GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec)
95{
96 for (unsigned int i = 0; NULL != spec[i].parser; i++)
97 if (NULL != spec[i].cleaner)
98 spec[i].cleaner (spec[i].cls,
99 &spec[i]);
100}
101
102
103/**
104 * Set an option with a JSON value from the command line.
105 * A pointer to this function should be passed as part of the
106 * 'struct GNUNET_GETOPT_CommandLineOption' array to initialize options
107 * of this type.
108 *
109 * @param ctx command line processing context
110 * @param scls additional closure (will point to the 'json_t *')
111 * @param option name of the option
112 * @param value actual value of the option as a string.
113 * @return #GNUNET_OK if parsing the value worked
114 */
115static enum GNUNET_GenericReturnValue
116set_json (struct GNUNET_GETOPT_CommandLineProcessorContext *ctx,
117 void *scls,
118 const char *option,
119 const char *value)
120{
121 json_t **json = scls;
122 json_error_t error;
123
124 *json = json_loads (value,
125 JSON_REJECT_DUPLICATES,
126 &error);
127 if (NULL == *json)
128 {
129 fprintf (stderr,
130 _ ("Failed to parse JSON in option `%s': %s (%s)\n"),
131 option,
132 error.text,
133 error.source);
134 return GNUNET_SYSERR;
135 }
136 return GNUNET_OK;
137}
138
139
140struct GNUNET_GETOPT_CommandLineOption
141GNUNET_JSON_getopt (char shortName,
142 const char *name,
143 const char *argumentHelp,
144 const char *description,
145 json_t **json)
146{
147 struct GNUNET_GETOPT_CommandLineOption clo = {
148 .shortName = shortName,
149 .name = name,
150 .argumentHelp = argumentHelp,
151 .description = description,
152 .require_argument = 1,
153 .processor = &set_json,
154 .scls = (void *) json
155 };
156
157 return clo;
158}
159
160
161/* end of json.c */