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.c1050
1 files changed, 0 insertions, 1050 deletions
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
deleted file mode 100644
index def26afb8..000000000
--- a/src/json/json_helper.c
+++ /dev/null
@@ -1,1050 +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 int
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 int
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 int
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 int
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 int
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 int
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 int
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 int
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 int
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 json_t *json_t_ms;
600 unsigned long long int tval;
601
602 if (! json_is_object (root))
603 {
604 GNUNET_break_op (0);
605 return GNUNET_SYSERR;
606 }
607 json_t_s = json_object_get (root,
608 "t_s");
609 if (json_is_integer (json_t_s))
610 {
611 tval = json_integer_value (json_t_s);
612 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
613 ts->abs_time.abs_value_us
614 = tval * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
615 if (ts->abs_time.abs_value_us
616 / GNUNET_TIME_UNIT_SECONDS.rel_value_us
617 != tval)
618 {
619 /* Integer overflow */
620 GNUNET_break_op (0);
621 return GNUNET_SYSERR;
622 }
623 return GNUNET_OK;
624 }
625 if (json_is_string (json_t_s))
626 {
627 const char *val;
628
629 val = json_string_value (json_t_s);
630 if ((0 == strcasecmp (val,
631 "never")))
632 {
633 ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS;
634 return GNUNET_OK;
635 }
636 GNUNET_break_op (0);
637 return GNUNET_SYSERR;
638 }
639 json_t_ms = json_object_get (root,
640 "t_ms");
641 if (json_is_integer (json_t_ms))
642 {
643 tval = json_integer_value (json_t_ms);
644 GNUNET_break_op (0 == tval % 1000);
645 tval -= tval % 1000;
646 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
647 ts->abs_time.abs_value_us
648 = tval * GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us;
649 if (ts->abs_time.abs_value_us
650 / GNUNET_TIME_UNIT_MILLISECONDS.rel_value_us
651 != tval)
652 {
653 /* Integer overflow */
654 GNUNET_break_op (0);
655 return GNUNET_SYSERR;
656 }
657 return GNUNET_OK;
658 }
659 if (json_is_string (json_t_ms))
660 {
661 const char *val;
662
663 val = json_string_value (json_t_ms);
664 if ((0 == strcasecmp (val,
665 "never")))
666 {
667 ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS;
668 return GNUNET_OK;
669 }
670 GNUNET_break_op (0);
671 return GNUNET_SYSERR;
672 }
673 GNUNET_break_op (0);
674 return GNUNET_SYSERR;
675}
676
677
678struct GNUNET_JSON_Specification
679GNUNET_JSON_spec_timestamp (const char *name,
680 struct GNUNET_TIME_Timestamp *t)
681{
682 struct GNUNET_JSON_Specification ret = {
683 .parser = &parse_timestamp,
684 .field = name,
685 .ptr = t,
686 .ptr_size = sizeof(struct GNUNET_TIME_Timestamp)
687 };
688
689 return ret;
690}
691
692
693/**
694 * Parse given JSON object to absolute time.
695 *
696 * @param cls closure, NULL
697 * @param root the json object representing data
698 * @param[out] spec where to write the data
699 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
700 */
701static enum GNUNET_GenericReturnValue
702parse_timestamp_nbo (void *cls,
703 json_t *root,
704 struct GNUNET_JSON_Specification *spec)
705{
706 struct GNUNET_TIME_TimestampNBO *ts = spec->ptr;
707 struct GNUNET_TIME_Timestamp a;
708 struct GNUNET_JSON_Specification ispec;
709
710 ispec = *spec;
711 ispec.parser = &parse_timestamp;
712 ispec.ptr = &a;
713 if (GNUNET_OK !=
714 parse_timestamp (NULL,
715 root,
716 &ispec))
717 return GNUNET_SYSERR;
718 *ts = GNUNET_TIME_timestamp_hton (a);
719 return GNUNET_OK;
720}
721
722
723struct GNUNET_JSON_Specification
724GNUNET_JSON_spec_timestamp_nbo (const char *name,
725 struct GNUNET_TIME_TimestampNBO *at)
726{
727 struct GNUNET_JSON_Specification ret = {
728 .parser = &parse_timestamp_nbo,
729 .field = name,
730 .ptr = at,
731 .ptr_size = sizeof(struct GNUNET_TIME_TimestampNBO)
732 };
733
734 return ret;
735}
736
737
738/**
739 * Parse given JSON object to relative time.
740 *
741 * @param cls closure, NULL
742 * @param root the json object representing data
743 * @param[out] spec where to write the data
744 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
745 */
746static enum GNUNET_GenericReturnValue
747parse_rel_time (void *cls,
748 json_t *root,
749 struct GNUNET_JSON_Specification *spec)
750{
751 struct GNUNET_TIME_Relative *rel = spec->ptr;
752 json_t *json_d_us;
753 json_t *json_d_ms;
754 unsigned long long int tval;
755
756 if (! json_is_object (root))
757 {
758 GNUNET_break_op (0);
759 return GNUNET_SYSERR;
760 }
761 json_d_us = json_object_get (root,
762 "d_us");
763 if (json_is_integer (json_d_us))
764 {
765 tval = json_integer_value (json_d_us);
766 if (tval >= (1LLU << 53))
767 {
768 /* value is larger than allowed */
769 GNUNET_break_op (0);
770 return GNUNET_SYSERR;
771 }
772 rel->rel_value_us = tval;
773 return GNUNET_OK;
774 }
775 if (json_is_string (json_d_us))
776 {
777 const char *val;
778
779 val = json_string_value (json_d_us);
780 if ((0 == strcasecmp (val,
781 "forever")))
782 {
783 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
784 return GNUNET_OK;
785 }
786 GNUNET_break_op (0);
787 return GNUNET_SYSERR;
788 }
789
790 json_d_ms = json_object_get (root,
791 "d_ms");
792 if (json_is_integer (json_d_ms))
793 {
794 tval = json_integer_value (json_d_ms);
795 *rel = GNUNET_TIME_relative_multiply (
796 GNUNET_TIME_UNIT_MILLISECONDS,
797 tval);
798 return GNUNET_OK;
799 }
800 if (json_is_string (json_d_ms))
801 {
802 const char *val;
803
804 val = json_string_value (json_d_ms);
805 if ((0 == strcasecmp (val,
806 "forever")))
807 {
808 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
809 return GNUNET_OK;
810 }
811 GNUNET_break_op (0);
812 return GNUNET_SYSERR;
813 }
814 GNUNET_break_op (0);
815 return GNUNET_SYSERR;
816}
817
818
819struct GNUNET_JSON_Specification
820GNUNET_JSON_spec_relative_time (const char *name,
821 struct GNUNET_TIME_Relative *rt)
822{
823 struct GNUNET_JSON_Specification ret = {
824 .parser = &parse_rel_time,
825 .field = name,
826 .ptr = rt,
827 .ptr_size = sizeof(struct GNUNET_TIME_Relative)
828 };
829
830 return ret;
831}
832
833
834/**
835 * Parse given JSON object to RSA public key.
836 *
837 * @param cls closure, NULL
838 * @param root the json object representing data
839 * @param[out] spec where to write the data
840 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
841 */
842static enum GNUNET_GenericReturnValue
843parse_rsa_public_key (void *cls,
844 json_t *root,
845 struct GNUNET_JSON_Specification *spec)
846{
847 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
848 const char *enc;
849 char *buf;
850 size_t len;
851 size_t buf_len;
852
853 if (NULL == (enc = json_string_value (root)))
854 {
855 GNUNET_break_op (0);
856 return GNUNET_SYSERR;
857 }
858 len = strlen (enc);
859 buf_len = (len * 5) / 8;
860 buf = GNUNET_malloc (buf_len);
861 if (GNUNET_OK !=
862 GNUNET_STRINGS_string_to_data (enc,
863 len,
864 buf,
865 buf_len))
866 {
867 GNUNET_break_op (0);
868 GNUNET_free (buf);
869 return GNUNET_SYSERR;
870 }
871 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
872 buf_len)))
873 {
874 GNUNET_break_op (0);
875 GNUNET_free (buf);
876 return GNUNET_SYSERR;
877 }
878 GNUNET_free (buf);
879 return GNUNET_OK;
880}
881
882
883/**
884 * Cleanup data left from parsing RSA public key.
885 *
886 * @param cls closure, NULL
887 * @param[out] spec where to free the data
888 */
889static void
890clean_rsa_public_key (void *cls,
891 struct GNUNET_JSON_Specification *spec)
892{
893 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
894
895 if (NULL != *pk)
896 {
897 GNUNET_CRYPTO_rsa_public_key_free (*pk);
898 *pk = NULL;
899 }
900}
901
902
903struct GNUNET_JSON_Specification
904GNUNET_JSON_spec_rsa_public_key (const char *name,
905 struct GNUNET_CRYPTO_RsaPublicKey **pk)
906{
907 struct GNUNET_JSON_Specification ret = {
908 .parser = &parse_rsa_public_key,
909 .cleaner = &clean_rsa_public_key,
910 .field = name,
911 .ptr = pk
912 };
913
914 *pk = NULL;
915 return ret;
916}
917
918
919/**
920 * Parse given JSON object to RSA signature.
921 *
922 * @param cls closure, NULL
923 * @param root the json object representing data
924 * @param[out] spec where to write the data
925 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
926 */
927static enum GNUNET_GenericReturnValue
928parse_rsa_signature (void *cls,
929 json_t *root,
930 struct GNUNET_JSON_Specification *spec)
931{
932 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
933 size_t size;
934 const char *str;
935 int res;
936 void *buf;
937
938 str = json_string_value (root);
939 if (NULL == str)
940 {
941 GNUNET_break_op (0);
942 return GNUNET_SYSERR;
943 }
944 size = (strlen (str) * 5) / 8;
945 buf = GNUNET_malloc (size);
946 res = GNUNET_STRINGS_string_to_data (str,
947 strlen (str),
948 buf,
949 size);
950 if (GNUNET_OK != res)
951 {
952 GNUNET_free (buf);
953 GNUNET_break_op (0);
954 return GNUNET_SYSERR;
955 }
956 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
957 size)))
958 {
959 GNUNET_break_op (0);
960 GNUNET_free (buf);
961 return GNUNET_SYSERR;
962 }
963 GNUNET_free (buf);
964 return GNUNET_OK;
965}
966
967
968/**
969 * Cleanup data left from parsing RSA signature.
970 *
971 * @param cls closure, NULL
972 * @param[out] spec where to free the data
973 */
974static void
975clean_rsa_signature (void *cls,
976 struct GNUNET_JSON_Specification *spec)
977{
978 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
979
980 if (NULL != *sig)
981 {
982 GNUNET_CRYPTO_rsa_signature_free (*sig);
983 *sig = NULL;
984 }
985}
986
987
988struct GNUNET_JSON_Specification
989GNUNET_JSON_spec_rsa_signature (const char *name,
990 struct GNUNET_CRYPTO_RsaSignature **sig)
991{
992 struct GNUNET_JSON_Specification ret = {
993 .parser = &parse_rsa_signature,
994 .cleaner = &clean_rsa_signature,
995 .cls = NULL,
996 .field = name,
997 .ptr = sig,
998 .ptr_size = 0,
999 .size_ptr = NULL
1000 };
1001
1002 *sig = NULL;
1003 return ret;
1004}
1005
1006
1007/**
1008 * Parse given JSON object to an int as a boolean.
1009 *
1010 * @param cls closure, NULL
1011 * @param root the json object representing data
1012 * @param[out] spec where to write the data
1013 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
1014 */
1015static enum GNUNET_GenericReturnValue
1016parse_boolean (void *cls,
1017 json_t *root,
1018 struct GNUNET_JSON_Specification *spec)
1019{
1020 int *bp = spec->ptr;
1021
1022 if (! json_is_boolean (root))
1023 {
1024 GNUNET_break_op (0);
1025 return GNUNET_SYSERR;
1026 }
1027 *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
1028 return GNUNET_OK;
1029}
1030
1031
1032struct GNUNET_JSON_Specification
1033GNUNET_JSON_spec_boolean (const char *name,
1034 int *boolean)
1035{
1036 struct GNUNET_JSON_Specification ret = {
1037 .parser = &parse_boolean,
1038 .cleaner = NULL,
1039 .cls = NULL,
1040 .field = name,
1041 .ptr = boolean,
1042 .ptr_size = sizeof(int),
1043 .size_ptr = NULL
1044 };
1045
1046 return ret;
1047}
1048
1049
1050/* end of json_helper.c */