aboutsummaryrefslogtreecommitdiff
path: root/src/json/json_helper.c
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2016-03-17 19:24:35 +0000
committerChristian Grothoff <christian@grothoff.org>2016-03-17 19:24:35 +0000
commita5361231e36224607d8c2c1376757c0b99f34f59 (patch)
treeee2ee9fa2c114c6b8e5850f9b31d2bbb54b8c5d2 /src/json/json_helper.c
parent23b982b51e8f1c152053154c0fce4cfc4cfcbf67 (diff)
downloadgnunet-a5361231e36224607d8c2c1376757c0b99f34f59.tar.gz
gnunet-a5361231e36224607d8c2c1376757c0b99f34f59.zip
adding library for basic JSON conversions
Diffstat (limited to 'src/json/json_helper.c')
-rw-r--r--src/json/json_helper.c864
1 files changed, 864 insertions, 0 deletions
diff --git a/src/json/json_helper.c b/src/json/json_helper.c
new file mode 100644
index 000000000..cf84ae997
--- /dev/null
+++ b/src/json/json_helper.c
@@ -0,0 +1,864 @@
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 under the
6 terms of the GNU General Public License as published by the Free Software
7 Foundation; either version 3, or (at your option) any later version.
8
9 GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY
10 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along with
14 GNUnet; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/>
15*/
16/**
17 * @file json/json_helper.c
18 * @brief functions to generate specifciations for JSON parsing
19 * @author Florian Dold
20 * @author Benedikt Mueller
21 * @author Christian Grothoff
22 */
23#include "platform.h"
24#include "gnunet_json_lib.h"
25
26
27/**
28 * End of a parser specification.
29 */
30struct GNUNET_JSON_Specification
31GNUNET_JSON_spec_end ()
32{
33 struct GNUNET_JSON_Specification ret = {
34 .parser = NULL,
35 .cleaner = NULL,
36 .cls = NULL
37 };
38 return ret;
39}
40
41
42/**
43 * Parse given JSON object to fixed size data
44 *
45 * @param cls closure, NULL
46 * @param root the json object representing data
47 * @param[out] spec where to write the data
48 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
49 */
50static int
51parse_fixed_data (void *cls,
52 json_t *root,
53 struct GNUNET_JSON_Specification *spec)
54{
55 const char *enc;
56 unsigned int len;
57
58 if (NULL == (enc = json_string_value (root)))
59 {
60 GNUNET_break_op (0);
61 return GNUNET_SYSERR;
62 }
63 len = strlen (enc);
64 if (((len * 5) / 8) != spec->ptr_size)
65 {
66 GNUNET_break_op (0);
67 return GNUNET_SYSERR;
68 }
69 if (GNUNET_OK !=
70 GNUNET_STRINGS_string_to_data (enc,
71 len,
72 spec->ptr,
73 spec->ptr_size))
74 {
75 GNUNET_break_op (0);
76 return GNUNET_SYSERR;
77 }
78 return GNUNET_OK;
79}
80
81
82/**
83 * Variable size object (in network byte order, encoded using Crockford
84 * Base32hex encoding).
85 *
86 * @param name name of the JSON field
87 * @param[out] obj pointer where to write the data, must have @a size bytes
88 * @param size number of bytes expected in @a obj
89 */
90struct GNUNET_JSON_Specification
91GNUNET_JSON_spec_fixed (const char *name,
92 void *obj,
93 size_t size)
94{
95 struct GNUNET_JSON_Specification ret = {
96 .parser = &parse_fixed_data,
97 .cleaner = NULL,
98 .cls = NULL,
99 .field = name,
100 .ptr = obj,
101 .ptr_size = size,
102 .size_ptr = NULL
103 };
104 return ret;
105}
106
107
108/**
109 * Parse given JSON object to variable size data
110 *
111 * @param cls closure, NULL
112 * @param root the json object representing data
113 * @param[out] spec where to write the data
114 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
115 */
116static int
117parse_variable_data (void *cls,
118 json_t *root,
119 struct GNUNET_JSON_Specification *spec)
120{
121 const char *str;
122 size_t size;
123 void *data;
124 int res;
125
126 str = json_string_value (root);
127 if (NULL == str)
128 {
129 GNUNET_break_op (0);
130 return GNUNET_SYSERR;
131 }
132 size = (strlen (str) * 5) / 8;
133 if (size >= 1024)
134 {
135 GNUNET_break_op (0);
136 return GNUNET_SYSERR;
137 }
138 data = GNUNET_malloc (size);
139 res = GNUNET_STRINGS_string_to_data (str,
140 strlen (str),
141 data,
142 size);
143 if (GNUNET_OK != res)
144 {
145 GNUNET_break_op (0);
146 GNUNET_free (data);
147 return GNUNET_SYSERR;
148 }
149 *(void**) spec->ptr = data;
150 *spec->size_ptr = size;
151 return GNUNET_OK;
152}
153
154
155/**
156 * Cleanup data left from parsing variable size data
157 *
158 * @param cls closure, NULL
159 * @param[out] spec where to free the data
160 */
161static void
162clean_variable_data (void *cls,
163 struct GNUNET_JSON_Specification *spec)
164{
165 if (0 != *spec->size_ptr)
166 {
167 GNUNET_free (*(void **) spec->ptr);
168 *(void**) spec->ptr = NULL;
169 *spec->size_ptr = 0;
170 }
171}
172
173
174/**
175 * Variable size object (in network byte order, encoded using
176 * Crockford Base32hex encoding).
177 *
178 * @param name name of the JSON field
179 * @param[out] obj pointer where to write the data, will be allocated
180 * @param[out] size where to store the number of bytes allocated for @a obj
181 */
182struct GNUNET_JSON_Specification
183GNUNET_JSON_spec_varsize (const char *name,
184 void **obj,
185 size_t *size)
186{
187 struct GNUNET_JSON_Specification ret = {
188 .parser = &parse_variable_data,
189 .cleaner = &clean_variable_data,
190 .cls = NULL,
191 .field = name,
192 .ptr = obj,
193 .ptr_size = 0,
194 .size_ptr = size
195 };
196 *obj = NULL;
197 *size = 0;
198 return ret;
199}
200
201
202/**
203 * Parse given JSON object to string.
204 *
205 * @param cls closure, NULL
206 * @param root the json object representing data
207 * @param[out] spec where to write the data
208 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
209 */
210static int
211parse_string (void *cls,
212 json_t *root,
213 struct GNUNET_JSON_Specification *spec)
214{
215 const char *str;
216
217 str = json_string_value (root);
218 if (NULL == str)
219 {
220 GNUNET_break_op (0);
221 return GNUNET_SYSERR;
222 }
223 *(const char **) spec->ptr = str;
224 return GNUNET_OK;
225}
226
227
228/**
229 * The expected field stores a string.
230 *
231 * @param name name of the JSON field
232 * @param strptr where to store a pointer to the field
233 */
234struct GNUNET_JSON_Specification
235GNUNET_JSON_spec_string (const char *name,
236 const char **strptr)
237{
238 struct GNUNET_JSON_Specification ret = {
239 .parser = &parse_string,
240 .cleaner = NULL,
241 .cls = NULL,
242 .field = name,
243 .ptr = strptr,
244 .ptr_size = 0,
245 .size_ptr = NULL
246 };
247 return ret;
248}
249
250
251/**
252 * Parse given JSON object to a JSON object. (Yes, trivial.)
253 *
254 * @param cls closure, NULL
255 * @param root the json object representing data
256 * @param[out] spec where to write the data
257 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
258 */
259static int
260parse_object (void *cls,
261 json_t *root,
262 struct GNUNET_JSON_Specification *spec)
263{
264 if (! (json_is_object (root) || json_is_array (root)) )
265 {
266 GNUNET_break_op (0);
267 return GNUNET_SYSERR;
268 }
269 json_incref (root);
270 *(json_t **) spec->ptr = root;
271 return GNUNET_OK;
272}
273
274
275/**
276 * Cleanup data left from parsing JSON object.
277 *
278 * @param cls closure, NULL
279 * @param[out] spec where to free the data
280 */
281static void
282clean_object (void *cls,
283 struct GNUNET_JSON_Specification *spec)
284{
285 json_t **ptr = (json_t **) spec->ptr;
286 if (NULL != *ptr)
287 {
288 json_decref (*ptr);
289 *ptr = NULL;
290 }
291}
292
293
294/**
295 * JSON object.
296 *
297 * @param name name of the JSON field
298 * @param[out] jsonp where to store the JSON found under @a name
299 */
300struct GNUNET_JSON_Specification
301GNUNET_JSON_spec_json (const char *name,
302 json_t **jsonp)
303{
304 struct GNUNET_JSON_Specification ret = {
305 .parser = &parse_object,
306 .cleaner = &clean_object,
307 .cls = NULL,
308 .field = name,
309 .ptr = jsonp,
310 .ptr_size = 0,
311 .size_ptr = NULL
312 };
313 return ret;
314}
315
316
317/**
318 * Parse given JSON object to a uint8_t.
319 *
320 * @param cls closure, NULL
321 * @param root the json object representing data
322 * @param[out] spec where to write the data
323 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
324 */
325static int
326parse_u8 (void *cls,
327 json_t *root,
328 struct GNUNET_JSON_Specification *spec)
329{
330 json_int_t val;
331 uint8_t *up = spec->ptr;
332
333 if (! json_is_integer (root))
334 {
335 GNUNET_break_op (0);
336 return GNUNET_SYSERR;
337 }
338 val = json_integer_value (root);
339 if ( (0 > val) || (val > UINT8_MAX) )
340 {
341 GNUNET_break_op (0);
342 return GNUNET_SYSERR;
343 }
344 *up = (uint8_t) val;
345 return GNUNET_OK;
346}
347
348
349/**
350 * 8-bit integer.
351 *
352 * @param name name of the JSON field
353 * @param[out] u8 where to store the integer found under @a name
354 */
355struct GNUNET_JSON_Specification
356GNUNET_JSON_spec_uint8 (const char *name,
357 uint8_t *u8)
358{
359 struct GNUNET_JSON_Specification ret = {
360 .parser = &parse_u8,
361 .cleaner = NULL,
362 .cls = NULL,
363 .field = name,
364 .ptr = u8,
365 .ptr_size = sizeof (uint8_t),
366 .size_ptr = NULL
367 };
368 return ret;
369}
370
371
372/**
373 * Parse given JSON object to a uint16_t.
374 *
375 * @param cls closure, NULL
376 * @param root the json object representing data
377 * @param[out] spec where to write the data
378 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
379 */
380static int
381parse_u16 (void *cls,
382 json_t *root,
383 struct GNUNET_JSON_Specification *spec)
384{
385 json_int_t val;
386 uint16_t *up = spec->ptr;
387
388 if (! json_is_integer (root))
389 {
390 GNUNET_break_op (0);
391 return GNUNET_SYSERR;
392 }
393 val = json_integer_value (root);
394 if ( (0 > val) || (val > UINT16_MAX) )
395 {
396 GNUNET_break_op (0);
397 return GNUNET_SYSERR;
398 }
399 *up = (uint16_t) val;
400 return GNUNET_OK;
401}
402
403
404/**
405 * 16-bit integer.
406 *
407 * @param name name of the JSON field
408 * @param[out] u16 where to store the integer found under @a name
409 */
410struct GNUNET_JSON_Specification
411GNUNET_JSON_spec_uint16 (const char *name,
412 uint16_t *u16)
413{
414 struct GNUNET_JSON_Specification ret = {
415 .parser = &parse_u16,
416 .cleaner = NULL,
417 .cls = NULL,
418 .field = name,
419 .ptr = u16,
420 .ptr_size = sizeof (uint16_t),
421 .size_ptr = NULL
422 };
423 return ret;
424}
425
426
427/**
428 * Parse given JSON object to a uint32_t.
429 *
430 * @param cls closure, NULL
431 * @param root the json object representing data
432 * @param[out] spec where to write the data
433 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
434 */
435static int
436parse_u32 (void *cls,
437 json_t *root,
438 struct GNUNET_JSON_Specification *spec)
439{
440 json_int_t val;
441 uint32_t *up = spec->ptr;
442
443 if (! json_is_integer (root))
444 {
445 GNUNET_break_op (0);
446 return GNUNET_SYSERR;
447 }
448 val = json_integer_value (root);
449 if ( (0 > val) || (val > UINT32_MAX) )
450 {
451 GNUNET_break_op (0);
452 return GNUNET_SYSERR;
453 }
454 *up = (uint32_t) val;
455 return GNUNET_OK;
456}
457
458
459/**
460 * 32-bit integer.
461 *
462 * @param name name of the JSON field
463 * @param[out] u32 where to store the integer found under @a name
464 */
465struct GNUNET_JSON_Specification
466GNUNET_JSON_spec_uint32 (const char *name,
467 uint32_t *u32)
468{
469 struct GNUNET_JSON_Specification ret = {
470 .parser = &parse_u32,
471 .cleaner = NULL,
472 .cls = NULL,
473 .field = name,
474 .ptr = u32,
475 .ptr_size = sizeof (uint32_t),
476 .size_ptr = NULL
477 };
478 return ret;
479}
480
481
482/**
483 * Parse given JSON object to a uint8_t.
484 *
485 * @param cls closure, NULL
486 * @param root the json object representing data
487 * @param[out] spec where to write the data
488 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
489 */
490static int
491parse_u64 (void *cls,
492 json_t *root,
493 struct GNUNET_JSON_Specification *spec)
494{
495 json_int_t val;
496 uint64_t *up = spec->ptr;
497
498 if (! json_is_integer (root))
499 {
500 GNUNET_break_op (0);
501 return GNUNET_SYSERR;
502 }
503 val = json_integer_value (root);
504 *up = (uint64_t) val;
505 return GNUNET_OK;
506}
507
508
509/**
510 * 64-bit integer.
511 *
512 * @param name name of the JSON field
513 * @param[out] u64 where to store the integer found under @a name
514 */
515struct GNUNET_JSON_Specification
516GNUNET_JSON_spec_uint64 (const char *name,
517 uint64_t *u64)
518{
519 struct GNUNET_JSON_Specification ret = {
520 .parser = &parse_u64,
521 .cleaner = NULL,
522 .cls = NULL,
523 .field = name,
524 .ptr = u64,
525 .ptr_size = sizeof (uint64_t),
526 .size_ptr = NULL
527 };
528 return ret;
529}
530
531
532/* ************ GNUnet-specific parser specifications ******************* */
533
534/**
535 * Parse given JSON object to absolute time.
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_abs_time (void *cls,
544 json_t *root,
545 struct GNUNET_JSON_Specification *spec)
546{
547 struct GNUNET_TIME_Absolute *abs = spec->ptr;
548 const char *val;
549 unsigned long long int tval;
550
551 val = json_string_value (root);
552 if (NULL == val)
553 {
554 GNUNET_break_op (0);
555 return GNUNET_SYSERR;
556 }
557 if ( (0 == strcasecmp (val,
558 "/forever/")) ||
559 (0 == strcasecmp (val,
560 "/end of time/")) ||
561 (0 == strcasecmp (val,
562 "/never/")) )
563 {
564 *abs = GNUNET_TIME_UNIT_FOREVER_ABS;
565 return GNUNET_OK;
566 }
567 if (1 != sscanf (val,
568 "/Date(%llu)/",
569 &tval))
570 {
571 GNUNET_break_op (0);
572 return GNUNET_SYSERR;
573 }
574 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
575 abs->abs_value_us = tval * 1000LL * 1000LL;
576 if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
577 {
578 /* Integer overflow */
579 GNUNET_break_op (0);
580 return GNUNET_SYSERR;
581 }
582 return GNUNET_OK;
583}
584
585
586/**
587 * Absolute time.
588 *
589 * @param name name of the JSON field
590 * @param[out] at where to store the absolute time found under @a name
591 */
592struct GNUNET_JSON_Specification
593GNUNET_JSON_spec_absolute_time (const char *name,
594 struct GNUNET_TIME_Absolute *at)
595{
596 struct GNUNET_JSON_Specification ret = {
597 .parser = &parse_abs_time,
598 .cleaner = NULL,
599 .cls = NULL,
600 .field = name,
601 .ptr = at,
602 .ptr_size = sizeof (uint64_t),
603 .size_ptr = NULL
604 };
605 return ret;
606}
607
608
609/**
610 * Parse given JSON object to relative time.
611 *
612 * @param cls closure, NULL
613 * @param root the json object representing data
614 * @param[out] spec where to write the data
615 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
616 */
617static int
618parse_rel_time (void *cls,
619 json_t *root,
620 struct GNUNET_JSON_Specification *spec)
621{
622 struct GNUNET_TIME_Relative *rel = spec->ptr;
623 const char *val;
624 unsigned long long int tval;
625
626 val = json_string_value (root);
627 if (NULL == val)
628 {
629 GNUNET_break_op (0);
630 return GNUNET_SYSERR;
631 }
632 if ( (0 == strcasecmp (val,
633 "/forever/")) )
634 {
635 *rel = GNUNET_TIME_UNIT_FOREVER_REL;
636 return GNUNET_OK;
637 }
638 if (1 != sscanf (val,
639 "/Delay(%llu)/",
640 &tval))
641 {
642 GNUNET_break_op (0);
643 return GNUNET_SYSERR;
644 }
645 /* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Relative */
646 rel->rel_value_us = tval * 1000LL * 1000LL;
647 if ( (rel->rel_value_us) / 1000LL / 1000LL != tval)
648 {
649 /* Integer overflow */
650 GNUNET_break_op (0);
651 return GNUNET_SYSERR;
652 }
653 return GNUNET_OK;
654}
655
656
657/**
658 * Relative time.
659 *
660 * @param name name of the JSON field
661 * @param[out] rt where to store the relative time found under @a name
662 */
663struct GNUNET_JSON_Specification
664GNUNET_JSON_spec_relative_time (const char *name,
665 struct GNUNET_TIME_Relative *rt)
666{
667 struct GNUNET_JSON_Specification ret = {
668 .parser = &parse_rel_time,
669 .cleaner = NULL,
670 .cls = NULL,
671 .field = name,
672 .ptr = rt,
673 .ptr_size = sizeof (uint64_t),
674 .size_ptr = NULL
675 };
676 return ret;
677}
678
679
680/**
681 * Parse given JSON object to RSA public key.
682 *
683 * @param cls closure, NULL
684 * @param root the json object representing data
685 * @param[out] spec where to write the data
686 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
687 */
688static int
689parse_rsa_public_key (void *cls,
690 json_t *root,
691 struct GNUNET_JSON_Specification *spec)
692{
693 struct GNUNET_CRYPTO_rsa_PublicKey **pk = spec->ptr;
694 const char *enc;
695 char *buf;
696 size_t len;
697 size_t buf_len;
698
699 if (NULL == (enc = json_string_value (root)))
700 {
701 GNUNET_break_op (0);
702 return GNUNET_SYSERR;
703 }
704 len = strlen (enc);
705 buf_len = (len * 5) / 8;
706 buf = GNUNET_malloc (buf_len);
707 if (GNUNET_OK !=
708 GNUNET_STRINGS_string_to_data (enc,
709 len,
710 buf,
711 buf_len))
712 {
713 GNUNET_break_op (0);
714 GNUNET_free (buf);
715 return GNUNET_SYSERR;
716 }
717 if (NULL == (*pk = GNUNET_CRYPTO_rsa_public_key_decode (buf,
718 buf_len)))
719 {
720 GNUNET_break_op (0);
721 GNUNET_free (buf);
722 return GNUNET_SYSERR;
723 }
724 GNUNET_free (buf);
725 return GNUNET_OK;
726}
727
728
729/**
730 * Cleanup data left from parsing RSA public key.
731 *
732 * @param cls closure, NULL
733 * @param[out] spec where to free the data
734 */
735static void
736clean_rsa_public_key (void *cls,
737 struct GNUNET_JSON_Specification *spec)
738{
739 struct GNUNET_CRYPTO_rsa_PublicKey **pk = spec->ptr;
740
741 if (NULL != *pk)
742 {
743 GNUNET_CRYPTO_rsa_public_key_free (*pk);
744 *pk = NULL;
745 }
746}
747
748
749/**
750 * Specification for parsing an RSA public key.
751 *
752 * @param name name of the JSON field
753 * @param pk where to store the RSA key found under @a name
754 */
755struct GNUNET_JSON_Specification
756GNUNET_JSON_spec_rsa_public_key (const char *name,
757 struct GNUNET_CRYPTO_rsa_PublicKey **pk)
758{
759 struct GNUNET_JSON_Specification ret = {
760 .parser = &parse_rsa_public_key,
761 .cleaner = &clean_rsa_public_key,
762 .cls = NULL,
763 .field = name,
764 .ptr = pk,
765 .ptr_size = 0,
766 .size_ptr = NULL
767 };
768 return ret;
769}
770
771
772/**
773 * Parse given JSON object to RSA signature.
774 *
775 * @param cls closure, NULL
776 * @param root the json object representing data
777 * @param[out] spec where to write the data
778 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
779 */
780static int
781parse_rsa_signature (void *cls,
782 json_t *root,
783 struct GNUNET_JSON_Specification *spec)
784{
785 struct GNUNET_CRYPTO_rsa_Signature **sig = spec->ptr;
786 size_t size;
787 const char *str;
788 int res;
789 void *buf;
790
791 str = json_string_value (root);
792 if (NULL == str)
793 {
794 GNUNET_break_op (0);
795 return GNUNET_SYSERR;
796 }
797 size = (strlen (str) * 5) / 8;
798 buf = GNUNET_malloc (size);
799 res = GNUNET_STRINGS_string_to_data (str,
800 strlen (str),
801 buf,
802 size);
803 if (GNUNET_OK != res)
804 {
805 GNUNET_free (buf);
806 GNUNET_break_op (0);
807 return GNUNET_SYSERR;
808 }
809 if (NULL == (*sig = GNUNET_CRYPTO_rsa_signature_decode (buf,
810 size)))
811 {
812 GNUNET_break_op (0);
813 GNUNET_free (buf);
814 return GNUNET_SYSERR;
815 }
816 GNUNET_free (buf);
817 return GNUNET_OK;
818}
819
820
821/**
822 * Cleanup data left from parsing RSA signature.
823 *
824 * @param cls closure, NULL
825 * @param[out] spec where to free the data
826 */
827static void
828clean_rsa_signature (void *cls,
829 struct GNUNET_JSON_Specification *spec)
830{
831 struct GNUNET_CRYPTO_rsa_Signature **sig = spec->ptr;
832
833 if (NULL != *sig)
834 {
835 GNUNET_CRYPTO_rsa_signature_free (*sig);
836 *sig = NULL;
837 }
838}
839
840
841/**
842 * Specification for parsing an RSA signature.
843 *
844 * @param name name of the JSON field
845 * @param sig where to store the RSA signature found under @a name
846 */
847struct GNUNET_JSON_Specification
848GNUNET_JSON_spec_rsa_signature (const char *name,
849 struct GNUNET_CRYPTO_rsa_Signature **sig)
850{
851 struct GNUNET_JSON_Specification ret = {
852 .parser = &parse_rsa_signature,
853 .cleaner = &clean_rsa_signature,
854 .cls = NULL,
855 .field = name,
856 .ptr = sig,
857 .ptr_size = 0,
858 .size_ptr = NULL
859 };
860 return ret;
861}
862
863
864/* end of json_helper.c */