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
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.
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.
16 * @file json/json_helper.c
17 * @brief functions to generate specifciations for JSON parsing
18 * @author Florian Dold
19 * @author Benedikt Mueller
20 * @author Christian Grothoff
23 #include "gnunet_json_lib.h"
27 * End of a parser specification.
29 struct GNUNET_JSON_Specification
30 GNUNET_JSON_spec_end ()
32 struct GNUNET_JSON_Specification ret = {
42 * Parse given JSON object to fixed size data
44 * @param cls closure, NULL
45 * @param root the json object representing data
46 * @param[out] spec where to write the data
47 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
50 parse_fixed_data (void *cls,
52 struct GNUNET_JSON_Specification *spec)
57 if (NULL == (enc = json_string_value (root)))
63 if (((len * 5) / 8) != spec->ptr_size)
69 GNUNET_STRINGS_string_to_data (enc,
82 * Variable size object (in network byte order, encoded using Crockford
83 * Base32hex encoding).
85 * @param name name of the JSON field
86 * @param[out] obj pointer where to write the data, must have @a size bytes
87 * @param size number of bytes expected in @a obj
89 struct GNUNET_JSON_Specification
90 GNUNET_JSON_spec_fixed (const char *name,
94 struct GNUNET_JSON_Specification ret = {
95 .parser = &parse_fixed_data,
108 * Parse given JSON object to variable size data
110 * @param cls closure, NULL
111 * @param root the json object representing data
112 * @param[out] spec where to write the data
113 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
116 parse_variable_data (void *cls,
118 struct GNUNET_JSON_Specification *spec)
125 str = json_string_value (root);
129 return GNUNET_SYSERR;
131 size = (strlen (str) * 5) / 8;
135 return GNUNET_SYSERR;
137 data = GNUNET_malloc (size);
138 res = GNUNET_STRINGS_string_to_data (str,
142 if (GNUNET_OK != res)
146 return GNUNET_SYSERR;
148 *(void**) spec->ptr = data;
149 *spec->size_ptr = size;
155 * Cleanup data left from parsing variable size data
157 * @param cls closure, NULL
158 * @param[out] spec where to free the data
161 clean_variable_data (void *cls,
162 struct GNUNET_JSON_Specification *spec)
164 if (0 != *spec->size_ptr)
166 GNUNET_free (*(void **) spec->ptr);
167 *(void**) spec->ptr = NULL;
174 * Variable size object (in network byte order, encoded using
175 * Crockford Base32hex encoding).
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
181 struct GNUNET_JSON_Specification
182 GNUNET_JSON_spec_varsize (const char *name,
186 struct GNUNET_JSON_Specification ret = {
187 .parser = &parse_variable_data,
188 .cleaner = &clean_variable_data,
202 * Parse given JSON object to string.
204 * @param cls closure, NULL
205 * @param root the json object representing data
206 * @param[out] spec where to write the data
207 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
210 parse_string (void *cls,
212 struct GNUNET_JSON_Specification *spec)
216 str = json_string_value (root);
220 return GNUNET_SYSERR;
222 *(const char **) spec->ptr = str;
228 * The expected field stores a string.
230 * @param name name of the JSON field
231 * @param strptr where to store a pointer to the field
233 struct GNUNET_JSON_Specification
234 GNUNET_JSON_spec_string (const char *name,
237 struct GNUNET_JSON_Specification ret = {
238 .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;
298 * @param name name of the JSON field
299 * @param[out] jsonp where to store the JSON found under @a name
301 struct GNUNET_JSON_Specification
302 GNUNET_JSON_spec_json (const char *name,
305 struct GNUNET_JSON_Specification ret = {
306 .parser = &parse_object,
307 .cleaner = &clean_object,
320 * Parse given JSON object to a uint8_t.
322 * @param cls closure, NULL
323 * @param root the json object representing data
324 * @param[out] spec where to write the data
325 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
330 struct GNUNET_JSON_Specification *spec)
333 uint8_t *up = spec->ptr;
335 if (! json_is_integer (root))
338 return GNUNET_SYSERR;
340 val = json_integer_value (root);
341 if ( (0 > val) || (val > UINT8_MAX) )
344 return GNUNET_SYSERR;
354 * @param name name of the JSON field
355 * @param[out] u8 where to store the integer found under @a name
357 struct GNUNET_JSON_Specification
358 GNUNET_JSON_spec_uint8 (const char *name,
361 struct GNUNET_JSON_Specification ret = {
367 .ptr_size = sizeof (uint8_t),
375 * Parse given JSON object to a uint16_t.
377 * @param cls closure, NULL
378 * @param root the json object representing data
379 * @param[out] spec where to write the data
380 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
383 parse_u16 (void *cls,
385 struct GNUNET_JSON_Specification *spec)
388 uint16_t *up = spec->ptr;
390 if (! json_is_integer (root))
393 return GNUNET_SYSERR;
395 val = json_integer_value (root);
396 if ( (0 > val) || (val > UINT16_MAX) )
399 return GNUNET_SYSERR;
401 *up = (uint16_t) val;
409 * @param name name of the JSON field
410 * @param[out] u16 where to store the integer found under @a name
412 struct GNUNET_JSON_Specification
413 GNUNET_JSON_spec_uint16 (const char *name,
416 struct GNUNET_JSON_Specification ret = {
417 .parser = &parse_u16,
422 .ptr_size = sizeof (uint16_t),
430 * Parse given JSON object to a uint32_t.
432 * @param cls closure, NULL
433 * @param root the json object representing data
434 * @param[out] spec where to write the data
435 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
438 parse_u32 (void *cls,
440 struct GNUNET_JSON_Specification *spec)
443 uint32_t *up = spec->ptr;
445 if (! json_is_integer (root))
448 return GNUNET_SYSERR;
450 val = json_integer_value (root);
451 if ( (0 > val) || (val > UINT32_MAX) )
454 return GNUNET_SYSERR;
456 *up = (uint32_t) val;
464 * @param name name of the JSON field
465 * @param[out] u32 where to store the integer found under @a name
467 struct GNUNET_JSON_Specification
468 GNUNET_JSON_spec_uint32 (const char *name,
471 struct GNUNET_JSON_Specification ret = {
472 .parser = &parse_u32,
477 .ptr_size = sizeof (uint32_t),
485 * Parse given JSON object to a uint8_t.
487 * @param cls closure, NULL
488 * @param root the json object representing data
489 * @param[out] spec where to write the data
490 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
493 parse_u64 (void *cls,
495 struct GNUNET_JSON_Specification *spec)
498 uint64_t *up = spec->ptr;
500 if (! json_is_integer (root))
503 return GNUNET_SYSERR;
505 val = json_integer_value (root);
506 *up = (uint64_t) val;
514 * @param name name of the JSON field
515 * @param[out] u64 where to store the integer found under @a name
517 struct GNUNET_JSON_Specification
518 GNUNET_JSON_spec_uint64 (const char *name,
521 struct GNUNET_JSON_Specification ret = {
522 .parser = &parse_u64,
527 .ptr_size = sizeof (uint64_t),
534 /* ************ GNUnet-specific parser specifications ******************* */
537 * Parse given JSON object to absolute time.
539 * @param cls closure, NULL
540 * @param root the json object representing data
541 * @param[out] spec where to write the data
542 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
545 parse_abs_time (void *cls,
547 struct GNUNET_JSON_Specification *spec)
549 struct GNUNET_TIME_Absolute *abs = spec->ptr;
551 unsigned long long int tval;
553 val = json_string_value (root);
557 return GNUNET_SYSERR;
559 if ( (0 == strcasecmp (val,
561 (0 == strcasecmp (val,
563 (0 == strcasecmp (val,
566 *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
569 if (1 != sscanf (val,
574 return GNUNET_SYSERR;
576 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
577 abs->abs_value_us = tval * 1000LL * 1000LL;
578 if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
580 /* Integer overflow */
582 return GNUNET_SYSERR;
591 * @param name name of the JSON field
592 * @param[out] at where to store the absolute time found under @a name
594 struct GNUNET_JSON_Specification
595 GNUNET_JSON_spec_absolute_time (const char *name,
596 struct GNUNET_TIME_Absolute *at)
598 struct GNUNET_JSON_Specification ret = {
599 .parser = &parse_abs_time,
604 .ptr_size = sizeof (uint64_t),
612 * Parse given JSON object to absolute time.
614 * @param cls closure, NULL
615 * @param root the json object representing data
616 * @param[out] spec where to write the data
617 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
620 parse_abs_time_nbo (void *cls,
622 struct GNUNET_JSON_Specification *spec)
624 struct GNUNET_TIME_AbsoluteNBO *abs = spec->ptr;
626 unsigned long long int tval;
627 struct GNUNET_TIME_Absolute a;
629 val = json_string_value (root);
633 return GNUNET_SYSERR;
635 if ( (0 == strcasecmp (val,
637 (0 == strcasecmp (val,
639 (0 == strcasecmp (val,
642 *abs = GNUNET_TIME_absolute_hton (GNUNET_TIME_UNIT_FOREVER_ABS);
645 if (1 != sscanf (val,
650 return GNUNET_SYSERR;
652 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
653 a.abs_value_us = tval * 1000LL * 1000LL;
654 if ( (a.abs_value_us) / 1000LL / 1000LL != tval)
656 /* Integer overflow */
658 return GNUNET_SYSERR;
660 *abs = GNUNET_TIME_absolute_hton (a);
666 * Absolute time in network byte order.
668 * @param name name of the JSON field
669 * @param[out] at where to store the absolute time found under @a name
671 struct GNUNET_JSON_Specification
672 GNUNET_JSON_spec_absolute_time_nbo (const char *name,
673 struct GNUNET_TIME_AbsoluteNBO *at)
675 struct GNUNET_JSON_Specification ret = {
676 .parser = &parse_abs_time_nbo,
681 .ptr_size = sizeof (uint64_t),
689 * Parse given JSON object to relative time.
691 * @param cls closure, NULL
692 * @param root the json object representing data
693 * @param[out] spec where to write the data
694 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
697 parse_rel_time (void *cls,
699 struct GNUNET_JSON_Specification *spec)
701 struct GNUNET_TIME_Relative *rel = spec->ptr;
703 unsigned long long int tval;
705 val = json_string_value (root);
709 return GNUNET_SYSERR;
711 if ( (0 == strcasecmp (val,
714 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
717 if (1 != sscanf (val,
722 return GNUNET_SYSERR;
724 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
725 rel->rel_value_us = tval * 1000LL * 1000LL;
726 if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
728 /* Integer overflow */
730 return GNUNET_SYSERR;
739 * @param name name of the JSON field
740 * @param[out] rt where to store the relative time found under @a name
742 struct GNUNET_JSON_Specification
743 GNUNET_JSON_spec_relative_time (const char *name,
744 struct GNUNET_TIME_Relative *rt)
746 struct GNUNET_JSON_Specification ret = {
747 .parser = &parse_rel_time,
752 .ptr_size = sizeof (uint64_t),
760 * Parse given JSON object to RSA public key.
762 * @param cls closure, NULL
763 * @param root the json object representing data
764 * @param[out] spec where to write the data
765 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
768 parse_rsa_public_key (void *cls,
770 struct GNUNET_JSON_Specification *spec)
772 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
778 if (NULL == (enc = json_string_value (root)))
781 return GNUNET_SYSERR;
784 buf_len = (len * 5) / 8;
785 buf = GNUNET_malloc (buf_len);
787 GNUNET_STRINGS_string_to_data (enc,
794 return GNUNET_SYSERR;
796 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
801 return GNUNET_SYSERR;
809 * Cleanup data left from parsing RSA public key.
811 * @param cls closure, NULL
812 * @param[out] spec where to free the data
815 clean_rsa_public_key (void *cls,
816 struct GNUNET_JSON_Specification *spec)
818 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
822 GNUNET_CRYPTO_rsa_public_key_free (*pk);
829 * Specification for parsing an RSA public key.
831 * @param name name of the JSON field
832 * @param pk where to store the RSA key found under @a name
834 struct GNUNET_JSON_Specification
835 GNUNET_JSON_spec_rsa_public_key (const char *name,
836 struct GNUNET_CRYPTO_RsaPublicKey **pk)
838 struct GNUNET_JSON_Specification ret = {
839 .parser = &parse_rsa_public_key,
840 .cleaner = &clean_rsa_public_key,
853 * Parse given JSON object to RSA signature.
855 * @param cls closure, NULL
856 * @param root the json object representing data
857 * @param[out] spec where to write the data
858 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
861 parse_rsa_signature (void *cls,
863 struct GNUNET_JSON_Specification *spec)
865 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
871 str = json_string_value (root);
875 return GNUNET_SYSERR;
877 size = (strlen (str) * 5) / 8;
878 buf = GNUNET_malloc (size);
879 res = GNUNET_STRINGS_string_to_data (str,
883 if (GNUNET_OK != res)
887 return GNUNET_SYSERR;
889 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
894 return GNUNET_SYSERR;
902 * Cleanup data left from parsing RSA signature.
904 * @param cls closure, NULL
905 * @param[out] spec where to free the data
908 clean_rsa_signature (void *cls,
909 struct GNUNET_JSON_Specification *spec)
911 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
915 GNUNET_CRYPTO_rsa_signature_free (*sig);
922 * Specification for parsing an RSA signature.
924 * @param name name of the JSON field
925 * @param sig where to store the RSA signature found under @a name
927 struct GNUNET_JSON_Specification
928 GNUNET_JSON_spec_rsa_signature (const char *name,
929 struct GNUNET_CRYPTO_RsaSignature **sig)
931 struct GNUNET_JSON_Specification ret = {
932 .parser = &parse_rsa_signature,
933 .cleaner = &clean_rsa_signature,
946 * Parse given JSON object to an int as a boolean.
948 * @param cls closure, NULL
949 * @param root the json object representing data
950 * @param[out] spec where to write the data
951 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
954 parse_boolean (void *cls,
956 struct GNUNET_JSON_Specification *spec)
960 if (! json_is_boolean (root))
963 return GNUNET_SYSERR;
965 *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
971 * Boolean (true mapped to GNUNET_YES, false mapped to GNUNET_NO).
973 * @param name name of the JSON field
974 * @param[out] boolean where to store the boolean found under @a name
976 struct GNUNET_JSON_Specification
977 GNUNET_JSON_spec_boolean (const char *name,
980 struct GNUNET_JSON_Specification ret = {
981 .parser = &parse_boolean,
986 .ptr_size = sizeof (int),
993 /* end of json_helper.c */