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;
56 struct GNUNET_JSONAPI_Error *err;
57 struct GNUNET_JSONAPI_Error *err_next;
60 for (err = doc->err_list_head;
64 GNUNET_CONTAINER_DLL_remove (doc->err_list_head,
67 GNUNET_JSONAPI_error_delete (err);
71 for (res = doc->res_list_head;
75 GNUNET_CONTAINER_DLL_remove (doc->res_list_head,
78 GNUNET_JSONAPI_resource_delete (res);
82 if (NULL != doc->meta)
83 json_decref (doc->meta);
89 * Create a JSON API primary data
91 * @return a new JSON API resource or NULL on error.
93 struct GNUNET_JSONAPI_Document*
94 GNUNET_JSONAPI_document_new ()
96 struct GNUNET_JSONAPI_Document *result;
98 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
99 result->res_count = 0;
100 result->err_count = 0;
106 * Add a JSON API error to document
108 * @param data The JSON API document to add to
109 * @param res the JSON API error to add
110 * @return the new number of resources
113 GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc,
114 struct GNUNET_JSONAPI_Error *err)
116 GNUNET_CONTAINER_DLL_insert (doc->err_list_head,
124 * Add a JSON API resource to primary data
126 * @param data The JSON API data to add to
127 * @param res the JSON API resource to add
128 * @return the new number of resources
131 GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *doc,
132 struct GNUNET_JSONAPI_Resource *res)
134 GNUNET_CONTAINER_DLL_insert (doc->res_list_head,
143 * Parse given JSON object to jsonapi document.
145 * @param cls closure, NULL
146 * @param root the json object representing data
147 * @param[out] spec where to write the data
148 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
151 parse_jsonapiobject (void *cls,
153 struct GNUNET_JSON_Specification *spec)
155 struct GNUNET_JSONAPI_Document *result;
156 struct GNUNET_JSONAPI_Error *error;
157 struct GNUNET_JSONAPI_Resource *resource;
159 json_t *resource_json;
164 struct GNUNET_JSON_Specification jsonapispecerrors[] = {
165 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ERRORS, &errors_json),
166 GNUNET_JSON_spec_end()
169 GNUNET_JSON_parse (root, jsonapispecerrors,
172 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
173 "JSONAPI document does not contain error objects\n");
174 } else if (!json_is_array (errors_json))
176 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
177 "Error object is not array!\n");
178 GNUNET_JSON_parse_free (jsonapispecerrors);
179 return GNUNET_SYSERR;
181 struct GNUNET_JSON_Specification jsonapispecmeta[] = {
182 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_META, &meta_json),
183 GNUNET_JSON_spec_end()
186 GNUNET_JSON_parse (root, jsonapispecmeta,
189 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
190 "JSONAPI document does not contain error objects\n");
192 struct GNUNET_JSON_Specification jsonapispecresource[] = {
193 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &resource_json),
194 GNUNET_JSON_spec_end()
197 GNUNET_JSON_parse (root, jsonapispecresource,
200 if (NULL == errors_json)
202 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
203 "JSONAPI document contains neither error nor data!\n");
204 GNUNET_JSON_parse_free (jsonapispecerrors);
205 GNUNET_JSON_parse_free (jsonapispecmeta);
206 return GNUNET_SYSERR;
209 if (NULL != errors_json)
211 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
212 "JSONAPI document contains both error and data!\n");
213 GNUNET_JSON_parse_free (jsonapispecerrors);
214 GNUNET_JSON_parse_free (jsonapispecmeta);
215 GNUNET_JSON_parse_free (jsonapispecresource);
216 return GNUNET_SYSERR;
220 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
221 result->res_count = 0;
222 result->err_count = 0;
223 if (NULL != meta_json)
224 result->meta = json_deep_copy (meta_json);
225 if (NULL != errors_json) {
226 json_array_foreach(errors_json, index, value) {
227 GNUNET_assert (GNUNET_OK ==
228 GNUNET_JSONAPI_json_to_error (value,
230 GNUNET_JSONAPI_document_error_add (result, error);
233 if (NULL != resource_json) {
234 if (0 != json_is_array (resource_json))
236 json_array_foreach(resource_json, index, value) {
237 GNUNET_assert (GNUNET_OK ==
238 GNUNET_JSONAPI_json_to_resource (value,
240 GNUNET_JSONAPI_document_resource_add (result, resource);
243 GNUNET_assert (GNUNET_OK ==
244 GNUNET_JSONAPI_json_to_resource (resource_json,
246 GNUNET_JSONAPI_document_resource_add (result, resource);
249 if (NULL != errors_json)
250 GNUNET_JSON_parse_free (jsonapispecerrors);
251 if (NULL != resource)
252 GNUNET_JSON_parse_free (jsonapispecresource);
253 if (NULL != meta_json)
254 GNUNET_JSON_parse_free (jsonapispecmeta);
255 *(struct GNUNET_JSONAPI_Document **) spec->ptr = result;
261 * Cleanup data left from parsing RSA public key.
263 * @param cls closure, NULL
264 * @param[out] spec where to free the data
267 clean_jsonapiobject (void *cls,
268 struct GNUNET_JSON_Specification *spec)
270 struct GNUNET_JSONAPI_Document **jsonapi_obj;
271 jsonapi_obj = (struct GNUNET_JSONAPI_Document **) spec->ptr;
272 if (NULL != *jsonapi_obj)
274 GNUNET_JSONAPI_document_delete (*jsonapi_obj);
280 * Add a JSON API resource to primary data
282 * @param data The JSON API data to add to
283 * @param res the JSON API resource to add
284 * @return the new number of resources
287 GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp,
288 struct GNUNET_JSONAPI_Resource *res)
290 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
298 * String serialze jsonapi primary data
300 * @param data the JSON API primary data
301 * @param result where to store the result
302 * @return GNUNET_SYSERR on error else GNUNET_OK
305 GNUNET_JSONAPI_document_to_json (const struct GNUNET_JSONAPI_Document *doc,
308 struct GNUNET_JSONAPI_Resource *res;
309 struct GNUNET_JSONAPI_Error *error;
311 json_t *res_json_tmp;
314 return GNUNET_SYSERR;
316 *root_json = json_object ();
318 //Check for errors first
319 if (doc->err_count != 0)
321 res_json = json_array ();
322 for (error = doc->err_list_head;
326 GNUNET_assert (GNUNET_OK ==
327 GNUNET_JSONAPI_error_to_json (error,
329 json_array_append_new (res_json, res_json_tmp);
331 json_object_set_new (*root_json,
332 GNUNET_JSONAPI_KEY_ERRORS,
335 switch (doc->res_count)
338 res_json = json_null();
341 GNUNET_assert (GNUNET_OK ==
342 GNUNET_JSONAPI_resource_to_json (doc->res_list_head,
346 res_json = json_array ();
347 for (res = doc->res_list_head;
351 GNUNET_assert (GNUNET_OK ==
352 GNUNET_JSONAPI_resource_to_json (res,
354 json_array_append (res_json, res_json_tmp);
358 json_object_set_new (*root_json,
359 GNUNET_JSONAPI_KEY_DATA,
362 json_object_set (*root_json,
363 GNUNET_JSONAPI_KEY_META,
369 * String serialze jsonapi primary data
371 * @param data the JSON API primary data
372 * @param result where to store the result
373 * @return GNUNET_SYSERR on error else GNUNET_OK
376 GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *doc,
380 if (GNUNET_OK != GNUNET_JSONAPI_document_to_json (doc,
382 return GNUNET_SYSERR;
384 *result = json_dumps (json_doc, JSON_INDENT(2));
385 json_decref (json_doc);
392 * @param name name of the JSON field
393 * @param[out] jsonp where to store the JSON found under @a name
395 struct GNUNET_JSON_Specification
396 GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_object)
398 struct GNUNET_JSON_Specification ret = {
399 .parser = &parse_jsonapiobject,
400 .cleaner = &clean_jsonapiobject,
403 .ptr = jsonapi_object,
407 *jsonapi_object = NULL;