2 This file is part of GNUnet
3 Copyright (C) 2014, 2015, 2016 GNUnet e.V.
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.
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.
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/>
17 * @file json/json_helper.c
18 * @brief functions to generate specifciations for JSON parsing
19 * @author Florian Dold
20 * @author Benedikt Mueller
21 * @author Christian Grothoff
24 #include "gnunet_json_lib.h"
28 * End of a parser specification.
30 struct GNUNET_JSON_Specification
31 GNUNET_JSON_spec_end ()
33 struct GNUNET_JSON_Specification ret = {
43 * Parse given JSON object to fixed size data
45 * @param cls closure, NULL
46 * @param root the json object representing data
47 * @param[out] spec where to write the data
48 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
51 parse_fixed_data (void *cls,
53 struct GNUNET_JSON_Specification *spec)
58 if (NULL == (enc = json_string_value (root)))
64 if (((len * 5) / 8) != spec->ptr_size)
70 GNUNET_STRINGS_string_to_data (enc,
83 * Variable size object (in network byte order, encoded using Crockford
84 * Base32hex encoding).
86 * @param name name of the JSON field
87 * @param[out] obj pointer where to write the data, must have @a size bytes
88 * @param size number of bytes expected in @a obj
90 struct GNUNET_JSON_Specification
91 GNUNET_JSON_spec_fixed (const char *name,
95 struct GNUNET_JSON_Specification ret = {
96 .parser = &parse_fixed_data,
109 * Parse given JSON object to variable size data
111 * @param cls closure, NULL
112 * @param root the json object representing data
113 * @param[out] spec where to write the data
114 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
117 parse_variable_data (void *cls,
119 struct GNUNET_JSON_Specification *spec)
126 str = json_string_value (root);
130 return GNUNET_SYSERR;
132 size = (strlen (str) * 5) / 8;
136 return GNUNET_SYSERR;
138 data = GNUNET_malloc (size);
139 res = GNUNET_STRINGS_string_to_data (str,
143 if (GNUNET_OK != res)
147 return GNUNET_SYSERR;
149 *(void**) spec->ptr = data;
150 *spec->size_ptr = size;
156 * Cleanup data left from parsing variable size data
158 * @param cls closure, NULL
159 * @param[out] spec where to free the data
162 clean_variable_data (void *cls,
163 struct GNUNET_JSON_Specification *spec)
165 if (0 != *spec->size_ptr)
167 GNUNET_free (*(void **) spec->ptr);
168 *(void**) spec->ptr = NULL;
175 * Variable size object (in network byte order, encoded using
176 * Crockford Base32hex encoding).
178 * @param name name of the JSON field
179 * @param[out] obj pointer where to write the data, will be allocated
180 * @param[out] size where to store the number of bytes allocated for @a obj
182 struct GNUNET_JSON_Specification
183 GNUNET_JSON_spec_varsize (const char *name,
187 struct GNUNET_JSON_Specification ret = {
188 .parser = &parse_variable_data,
189 .cleaner = &clean_variable_data,
203 * Parse given JSON object to string.
205 * @param cls closure, NULL
206 * @param root the json object representing data
207 * @param[out] spec where to write the data
208 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
211 parse_string (void *cls,
213 struct GNUNET_JSON_Specification *spec)
217 str = json_string_value (root);
221 return GNUNET_SYSERR;
223 *(const char **) spec->ptr = str;
229 * The expected field stores a string.
231 * @param name name of the JSON field
232 * @param strptr where to store a pointer to the field
234 struct GNUNET_JSON_Specification
235 GNUNET_JSON_spec_string (const char *name,
238 struct GNUNET_JSON_Specification ret = {
239 .parser = &parse_string,
252 * Parse given JSON object to a JSON object. (Yes, trivial.)
254 * @param cls closure, NULL
255 * @param root the json object representing data
256 * @param[out] spec where to write the data
257 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
260 parse_object (void *cls,
262 struct GNUNET_JSON_Specification *spec)
264 if (! (json_is_object (root) || json_is_array (root)) )
267 return GNUNET_SYSERR;
270 *(json_t **) spec->ptr = root;
276 * Cleanup data left from parsing JSON object.
278 * @param cls closure, NULL
279 * @param[out] spec where to free the data
282 clean_object (void *cls,
283 struct GNUNET_JSON_Specification *spec)
285 json_t **ptr = (json_t **) spec->ptr;
297 * @param name name of the JSON field
298 * @param[out] jsonp where to store the JSON found under @a name
300 struct GNUNET_JSON_Specification
301 GNUNET_JSON_spec_json (const char *name,
304 struct GNUNET_JSON_Specification ret = {
305 .parser = &parse_object,
306 .cleaner = &clean_object,
318 * Parse given JSON object to a uint8_t.
320 * @param cls closure, NULL
321 * @param root the json object representing data
322 * @param[out] spec where to write the data
323 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
328 struct GNUNET_JSON_Specification *spec)
331 uint8_t *up = spec->ptr;
333 if (! json_is_integer (root))
336 return GNUNET_SYSERR;
338 val = json_integer_value (root);
339 if ( (0 > val) || (val > UINT8_MAX) )
342 return GNUNET_SYSERR;
352 * @param name name of the JSON field
353 * @param[out] u8 where to store the integer found under @a name
355 struct GNUNET_JSON_Specification
356 GNUNET_JSON_spec_uint8 (const char *name,
359 struct GNUNET_JSON_Specification ret = {
365 .ptr_size = sizeof (uint8_t),
373 * Parse given JSON object to a uint16_t.
375 * @param cls closure, NULL
376 * @param root the json object representing data
377 * @param[out] spec where to write the data
378 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
381 parse_u16 (void *cls,
383 struct GNUNET_JSON_Specification *spec)
386 uint16_t *up = spec->ptr;
388 if (! json_is_integer (root))
391 return GNUNET_SYSERR;
393 val = json_integer_value (root);
394 if ( (0 > val) || (val > UINT16_MAX) )
397 return GNUNET_SYSERR;
399 *up = (uint16_t) val;
407 * @param name name of the JSON field
408 * @param[out] u16 where to store the integer found under @a name
410 struct GNUNET_JSON_Specification
411 GNUNET_JSON_spec_uint16 (const char *name,
414 struct GNUNET_JSON_Specification ret = {
415 .parser = &parse_u16,
420 .ptr_size = sizeof (uint16_t),
428 * Parse given JSON object to a uint32_t.
430 * @param cls closure, NULL
431 * @param root the json object representing data
432 * @param[out] spec where to write the data
433 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
436 parse_u32 (void *cls,
438 struct GNUNET_JSON_Specification *spec)
441 uint32_t *up = spec->ptr;
443 if (! json_is_integer (root))
446 return GNUNET_SYSERR;
448 val = json_integer_value (root);
449 if ( (0 > val) || (val > UINT32_MAX) )
452 return GNUNET_SYSERR;
454 *up = (uint32_t) val;
462 * @param name name of the JSON field
463 * @param[out] u32 where to store the integer found under @a name
465 struct GNUNET_JSON_Specification
466 GNUNET_JSON_spec_uint32 (const char *name,
469 struct GNUNET_JSON_Specification ret = {
470 .parser = &parse_u32,
475 .ptr_size = sizeof (uint32_t),
483 * Parse given JSON object to a uint8_t.
485 * @param cls closure, NULL
486 * @param root the json object representing data
487 * @param[out] spec where to write the data
488 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
491 parse_u64 (void *cls,
493 struct GNUNET_JSON_Specification *spec)
496 uint64_t *up = spec->ptr;
498 if (! json_is_integer (root))
501 return GNUNET_SYSERR;
503 val = json_integer_value (root);
504 *up = (uint64_t) val;
512 * @param name name of the JSON field
513 * @param[out] u64 where to store the integer found under @a name
515 struct GNUNET_JSON_Specification
516 GNUNET_JSON_spec_uint64 (const char *name,
519 struct GNUNET_JSON_Specification ret = {
520 .parser = &parse_u64,
525 .ptr_size = sizeof (uint64_t),
532 /* ************ GNUnet-specific parser specifications ******************* */
535 * Parse given JSON object to absolute time.
537 * @param cls closure, NULL
538 * @param root the json object representing data
539 * @param[out] spec where to write the data
540 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
543 parse_abs_time (void *cls,
545 struct GNUNET_JSON_Specification *spec)
547 struct GNUNET_TIME_Absolute *abs = spec->ptr;
549 unsigned long long int tval;
551 val = json_string_value (root);
555 return GNUNET_SYSERR;
557 if ( (0 == strcasecmp (val,
559 (0 == strcasecmp (val,
561 (0 == strcasecmp (val,
564 *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
567 if (1 != sscanf (val,
572 return GNUNET_SYSERR;
574 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
575 abs->abs_value_us = tval * 1000LL * 1000LL;
576 if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
578 /* Integer overflow */
580 return GNUNET_SYSERR;
589 * @param name name of the JSON field
590 * @param[out] at where to store the absolute time found under @a name
592 struct GNUNET_JSON_Specification
593 GNUNET_JSON_spec_absolute_time (const char *name,
594 struct GNUNET_TIME_Absolute *at)
596 struct GNUNET_JSON_Specification ret = {
597 .parser = &parse_abs_time,
602 .ptr_size = sizeof (uint64_t),
610 * Parse given JSON object to relative time.
612 * @param cls closure, NULL
613 * @param root the json object representing data
614 * @param[out] spec where to write the data
615 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
618 parse_rel_time (void *cls,
620 struct GNUNET_JSON_Specification *spec)
622 struct GNUNET_TIME_Relative *rel = spec->ptr;
624 unsigned long long int tval;
626 val = json_string_value (root);
630 return GNUNET_SYSERR;
632 if ( (0 == strcasecmp (val,
635 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
638 if (1 != sscanf (val,
643 return GNUNET_SYSERR;
645 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
646 rel->rel_value_us = tval * 1000LL * 1000LL;
647 if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
649 /* Integer overflow */
651 return GNUNET_SYSERR;
660 * @param name name of the JSON field
661 * @param[out] rt where to store the relative time found under @a name
663 struct GNUNET_JSON_Specification
664 GNUNET_JSON_spec_relative_time (const char *name,
665 struct GNUNET_TIME_Relative *rt)
667 struct GNUNET_JSON_Specification ret = {
668 .parser = &parse_rel_time,
673 .ptr_size = sizeof (uint64_t),
681 * Parse given JSON object to RSA public key.
683 * @param cls closure, NULL
684 * @param root the json object representing data
685 * @param[out] spec where to write the data
686 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
689 parse_rsa_public_key (void *cls,
691 struct GNUNET_JSON_Specification *spec)
693 struct GNUNET_CRYPTO_rsa_PublicKey **pk = spec->ptr;
699 if (NULL == (enc = json_string_value (root)))
702 return GNUNET_SYSERR;
705 buf_len = (len * 5) / 8;
706 buf = GNUNET_malloc (buf_len);
708 GNUNET_STRINGS_string_to_data (enc,
715 return GNUNET_SYSERR;
717 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
722 return GNUNET_SYSERR;
730 * Cleanup data left from parsing RSA public key.
732 * @param cls closure, NULL
733 * @param[out] spec where to free the data
736 clean_rsa_public_key (void *cls,
737 struct GNUNET_JSON_Specification *spec)
739 struct GNUNET_CRYPTO_rsa_PublicKey **pk = spec->ptr;
743 GNUNET_CRYPTO_rsa_public_key_free (*pk);
750 * Specification for parsing an RSA public key.
752 * @param name name of the JSON field
753 * @param pk where to store the RSA key found under @a name
755 struct GNUNET_JSON_Specification
756 GNUNET_JSON_spec_rsa_public_key (const char *name,
757 struct GNUNET_CRYPTO_rsa_PublicKey **pk)
759 struct GNUNET_JSON_Specification ret = {
760 .parser = &parse_rsa_public_key,
761 .cleaner = &clean_rsa_public_key,
773 * Parse given JSON object to RSA signature.
775 * @param cls closure, NULL
776 * @param root the json object representing data
777 * @param[out] spec where to write the data
778 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
781 parse_rsa_signature (void *cls,
783 struct GNUNET_JSON_Specification *spec)
785 struct GNUNET_CRYPTO_rsa_Signature **sig = spec->ptr;
791 str = json_string_value (root);
795 return GNUNET_SYSERR;
797 size = (strlen (str) * 5) / 8;
798 buf = GNUNET_malloc (size);
799 res = GNUNET_STRINGS_string_to_data (str,
803 if (GNUNET_OK != res)
807 return GNUNET_SYSERR;
809 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
814 return GNUNET_SYSERR;
822 * Cleanup data left from parsing RSA signature.
824 * @param cls closure, NULL
825 * @param[out] spec where to free the data
828 clean_rsa_signature (void *cls,
829 struct GNUNET_JSON_Specification *spec)
831 struct GNUNET_CRYPTO_rsa_Signature **sig = spec->ptr;
835 GNUNET_CRYPTO_rsa_signature_free (*sig);
842 * Specification for parsing an RSA signature.
844 * @param name name of the JSON field
845 * @param sig where to store the RSA signature found under @a name
847 struct GNUNET_JSON_Specification
848 GNUNET_JSON_spec_rsa_signature (const char *name,
849 struct GNUNET_CRYPTO_rsa_Signature **sig)
851 struct GNUNET_JSON_Specification ret = {
852 .parser = &parse_rsa_signature,
853 .cleaner = &clean_rsa_signature,
864 /* end of json_helper.c */