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