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.c1139
1 files changed, 0 insertions, 1139 deletions
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
deleted file mode 100644
index 515cc4c7f..000000000
--- a/src/json/json_helper.c
+++ /dev/null
@@ -1,1139 +0,0 @@
1/*
2 This file is part of GNUnet
3 Copyright (C) 2014-2022 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 fixed 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_fixed64_data (void *cls,
116 json_t *root,
117 struct GNUNET_JSON_Specification *spec)
118{
119 const char *enc;
120 unsigned int len;
121 void *output;
122 size_t olen;
123
124 if (NULL == (enc = json_string_value (root)))
125 {
126 GNUNET_break_op (0);
127 return GNUNET_SYSERR;
128 }
129 len = strlen (enc);
130 output = NULL;
131 olen = GNUNET_STRINGS_base64_decode (enc,
132 len,
133 &output);
134 if (olen != spec->ptr_size)
135 {
136 GNUNET_break_op (0);
137 GNUNET_log (GNUNET_ERROR_TYPE_WARNING,
138 "Field `%s' has wrong length\n",
139 spec->field);
140 GNUNET_free (output);
141 return GNUNET_SYSERR;
142 }
143 memcpy (spec->ptr,
144 output,
145 olen);
146 GNUNET_free (output);
147 return GNUNET_OK;
148}
149
150
151struct GNUNET_JSON_Specification
152GNUNET_JSON_spec_fixed64 (const char *name,
153 void *obj,
154 size_t size)
155{
156 struct GNUNET_JSON_Specification ret = {
157 .parser = &parse_fixed64_data,
158 .cleaner = NULL,
159 .cls = NULL,
160 .field = name,
161 .ptr = obj,
162 .ptr_size = size,
163 .size_ptr = NULL
164 };
165
166 return ret;
167}
168
169
170/**
171 * Parse given JSON object to variable size data
172 *
173 * @param cls closure, NULL
174 * @param root the json object representing data
175 * @param[out] spec where to write the data
176 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
177 */
178static enum GNUNET_GenericReturnValue
179parse_variable_data (void *cls,
180 json_t *root,
181 struct GNUNET_JSON_Specification *spec)
182{
183 const char *str;
184 size_t size;
185 void *data;
186
187 str = json_string_value (root);
188 if (NULL == str)
189 {
190 GNUNET_break_op (0);
191 return GNUNET_SYSERR;
192 }
193 if (GNUNET_OK !=
194 GNUNET_STRINGS_string_to_data_alloc (str,
195 strlen (str),
196 &data,
197 &size))
198 {
199 GNUNET_break_op (0);
200 return GNUNET_SYSERR;
201 }
202 *(void **) spec->ptr = data;
203 *spec->size_ptr = size;
204 return GNUNET_OK;
205}
206
207
208/**
209 * Cleanup data left from parsing variable size data
210 *
211 * @param cls closure, NULL
212 * @param[out] spec where to free the data
213 */
214static void
215clean_variable_data (void *cls,
216 struct GNUNET_JSON_Specification *spec)
217{
218 (void) cls;
219 if (0 != *spec->size_ptr)
220 {
221 GNUNET_free (*(void **) spec->ptr);
222 *(void **) spec->ptr = NULL;
223 *spec->size_ptr = 0;
224 }
225}
226
227
228struct GNUNET_JSON_Specification
229GNUNET_JSON_spec_varsize (const char *name,
230 void **obj,
231 size_t *size)
232{
233 struct GNUNET_JSON_Specification ret = {
234 .parser = &parse_variable_data,
235 .cleaner = &clean_variable_data,
236 .cls = NULL,
237 .field = name,
238 .ptr = obj,
239 .ptr_size = 0,
240 .size_ptr = size
241 };
242
243 *obj = NULL;
244 *size = 0;
245 return ret;
246}
247
248
249/**
250 * Parse given JSON object to string.
251 *
252 * @param cls closure, NULL
253 * @param root the json object representing data
254 * @param[out] spec where to write the data
255 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
256 */
257static enum GNUNET_GenericReturnValue
258parse_string (void *cls,
259 json_t *root,
260 struct GNUNET_JSON_Specification *spec)
261{
262 const char *str;
263
264 (void) cls;
265 str = json_string_value (root);
266 if (NULL == str)
267 {
268 GNUNET_break_op (0);
269 return GNUNET_SYSERR;
270 }
271 *(const char **) spec->ptr = str;
272 return GNUNET_OK;
273}
274
275
276struct GNUNET_JSON_Specification
277GNUNET_JSON_spec_string (const char *name,
278 const char **strptr)
279{
280 struct GNUNET_JSON_Specification ret = {
281 .parser = &parse_string,
282 .cleaner = NULL,
283 .cls = NULL,
284 .field = name,
285 .ptr = strptr,
286 .ptr_size = 0,
287 .size_ptr = NULL
288 };
289
290 *strptr = NULL;
291 return ret;
292}
293
294
295/**
296 * Parse given JSON object to a JSON object. (Yes, trivial.)
297 *
298 * @param cls closure, NULL
299 * @param root the json object representing data
300 * @param[out] spec where to write the data
301 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
302 */
303static enum GNUNET_GenericReturnValue
304parse_json (void *cls,
305 json_t *root,
306 struct GNUNET_JSON_Specification *spec)
307{
308 if (! (json_is_object (root) || json_is_array (root)))
309 {
310 GNUNET_break_op (0);
311 return GNUNET_SYSERR;
312 }
313 json_incref (root);
314 *(json_t **) spec->ptr = root;
315 return GNUNET_OK;
316}
317
318
319/**
320 * Cleanup data left from parsing JSON object.
321 *
322 * @param cls closure, NULL
323 * @param[out] spec where to free the data
324 */
325static void
326clean_json (void *cls,
327 struct GNUNET_JSON_Specification *spec)
328{
329 json_t **ptr = (json_t **) spec->ptr;
330
331 if (NULL != *ptr)
332 {
333 json_decref (*ptr);
334 *ptr = NULL;
335 }
336}
337
338
339struct GNUNET_JSON_Specification
340GNUNET_JSON_spec_json (const char *name,
341 json_t **jsonp)
342{
343 struct GNUNET_JSON_Specification ret = {
344 .parser = &parse_json,
345 .cleaner = &clean_json,
346 .cls = NULL,
347 .field = name,
348 .ptr = jsonp,
349 .ptr_size = 0,
350 .size_ptr = NULL
351 };
352
353 *jsonp = NULL;
354 return ret;
355}
356
357
358/**
359 * Parse given JSON object to a JSON object.
360 *
361 * @param cls closure, NULL
362 * @param root the json object representing data
363 * @param[out] spec where to write the data
364 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
365 */
366static enum GNUNET_GenericReturnValue
367parse_object_const (void *cls,
368 json_t *root,
369 struct GNUNET_JSON_Specification *spec)
370{
371 if (NULL == root)
372 return GNUNET_OK;
373 if (! json_is_object (root))
374 {
375 GNUNET_break_op (0);
376 return GNUNET_SYSERR;
377 }
378 *(const json_t **) spec->ptr = (const json_t *) root;
379 return GNUNET_OK;
380}
381
382
383struct GNUNET_JSON_Specification
384GNUNET_JSON_spec_object_const (const char *name,
385 const json_t **jsonp)
386{
387 struct GNUNET_JSON_Specification ret = {
388 .parser = &parse_object_const,
389 .cls = NULL,
390 .field = name,
391 .ptr = jsonp,
392 .ptr_size = 0,
393 .size_ptr = NULL
394 };
395
396 *jsonp = NULL;
397 return ret;
398}
399
400
401/**
402 * Parse given JSON to a JSON array.
403 *
404 * @param cls closure, NULL
405 * @param root the json object representing data
406 * @param[out] spec where to write the data
407 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
408 */
409static enum GNUNET_GenericReturnValue
410parse_array_const (void *cls,
411 json_t *root,
412 struct GNUNET_JSON_Specification *spec)
413{
414 if (NULL == root)
415 return GNUNET_OK;
416 if (! json_is_array (root))
417 {
418 GNUNET_break_op (0);
419 return GNUNET_SYSERR;
420 }
421 *(const json_t **) spec->ptr = (const json_t *) root;
422 return GNUNET_OK;
423}
424
425
426struct GNUNET_JSON_Specification
427GNUNET_JSON_spec_array_const (const char *name,
428 const json_t **jsonp)
429{
430 struct GNUNET_JSON_Specification ret = {
431 .parser = &parse_array_const,
432 .cls = NULL,
433 .field = name,
434 .ptr = jsonp,
435 .ptr_size = 0,
436 .size_ptr = NULL
437 };
438
439 *jsonp = NULL;
440 return ret;
441}
442
443
444/**
445 * Parse given JSON object to a bool.
446 *
447 * @param cls closure, NULL
448 * @param root the json object representing data
449 * @param[out] spec where to write the data
450 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
451 */
452static enum GNUNET_GenericReturnValue
453parse_bool (void *cls,
454 json_t *root,
455 struct GNUNET_JSON_Specification *spec)
456{
457 bool *b = spec->ptr;
458
459 if (json_true () == root)
460 {
461 *b = true;
462 return GNUNET_OK;
463 }
464 if (json_false () == root)
465 {
466 *b = false;
467 return GNUNET_OK;
468 }
469 GNUNET_break_op (0);
470 return GNUNET_SYSERR;
471}
472
473
474struct GNUNET_JSON_Specification
475GNUNET_JSON_spec_bool (const char *name,
476 bool *b)
477{
478 struct GNUNET_JSON_Specification ret = {
479 .parser = &parse_bool,
480 .cleaner = NULL,
481 .cls = NULL,
482 .field = name,
483 .ptr = b,
484 .ptr_size = sizeof(bool),
485 .size_ptr = NULL
486 };
487
488 return ret;
489}
490
491
492/**
493 * Parse given JSON object to a uint8_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_u8 (void *cls,
502 json_t *root,
503 struct GNUNET_JSON_Specification *spec)
504{
505 json_int_t val;
506 uint8_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 if ((0 > val) || (val > UINT8_MAX))
515 {
516 GNUNET_break_op (0);
517 return GNUNET_SYSERR;
518 }
519 *up = (uint8_t) val;
520 return GNUNET_OK;
521}
522
523
524struct GNUNET_JSON_Specification
525GNUNET_JSON_spec_uint8 (const char *name,
526 uint8_t *u8)
527{
528 struct GNUNET_JSON_Specification ret = {
529 .parser = &parse_u8,
530 .cleaner = NULL,
531 .cls = NULL,
532 .field = name,
533 .ptr = u8,
534 .ptr_size = sizeof(uint8_t),
535 .size_ptr = NULL
536 };
537
538 return ret;
539}
540
541
542/**
543 * Parse given JSON object to a uint16_t.
544 *
545 * @param cls closure, NULL
546 * @param root the json object representing data
547 * @param[out] spec where to write the data
548 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
549 */
550static enum GNUNET_GenericReturnValue
551parse_u16 (void *cls,
552 json_t *root,
553 struct GNUNET_JSON_Specification *spec)
554{
555 json_int_t val;
556 uint16_t *up = spec->ptr;
557
558 if (! json_is_integer (root))
559 {
560 GNUNET_break_op (0);
561 return GNUNET_SYSERR;
562 }
563 val = json_integer_value (root);
564 if ((0 > val) || (val > UINT16_MAX))
565 {
566 GNUNET_break_op (0);
567 return GNUNET_SYSERR;
568 }
569 *up = (uint16_t) val;
570 return GNUNET_OK;
571}
572
573
574struct GNUNET_JSON_Specification
575GNUNET_JSON_spec_uint16 (const char *name,
576 uint16_t *u16)
577{
578 struct GNUNET_JSON_Specification ret = {
579 .parser = &parse_u16,
580 .cleaner = NULL,
581 .cls = NULL,
582 .field = name,
583 .ptr = u16,
584 .ptr_size = sizeof(uint16_t),
585 .size_ptr = NULL
586 };
587
588 return ret;
589}
590
591
592/**
593 * Parse given JSON object to a uint32_t.
594 *
595 * @param cls closure, NULL
596 * @param root the json object representing data
597 * @param[out] spec where to write the data
598 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
599 */
600static enum GNUNET_GenericReturnValue
601parse_u32 (void *cls,
602 json_t *root,
603 struct GNUNET_JSON_Specification *spec)
604{
605 json_int_t val;
606 uint32_t *up = spec->ptr;
607
608 if (! json_is_integer (root))
609 {
610 GNUNET_break_op (0);
611 return GNUNET_SYSERR;
612 }
613 val = json_integer_value (root);
614 if ((0 > val) || (val > UINT32_MAX))
615 {
616 GNUNET_break_op (0);
617 return GNUNET_SYSERR;
618 }
619 *up = (uint32_t) val;
620 return GNUNET_OK;
621}
622
623
624struct GNUNET_JSON_Specification
625GNUNET_JSON_spec_uint32 (const char *name,
626 uint32_t *u32)
627{
628 struct GNUNET_JSON_Specification ret = {
629 .parser = &parse_u32,
630 .cleaner = NULL,
631 .cls = NULL,
632 .field = name,
633 .ptr = u32,
634 .ptr_size = sizeof(uint32_t),
635 .size_ptr = NULL
636 };
637
638 return ret;
639}
640
641
642/**
643 * Parse given JSON object to a uint64_t.
644 *
645 * @param cls closure, NULL
646 * @param root the json object representing data
647 * @param[out] spec where to write the data
648 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
649 */
650static enum GNUNET_GenericReturnValue
651parse_u64 (void *cls,
652 json_t *root,
653 struct GNUNET_JSON_Specification *spec)
654{
655 json_int_t val;
656 uint64_t *up = spec->ptr;
657
658 if (! json_is_integer (root))
659 {
660 GNUNET_break_op (0);
661 return GNUNET_SYSERR;
662 }
663 val = json_integer_value (root);
664 *up = (uint64_t) val;
665 return GNUNET_OK;
666}
667
668
669struct GNUNET_JSON_Specification
670GNUNET_JSON_spec_uint64 (const char *name,
671 uint64_t *u64)
672{
673 struct GNUNET_JSON_Specification ret = {
674 .parser = &parse_u64,
675 .cleaner = NULL,
676 .cls = NULL,
677 .field = name,
678 .ptr = u64,
679 .ptr_size = sizeof(uint64_t),
680 .size_ptr = NULL
681 };
682
683 return ret;
684}
685
686
687/**
688 * Parse given JSON object to a int64_t.
689 *
690 * @param cls closure, NULL
691 * @param root the json object representing data
692 * @param[out] spec where to write the data
693 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
694 */
695static enum GNUNET_GenericReturnValue
696parse_i64 (void *cls,
697 json_t *root,
698 struct GNUNET_JSON_Specification *spec)
699{
700 json_int_t val;
701 int64_t *up = spec->ptr;
702
703 if (! json_is_integer (root))
704 {
705 GNUNET_break_op (0);
706 return GNUNET_SYSERR;
707 }
708 val = json_integer_value (root);
709 *up = (int64_t) val;
710 return GNUNET_OK;
711}
712
713
714struct GNUNET_JSON_Specification
715GNUNET_JSON_spec_int64 (const char *name,
716 int64_t *i64)
717{
718 struct GNUNET_JSON_Specification ret = {
719 .parser = &parse_i64,
720 .cleaner = NULL,
721 .cls = NULL,
722 .field = name,
723 .ptr = i64,
724 .ptr_size = sizeof(int64_t),
725 .size_ptr = NULL
726 };
727
728 return ret;
729}
730
731
732/* ************ GNUnet-specific parser specifications ******************* */
733
734/**
735 * Parse given JSON object to a timestamp.
736 *
737 * @param cls closure, NULL
738 * @param root the json object representing data
739 * @param[out] spec where to write the data
740 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
741 */
742static enum GNUNET_GenericReturnValue
743parse_timestamp (void *cls,
744 json_t *root,
745 struct GNUNET_JSON_Specification *spec)
746{
747 struct GNUNET_TIME_Timestamp *ts = spec->ptr;
748 json_t *json_t_s;
749 unsigned long long int tval;
750
751 if (! json_is_object (root))
752 {
753 GNUNET_break_op (0);
754 return GNUNET_SYSERR;
755 }
756 json_t_s = json_object_get (root,
757 "t_s");
758 if (json_is_integer (json_t_s))
759 {
760 tval = json_integer_value (json_t_s);
761 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
762 ts->abs_time.abs_value_us
763 = tval * GNUNET_TIME_UNIT_SECONDS.rel_value_us;
764 if (ts->abs_time.abs_value_us
765 / GNUNET_TIME_UNIT_SECONDS.rel_value_us
766 != tval)
767 {
768 /* Integer overflow */
769 GNUNET_break_op (0);
770 return GNUNET_SYSERR;
771 }
772 return GNUNET_OK;
773 }
774 if (json_is_string (json_t_s))
775 {
776 const char *val;
777
778 val = json_string_value (json_t_s);
779 if ((0 == strcasecmp (val,
780 "never")))
781 {
782 ts->abs_time = GNUNET_TIME_UNIT_FOREVER_ABS;
783 return GNUNET_OK;
784 }
785 GNUNET_break_op (0);
786 return GNUNET_SYSERR;
787 }
788 GNUNET_break_op (0);
789 return GNUNET_SYSERR;
790}
791
792
793struct GNUNET_JSON_Specification
794GNUNET_JSON_spec_timestamp (const char *name,
795 struct GNUNET_TIME_Timestamp *t)
796{
797 struct GNUNET_JSON_Specification ret = {
798 .parser = &parse_timestamp,
799 .field = name,
800 .ptr = t,
801 .ptr_size = sizeof(struct GNUNET_TIME_Timestamp)
802 };
803
804 return ret;
805}
806
807
808/**
809 * Parse given JSON object to absolute time.
810 *
811 * @param cls closure, NULL
812 * @param root the json object representing data
813 * @param[out] spec where to write the data
814 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
815 */
816static enum GNUNET_GenericReturnValue
817parse_timestamp_nbo (void *cls,
818 json_t *root,
819 struct GNUNET_JSON_Specification *spec)
820{
821 struct GNUNET_TIME_TimestampNBO *ts = spec->ptr;
822 struct GNUNET_TIME_Timestamp a;
823 struct GNUNET_JSON_Specification ispec;
824
825 ispec = *spec;
826 ispec.parser = &parse_timestamp;
827 ispec.ptr = &a;
828 if (GNUNET_OK !=
829 parse_timestamp (NULL,
830 root,
831 &ispec))
832 return GNUNET_SYSERR;
833 *ts = GNUNET_TIME_timestamp_hton (a);
834 return GNUNET_OK;
835}
836
837
838struct GNUNET_JSON_Specification
839GNUNET_JSON_spec_timestamp_nbo (const char *name,
840 struct GNUNET_TIME_TimestampNBO *at)
841{
842 struct GNUNET_JSON_Specification ret = {
843 .parser = &parse_timestamp_nbo,
844 .field = name,
845 .ptr = at,
846 .ptr_size = sizeof(struct GNUNET_TIME_TimestampNBO)
847 };
848
849 return ret;
850}
851
852
853/**
854 * Parse given JSON object to relative time.
855 *
856 * @param cls closure, NULL
857 * @param root the json object representing data
858 * @param[out] spec where to write the data
859 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
860 */
861static enum GNUNET_GenericReturnValue
862parse_rel_time (void *cls,
863 json_t *root,
864 struct GNUNET_JSON_Specification *spec)
865{
866 struct GNUNET_TIME_Relative *rel = spec->ptr;
867 json_t *json_d_us;
868 unsigned long long int tval;
869
870 if (! json_is_object (root))
871 {
872 GNUNET_break_op (0);
873 return GNUNET_SYSERR;
874 }
875 json_d_us = json_object_get (root,
876 "d_us");
877 if (json_is_integer (json_d_us))
878 {
879 tval = json_integer_value (json_d_us);
880 if (tval >= (1LLU << 53))
881 {
882 /* value is larger than allowed */
883 GNUNET_break_op (0);
884 return GNUNET_SYSERR;
885 }
886 rel->rel_value_us = tval;
887 return GNUNET_OK;
888 }
889 if (json_is_string (json_d_us))
890 {
891 const char *val;
892
893 val = json_string_value (json_d_us);
894 if ((0 == strcasecmp (val,
895 "forever")))
896 {
897 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
898 return GNUNET_OK;
899 }
900 GNUNET_break_op (0);
901 return GNUNET_SYSERR;
902 }
903 GNUNET_break_op (0);
904 return GNUNET_SYSERR;
905}
906
907
908struct GNUNET_JSON_Specification
909GNUNET_JSON_spec_relative_time (const char *name,
910 struct GNUNET_TIME_Relative *rt)
911{
912 struct GNUNET_JSON_Specification ret = {
913 .parser = &parse_rel_time,
914 .field = name,
915 .ptr = rt,
916 .ptr_size = sizeof(struct GNUNET_TIME_Relative)
917 };
918
919 return ret;
920}
921
922
923/**
924 * Parse given JSON object to RSA public key.
925 *
926 * @param cls closure, NULL
927 * @param root the json object representing data
928 * @param[out] spec where to write the data
929 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
930 */
931static enum GNUNET_GenericReturnValue
932parse_rsa_public_key (void *cls,
933 json_t *root,
934 struct GNUNET_JSON_Specification *spec)
935{
936 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
937 const char *enc;
938 char *buf;
939 size_t len;
940 size_t buf_len;
941
942 if (NULL == (enc = json_string_value (root)))
943 {
944 GNUNET_break_op (0);
945 return GNUNET_SYSERR;
946 }
947 len = strlen (enc);
948 buf_len = (len * 5) / 8;
949 buf = GNUNET_malloc (buf_len);
950 if (GNUNET_OK !=
951 GNUNET_STRINGS_string_to_data (enc,
952 len,
953 buf,
954 buf_len))
955 {
956 GNUNET_break_op (0);
957 GNUNET_free (buf);
958 return GNUNET_SYSERR;
959 }
960 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
961 buf_len)))
962 {
963 GNUNET_break_op (0);
964 GNUNET_free (buf);
965 return GNUNET_SYSERR;
966 }
967 GNUNET_free (buf);
968 return GNUNET_OK;
969}
970
971
972/**
973 * Cleanup data left from parsing RSA public key.
974 *
975 * @param cls closure, NULL
976 * @param[out] spec where to free the data
977 */
978static void
979clean_rsa_public_key (void *cls,
980 struct GNUNET_JSON_Specification *spec)
981{
982 struct GNUNET_CRYPTO_RsaPublicKey **pk = spec->ptr;
983
984 if (NULL != *pk)
985 {
986 GNUNET_CRYPTO_rsa_public_key_free (*pk);
987 *pk = NULL;
988 }
989}
990
991
992struct GNUNET_JSON_Specification
993GNUNET_JSON_spec_rsa_public_key (const char *name,
994 struct GNUNET_CRYPTO_RsaPublicKey **pk)
995{
996 struct GNUNET_JSON_Specification ret = {
997 .parser = &parse_rsa_public_key,
998 .cleaner = &clean_rsa_public_key,
999 .field = name,
1000 .ptr = pk
1001 };
1002
1003 *pk = NULL;
1004 return ret;
1005}
1006
1007
1008/**
1009 * Parse given JSON object to RSA signature.
1010 *
1011 * @param cls closure, NULL
1012 * @param root the json object representing data
1013 * @param[out] spec where to write the data
1014 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
1015 */
1016static enum GNUNET_GenericReturnValue
1017parse_rsa_signature (void *cls,
1018 json_t *root,
1019 struct GNUNET_JSON_Specification *spec)
1020{
1021 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
1022 size_t size;
1023 const char *str;
1024 int res;
1025 void *buf;
1026
1027 str = json_string_value (root);
1028 if (NULL == str)
1029 {
1030 GNUNET_break_op (0);
1031 return GNUNET_SYSERR;
1032 }
1033 size = (strlen (str) * 5) / 8;
1034 buf = GNUNET_malloc (size);
1035 res = GNUNET_STRINGS_string_to_data (str,
1036 strlen (str),
1037 buf,
1038 size);
1039 if (GNUNET_OK != res)
1040 {
1041 GNUNET_free (buf);
1042 GNUNET_break_op (0);
1043 return GNUNET_SYSERR;
1044 }
1045 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
1046 size)))
1047 {
1048 GNUNET_break_op (0);
1049 GNUNET_free (buf);
1050 return GNUNET_SYSERR;
1051 }
1052 GNUNET_free (buf);
1053 return GNUNET_OK;
1054}
1055
1056
1057/**
1058 * Cleanup data left from parsing RSA signature.
1059 *
1060 * @param cls closure, NULL
1061 * @param[out] spec where to free the data
1062 */
1063static void
1064clean_rsa_signature (void *cls,
1065 struct GNUNET_JSON_Specification *spec)
1066{
1067 struct GNUNET_CRYPTO_RsaSignature **sig = spec->ptr;
1068
1069 if (NULL != *sig)
1070 {
1071 GNUNET_CRYPTO_rsa_signature_free (*sig);
1072 *sig = NULL;
1073 }
1074}
1075
1076
1077struct GNUNET_JSON_Specification
1078GNUNET_JSON_spec_rsa_signature (const char *name,
1079 struct GNUNET_CRYPTO_RsaSignature **sig)
1080{
1081 struct GNUNET_JSON_Specification ret = {
1082 .parser = &parse_rsa_signature,
1083 .cleaner = &clean_rsa_signature,
1084 .cls = NULL,
1085 .field = name,
1086 .ptr = sig,
1087 .ptr_size = 0,
1088 .size_ptr = NULL
1089 };
1090
1091 *sig = NULL;
1092 return ret;
1093}
1094
1095
1096/**
1097 * Parse given JSON object to an int as a boolean.
1098 *
1099 * @param cls closure, NULL
1100 * @param root the json object representing data
1101 * @param[out] spec where to write the data
1102 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
1103 */
1104static enum GNUNET_GenericReturnValue
1105parse_boolean (void *cls,
1106 json_t *root,
1107 struct GNUNET_JSON_Specification *spec)
1108{
1109 int *bp = spec->ptr;
1110
1111 if (! json_is_boolean (root))
1112 {
1113 GNUNET_break_op (0);
1114 return GNUNET_SYSERR;
1115 }
1116 *bp = json_boolean_value (root) ? GNUNET_YES : GNUNET_NO;
1117 return GNUNET_OK;
1118}
1119
1120
1121struct GNUNET_JSON_Specification
1122GNUNET_JSON_spec_boolean (const char *name,
1123 int *boolean)
1124{
1125 struct GNUNET_JSON_Specification ret = {
1126 .parser = &parse_boolean,
1127 .cleaner = NULL,
1128 .cls = NULL,
1129 .field = name,
1130 .ptr = boolean,
1131 .ptr_size = sizeof(int),
1132 .size_ptr = NULL
1133 };
1134
1135 return ret;
1136}
1137
1138
1139/* end of json_helper.c */