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 relative 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_rel_time (void *cls,
623 struct GNUNET_JSON_Specification *spec)
625 struct GNUNET_TIME_Relative *rel = spec->ptr;
627 unsigned long long int tval;
629 val = json_string_value (root);
633 return GNUNET_SYSERR;
635 if ( (0 == strcasecmp (val,
638 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
641 if (1 != sscanf (val,
646 return GNUNET_SYSERR;
648 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
649 rel->rel_value_us = tval * 1000LL * 1000LL;
650 if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
652 /* Integer overflow */
654 return GNUNET_SYSERR;
663 * @param name name of the JSON field
664 * @param[out] rt where to store the relative time found under @a name
666 struct GNUNET_JSON_Specification
667 GNUNET_JSON_spec_relative_time (const char *name,
668 struct GNUNET_TIME_Relative *rt)
670 struct GNUNET_JSON_Specification ret = {
671 .parser = &parse_rel_time,
676 .ptr_size = sizeof (uint64_t),
684 * Parse given JSON object to RSA public key.
686 * @param cls closure, NULL
687 * @param root the json object representing data
688 * @param[out] spec where to write the data
689 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
692 parse_rsa_public_key (void *cls,
694 struct GNUNET_JSON_Specification *spec)
696 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
702 if (NULL == (enc = json_string_value (root)))
705 return GNUNET_SYSERR;
708 buf_len = (len * 5) / 8;
709 buf = GNUNET_malloc (buf_len);
711 GNUNET_STRINGS_string_to_data (enc,
718 return GNUNET_SYSERR;
720 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
725 return GNUNET_SYSERR;
733 * Cleanup data left from parsing RSA public key.
735 * @param cls closure, NULL
736 * @param[out] spec where to free the data
739 clean_rsa_public_key (void *cls,
740 struct GNUNET_JSON_Specification *spec)
742 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
746 GNUNET_CRYPTO_rsa_public_key_free (*pk);
753 * Specification for parsing an RSA public key.
755 * @param name name of the JSON field
756 * @param pk where to store the RSA key found under @a name
758 struct GNUNET_JSON_Specification
759 GNUNET_JSON_spec_rsa_public_key (const char *name,
760 struct GNUNET_CRYPTO_RsaPublicKey **pk)
762 struct GNUNET_JSON_Specification ret = {
763 .parser = &parse_rsa_public_key,
764 .cleaner = &clean_rsa_public_key,
777 * Parse given JSON object to RSA signature.
779 * @param cls closure, NULL
780 * @param root the json object representing data
781 * @param[out] spec where to write the data
782 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
785 parse_rsa_signature (void *cls,
787 struct GNUNET_JSON_Specification *spec)
789 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
795 str = json_string_value (root);
799 return GNUNET_SYSERR;
801 size = (strlen (str) * 5) / 8;
802 buf = GNUNET_malloc (size);
803 res = GNUNET_STRINGS_string_to_data (str,
807 if (GNUNET_OK != res)
811 return GNUNET_SYSERR;
813 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
818 return GNUNET_SYSERR;
826 * Cleanup data left from parsing RSA signature.
828 * @param cls closure, NULL
829 * @param[out] spec where to free the data
832 clean_rsa_signature (void *cls,
833 struct GNUNET_JSON_Specification *spec)
835 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
839 GNUNET_CRYPTO_rsa_signature_free (*sig);
846 * Specification for parsing an RSA signature.
848 * @param name name of the JSON field
849 * @param sig where to store the RSA signature found under @a name
851 struct GNUNET_JSON_Specification
852 GNUNET_JSON_spec_rsa_signature (const char *name,
853 struct GNUNET_CRYPTO_RsaSignature **sig)
855 struct GNUNET_JSON_Specification ret = {
856 .parser = &parse_rsa_signature,
857 .cleaner = &clean_rsa_signature,
869 /* end of json_helper.c */