aboutsummaryrefslogtreecommitdiff
path: root/src/json/json_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/json/json_helper.c')
-rw-r--r--src/json/json_helper.c989
1 files changed, 0 insertions, 989 deletions
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
deleted file mode 100644
index a15dc74c0..000000000
--- a/src/json/json_helper.c
+++ /dev/null
@@ -1,989 +0,0 @@
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
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.
9
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.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17
18 SPDX-License-Identifier: AGPL3.0-or-later
19 */
20/**
21 * @file json/json_helper.c
22 * @brief functions to generate specifciations for JSON parsing
23 * @author Florian Dold
24 * @author Benedikt Mueller
25 * @author Christian Grothoff
26 */
27#include "platform.h"
28#include "gnunet_json_lib.h"
29
30
31struct GNUNET_JSON_Specification
32GNUNET_JSON_spec_end ()
33{
34 struct GNUNET_JSON_Specification ret = {
35 .parser = NULL,
36 .cleaner = NULL,
37 .cls = NULL
38 };
39
40 return ret;
41}
42
43
44/**
45 * Parse given JSON object to fixed size data
46 *
47 * @param cls closure, NULL
48 * @param root the json object representing data
49 * @param[out] spec where to write the data
50 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
51 */
52static enum GNUNET_GenericReturnValue
53parse_fixed_data (void *cls,
54 json_t *root,
55 struct GNUNET_JSON_Specification *spec)
56{
57 const char *enc;
58 unsigned int len;
59
60 if (NULL == (enc = json_string_value (root)))
61 {
62 GNUNET_break_op (0);
63 return GNUNET_SYSERR;
64 }
65 len = strlen (enc);
66 if (((len * 5) / 8) != spec->ptr_size)
67 {
68 GNUNET_break_op (0);
69 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
70 "Field `%s' has wrong length\n",
71 spec->field);
72 return GNUNET_SYSERR;
73 }
74 if (GNUNET_OK !=
75 GNUNET_STRINGS_string_to_data (enc,
76 len,
77 spec->ptr,
78 spec->ptr_size))
79 {
80 GNUNET_break_op (0);
81 return GNUNET_SYSERR;
82 }
83 return GNUNET_OK;
84}
85
86
87struct GNUNET_JSON_Specification
88GNUNET_JSON_spec_fixed (const char *name,
89 void *obj,
90 size_t size)
91{
92 struct GNUNET_JSON_Specification ret = {
93 .parser = &parse_fixed_data,
94 .cleaner = NULL,
95 .cls = NULL,
96 .field = name,
97 .ptr = obj,
98 .ptr_size = size,
99 .size_ptr = NULL
100 };
101
102 return ret;
103}
104
105
106/**
107 * Parse given JSON object to variable size data
108 *
109 * @param cls closure, NULL
110 * @param root the json object representing data
111 * @param[out] spec where to write the data
112 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
113 */
114static enum GNUNET_GenericReturnValue
115parse_variable_data (void *cls,
116 json_t *root,
117 struct GNUNET_JSON_Specification *spec)
118{
119 const char *str;
120 size_t size;
121 void *data;
122
123 str = json_string_value (root);
124 if (NULL == str)
125 {
126 GNUNET_break_op (0);
127 return GNUNET_SYSERR;
128 }
129 if (GNUNET_OK !=
130 GNUNET_STRINGS_string_to_data_alloc (str,
131 strlen (str),
132 &data,
133 &size))
134 {
135 GNUNET_break_op (0);
136 return GNUNET_SYSERR;
137 }
138 *(void **) spec->ptr = data;
139 *spec->size_ptr = size;
140 return GNUNET_OK;
141}
142
143
144/**
145 * Cleanup data left from parsing variable size data
146 *
147 * @param cls closure, NULL
148 * @param[out] spec where to free the data
149 */
150static void
151clean_variable_data (void *cls,
152 struct GNUNET_JSON_Specification *spec)
153{
154 (void) cls;
155 if (0 != *spec->size_ptr)
156 {
157 GNUNET_free (*(void **) spec->ptr);
158 *(void **) spec->ptr = NULL;
159 *spec->size_ptr = 0;
160 }
161}
162
163
164struct GNUNET_JSON_Specification
165GNUNET_JSON_spec_varsize (const char *name,
166 void **obj,
167 size_t *size)
168{
169 struct GNUNET_JSON_Specification ret = {
170 .parser = &parse_variable_data,
171 .cleaner = &clean_variable_data,
172 .cls = NULL,
173 .field = name,
174 .ptr = obj,
175 .ptr_size = 0,
176 .size_ptr = size
177 };
178
179 *obj = NULL;
180 *size = 0;
181 return ret;
182}
183
184
185/**
186 * Parse given JSON object to string.
187 *
188 * @param cls closure, NULL
189 * @param root the json object representing data
190 * @param[out] spec where to write the data
191 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
192 */
193static enum GNUNET_GenericReturnValue
194parse_string (void *cls,
195 json_t *root,
196 struct GNUNET_JSON_Specification *spec)
197{
198 const char *str;
199
200 (void) cls;
201 str = json_string_value (root);
202 if (NULL == str)
203 {
204 GNUNET_break_op (0);
205 return GNUNET_SYSERR;
206 }
207 *(const char **) spec->ptr = str;
208 return GNUNET_OK;
209}
210
211
212struct GNUNET_JSON_Specification
213GNUNET_JSON_spec_string (const char *name,
214 const char **strptr)
215{
216 struct GNUNET_JSON_Specification ret = {
217 .parser = &parse_string,
218 .cleaner = NULL,
219 .cls = NULL,
220 .field = name,
221 .ptr = strptr,
222 .ptr_size = 0,
223 .size_ptr = NULL
224 };
225
226 *strptr = NULL;
227 return ret;
228}
229
230
231/**
232 * Parse given JSON object to a JSON object. (Yes, trivial.)
233 *
234 * @param cls closure, NULL
235 * @param root the json object representing data
236 * @param[out] spec where to write the data
237 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
238 */
239static enum GNUNET_GenericReturnValue
240parse_object (void *cls,
241 json_t *root,
242 struct GNUNET_JSON_Specification *spec)
243{
244 if (! (json_is_object (root) || json_is_array (root)))
245 {
246 GNUNET_break_op (0);
247 return GNUNET_SYSERR;
248 }
249 json_incref (root);
250 *(json_t **) spec->ptr = root;
251 return GNUNET_OK;
252}
253
254
255/**
256 * Cleanup data left from parsing JSON object.
257 *
258 * @param cls closure, NULL
259 * @param[out] spec where to free the data
260 */
261static void
262clean_object (void *cls,
263 struct GNUNET_JSON_Specification *spec)
264{
265 json_t **ptr = (json_t **) spec->ptr;
266
267 if (NULL != *ptr)
268 {
269 json_decref (*ptr);
270 *ptr = NULL;
271 }
272}
273
274
275struct GNUNET_JSON_Specification
276GNUNET_JSON_spec_json (const char *name,
277 json_t **jsonp)
278{
279 struct GNUNET_JSON_Specification ret = {
280 .parser = &parse_object,
281 .cleaner = &clean_object,
282 .cls = NULL,
283 .field = name,
284 .ptr = jsonp,
285 .ptr_size = 0,
286 .size_ptr = NULL
287 };
288
289 *jsonp = NULL;
290 return ret;
291}
292
293
294/**
295 * Parse given JSON object to a bool.
296 *
297 * @param cls closure, NULL
298 * @param root the json object representing data
299 * @param[out] spec where to write the data
300 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
301 */
302static enum GNUNET_GenericReturnValue
303parse_bool (void *cls,
304 json_t *root,
305 struct GNUNET_JSON_Specification *spec)
306{
307 bool *b = spec->ptr;
308
309 if (json_true () == root)
310 {
311 *b = true;
312 return GNUNET_OK;
313 }
314 if (json_false () == root)
315 {
316 *b = false;
317 return GNUNET_OK;
318 }
319 GNUNET_break_op (0);
320 return GNUNET_SYSERR;
321}
322
323
324struct GNUNET_JSON_Specification
325GNUNET_JSON_spec_bool (const char *name,
326 bool *b)
327{
328 struct GNUNET_JSON_Specification ret = {
329 .parser = &parse_bool,
330 .cleaner = NULL,
331 .cls = NULL,
332 .field = name,
333 .ptr = b,
334 .ptr_size = sizeof(bool),
335 .size_ptr = NULL
336 };
337
338 return ret;
339}
340
341
342/**
343 * Parse given JSON object to a uint8_t.
344 *
345 * @param cls closure, NULL
346 * @param root the json object representing data
347 * @param[out] spec where to write the data
348 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
349 */
350static enum GNUNET_GenericReturnValue
351parse_u8 (void *cls,
352 json_t *root,
353 struct GNUNET_JSON_Specification *spec)
354{
355 json_int_t val;
356 uint8_t *up = spec->ptr;
357
358 if (! json_is_integer (root))
359 {
360 GNUNET_break_op (0);
361 return GNUNET_SYSERR;
362 }
363 val = json_integer_value (root);
364 if ((0 > val) || (val > UINT8_MAX))
365 {
366 GNUNET_break_op (0);
367 return GNUNET_SYSERR;
368 }
369 *up = (uint8_t) val;
370 return GNUNET_OK;
371}
372
373
374struct GNUNET_JSON_Specification
375GNUNET_JSON_spec_uint8 (const char *name,
376 uint8_t *u8)
377{
378 struct GNUNET_JSON_Specification ret = {
379 .parser = &parse_u8,
380 .cleaner = NULL,
381 .cls = NULL,
382 .field = name,
383 .ptr = u8,
384 .ptr_size = sizeof(uint8_t),
385 .size_ptr = NULL
386 };
387
388 return ret;
389}
390
391
392/**
393 * Parse given JSON object to a uint16_t.
394 *
395 * @param cls closure, NULL
396 * @param root the json object representing data
397 * @param[out] spec where to write the data
398 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
399 */
400static enum GNUNET_GenericReturnValue
401parse_u16 (void *cls,
402 json_t *root,
403 struct GNUNET_JSON_Specification *spec)
404{
405 json_int_t val;
406 uint16_t *up = spec->ptr;
407
408 if (! json_is_integer (root))
409 {
410 GNUNET_break_op (0);
411 return GNUNET_SYSERR;
412 }
413 val = json_integer_value (root);
414 if ((0 > val) || (val > UINT16_MAX))
415 {
416 GNUNET_break_op (0);
417 return GNUNET_SYSERR;
418 }
419 *up = (uint16_t) val;
420 return GNUNET_OK;
421}
422
423
424struct GNUNET_JSON_Specification
425GNUNET_JSON_spec_uint16 (const char *name,
426 uint16_t *u16)
427{
428 struct GNUNET_JSON_Specification ret = {
429 .parser = &parse_u16,
430 .cleaner = NULL,
431 .cls = NULL,
432 .field = name,
433 .ptr = u16,
434 .ptr_size = sizeof(uint16_t),
435 .size_ptr = NULL
436 };
437
438 return ret;
439}
440
441
442/**
443 * Parse given JSON object to a uint32_t.
444 *
445 * @param cls closure, NULL
446 * @param root the json object representing data
447 * @param[out] spec where to write the data
448 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
449 */
450static enum GNUNET_GenericReturnValue
451parse_u32 (void *cls,
452 json_t *root,
453 struct GNUNET_JSON_Specification *spec)
454{
455 json_int_t val;
456 uint32_t *up = spec->ptr;
457
458 if (! json_is_integer (root))
459 {
460 GNUNET_break_op (0);
461 return GNUNET_SYSERR;
462 }
463 val = json_integer_value (root);
464 if ((0 > val) || (val > UINT32_MAX))
465 {
466 GNUNET_break_op (0);
467 return GNUNET_SYSERR;
468 }
469 *up = (uint32_t) val;
470 return GNUNET_OK;
471}
472
473
474struct GNUNET_JSON_Specification
475GNUNET_JSON_spec_uint32 (const char *name,
476 uint32_t *u32)
477{
478 struct GNUNET_JSON_Specification ret = {
479 .parser = &parse_u32,
480 .cleaner = NULL,
481 .cls = NULL,
482 .field = name,
483 .ptr = u32,
484 .ptr_size = sizeof(uint32_t),
485 .size_ptr = NULL
486 };
487
488 return ret;
489}
490
491
492/**
493 * Parse given JSON object to a uint64_t.
494 *
495 * @param cls closure, NULL
496 * @param root the json object representing data
497 * @param[out] spec where to write the data
498 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
499 */
500static enum GNUNET_GenericReturnValue
501parse_u64 (void *cls,
502 json_t *root,
503 struct GNUNET_JSON_Specification *spec)
504{
505 json_int_t val;
506 uint64_t *up = spec->ptr;
507
508 if (! json_is_integer (root))
509 {
510 GNUNET_break_op (0);
511 return GNUNET_SYSERR;
512 }
513 val = json_integer_value (root);
514 *up = (uint64_t) val;
515 return GNUNET_OK;
516}
517
518
519struct GNUNET_JSON_Specification
520GNUNET_JSON_spec_uint64 (const char *name,
521 uint64_t *u64)
522{
523 struct GNUNET_JSON_Specification ret = {
524 .parser = &parse_u64,
525 .cleaner = NULL,
526 .cls = NULL,
527 .field = name,
528 .ptr = u64,
529 .ptr_size = sizeof(uint64_t),
530 .size_ptr = NULL
531 };
532
533 return ret;
534}
535
536
537/**
538 * Parse given JSON object to a int64_t.
539 *
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
544 */
545static enum GNUNET_GenericReturnValue
546parse_i64 (void *cls,
547 json_t *root,
548 struct GNUNET_JSON_Specification *spec)
549{
550 json_int_t val;
551 int64_t *up = spec->ptr;
552
553 if (! json_is_integer (root))
554 {
555 GNUNET_break_op (0);
556 return GNUNET_SYSERR;
557 }
558 val = json_integer_value (root);
559 *up = (int64_t) val;
560 return GNUNET_OK;
561}
562
563
564struct GNUNET_JSON_Specification
565GNUNET_JSON_spec_int64 (const char *name,
566 int64_t *i64)
567{
568 struct GNUNET_JSON_Specification ret = {
569 .parser = &parse_i64,
570 .cleaner = NULL,
571 .cls = NULL,
572 .field = name,
573 .ptr = i64,
574 .ptr_size = sizeof(int64_t),
575 .size_ptr = NULL
576 };
577
578 return ret;
579}
580
581
582/* ************ GNUnet-specific parser specifications ******************* */
583
584/**
585 * Parse given JSON object to a timestamp.
586 *
587 * @param cls closure, NULL
588 * @param root the json object representing data
589 * @param[out] spec where to write the data
590 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
591 */
592static enum GNUNET_GenericReturnValue
593parse_timestamp (void *cls,
594 json_t *root,
595 struct GNUNET_JSON_Specification *spec)
596{
597 struct GNUNET_TIME_Timestamp *ts = spec->ptr;
598 json_t *json_t_s;
599 unsigned long long int tval;
600
601 if (! json_is_object (root))
602 {
603 GNUNET_break_op (0);
604 return GNUNET_SYSERR;
605 }
606 json_t_s = json_object_get (root,
607 "t_s");
608 if (json_is_integer (json_t_s))
609 {
610 tval = json_integer_value (json_t_s);
611 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
612 ts->abs_time.abs_value_us
613 = tval * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
614 if (ts->abs_time.abs_value_us
615 / GNUNET_TIME_UNIT_SECONDS.rel_value_us
616 != tval)
617 {
618 /* Integer overflow */
619 GNUNET_break_op (0);
620 return GNUNET_SYSERR;
621 }
622 return GNUNET_OK;
623 }
624 if (json_is_string (json_t_s))
625 {
626 const char *val;
627
628 val = json_string_value (json_t_s);
629 if ((0 == strcasecmp (val,
630 "never")))
631 {
632 ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS;
633 return GNUNET_OK;
634 }
635 GNUNET_break_op (0);
636 return GNUNET_SYSERR;
637 }
638 GNUNET_break_op (0);
639 return GNUNET_SYSERR;
640}
641
642
643struct GNUNET_JSON_Specification
644GNUNET_JSON_spec_timestamp (const char *name,
645 struct GNUNET_TIME_Timestamp *t)
646{
647 struct GNUNET_JSON_Specification ret = {
648 .parser = &parse_timestamp,
649 .field = name,
650 .ptr = t,
651 .ptr_size = sizeof(struct GNUNET_TIME_Timestamp)
652 };
653
654 return ret;
655}
656
657
658/**
659 * Parse given JSON object to absolute time.
660 *
661 * @param cls closure, NULL
662 * @param root the json object representing data
663 * @param[out] spec where to write the data
664 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
665 */
666static enum GNUNET_GenericReturnValue
667parse_timestamp_nbo (void *cls,
668 json_t *root,
669 struct GNUNET_JSON_Specification *spec)
670{
671 struct GNUNET_TIME_TimestampNBO *ts = spec->ptr;
672 struct GNUNET_TIME_Timestamp a;
673 struct GNUNET_JSON_Specification ispec;
674
675 ispec = *spec;
676 ispec.parser = &parse_timestamp;
677 ispec.ptr = &a;
678 if (GNUNET_OK !=
679 parse_timestamp (NULL,
680 root,
681 &ispec))
682 return GNUNET_SYSERR;
683 *ts = GNUNET_TIME_timestamp_hton (a);
684 return GNUNET_OK;
685}
686
687
688struct GNUNET_JSON_Specification
689GNUNET_JSON_spec_timestamp_nbo (const char *name,
690 struct GNUNET_TIME_TimestampNBO *at)
691{
692 struct GNUNET_JSON_Specification ret = {
693 .parser = &parse_timestamp_nbo,
694 .field = name,
695 .ptr = at,
696 .ptr_size = sizeof(struct GNUNET_TIME_TimestampNBO)
697 };
698
699 return ret;
700}
701
702
703/**
704 * Parse given JSON object to relative time.
705 *
706 * @param cls closure, NULL
707 * @param root the json object representing data
708 * @param[out] spec where to write the data
709 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
710 */
711static enum GNUNET_GenericReturnValue
712parse_rel_time (void *cls,
713 json_t *root,
714 struct GNUNET_JSON_Specification *spec)
715{
716 struct GNUNET_TIME_Relative *rel = spec->ptr;
717 json_t *json_d_us;
718 unsigned long long int tval;
719
720 if (! json_is_object (root))
721 {
722 GNUNET_break_op (0);
723 return GNUNET_SYSERR;
724 }
725 json_d_us = json_object_get (root,
726 "d_us");
727 if (json_is_integer (json_d_us))
728 {
729 tval = json_integer_value (json_d_us);
730 if (tval >= (1LLU << 53))
731 {
732 /* value is larger than allowed */
733 GNUNET_break_op (0);
734 return GNUNET_SYSERR;
735 }
736 rel->rel_value_us = tval;
737 return GNUNET_OK;
738 }
739 if (json_is_string (json_d_us))
740 {
741 const char *val;
742
743 val = json_string_value (json_d_us);
744 if ((0 == strcasecmp (val,
745 "forever")))
746 {
747 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
748 return GNUNET_OK;
749 }
750 GNUNET_break_op (0);
751 return GNUNET_SYSERR;
752 }
753 GNUNET_break_op (0);
754 return GNUNET_SYSERR;
755}
756
757
758struct GNUNET_JSON_Specification
759GNUNET_JSON_spec_relative_time (const char *name,
760 struct GNUNET_TIME_Relative *rt)
761{
762 struct GNUNET_JSON_Specification ret = {
763 .parser = &parse_rel_time,
764 .field = name,
765 .ptr = rt,
766 .ptr_size = sizeof(struct GNUNET_TIME_Relative)
767 };
768
769 return ret;
770}
771
772
773/**
774 * Parse given JSON object to RSA public key.
775 *
776 * @param cls closure, NULL
777 * @param root the json object representing data
778 * @param[out] spec where to write the data
779 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
780 */
781static enum GNUNET_GenericReturnValue
782parse_rsa_public_key (void *cls,
783 json_t *root,
784 struct GNUNET_JSON_Specification *spec)
785{
786 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
787 const char *enc;
788 char *buf;
789 size_t len;
790 size_t buf_len;
791
792 if (NULL == (enc = json_string_value (root)))
793 {
794 GNUNET_break_op (0);
795 return GNUNET_SYSERR;
796 }
797 len = strlen (enc);
798 buf_len = (len * 5) / 8;
799 buf = GNUNET_malloc (buf_len);
800 if (GNUNET_OK !=
801 GNUNET_STRINGS_string_to_data (enc,
802 len,
803 buf,
804 buf_len))
805 {
806 GNUNET_break_op (0);
807 GNUNET_free (buf);
808 return GNUNET_SYSERR;
809 }
810 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
811 buf_len)))
812 {
813 GNUNET_break_op (0);
814 GNUNET_free (buf);
815 return GNUNET_SYSERR;
816 }
817 GNUNET_free (buf);
818 return GNUNET_OK;
819}
820
821
822/**
823 * Cleanup data left from parsing RSA public key.
824 *
825 * @param cls closure, NULL
826 * @param[out] spec where to free the data
827 */
828static void
829clean_rsa_public_key (void *cls,
830 struct GNUNET_JSON_Specification *spec)
831{
832 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
833
834 if (NULL != *pk)
835 {
836 GNUNET_CRYPTO_rsa_public_key_free (*pk);
837 *pk = NULL;
838 }
839}
840
841
842struct GNUNET_JSON_Specification
843GNUNET_JSON_spec_rsa_public_key (const char *name,
844 struct GNUNET_CRYPTO_RsaPublicKey **pk)
845{
846 struct GNUNET_JSON_Specification ret = {
847 .parser = &parse_rsa_public_key,
848 .cleaner = &clean_rsa_public_key,
849 .field = name,
850 .ptr = pk
851 };
852
853 *pk = NULL;
854 return ret;
855}
856
857
858/**
859 * Parse given JSON object to RSA signature.
860 *
861 * @param cls closure, NULL
862 * @param root the json object representing data
863 * @param[out] spec where to write the data
864 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
865 */
866static enum GNUNET_GenericReturnValue
867parse_rsa_signature (void *cls,
868 json_t *root,
869 struct GNUNET_JSON_Specification *spec)
870{
871 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
872 size_t size;
873 const char *str;
874 int res;
875 void *buf;
876
877 str = json_string_value (root);
878 if (NULL == str)
879 {
880 GNUNET_break_op (0);
881 return GNUNET_SYSERR;
882 }
883 size = (strlen (str) * 5) / 8;
884 buf = GNUNET_malloc (size);
885 res = GNUNET_STRINGS_string_to_data (str,
886 strlen (str),
887 buf,
888 size);
889 if (GNUNET_OK != res)
890 {
891 GNUNET_free (buf);
892 GNUNET_break_op (0);
893 return GNUNET_SYSERR;
894 }
895 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
896 size)))
897 {
898 GNUNET_break_op (0);
899 GNUNET_free (buf);
900 return GNUNET_SYSERR;
901 }
902 GNUNET_free (buf);
903 return GNUNET_OK;
904}
905
906
907/**
908 * Cleanup data left from parsing RSA signature.
909 *
910 * @param cls closure, NULL
911 * @param[out] spec where to free the data
912 */
913static void
914clean_rsa_signature (void *cls,
915 struct GNUNET_JSON_Specification *spec)
916{
917 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
918
919 if (NULL != *sig)
920 {
921 GNUNET_CRYPTO_rsa_signature_free (*sig);
922 *sig = NULL;
923 }
924}
925
926
927struct GNUNET_JSON_Specification
928GNUNET_JSON_spec_rsa_signature (const char *name,
929 struct GNUNET_CRYPTO_RsaSignature **sig)
930{
931 struct GNUNET_JSON_Specification ret = {
932 .parser = &parse_rsa_signature,
933 .cleaner = &clean_rsa_signature,
934 .cls = NULL,
935 .field = name,
936 .ptr = sig,
937 .ptr_size = 0,
938 .size_ptr = NULL
939 };
940
941 *sig = NULL;
942 return ret;
943}
944
945
946/**
947 * Parse given JSON object to an int as a boolean.
948 *
949 * @param cls closure, NULL
950 * @param root the json object representing data
951 * @param[out] spec where to write the data
952 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
953 */
954static enum GNUNET_GenericReturnValue
955parse_boolean (void *cls,
956 json_t *root,
957 struct GNUNET_JSON_Specification *spec)
958{
959 int *bp = spec->ptr;
960
961 if (! json_is_boolean (root))
962 {
963 GNUNET_break_op (0);
964 return GNUNET_SYSERR;
965 }
966 *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
967 return GNUNET_OK;
968}
969
970
971struct GNUNET_JSON_Specification
972GNUNET_JSON_spec_boolean (const char *name,
973 int *boolean)
974{
975 struct GNUNET_JSON_Specification ret = {
976 .parser = &parse_boolean,
977 .cleaner = NULL,
978 .cls = NULL,
979 .field = name,
980 .ptr = boolean,
981 .ptr_size = sizeof(int),
982 .size_ptr = NULL
983 };
984
985 return ret;
986}
987
988
989/* end of json_helper.c */