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,
253 * Parse given JSON object to a JSON object. (Yes, trivial.)
255 * @param cls closure, NULL
256 * @param root the json object representing data
257 * @param[out] spec where to write the data
258 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
261 parse_object (void *cls,
263 struct GNUNET_JSON_Specification *spec)
265 if (! (json_is_object (root) || json_is_array (root)) )
268 return GNUNET_SYSERR;
271 *(json_t **) spec->ptr = root;
277 * Cleanup data left from parsing JSON object.
279 * @param cls closure, NULL
280 * @param[out] spec where to free the data
283 clean_object (void *cls,
284 struct GNUNET_JSON_Specification *spec)
286 json_t **ptr = (json_t **) spec->ptr;
299 * @param name name of the JSON field
300 * @param[out] jsonp where to store the JSON found under @a name
302 struct GNUNET_JSON_Specification
303 GNUNET_JSON_spec_json (const char *name,
306 struct GNUNET_JSON_Specification ret = {
307 .parser = &parse_object,
308 .cleaner = &clean_object,
321 * Parse given JSON object to a uint8_t.
323 * @param cls closure, NULL
324 * @param root the json object representing data
325 * @param[out] spec where to write the data
326 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
331 struct GNUNET_JSON_Specification *spec)
334 uint8_t *up = spec->ptr;
336 if (! json_is_integer (root))
339 return GNUNET_SYSERR;
341 val = json_integer_value (root);
342 if ( (0 > val) || (val > UINT8_MAX) )
345 return GNUNET_SYSERR;
355 * @param name name of the JSON field
356 * @param[out] u8 where to store the integer found under @a name
358 struct GNUNET_JSON_Specification
359 GNUNET_JSON_spec_uint8 (const char *name,
362 struct GNUNET_JSON_Specification ret = {
368 .ptr_size = sizeof (uint8_t),
376 * Parse given JSON object to a uint16_t.
378 * @param cls closure, NULL
379 * @param root the json object representing data
380 * @param[out] spec where to write the data
381 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
384 parse_u16 (void *cls,
386 struct GNUNET_JSON_Specification *spec)
389 uint16_t *up = spec->ptr;
391 if (! json_is_integer (root))
394 return GNUNET_SYSERR;
396 val = json_integer_value (root);
397 if ( (0 > val) || (val > UINT16_MAX) )
400 return GNUNET_SYSERR;
402 *up = (uint16_t) val;
410 * @param name name of the JSON field
411 * @param[out] u16 where to store the integer found under @a name
413 struct GNUNET_JSON_Specification
414 GNUNET_JSON_spec_uint16 (const char *name,
417 struct GNUNET_JSON_Specification ret = {
418 .parser = &parse_u16,
423 .ptr_size = sizeof (uint16_t),
431 * Parse given JSON object to a uint32_t.
433 * @param cls closure, NULL
434 * @param root the json object representing data
435 * @param[out] spec where to write the data
436 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
439 parse_u32 (void *cls,
441 struct GNUNET_JSON_Specification *spec)
444 uint32_t *up = spec->ptr;
446 if (! json_is_integer (root))
449 return GNUNET_SYSERR;
451 val = json_integer_value (root);
452 if ( (0 > val) || (val > UINT32_MAX) )
455 return GNUNET_SYSERR;
457 *up = (uint32_t) val;
465 * @param name name of the JSON field
466 * @param[out] u32 where to store the integer found under @a name
468 struct GNUNET_JSON_Specification
469 GNUNET_JSON_spec_uint32 (const char *name,
472 struct GNUNET_JSON_Specification ret = {
473 .parser = &parse_u32,
478 .ptr_size = sizeof (uint32_t),
486 * Parse given JSON object to a uint8_t.
488 * @param cls closure, NULL
489 * @param root the json object representing data
490 * @param[out] spec where to write the data
491 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
494 parse_u64 (void *cls,
496 struct GNUNET_JSON_Specification *spec)
499 uint64_t *up = spec->ptr;
501 if (! json_is_integer (root))
504 return GNUNET_SYSERR;
506 val = json_integer_value (root);
507 *up = (uint64_t) val;
515 * @param name name of the JSON field
516 * @param[out] u64 where to store the integer found under @a name
518 struct GNUNET_JSON_Specification
519 GNUNET_JSON_spec_uint64 (const char *name,
522 struct GNUNET_JSON_Specification ret = {
523 .parser = &parse_u64,
528 .ptr_size = sizeof (uint64_t),
535 /* ************ GNUnet-specific parser specifications ******************* */
538 * Parse given JSON object to absolute time.
540 * @param cls closure, NULL
541 * @param root the json object representing data
542 * @param[out] spec where to write the data
543 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
546 parse_abs_time (void *cls,
548 struct GNUNET_JSON_Specification *spec)
550 struct GNUNET_TIME_Absolute *abs = spec->ptr;
552 unsigned long long int tval;
554 val = json_string_value (root);
558 return GNUNET_SYSERR;
560 if ( (0 == strcasecmp (val,
562 (0 == strcasecmp (val,
564 (0 == strcasecmp (val,
567 *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
570 if (1 != sscanf (val,
575 return GNUNET_SYSERR;
577 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
578 abs->abs_value_us = tval * 1000LL * 1000LL;
579 if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
581 /* Integer overflow */
583 return GNUNET_SYSERR;
592 * @param name name of the JSON field
593 * @param[out] at where to store the absolute time found under @a name
595 struct GNUNET_JSON_Specification
596 GNUNET_JSON_spec_absolute_time (const char *name,
597 struct GNUNET_TIME_Absolute *at)
599 struct GNUNET_JSON_Specification ret = {
600 .parser = &parse_abs_time,
605 .ptr_size = sizeof (uint64_t),
613 * Parse given JSON object to absolute time.
615 * @param cls closure, NULL
616 * @param root the json object representing data
617 * @param[out] spec where to write the data
618 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
621 parse_abs_time_nbo (void *cls,
623 struct GNUNET_JSON_Specification *spec)
625 struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr;
627 unsigned long long int tval;
628 struct GNUNET_TIME_Absolute a;
630 val = json_string_value (root);
634 return GNUNET_SYSERR;
636 if ( (0 == strcasecmp (val,
638 (0 == strcasecmp (val,
640 (0 == strcasecmp (val,
643 *abs = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
646 if (1 != sscanf (val,
651 return GNUNET_SYSERR;
653 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
654 a.abs_value_us = tval * 1000LL * 1000LL;
655 if ( (a.abs_value_us) / 1000LL / 1000LL != tval)
657 /* Integer overflow */
659 return GNUNET_SYSERR;
661 *abs = GNUNET_TIME_absolute_hton (a);
667 * Absolute time in network byte order.
669 * @param name name of the JSON field
670 * @param[out] at where to store the absolute time found under @a name
672 struct GNUNET_JSON_Specification
673 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
674 struct GNUNET_TIME_AbsoluteNBO *at)
676 struct GNUNET_JSON_Specification ret = {
677 .parser = &parse_abs_time_nbo,
682 .ptr_size = sizeof (uint64_t),
690 * Parse given JSON object to relative time.
692 * @param cls closure, NULL
693 * @param root the json object representing data
694 * @param[out] spec where to write the data
695 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
698 parse_rel_time (void *cls,
700 struct GNUNET_JSON_Specification *spec)
702 struct GNUNET_TIME_Relative *rel = spec->ptr;
704 unsigned long long int tval;
706 val = json_string_value (root);
710 return GNUNET_SYSERR;
712 if ( (0 == strcasecmp (val,
715 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
718 if (1 != sscanf (val,
723 return GNUNET_SYSERR;
725 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
726 rel->rel_value_us = tval * 1000LL * 1000LL;
727 if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
729 /* Integer overflow */
731 return GNUNET_SYSERR;
740 * @param name name of the JSON field
741 * @param[out] rt where to store the relative time found under @a name
743 struct GNUNET_JSON_Specification
744 GNUNET_JSON_spec_relative_time (const char *name,
745 struct GNUNET_TIME_Relative *rt)
747 struct GNUNET_JSON_Specification ret = {
748 .parser = &parse_rel_time,
753 .ptr_size = sizeof (uint64_t),
761 * Parse given JSON object to RSA public key.
763 * @param cls closure, NULL
764 * @param root the json object representing data
765 * @param[out] spec where to write the data
766 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
769 parse_rsa_public_key (void *cls,
771 struct GNUNET_JSON_Specification *spec)
773 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
779 if (NULL == (enc = json_string_value (root)))
782 return GNUNET_SYSERR;
785 buf_len = (len * 5) / 8;
786 buf = GNUNET_malloc (buf_len);
788 GNUNET_STRINGS_string_to_data (enc,
795 return GNUNET_SYSERR;
797 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
802 return GNUNET_SYSERR;
810 * Cleanup data left from parsing RSA public key.
812 * @param cls closure, NULL
813 * @param[out] spec where to free the data
816 clean_rsa_public_key (void *cls,
817 struct GNUNET_JSON_Specification *spec)
819 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
823 GNUNET_CRYPTO_rsa_public_key_free (*pk);
830 * Specification for parsing an RSA public key.
832 * @param name name of the JSON field
833 * @param pk where to store the RSA key found under @a name
835 struct GNUNET_JSON_Specification
836 GNUNET_JSON_spec_rsa_public_key (const char *name,
837 struct GNUNET_CRYPTO_RsaPublicKey **pk)
839 struct GNUNET_JSON_Specification ret = {
840 .parser = &parse_rsa_public_key,
841 .cleaner = &clean_rsa_public_key,
854 * Parse given JSON object to RSA signature.
856 * @param cls closure, NULL
857 * @param root the json object representing data
858 * @param[out] spec where to write the data
859 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
862 parse_rsa_signature (void *cls,
864 struct GNUNET_JSON_Specification *spec)
866 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
872 str = json_string_value (root);
876 return GNUNET_SYSERR;
878 size = (strlen (str) * 5) / 8;
879 buf = GNUNET_malloc (size);
880 res = GNUNET_STRINGS_string_to_data (str,
884 if (GNUNET_OK != res)
888 return GNUNET_SYSERR;
890 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
895 return GNUNET_SYSERR;
903 * Cleanup data left from parsing RSA signature.
905 * @param cls closure, NULL
906 * @param[out] spec where to free the data
909 clean_rsa_signature (void *cls,
910 struct GNUNET_JSON_Specification *spec)
912 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
916 GNUNET_CRYPTO_rsa_signature_free (*sig);
923 * Specification for parsing an RSA signature.
925 * @param name name of the JSON field
926 * @param sig where to store the RSA signature found under @a name
928 struct GNUNET_JSON_Specification
929 GNUNET_JSON_spec_rsa_signature (const char *name,
930 struct GNUNET_CRYPTO_RsaSignature **sig)
932 struct GNUNET_JSON_Specification ret = {
933 .parser = &parse_rsa_signature,
934 .cleaner = &clean_rsa_signature,
946 /* end of json_helper.c */