Line data Source code
1 : /*
2 : This file is part of TALER
3 : (C) 2025 Taler Systems SA
4 :
5 : TALER is free software; you can redistribute it and/or modify it under the
6 : terms of the GNU Lesser General Public License as published by the Free Software
7 : Foundation; either version 3, or (at your option) any later version.
8 :
9 : TALER 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 : TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
15 : */
16 : /**
17 : * @file util/json.c
18 : * @brief helper functions to parse JSON
19 : * @author Christian Grothoff
20 : */
21 : #include "platform.h"
22 : #include <gnunet/gnunet_common.h>
23 : #include <gnunet/gnunet_json_lib.h>
24 : #include <jansson.h>
25 : #include <taler/taler_json_lib.h>
26 : #include <taler/taler_util.h>
27 : #include "taler_merchant_util.h"
28 :
29 :
30 : /**
31 : * Parse given JSON object to `enum TALER_MERCHANT_ContractInputType`
32 : *
33 : * @param cls closure, NULL
34 : * @param root the json object representing data
35 : * @param[out] spec where to write the data
36 : * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
37 : */
38 : static enum GNUNET_GenericReturnValue
39 15 : parse_contract_input_type (void *cls,
40 : json_t *root,
41 : struct GNUNET_JSON_Specification *spec)
42 : {
43 : static const struct Entry
44 : {
45 : const char *name;
46 : enum TALER_MERCHANT_ContractInputType val;
47 : } lt [] = {
48 : #if FUTURE
49 : { .name = "coin",
50 : .val = TALER_MERCHANT_CONTRACT_INPUT_TYPE_COIN },
51 : #endif
52 : { .name = "token",
53 : .val = TALER_MERCHANT_CONTRACT_INPUT_TYPE_TOKEN },
54 : { .name = NULL,
55 : .val = TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID }
56 : };
57 15 : enum TALER_MERCHANT_ContractInputType *res
58 : = (enum TALER_MERCHANT_ContractInputType *) spec->ptr;
59 :
60 : (void) cls;
61 15 : if (json_is_string (root))
62 : {
63 : const char *str;
64 :
65 15 : str = json_string_value (root);
66 15 : if (NULL == str)
67 : {
68 0 : GNUNET_break_op (0);
69 0 : return GNUNET_SYSERR;
70 : }
71 15 : for (unsigned int i = 0; NULL != lt[i].name; i++)
72 : {
73 15 : if (0 == strcasecmp (str,
74 15 : lt[i].name))
75 : {
76 15 : *res = lt[i].val;
77 15 : return GNUNET_OK;
78 : }
79 : }
80 : }
81 0 : GNUNET_break_op (0);
82 0 : return GNUNET_SYSERR;
83 : }
84 :
85 :
86 : struct GNUNET_JSON_Specification
87 15 : TALER_MERCHANT_json_spec_cit (const char *name,
88 : enum TALER_MERCHANT_ContractInputType *cit)
89 : {
90 15 : struct GNUNET_JSON_Specification ret = {
91 : .parser = &parse_contract_input_type,
92 : .field = name,
93 : .ptr = cit
94 : };
95 :
96 15 : *cit = TALER_MERCHANT_CONTRACT_INPUT_TYPE_INVALID;
97 15 : return ret;
98 : }
99 :
100 :
101 : /**
102 : * Parse given JSON object to `enum TALER_MERCHANT_ContractOutputType`
103 : *
104 : * @param cls closure, NULL
105 : * @param root the json object representing data
106 : * @param[out] spec where to write the data
107 : * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
108 : */
109 : static enum GNUNET_GenericReturnValue
110 16 : parse_contract_output_type (void *cls,
111 : json_t *root,
112 : struct GNUNET_JSON_Specification *spec)
113 : {
114 : static const struct Entry
115 : {
116 : const char *name;
117 : enum TALER_MERCHANT_ContractOutputType val;
118 : } lt [] = {
119 : { .name = "token",
120 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_TOKEN },
121 : { .name = "tax-receipt",
122 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_DONATION_RECEIPT },
123 : #if FUTURE
124 : { .name = "coin",
125 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_COIN },
126 : #endif
127 : { .name = NULL,
128 : .val = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID }
129 : };
130 16 : enum TALER_MERCHANT_ContractOutputType *res
131 : = (enum TALER_MERCHANT_ContractOutputType *) spec->ptr;
132 :
133 : (void) cls;
134 16 : if (json_is_string (root))
135 : {
136 : const char *str;
137 :
138 16 : str = json_string_value (root);
139 16 : if (NULL == str)
140 : {
141 0 : GNUNET_break_op (0);
142 0 : return GNUNET_SYSERR;
143 : }
144 17 : for (unsigned int i = 0; NULL != lt[i].name; i++)
145 : {
146 17 : if (0 == strcasecmp (str,
147 17 : lt[i].name))
148 : {
149 16 : *res = lt[i].val;
150 16 : return GNUNET_OK;
151 : }
152 : }
153 : }
154 0 : GNUNET_break_op (0);
155 0 : return GNUNET_SYSERR;
156 : }
157 :
158 :
159 : struct GNUNET_JSON_Specification
160 16 : TALER_MERCHANT_json_spec_cot (const char *name,
161 : enum TALER_MERCHANT_ContractOutputType *cot)
162 : {
163 16 : struct GNUNET_JSON_Specification ret = {
164 : .parser = &parse_contract_output_type,
165 : .field = name,
166 : .ptr = cot
167 : };
168 :
169 16 : *cot = TALER_MERCHANT_CONTRACT_OUTPUT_TYPE_INVALID;
170 16 : return ret;
171 : }
|