Use Suffix Extensions in Makefiles (doc, src/{arm,dht,integration,statistics}) for...
[oweals/gnunet.git] / src / jsonapi / jsonapi_error.c
1 #include "platform.h"
2 #include "gnunet_jsonapi_lib.h"
3 #include "jsonapi_objects.h"
4
5 /**
6  * Parse json to error object
7  *
8  * @param err_json JSON object
9  * @param[out] err error object
10  * @return GNUNET_OK on success
11  */
12 int
13 GNUNET_JSONAPI_json_to_error (json_t *err_json,
14                               struct GNUNET_JSONAPI_Error **err)
15 {
16   struct GNUNET_JSON_Specification jsonapispecerror[] = {
17     GNUNET_JSON_spec_jsonapi_error (err),
18     GNUNET_JSON_spec_end()
19   };
20   return GNUNET_JSON_parse (err_json, jsonapispecerror,
21                             NULL, NULL);
22 }
23
24 /**
25  * Serialze jsonapi errors
26  *
27  * @param data the JSON API errors
28  * @param result where to store the result
29  * @return GNUNET_SYSERR on error else GNUNET_OK
30  */
31 int
32 GNUNET_JSONAPI_error_to_json (const struct GNUNET_JSONAPI_Error *err,
33                               json_t **result)
34 {
35   *result = json_object ();
36
37   if ((NULL != err->id) &&
38       (0 != json_object_set_new (*result,
39                                  GNUNET_JSONAPI_KEY_ID,
40                                  json_string (err->id))))
41     return GNUNET_SYSERR;
42   if ((NULL != err->status) &&
43       (0 != json_object_set_new (*result,
44                                  GNUNET_JSONAPI_KEY_STATUS,
45                                  json_string (err->status))))
46     return GNUNET_SYSERR;
47   if ((NULL != err->code) &&
48       (0 != json_object_set_new (*result,
49                                  GNUNET_JSONAPI_KEY_CODE,
50                                  json_string (err->code))))
51     return GNUNET_SYSERR;
52
53   if ((NULL != err->title) &&
54       (0 != json_object_set_new (*result,
55                                  GNUNET_JSONAPI_KEY_TITLE,
56                                  json_string (err->title))))
57     return GNUNET_SYSERR;
58   if ((NULL != err->detail) &&
59       (0 != json_object_set_new (*result,
60                                  GNUNET_JSONAPI_KEY_DETAIL,
61                                  json_string (err->detail))))
62     return GNUNET_SYSERR;
63   if ((NULL != err->source) &&
64       (0 != json_object_set_new (*result,
65                                  GNUNET_JSONAPI_KEY_SOURCE,
66                                  err->source)))
67     return GNUNET_SYSERR;
68   if ((NULL != err->links) &&
69       (0 != json_object_set_new (*result,
70                                  GNUNET_JSONAPI_KEY_LINKS,
71                                  err->links)))
72     return GNUNET_SYSERR;
73   if ((NULL != err->meta) &&
74       (0 != json_object_set_new (*result,
75                                  GNUNET_JSONAPI_KEY_META,
76                                  err->meta)))
77     return GNUNET_SYSERR;
78   return GNUNET_OK;
79 }
80
81
82 /**
83  * Parse given JSON object to jsonapi document.
84  *
85  * @param cls closure, NULL
86  * @param root the json object representing data
87  * @param[out] spec where to write the data
88  * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
89  */
90 static int
91 parse_jsonapierror (void *cls,
92                      json_t *root,
93                      struct GNUNET_JSON_Specification *spec)
94 {
95   struct GNUNET_JSONAPI_Error *result;
96   json_t *pos;
97   
98   GNUNET_assert (NULL != root);
99   result = GNUNET_new (struct GNUNET_JSONAPI_Error);
100   pos = json_object_get (root, GNUNET_JSONAPI_KEY_ID);
101   if (json_is_string (pos))
102     result->id = GNUNET_strdup (json_string_value (pos));
103   
104   pos = json_object_get (root, GNUNET_JSONAPI_KEY_LINKS);
105   if (json_is_object (pos))
106     result->links = json_deep_copy (pos);
107   
108   pos = json_object_get (root, GNUNET_JSONAPI_KEY_STATUS);
109   if (json_is_string (pos))
110     result->status = GNUNET_strdup (json_string_value (pos));
111
112   pos = json_object_get (root, GNUNET_JSONAPI_KEY_CODE);
113   if (json_is_string (pos))
114     result->code = GNUNET_strdup (json_string_value (pos));
115
116   pos = json_object_get (root, GNUNET_JSONAPI_KEY_TITLE);
117   if (json_is_string (pos))
118     result->title = GNUNET_strdup (json_string_value (pos));
119
120   pos = json_object_get (root, GNUNET_JSONAPI_KEY_DETAIL);
121   if (json_is_string (pos))
122     result->detail = GNUNET_strdup (json_string_value (pos));
123
124   pos = json_object_get (root, GNUNET_JSONAPI_KEY_SOURCE);
125   if (json_is_object (pos))
126     result->source = json_deep_copy (pos);
127   pos = json_object_get (root, GNUNET_JSONAPI_KEY_META);
128   if (json_is_object (pos))
129     result->meta = json_deep_copy (pos);
130   *(struct GNUNET_JSONAPI_Error **) spec->ptr = result;
131   return GNUNET_OK;
132 }
133
134 /**
135  * Create a JSON API error
136  *
137  * @param res the JSON error
138  */
139 struct GNUNET_JSONAPI_Error*
140 GNUNET_JSONAPI_error_new (const char *id,
141                           const char *status,
142                           const char *code,
143                           const char *title,
144                           const char *detail,
145                           json_t *links,
146                           json_t *source,
147                           json_t *meta)
148 {
149   struct GNUNET_JSONAPI_Error *error;
150   error = GNUNET_new (struct GNUNET_JSONAPI_Error);
151
152   if (NULL != id)
153     error->id = GNUNET_strdup (id);
154   if (NULL != status)
155     error->status = GNUNET_strdup (status);
156   if (NULL != code)
157     error->code = GNUNET_strdup (code);
158   if (NULL != title)
159     error->title = GNUNET_strdup (title);
160   if (NULL != detail)
161     error->detail = GNUNET_strdup (detail);
162   if (NULL != links)
163     error->links = json_deep_copy (links);
164   if (NULL != source)
165     error->source = json_deep_copy (source);
166   if (NULL != meta)
167     error->meta = json_deep_copy (meta);
168   return error;
169 }
170 /**
171  * Delete a JSON API error
172  *
173  * @param res the JSON error
174  */
175 void
176 GNUNET_JSONAPI_error_delete (struct GNUNET_JSONAPI_Error *error)
177 {
178   GNUNET_assert (NULL != error);
179
180   if (NULL != error->id)
181     GNUNET_free (error->id);
182   if (NULL != error->status)
183     GNUNET_free (error->status);
184   if (NULL != error->code)
185     GNUNET_free (error->code);
186   if (NULL != error->title)
187     GNUNET_free (error->title);
188   if (NULL != error->detail)
189     GNUNET_free (error->detail);
190   if (NULL != error->links)
191     json_decref (error->links);
192   if (NULL != error->source)
193     json_decref (error->source);
194   if (NULL != error->meta)
195     json_decref (error->meta);
196   GNUNET_free (error);
197 }
198
199
200
201 /**
202  * Cleanup data left from parsing RSA public key.
203  *
204  * @param cls closure, NULL
205  * @param[out] spec where to free the data
206  */
207 static void
208 clean_jsonapierror (void *cls,
209                      struct GNUNET_JSON_Specification *spec)
210 {
211   struct GNUNET_JSONAPI_Error **jsonapi_obj;
212   jsonapi_obj = (struct GNUNET_JSONAPI_Error **) spec->ptr;
213   if (NULL != *jsonapi_obj)
214   {
215     GNUNET_JSONAPI_error_delete (*jsonapi_obj);
216     *jsonapi_obj = NULL;
217   }
218 }
219 /**
220  * JSON object.
221  *
222  * @param name name of the JSON field
223  * @param[out] jsonp where to store the JSON found under @a name
224  */
225 struct GNUNET_JSON_Specification
226 GNUNET_JSON_spec_jsonapi_error (struct GNUNET_JSONAPI_Error **jsonapi_object)
227 {
228   struct GNUNET_JSON_Specification ret = {
229     .parser = &parse_jsonapierror,
230     .cleaner = &clean_jsonapierror,
231     .cls = NULL,
232     .field = NULL,
233     .ptr = jsonapi_object,
234     .ptr_size = 0,
235     .size_ptr = NULL
236   };
237   *jsonapi_object = NULL;
238   return ret;
239 }
240
241