3 #include "gnunet_util_lib.h"
4 #include "gnunet_json_lib.h"
5 #include "jsonapi_objects.h"
8 * Get a JSON API object resource count
10 * @param resp the JSON API object
11 * @return the number of resources
14 GNUNET_JSONAPI_document_resource_count (struct GNUNET_JSONAPI_Document *doc)
16 return doc->res_count;
20 * Get a JSON API object resource by index
22 * @param resp the JSON API object
23 * @param idx index of the resource
24 * @return the resource
26 struct GNUNET_JSONAPI_Resource*
27 GNUNET_JSONAPI_document_get_resource (struct GNUNET_JSONAPI_Document *doc,
30 struct GNUNET_JSONAPI_Resource *res;
33 if ((0 == doc->res_count) ||
34 (idx >= doc->res_count))
36 res = doc->res_list_head;
37 for (i = 0; i < idx; i++)
45 * Delete a JSON API primary data
47 * @param type the JSON API resource type
48 * @param id the JSON API resource id
49 * @return a new JSON API resource or NULL on error.
52 GNUNET_JSONAPI_document_delete (struct GNUNET_JSONAPI_Document *doc)
54 struct GNUNET_JSONAPI_Resource *res;
55 struct GNUNET_JSONAPI_Resource *res_next;
58 for (res = doc->res_list_head;
62 GNUNET_CONTAINER_DLL_remove (doc->res_list_head,
65 GNUNET_JSONAPI_resource_delete (res);
73 * Create a JSON API primary data
75 * @return a new JSON API resource or NULL on error.
77 struct GNUNET_JSONAPI_Document*
78 GNUNET_JSONAPI_document_new ()
80 struct GNUNET_JSONAPI_Document *result;
82 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
83 result->res_count = 0;
84 result->err_count = 0;
90 * Add a JSON API error to document
92 * @param data The JSON API document to add to
93 * @param res the JSON API error to add
94 * @return the new number of resources
97 GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc,
98 struct GNUNET_JSONAPI_Error *err)
100 GNUNET_CONTAINER_DLL_insert (doc->err_list_head,
108 * Add a JSON API resource to primary data
110 * @param data The JSON API data to add to
111 * @param res the JSON API resource to add
112 * @return the new number of resources
115 GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *doc,
116 struct GNUNET_JSONAPI_Resource *res)
118 GNUNET_CONTAINER_DLL_insert (doc->res_list_head,
127 * Parse given JSON object to jsonapi document.
129 * @param cls closure, NULL
130 * @param root the json object representing data
131 * @param[out] spec where to write the data
132 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
135 parse_jsonapiobject (void *cls,
137 struct GNUNET_JSON_Specification *spec)
139 struct GNUNET_JSONAPI_Document *result;
140 struct GNUNET_JSONAPI_Error *error;
141 struct GNUNET_JSONAPI_Resource *resource;
143 json_t *resource_json;
148 struct GNUNET_JSON_Specification jsonapispecerrors[] = {
149 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ERRORS, &errors_json),
150 GNUNET_JSON_spec_end()
153 GNUNET_JSON_parse (root, jsonapispecerrors,
156 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
157 "JSONAPI document does not contain error objects\n");
158 } else if (!json_is_array (errors_json))
160 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
161 "Error object is not array!\n");
162 GNUNET_JSON_parse_free (jsonapispecerrors);
163 return GNUNET_SYSERR;
165 struct GNUNET_JSON_Specification jsonapispecmeta[] = {
166 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_META, &meta_json),
167 GNUNET_JSON_spec_end()
170 GNUNET_JSON_parse (root, jsonapispecmeta,
173 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
174 "JSONAPI document does not contain error objects\n");
176 struct GNUNET_JSON_Specification jsonapispecresource[] = {
177 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &resource_json),
178 GNUNET_JSON_spec_end()
181 GNUNET_JSON_parse (root, jsonapispecresource,
184 if (NULL == errors_json)
186 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
187 "JSONAPI document contains neither error nor data!\n");
188 GNUNET_JSON_parse_free (jsonapispecerrors);
189 GNUNET_JSON_parse_free (jsonapispecmeta);
190 return GNUNET_SYSERR;
193 if (NULL != errors_json)
195 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
196 "JSONAPI document contains both error and data!\n");
197 GNUNET_JSON_parse_free (jsonapispecerrors);
198 GNUNET_JSON_parse_free (jsonapispecmeta);
199 GNUNET_JSON_parse_free (jsonapispecresource);
200 return GNUNET_SYSERR;
204 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
205 result->res_count = 0;
206 result->err_count = 0;
207 if (NULL != meta_json)
208 result->meta = json_deep_copy (meta_json);
209 if (NULL != errors_json) {
210 json_array_foreach(errors_json, index, value) {
211 GNUNET_assert (GNUNET_OK ==
212 GNUNET_JSONAPI_json_to_error (value,
214 GNUNET_JSONAPI_document_error_add (result, error);
217 if (NULL != resource_json) {
218 if (0 != json_is_array (resource_json))
220 json_array_foreach(resource_json, index, value) {
221 GNUNET_assert (GNUNET_OK ==
222 GNUNET_JSONAPI_json_to_resource (value,
224 GNUNET_JSONAPI_document_resource_add (result, resource);
227 GNUNET_assert (GNUNET_OK ==
228 GNUNET_JSONAPI_json_to_resource (resource_json,
230 GNUNET_JSONAPI_document_resource_add (result, resource);
233 if (NULL != errors_json)
234 GNUNET_JSON_parse_free (jsonapispecerrors);
235 if (NULL != resource)
236 GNUNET_JSON_parse_free (jsonapispecresource);
237 if (NULL != meta_json)
238 GNUNET_JSON_parse_free (jsonapispecmeta);
239 *(struct GNUNET_JSONAPI_Document **) spec->ptr = result;
245 * Cleanup data left from parsing RSA public key.
247 * @param cls closure, NULL
248 * @param[out] spec where to free the data
251 clean_jsonapiobject (void *cls,
252 struct GNUNET_JSON_Specification *spec)
254 struct GNUNET_JSONAPI_Document **jsonapi_obj;
255 jsonapi_obj = (struct GNUNET_JSONAPI_Document **) spec->ptr;
256 if (NULL != *jsonapi_obj)
258 GNUNET_JSONAPI_document_delete (*jsonapi_obj);
264 * Add a JSON API resource to primary data
266 * @param data The JSON API data to add to
267 * @param res the JSON API resource to add
268 * @return the new number of resources
271 GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp,
272 struct GNUNET_JSONAPI_Resource *res)
274 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
282 * String serialze jsonapi primary data
284 * @param data the JSON API primary data
285 * @param result where to store the result
286 * @return GNUNET_SYSERR on error else GNUNET_OK
289 GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *doc,
292 struct GNUNET_JSONAPI_Resource *res;
293 struct GNUNET_JSONAPI_Error *error;
296 json_t *res_json_tmp;
299 return GNUNET_SYSERR;
301 root_json = json_object ();
303 //Check for errors first
304 if (doc->err_count != 0)
306 res_json = json_array ();
307 for (error = doc->err_list_head;
311 GNUNET_assert (GNUNET_OK ==
312 GNUNET_JSONAPI_error_to_json (error,
314 json_array_append (res_json, res_json_tmp);
316 json_object_set (root_json, GNUNET_JSONAPI_KEY_ERRORS, res_json);
318 switch (doc->res_count)
321 res_json = json_null();
324 GNUNET_assert (GNUNET_OK ==
325 GNUNET_JSONAPI_resource_to_json (doc->res_list_head,
329 res_json = json_array ();
330 for (res = doc->res_list_head;
334 GNUNET_assert (GNUNET_OK ==
335 GNUNET_JSONAPI_resource_to_json (res,
337 json_array_append (res_json, res_json_tmp);
341 json_object_set (root_json, GNUNET_JSONAPI_KEY_DATA, res_json);
345 json_object_set (root_json, GNUNET_JSONAPI_KEY_META, doc->meta);
346 *result = json_dumps (root_json, JSON_INDENT(2));
347 json_decref (root_json);
348 json_decref (res_json);
355 * @param name name of the JSON field
356 * @param[out] jsonp where to store the JSON found under @a name
358 struct GNUNET_JSON_Specification
359 GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_object)
361 struct GNUNET_JSON_Specification ret = {
362 .parser = &parse_jsonapiobject,
363 .cleaner = &clean_jsonapiobject,
366 .ptr = jsonapi_object,
370 *jsonapi_object = NULL;