reduce loop counters to more practical levels
[oweals/gnunet.git] / src / include / gnunet_json_lib.h
1 /*
2   This file is part of GNUnet
3   Copyright (C) 2014, 2015, 2016 GNUnet e.V.
4
5   GNUnet is free software; you can redistribute it and/or modify it under the
6   terms of the GNU General Public License as published by the Free Software
7   Foundation; either version 3, or (at your option) any later version.
8
9   GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10   WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11   A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
12
13   You should have received a copy of the GNU General Public License along with
14   GNUnet; see the file COPYING.  If not, If not, see <http://www.gnu.org/licenses/>
15 */
16 /**
17  * @file gnunet_json_lib.h
18  * @brief functions to parse JSON objects into GNUnet objects
19  * @author Florian Dold
20  * @author Benedikt Mueller
21  * @author Christian Grothoff
22  */
23 #ifndef GNUNET_JSON_LIB_H
24 #define GNUNET_JSON_LIB_H
25
26 #include "gnunet_util_lib.h"
27 #include <jansson.h>
28
29
30 /* ****************** Generic parser interface ******************* */
31
32 /**
33  * @brief Entry in parser specification for #GNUNET_JSON_parse().
34  */
35 struct GNUNET_JSON_Specification;
36
37
38 /**
39  * Function called to parse JSON argument.
40  *
41  * @param cls closure
42  * @param root JSON to parse
43  * @param spec our specification entry with further details
44  * @return #GNUNET_SYSERR on error,
45  *         #GNUNET_OK on success
46  */
47 typedef int
48 (*GNUNET_JSON_Parser)(void *cls,
49                       json_t *root,
50                       struct GNUNET_JSON_Specification *spec);
51
52
53 /**
54  * Function called to clean up data from earlier parsing.
55  *
56  * @param cls closure
57  * @param spec our specification entry with data to clean.
58  */
59 typedef void
60 (*GNUNET_JSON_Cleaner)(void *cls,
61                        struct GNUNET_JSON_Specification *spec);
62
63
64 /**
65  * @brief Entry in parser specification for #GNUNET_JSON_parse().
66  */
67 struct GNUNET_JSON_Specification
68 {
69   /**
70    * Function for how to parse this type of entry.
71    */
72   GNUNET_JSON_Parser parser;
73
74   /**
75    * Function for how to clean up this type of entry.
76    */
77   GNUNET_JSON_Cleaner cleaner;
78
79   /**
80    * Closure for @e parser and @e cleaner.
81    */
82   void *cls;
83
84   /**
85    * Name of the field to parse, use NULL to get the JSON
86    * of the main object instead of the JSON of an individual field.
87    */
88   const char *field;
89
90   /**
91    * Pointer, details specific to the @e parser.
92    */
93   void *ptr;
94
95   /**
96    * Number of bytes available in @e ptr.
97    */
98   size_t ptr_size;
99
100   /**
101    * Where should we store the final size of @e ptr.
102    */
103   size_t *size_ptr;
104
105 };
106
107
108 /**
109  * Navigate and parse data in a JSON tree.  Tries to parse the @a root
110  * to find all of the values given in the @a spec.  If one of the
111  * entries in @a spec cannot be found or parsed, the name of the JSON
112  * field is returned in @a error_json_name, and the offset of the
113  * entry in @a spec is returned in @a error_line.
114  *
115  * @param root the JSON node to start the navigation at.
116  * @param spec parse specification array
117  * @param[out] error_json_name which JSON field was problematic
118  * @param[out] which index into @a spec did we encounter an error
119  * @return #GNUNET_OK on success, #GNUNET_SYSERR on error
120  */
121 int
122 GNUNET_JSON_parse (const json_t *root,
123                    struct GNUNET_JSON_Specification *spec,
124                    const char **error_json_name,
125                    unsigned int *error_line);
126
127
128 /**
129  * Frees all elements allocated during a #GNUNET_JSON_parse()
130  * operation.
131  *
132  * @param spec specification of the parse operation
133  */
134 void
135 GNUNET_JSON_parse_free (struct GNUNET_JSON_Specification *spec);
136
137
138
139 /* ****************** Canonical parser specifications ******************* */
140
141
142 /**
143  * End of a parser specification.
144  */
145 struct GNUNET_JSON_Specification
146 GNUNET_JSON_spec_end (void);
147
148
149 /**
150  * Variable size object (in network byte order, encoded using Crockford
151  * Base32hex encoding).
152  *
153  * @param name name of the JSON field
154  * @param[out] obj pointer where to write the data, must have @a size bytes
155  * @param size number of bytes expected in @a obj
156  */
157 struct GNUNET_JSON_Specification
158 GNUNET_JSON_spec_fixed (const char *name,
159                         void *obj,
160                         size_t size);
161
162
163 /**
164  * Fixed size object (in network byte order, encoded using Crockford
165  * Base32hex encoding).
166  *
167  * @param name name of the JSON field
168  * @param obj pointer where to write the data (type of `*obj` will determine size)
169  */
170 #define GNUNET_JSON_spec_fixed_auto(name,obj) GNUNET_JSON_spec_fixed (name, obj, sizeof (*obj))
171
172
173 /**
174  * Variable size object (in network byte order, encoded using
175  * Crockford Base32hex encoding).
176  *
177  * @param name name of the JSON field
178  * @param[out] obj pointer where to write the data, will be allocated
179  * @param[out] size where to store the number of bytes allocated for @a obj
180  */
181 struct GNUNET_JSON_Specification
182 GNUNET_JSON_spec_varsize (const char *name,
183                           void **obj,
184                           size_t *size);
185
186
187 /**
188  * The expected field stores a string.
189  *
190  * @param name name of the JSON field
191  * @param strptr where to store a pointer to the field
192  */
193 struct GNUNET_JSON_Specification
194 GNUNET_JSON_spec_string (const char *name,
195                          const char **strptr);
196
197 /**
198  * JSON object.
199  *
200  * @param name name of the JSON field
201  * @param[out] jsonp where to store the JSON found under @a name
202  */
203 struct GNUNET_JSON_Specification
204 GNUNET_JSON_spec_json (const char *name,
205                        json_t **jsonp);
206
207
208 /**
209  * 8-bit integer.
210  *
211  * @param name name of the JSON field
212  * @param[out] u8 where to store the integer found under @a name
213  */
214 struct GNUNET_JSON_Specification
215 GNUNET_JSON_spec_uint8 (const char *name,
216                         uint8_t *u8);
217
218
219 /**
220  * 16-bit integer.
221  *
222  * @param name name of the JSON field
223  * @param[out] u16 where to store the integer found under @a name
224  */
225 struct GNUNET_JSON_Specification
226 GNUNET_JSON_spec_uint16 (const char *name,
227                          uint16_t *u16);
228
229
230 /**
231  * 32-bit integer.
232  *
233  * @param name name of the JSON field
234  * @param[out] u32 where to store the integer found under @a name
235  */
236 struct GNUNET_JSON_Specification
237 GNUNET_JSON_spec_uint32 (const char *name,
238                          uint32_t *u32);
239
240
241 /**
242  * 64-bit integer.
243  *
244  * @param name name of the JSON field
245  * @param[out] u64 where to store the integer found under @a name
246  */
247 struct GNUNET_JSON_Specification
248 GNUNET_JSON_spec_uint64 (const char *name,
249                          uint64_t *u64);
250
251 /**
252  * Boolean (true mapped to GNUNET_YES, false mapped to GNUNET_NO).
253  *
254  * @param name name of the JSON field
255  * @param[out] boolean where to store the boolean found under @a name
256  */
257 struct GNUNET_JSON_Specification
258 GNUNET_JSON_spec_boolean (const char *name,
259                           int *boolean);
260
261
262 /* ************ GNUnet-specific parser specifications ******************* */
263
264 /**
265  * Absolute time.
266  *
267  * @param name name of the JSON field
268  * @param[out] at where to store the absolute time found under @a name
269  */
270 struct GNUNET_JSON_Specification
271 GNUNET_JSON_spec_absolute_time (const char *name,
272                                 struct GNUNET_TIME_Absolute *at);
273
274
275 /**
276  * Absolute time in network byte order.
277  *
278  * @param name name of the JSON field
279  * @param[out] at where to store the absolute time found under @a name
280  */
281 struct GNUNET_JSON_Specification
282 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
283                                     struct GNUNET_TIME_AbsoluteNBO *at);
284
285
286 /**
287  * Relative time.
288  *
289  * @param name name of the JSON field
290  * @param[out] rt where to store the relative time found under @a name
291  */
292 struct GNUNET_JSON_Specification
293 GNUNET_JSON_spec_relative_time (const char *name,
294                                 struct GNUNET_TIME_Relative *rt);
295
296
297 /**
298  * Specification for parsing an RSA public key.
299  *
300  * @param name name of the JSON field
301  * @param pk where to store the RSA key found under @a name
302  */
303 struct GNUNET_JSON_Specification
304 GNUNET_JSON_spec_rsa_public_key (const char *name,
305                                  struct GNUNET_CRYPTO_RsaPublicKey **pk);
306
307
308 /**
309  * Specification for parsing an RSA signature.
310  *
311  * @param name name of the JSON field
312  * @param sig where to store the RSA signature found under @a name
313  */
314 struct GNUNET_JSON_Specification
315 GNUNET_JSON_spec_rsa_signature (const char *name,
316                                 struct GNUNET_CRYPTO_RsaSignature **sig);
317
318
319 /* ****************** Generic generator interface ******************* */
320
321
322 /**
323  * Convert binary data to a JSON string with the base32crockford
324  * encoding.
325  *
326  * @param data binary data
327  * @param size size of @a data in bytes
328  * @return json string that encodes @a data
329  */
330 json_t *
331 GNUNET_JSON_from_data (const void *data,
332                        size_t size);
333
334
335 /**
336  * Convert binary data to a JSON string with the base32crockford
337  * encoding.
338  *
339  * @param ptr binary data, sizeof (*ptr) must yield correct size
340  * @return json string that encodes @a data
341  */
342 #define GNUNET_JSON_from_data_auto(ptr) GNUNET_JSON_from_data(ptr, sizeof (*ptr))
343
344
345 /**
346  * Convert absolute timestamp to a json string.
347  *
348  * @param stamp the time stamp
349  * @return a json string with the timestamp in @a stamp
350  */
351 json_t *
352 GNUNET_JSON_from_time_abs (struct GNUNET_TIME_Absolute stamp);
353
354
355 /**
356  * Convert absolute timestamp to a json string.
357  *
358  * @param stamp the time stamp
359  * @return a json string with the timestamp in @a stamp
360  */
361 json_t *
362 GNUNET_JSON_from_time_abs_nbo (struct GNUNET_TIME_AbsoluteNBO stamp);
363
364
365 /**
366  * Convert relative timestamp to a json string.
367  *
368  * @param stamp the time stamp
369  * @return a json string with the timestamp in @a stamp
370  */
371 json_t *
372 GNUNET_JSON_from_time_rel (struct GNUNET_TIME_Relative stamp);
373
374
375 /**
376  * Convert RSA public key to JSON.
377  *
378  * @param pk public key to convert
379  * @return corresponding JSON encoding
380  */
381 json_t *
382 GNUNET_JSON_from_rsa_public_key (const struct GNUNET_CRYPTO_RsaPublicKey *pk);
383
384
385 /**
386  * Convert RSA signature to JSON.
387  *
388  * @param sig signature to convert
389  * @return corresponding JSON encoding
390  */
391 json_t *
392 GNUNET_JSON_from_rsa_signature (const struct GNUNET_CRYPTO_RsaSignature *sig);
393
394
395 /* ******************* Helpers for MHD upload handling ******************* */
396
397 /**
398  * Return codes from #GNUNET_JSON_post_parser().
399  */
400 enum GNUNET_JSON_PostResult {
401   /**
402    * Parsing successful, JSON result is in `*json`.
403    */
404   GNUNET_JSON_PR_SUCCESS,
405
406   /**
407    * Parsing continues, call again soon!
408    */
409   GNUNET_JSON_PR_CONTINUE,
410
411   /**
412    * Sorry, memory allocation (malloc()) failed.
413    */
414   GNUNET_JSON_PR_OUT_OF_MEMORY,
415
416   /**
417    * Request size exceeded `buffer_max` argument.
418    */
419   GNUNET_JSON_PR_REQUEST_TOO_LARGE,
420
421   /**
422    * JSON parsing failed. This was not a JSON upload.
423    */
424   GNUNET_JSON_PR_JSON_INVALID
425 };
426
427
428 /**
429  * Process a POST request containing a JSON object.  This function
430  * realizes an MHD POST processor that will (incrementally) process
431  * JSON data uploaded to the HTTP server.  It will store the required
432  * state in the @a con_cls, which must be cleaned up using
433  * #GNUNET_JSON_post_parser_callback().
434  *
435  * @param buffer_max maximum allowed size for the buffer
436  * @param con_cls the closure (will point to a `struct Buffer *`)
437  * @param upload_data the POST data
438  * @param upload_data_size number of bytes in @a upload_data
439  * @param json the JSON object for a completed request
440  * @return result code indicating the status of the operation
441  */
442 enum GNUNET_JSON_PostResult
443 GNUNET_JSON_post_parser (size_t buffer_max,
444                          void **con_cls,
445                          const char *upload_data,
446                          size_t *upload_data_size,
447                          json_t **json);
448
449
450 /**
451  * Function called whenever we are done with a request
452  * to clean up our state.
453  *
454  * @param con_cls value as it was left by
455  *        #GNUNET_JSON_post_parser(), to be cleaned up
456  */
457 void
458 GNUNET_JSON_post_parser_cleanup (void *con_cls);
459
460
461 /* ****************** GETOPT JSON helper ******************* */
462
463
464 /**
465  * Allow user to specify a JSON input value.
466  *
467  * @param shortName short name of the option
468  * @param name long name of the option
469  * @param argumentHelp help text for the option argument
470  * @param description long help text for the option
471  * @param[out] val set to the JSON specified at the command line
472  */
473 struct GNUNET_GETOPT_CommandLineOption
474 GNUNET_JSON_getopt (char shortName,
475                     const char *name,
476                     const char *argumentHelp,
477                     const char *description,
478                     json_t **json);
479
480
481 #endif
482
483 /* end of gnunet_json_lib.h */