aboutsummaryrefslogtreecommitdiff
path: root/src/jsonapi
diff options
context:
space:
mode:
authorMartin Schanzenbach <mschanzenbach@posteo.de>2016-05-04 17:18:02 +0000
committerMartin Schanzenbach <mschanzenbach@posteo.de>2016-05-04 17:18:02 +0000
commita44744499d8f3df64cc1d15cd6b40b4b0e4a3683 (patch)
tree27621a6ee20cbe8e344ffdc18c05754e67d67bf3 /src/jsonapi
parentca11046195a840932edb04900669a38cd60ae682 (diff)
downloadgnunet-a44744499d8f3df64cc1d15cd6b40b4b0e4a3683.tar.gz
gnunet-a44744499d8f3df64cc1d15cd6b40b4b0e4a3683.zip
Update jsonapi to current specs, refactor
Diffstat (limited to 'src/jsonapi')
-rw-r--r--src/jsonapi/Makefile.am6
-rw-r--r--src/jsonapi/jsonapi.c454
-rw-r--r--src/jsonapi/jsonapi_document.c374
-rw-r--r--src/jsonapi/jsonapi_error.c205
-rw-r--r--src/jsonapi/jsonapi_objects.h162
-rw-r--r--src/jsonapi/jsonapi_relationship.c17
-rw-r--r--src/jsonapi/jsonapi_resource.c367
-rw-r--r--src/jsonapi/test_jsonapi.c18
8 files changed, 1140 insertions, 463 deletions
diff --git a/src/jsonapi/Makefile.am b/src/jsonapi/Makefile.am
index bcd4172c6..7e881acbd 100644
--- a/src/jsonapi/Makefile.am
+++ b/src/jsonapi/Makefile.am
@@ -13,7 +13,11 @@ libgnunetjsonapi_la_LDFLAGS = \
13 -version-info 0:0:0 \ 13 -version-info 0:0:0 \
14 -no-undefined 14 -no-undefined
15libgnunetjsonapi_la_SOURCES = \ 15libgnunetjsonapi_la_SOURCES = \
16 jsonapi.c 16 jsonapi.c \
17 jsonapi_document.c \
18 jsonapi_resource.c \
19 jsonapi_error.c \
20 jsonapi_relationship.c
17libgnunetjsonapi_la_LIBADD = \ 21libgnunetjsonapi_la_LIBADD = \
18 $(top_builddir)/src/util/libgnunetutil.la \ 22 $(top_builddir)/src/util/libgnunetutil.la \
19 $(top_builddir)/src/json/libgnunetjson.la \ 23 $(top_builddir)/src/json/libgnunetjson.la \
diff --git a/src/jsonapi/jsonapi.c b/src/jsonapi/jsonapi.c
index b648590e5..53ff64694 100644
--- a/src/jsonapi/jsonapi.c
+++ b/src/jsonapi/jsonapi.c
@@ -22,462 +22,10 @@
22#include "gnunet_json_lib.h" 22#include "gnunet_json_lib.h"
23#include "gnunet_rest_lib.h" 23#include "gnunet_rest_lib.h"
24 24
25#define GNUNET_JSONAPI_KEY_DATA "data"
26
27#define GNUNET_JSONAPI_KEY_ID "id"
28
29#define GNUNET_JSONAPI_KEY_TYPE "type"
30
31struct GNUNET_JSONAPI_Resource
32{
33 /**
34 * DLL
35 */
36 struct GNUNET_JSONAPI_Resource *next;
37
38 /**
39 * DLL
40 */
41 struct GNUNET_JSONAPI_Resource *prev;
42
43 /**
44 * Resource content
45 */
46 json_t *res_obj;
47};
48
49
50struct GNUNET_JSONAPI_Object
51{
52 /**
53 * DLL Resource
54 */
55 struct GNUNET_JSONAPI_Resource *res_list_head;
56
57 /**
58 * DLL Resource
59 */
60 struct GNUNET_JSONAPI_Resource *res_list_tail;
61
62 /**
63 * num resources
64 */
65 int res_count;
66};
67
68
69/** 25/**
70 * JSON API 26 * TODO move this to jsonapi-utils
71 */ 27 */
72 28
73
74/**
75 * Create a JSON API resource
76 *
77 * @param type the JSON API resource type
78 * @param id the JSON API resource id
79 * @return a new JSON API resource or NULL on error.
80 */
81struct GNUNET_JSONAPI_Resource*
82GNUNET_JSONAPI_resource_new (const char *type, const char *id)
83{
84 struct GNUNET_JSONAPI_Resource *res;
85
86 if ( (NULL == type) || (0 == strlen (type)) )
87 return NULL;
88 if ( (NULL == id) || (0 == strlen (id)) )
89 return NULL;
90
91 res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
92 res->prev = NULL;
93 res->next = NULL;
94
95 res->res_obj = json_object ();
96
97 json_object_set_new (res->res_obj, GNUNET_JSONAPI_KEY_ID, json_string (id));
98 json_object_set_new (res->res_obj, GNUNET_JSONAPI_KEY_TYPE, json_string (type));
99
100 return res;
101}
102
103
104
105/**
106 * Add a JSON API attribute
107 *
108 * @param res the JSON resource
109 * @param key the key for the attribute
110 * @param json the json_t attribute to add
111 * @return #GNUNET_OK if added successfully
112 * #GNUNET_SYSERR if not
113 */
114int
115GNUNET_JSONAPI_resource_add_attr (const struct GNUNET_JSONAPI_Resource *resource,
116 const char* key,
117 json_t *json)
118{
119 if ( (NULL == resource) ||
120 (NULL == key) ||
121 (NULL == json) )
122 return GNUNET_SYSERR;
123 json_object_set (resource->res_obj, key, json);
124 return GNUNET_OK;
125}
126
127/**
128 * Read a JSON API attribute
129 *
130 * @param res the JSON resource
131 * @param key the key for the attribute
132 * @return the json_t object
133 */
134json_t*
135GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource,
136 const char* key)
137{
138 if ( (NULL == resource) ||
139 (NULL == key))
140 return NULL;
141 return json_object_get (resource->res_obj, key);
142}
143
144int
145check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource,
146 const char* key,
147 const char* attr)
148{
149 json_t *value;
150 if ( (NULL == resource) ||
151 (NULL == key) ||
152 (NULL == attr))
153 return GNUNET_NO;
154 value = json_object_get (resource->res_obj, key);
155 if (NULL == value)
156 return GNUNET_NO;
157 if (!json_is_string (value) ||
158 (0 != strcmp (attr, json_string_value(value))))
159 {
160 return GNUNET_NO;
161 }
162 return GNUNET_YES;
163}
164
165/**
166 * Check a JSON API resource id
167 *
168 * @param res the JSON resource
169 * @param id the expected id
170 * @return GNUNET_YES if id matches
171 */
172int
173GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource,
174 const char* id)
175{
176 return check_resource_attr_str (resource, GNUNET_JSONAPI_KEY_ID, id);
177}
178
179/**
180 * Check a JSON API resource id
181 *
182 * @param res the JSON resource
183 * @return the resource id
184 */
185json_t*
186GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource)
187{
188 return GNUNET_JSONAPI_resource_read_attr (resource, GNUNET_JSONAPI_KEY_ID);
189}
190
191/**
192 * Check a JSON API resource type
193 *
194 * @param res the JSON resource
195 * @param type the expected type
196 * @return GNUNET_YES if id matches
197 */
198int
199GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource,
200 const char* type)
201{
202 return check_resource_attr_str (resource, GNUNET_JSONAPI_KEY_TYPE, type);
203}
204
205/**
206 * Get a JSON API object resource count
207 *
208 * @param resp the JSON API object
209 * @return the number of resources
210 */
211int
212GNUNET_JSONAPI_object_resource_count (struct GNUNET_JSONAPI_Object *resp)
213{
214 return resp->res_count;
215}
216
217/**
218 * Get a JSON API object resource by index
219 *
220 * @param resp the JSON API object
221 * @param num the number of the resource
222 * @return the resource
223 */
224struct GNUNET_JSONAPI_Resource*
225GNUNET_JSONAPI_object_get_resource (struct GNUNET_JSONAPI_Object *resp,
226 int num)
227{
228 struct GNUNET_JSONAPI_Resource *res;
229 int i;
230
231 if ((0 == resp->res_count) ||
232 (num >= resp->res_count))
233 return NULL;
234 res = resp->res_list_head;
235 for (i = 0; i < num; i++)
236 {
237 res = res->next;
238 }
239 return res;
240}
241
242/**
243 * Delete a JSON API resource
244 *
245 * @param res the JSON resource
246 * @param result Pointer where the resource should be stored
247 */
248void
249GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource)
250{
251 json_decref (resource->res_obj);
252 GNUNET_free (resource);
253 resource = NULL;
254}
255
256/**
257 * Delete a JSON API primary data
258 *
259 * @param type the JSON API resource type
260 * @param id the JSON API resource id
261 * @return a new JSON API resource or NULL on error.
262 */
263void
264GNUNET_JSONAPI_object_delete (struct GNUNET_JSONAPI_Object *resp)
265{
266 struct GNUNET_JSONAPI_Resource *res;
267 struct GNUNET_JSONAPI_Resource *res_next;
268
269 for (res = resp->res_list_head;
270 res != NULL;)
271 {
272 res_next = res->next;
273 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
274 resp->res_list_tail,
275 res);
276 GNUNET_JSONAPI_resource_delete (res);
277 res = res_next;
278 }
279 GNUNET_free (resp);
280 resp = NULL;
281}
282
283/**
284 * Create a JSON API primary data
285 *
286 * @return a new JSON API resource or NULL on error.
287 */
288struct GNUNET_JSONAPI_Object*
289GNUNET_JSONAPI_object_new ()
290{
291 struct GNUNET_JSONAPI_Object *result;
292
293 result = GNUNET_new (struct GNUNET_JSONAPI_Object);
294 result->res_count = 0;
295 return result;
296}
297
298/**
299 * Add a JSON API object to primary data
300 *
301 * @param data The JSON API data to add to
302 * @param res the JSON API resource to add
303 * @return the new number of resources
304 */
305void
306GNUNET_JSONAPI_object_resource_add (struct GNUNET_JSONAPI_Object *resp,
307 struct GNUNET_JSONAPI_Resource *res)
308{
309 GNUNET_CONTAINER_DLL_insert (resp->res_list_head,
310 resp->res_list_tail,
311 res);
312
313 resp->res_count++;
314}
315
316static void
317add_json_resource (struct GNUNET_JSONAPI_Object *obj,
318 const json_t *res_json)
319{
320 struct GNUNET_JSONAPI_Resource *res;
321 const char *type_json;
322
323 struct GNUNET_JSON_Specification dspec[] = {
324 GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type_json),
325 GNUNET_JSON_spec_end()
326 };
327
328 GNUNET_assert (GNUNET_OK ==
329 GNUNET_JSON_parse (res_json, dspec,
330 NULL, NULL));
331 GNUNET_JSON_parse_free (dspec);
332 res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
333 res->next = NULL;
334 res->prev = NULL;
335 res->res_obj = json_deep_copy (res_json);
336 GNUNET_JSONAPI_object_resource_add (obj, res);
337}
338
339/**
340 * Parse given JSON object to RSA public key.
341 *
342 * @param cls closure, NULL
343 * @param root the json object representing data
344 * @param[out] spec where to write the data
345 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
346 */
347static int
348parse_jsonapiobject (void *cls,
349 json_t *root,
350 struct GNUNET_JSON_Specification *spec)
351{
352 struct GNUNET_JSONAPI_Object *result;
353 json_t *data_json;
354 int res_count = 0;
355 int i;
356
357 struct GNUNET_JSON_Specification jsonapispec[] = {
358 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &data_json),
359 GNUNET_JSON_spec_end()
360 };
361 if (GNUNET_OK !=
362 GNUNET_JSON_parse (root, jsonapispec,
363 NULL, NULL) || (NULL == data_json))
364 {
365 return GNUNET_SYSERR;
366 }
367
368 result = GNUNET_new (struct GNUNET_JSONAPI_Object);
369 result->res_count = 0;
370 if (json_is_object (data_json))
371 add_json_resource (result, data_json);
372 else if (json_is_array (data_json))
373 {
374 res_count = json_array_size (data_json);
375 for (i = 0; i < res_count; i++)
376 add_json_resource (result, json_array_get (data_json, i));
377 }
378 if (0 == result->res_count)
379 {
380 GNUNET_free (result);
381 GNUNET_JSON_parse_free (jsonapispec);
382 return GNUNET_SYSERR;
383 }
384 *(struct GNUNET_JSONAPI_Object **) spec->ptr = result;
385 GNUNET_JSON_parse_free (jsonapispec);
386 return GNUNET_OK;
387}
388
389
390/**
391 * Cleanup data left from parsing RSA public key.
392 *
393 * @param cls closure, NULL
394 * @param[out] spec where to free the data
395 */
396static void
397clean_jsonapiobject (void *cls,
398 struct GNUNET_JSON_Specification *spec)
399{
400 struct GNUNET_JSONAPI_Object **jsonapi_obj;
401 jsonapi_obj = (struct GNUNET_JSONAPI_Object **) spec->ptr;
402 if (NULL != *jsonapi_obj)
403 {
404 GNUNET_JSONAPI_object_delete (*jsonapi_obj);
405 *jsonapi_obj = NULL;
406 }
407}
408
409/**
410 * Add a JSON API resource to primary data
411 *
412 * @param data The JSON API data to add to
413 * @param res the JSON API resource to add
414 * @return the new number of resources
415 */
416void
417GNUNET_JSONAPI_data_resource_remove (struct GNUNET_JSONAPI_Object *resp,
418 struct GNUNET_JSONAPI_Resource *res)
419{
420 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
421 resp->res_list_tail,
422 res);
423 resp->res_count--;
424}
425
426/**
427 * String serialze jsonapi primary data
428 *
429 * @param data the JSON API primary data
430 * @param result where to store the result
431 * @return GNUNET_SYSERR on error else GNUNET_OK
432 */
433int
434GNUNET_JSONAPI_data_serialize (const struct GNUNET_JSONAPI_Object *resp,
435 char **result)
436{
437 struct GNUNET_JSONAPI_Resource *res;
438 json_t *root_json;
439 json_t *res_arr;
440
441 if ((NULL == resp))
442 return GNUNET_SYSERR;
443
444 root_json = json_object ();
445 res_arr = json_array ();
446 for (res = resp->res_list_head;
447 res != NULL;
448 res = res->next)
449 {
450 json_array_append (res_arr, res->res_obj);
451 }
452 json_object_set (root_json, GNUNET_JSONAPI_KEY_DATA, res_arr);
453 *result = json_dumps (root_json, JSON_INDENT(2));
454 json_decref (root_json);
455 json_decref (res_arr);
456 return GNUNET_OK;
457}
458
459/**
460 * JSON object.
461 *
462 * @param name name of the JSON field
463 * @param[out] jsonp where to store the JSON found under @a name
464 */
465struct GNUNET_JSON_Specification
466GNUNET_JSON_spec_jsonapi (struct GNUNET_JSONAPI_Object **jsonapi_object)
467{
468 struct GNUNET_JSON_Specification ret = {
469 .parser = &parse_jsonapiobject,
470 .cleaner = &clean_jsonapiobject,
471 .cls = NULL,
472 .field = NULL,
473 .ptr = jsonapi_object,
474 .ptr_size = 0,
475 .size_ptr = NULL
476 };
477 *jsonapi_object = NULL;
478 return ret;
479}
480
481/** 29/**
482 * Check rest request for validity 30 * Check rest request for validity
483 * 31 *
diff --git a/src/jsonapi/jsonapi_document.c b/src/jsonapi/jsonapi_document.c
new file mode 100644
index 000000000..4837ee2be
--- /dev/null
+++ b/src/jsonapi/jsonapi_document.c
@@ -0,0 +1,374 @@
1
2#include "platform.h"
3#include "gnunet_util_lib.h"
4#include "gnunet_json_lib.h"
5#include "jsonapi_objects.h"
6
7/**
8 * Get a JSON API object resource count
9 *
10 * @param resp the JSON API object
11 * @return the number of resources
12 */
13int
14GNUNET_JSONAPI_document_resource_count (struct GNUNET_JSONAPI_Document *doc)
15{
16 return doc->res_count;
17}
18
19/**
20 * Get a JSON API object resource by index
21 *
22 * @param resp the JSON API object
23 * @param idx index of the resource
24 * @return the resource
25 */
26struct GNUNET_JSONAPI_Resource*
27GNUNET_JSONAPI_document_get_resource (struct GNUNET_JSONAPI_Document *doc,
28 int idx)
29{
30 struct GNUNET_JSONAPI_Resource *res;
31 int i;
32
33 if ((0 == doc->res_count) ||
34 (idx >= doc->res_count))
35 return NULL;
36 res = doc->res_list_head;
37 for (i = 0; i < idx; i++)
38 {
39 res = res->next;
40 }
41 return res;
42}
43
44/**
45 * Delete a JSON API primary data
46 *
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.
50 */
51void
52GNUNET_JSONAPI_document_delete (struct GNUNET_JSONAPI_Document *doc)
53{
54 struct GNUNET_JSONAPI_Resource *res;
55 struct GNUNET_JSONAPI_Resource *res_next;
56
57
58 for (res = doc->res_list_head;
59 res != NULL;)
60 {
61 res_next = res->next;
62 GNUNET_CONTAINER_DLL_remove (doc->res_list_head,
63 doc->res_list_tail,
64 res);
65 GNUNET_JSONAPI_resource_delete (res);
66 res = res_next;
67 }
68 GNUNET_free (doc);
69 doc = NULL;
70}
71
72/**
73 * Create a JSON API primary data
74 *
75 * @return a new JSON API resource or NULL on error.
76 */
77struct GNUNET_JSONAPI_Document*
78GNUNET_JSONAPI_document_new ()
79{
80 struct GNUNET_JSONAPI_Document *result;
81
82 result = GNUNET_new (struct GNUNET_JSONAPI_Document);
83 result->res_count = 0;
84 result->err_count = 0;
85 result->meta = 0;
86 return result;
87}
88
89/**
90 * Add a JSON API error to document
91 *
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
95 */
96void
97GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc,
98 struct GNUNET_JSONAPI_Error *err)
99{
100 GNUNET_CONTAINER_DLL_insert (doc->err_list_head,
101 doc->err_list_tail,
102 err);
103
104 doc->err_count++;
105}
106
107/**
108 * Add a JSON API resource to primary data
109 *
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
113 */
114void
115GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *doc,
116 struct GNUNET_JSONAPI_Resource *res)
117{
118 GNUNET_CONTAINER_DLL_insert (doc->res_list_head,
119 doc->res_list_tail,
120 res);
121
122 doc->res_count++;
123}
124
125
126/**
127 * Parse given JSON object to jsonapi document.
128 *
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
133 */
134static int
135parse_jsonapiobject (void *cls,
136 json_t *root,
137 struct GNUNET_JSON_Specification *spec)
138{
139 struct GNUNET_JSONAPI_Document *result;
140 struct GNUNET_JSONAPI_Error *error;
141 struct GNUNET_JSONAPI_Resource *resource;
142 json_t *meta_json;
143 json_t *resource_json;
144 json_t *errors_json;
145 json_t *value;
146 size_t index;
147
148 struct GNUNET_JSON_Specification jsonapispecerrors[] = {
149 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ERRORS, &errors_json),
150 GNUNET_JSON_spec_end()
151 };
152 if (GNUNET_OK !=
153 GNUNET_JSON_parse (root, jsonapispecerrors,
154 NULL, NULL))
155 {
156 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
157 "JSONAPI document does not contain error objects\n");
158 } else if (!json_is_array (errors_json))
159 {
160 GNUNET_log (GNUNET_ERROR_TYPE_ERROR,
161 "Error object is not array!\n");
162 GNUNET_JSON_parse_free (jsonapispecerrors);
163 return GNUNET_SYSERR;
164 }
165 struct GNUNET_JSON_Specification jsonapispecmeta[] = {
166 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_META, &meta_json),
167 GNUNET_JSON_spec_end()
168 };
169 if (GNUNET_OK !=
170 GNUNET_JSON_parse (root, jsonapispecmeta,
171 NULL, NULL))
172 {
173 GNUNET_log (GNUNET_ERROR_TYPE_INFO,
174 "JSONAPI document does not contain error objects\n");
175 }
176 struct GNUNET_JSON_Specification jsonapispecresource[] = {
177 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &resource_json),
178 GNUNET_JSON_spec_end()
179 };
180 if (GNUNET_OK !=
181 GNUNET_JSON_parse (root, jsonapispecresource,
182 NULL, NULL))
183 {
184 if (NULL == errors_json)
185 {
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;
191 }
192 } else {
193 if (NULL != errors_json)
194 {
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;
201 }
202 }
203
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,
213 &error));
214 GNUNET_JSONAPI_document_error_add (result, error);
215 }
216 }
217 if (NULL != resource_json) {
218 if (0 != json_is_array (resource_json))
219 {
220 json_array_foreach(resource_json, index, value) {
221 GNUNET_assert (GNUNET_OK ==
222 GNUNET_JSONAPI_json_to_resource (value,
223 &resource));
224 GNUNET_JSONAPI_document_resource_add (result, resource);
225 }
226 } else {
227 GNUNET_assert (GNUNET_OK ==
228 GNUNET_JSONAPI_json_to_resource (resource_json,
229 &resource));
230 GNUNET_JSONAPI_document_resource_add (result, resource);
231 }
232 }
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;
240 return GNUNET_OK;
241}
242
243
244/**
245 * Cleanup data left from parsing RSA public key.
246 *
247 * @param cls closure, NULL
248 * @param[out] spec where to free the data
249 */
250static void
251clean_jsonapiobject (void *cls,
252 struct GNUNET_JSON_Specification *spec)
253{
254 struct GNUNET_JSONAPI_Document **jsonapi_obj;
255 jsonapi_obj = (struct GNUNET_JSONAPI_Document **) spec->ptr;
256 if (NULL != *jsonapi_obj)
257 {
258 GNUNET_JSONAPI_document_delete (*jsonapi_obj);
259 *jsonapi_obj = NULL;
260 }
261}
262
263/**
264 * Add a JSON API resource to primary data
265 *
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
269 */
270void
271GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp,
272 struct GNUNET_JSONAPI_Resource *res)
273{
274 GNUNET_CONTAINER_DLL_remove (resp->res_list_head,
275 resp->res_list_tail,
276 res);
277 resp->res_count--;
278}
279
280
281/**
282 * String serialze jsonapi primary data
283 *
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
287 */
288int
289GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *doc,
290 char **result)
291{
292 struct GNUNET_JSONAPI_Resource *res;
293 struct GNUNET_JSONAPI_Error *error;
294 json_t *root_json;
295 json_t *res_json;
296 json_t *res_json_tmp;
297
298 if ((NULL == doc))
299 return GNUNET_SYSERR;
300
301 root_json = json_object ();
302
303 //Check for errors first
304 if (doc->err_count != 0)
305 {
306 res_json = json_array ();
307 for (error = doc->err_list_head;
308 error != NULL;
309 error = error->next)
310 {
311 GNUNET_assert (GNUNET_OK ==
312 GNUNET_JSONAPI_error_to_json (error,
313 &res_json_tmp));
314 json_array_append (res_json, res_json_tmp);
315 }
316 json_object_set (root_json, GNUNET_JSONAPI_KEY_ERRORS, res_json);
317 } else {
318 switch (doc->res_count)
319 {
320 case 0:
321 res_json = json_null();
322 break;
323 case 1:
324 GNUNET_assert (GNUNET_OK ==
325 GNUNET_JSONAPI_resource_to_json (doc->res_list_head,
326 &res_json));
327 break;
328 default:
329 res_json = json_array ();
330 for (res = doc->res_list_head;
331 res != NULL;
332 res = res->next)
333 {
334 GNUNET_assert (GNUNET_OK ==
335 GNUNET_JSONAPI_resource_to_json (res,
336 &res_json_tmp));
337 json_array_append (res_json, res_json_tmp);
338 }
339 break;
340 }
341 json_object_set (root_json, GNUNET_JSONAPI_KEY_DATA, res_json);
342 }
343
344 //Add meta
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);
349 return GNUNET_OK;
350}
351
352/**
353 * JSON object.
354 *
355 * @param name name of the JSON field
356 * @param[out] jsonp where to store the JSON found under @a name
357 */
358struct GNUNET_JSON_Specification
359GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_object)
360{
361 struct GNUNET_JSON_Specification ret = {
362 .parser = &parse_jsonapiobject,
363 .cleaner = &clean_jsonapiobject,
364 .cls = NULL,
365 .field = NULL,
366 .ptr = jsonapi_object,
367 .ptr_size = 0,
368 .size_ptr = NULL
369 };
370 *jsonapi_object = NULL;
371 return ret;
372}
373
374
diff --git a/src/jsonapi/jsonapi_error.c b/src/jsonapi/jsonapi_error.c
new file mode 100644
index 000000000..d91f0a650
--- /dev/null
+++ b/src/jsonapi/jsonapi_error.c
@@ -0,0 +1,205 @@
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 */
12int
13GNUNET_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 */
31int
32GNUNET_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 */
90static int
91parse_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 * Delete a JSON API error
136 *
137 * @param res the JSON error
138 */
139void
140GNUNET_JSONAPI_error_delete (struct GNUNET_JSONAPI_Error *error)
141{
142 GNUNET_assert (NULL != error);
143
144 if (NULL != error->id)
145 GNUNET_free (error->id);
146 if (NULL != error->status)
147 GNUNET_free (error->status);
148 if (NULL != error->code)
149 GNUNET_free (error->code);
150 if (NULL != error->title)
151 GNUNET_free (error->title);
152 if (NULL != error->detail)
153 GNUNET_free (error->detail);
154 if (NULL != error->links)
155 json_decref (error->links);
156 if (NULL != error->source)
157 json_decref (error->source);
158 if (NULL != error->meta)
159 json_decref (error->meta);
160 GNUNET_free (error);
161}
162
163
164
165/**
166 * Cleanup data left from parsing RSA public key.
167 *
168 * @param cls closure, NULL
169 * @param[out] spec where to free the data
170 */
171static void
172clean_jsonapierror (void *cls,
173 struct GNUNET_JSON_Specification *spec)
174{
175 struct GNUNET_JSONAPI_Error **jsonapi_obj;
176 jsonapi_obj = (struct GNUNET_JSONAPI_Error **) spec->ptr;
177 if (NULL != *jsonapi_obj)
178 {
179 GNUNET_JSONAPI_error_delete (*jsonapi_obj);
180 *jsonapi_obj = NULL;
181 }
182}
183/**
184 * JSON object.
185 *
186 * @param name name of the JSON field
187 * @param[out] jsonp where to store the JSON found under @a name
188 */
189struct GNUNET_JSON_Specification
190GNUNET_JSON_spec_jsonapi_error (struct GNUNET_JSONAPI_Error **jsonapi_object)
191{
192 struct GNUNET_JSON_Specification ret = {
193 .parser = &parse_jsonapierror,
194 .cleaner = &clean_jsonapierror,
195 .cls = NULL,
196 .field = NULL,
197 .ptr = jsonapi_object,
198 .ptr_size = 0,
199 .size_ptr = NULL
200 };
201 *jsonapi_object = NULL;
202 return ret;
203}
204
205
diff --git a/src/jsonapi/jsonapi_objects.h b/src/jsonapi/jsonapi_objects.h
new file mode 100644
index 000000000..27c64eeb7
--- /dev/null
+++ b/src/jsonapi/jsonapi_objects.h
@@ -0,0 +1,162 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3/**
4 * jsonapi error object
5 */
6struct GNUNET_JSONAPI_Error
7{
8 /**
9 * DLL
10 */
11 struct GNUNET_JSONAPI_Error *next;
12
13 /**
14 * DLL
15 */
16 struct GNUNET_JSONAPI_Error *prev;
17
18 /**
19 * Unique error id
20 */
21 char *id;
22
23 /**
24 * Links object
25 */
26 json_t *links;
27
28 /**
29 * HTTP status code for this error
30 */
31 char *status;
32
33 /**
34 * Application error code
35 */
36 char *code;
37
38 /**
39 * Error title
40 */
41 char *title;
42
43 /**
44 * Error details
45 */
46 char *detail;
47
48 /**
49 * Error source
50 */
51 json_t *source;
52
53 /**
54 * Meta info for the error
55 */
56 json_t *meta;
57};
58
59struct GNUNET_JSONAPI_Relationship
60{
61 /**
62 * Links object
63 */
64 struct GNUNET_JSONAPI_Link *links;
65
66 /**
67 * Resource linkage data
68 */
69 struct GNUNET_JSONAPI_Resource *res_list_head;
70
71 /**
72 * DLL
73 */
74 struct GNUNET_JSONAPI_Resource *res_list_tail;
75
76 /**
77 * Number of resources in data section
78 */
79 int res_count;
80
81 /**
82 * Meta information
83 */
84 json_t *meta;
85};
86
87/**
88 * A jsonapi resource object
89 */
90struct GNUNET_JSONAPI_Resource
91{
92 /**
93 * DLL
94 */
95 struct GNUNET_JSONAPI_Resource *next;
96
97 /**
98 * DLL
99 */
100 struct GNUNET_JSONAPI_Resource *prev;
101
102 /**
103 * Resource type
104 */
105 char *type;
106
107 /**
108 * Resource ID
109 */
110 char *id;
111
112 /**
113 * Attributes object
114 */
115 json_t *attr_obj;
116
117 /**
118 * Relationship
119 */
120 struct GNUNET_JSONAPI_Relationship *relationship;
121};
122
123
124struct GNUNET_JSONAPI_Document
125{
126 /**
127 * DLL Resource
128 */
129 struct GNUNET_JSONAPI_Resource *res_list_head;
130
131 /**
132 * DLL Resource
133 */
134 struct GNUNET_JSONAPI_Resource *res_list_tail;
135
136 /**
137 * num resources
138 */
139 int res_count;
140
141 /**
142 * DLL Error
143 */
144 struct GNUNET_JSONAPI_Error *err_list_head;
145
146 /**
147 * DLL Error
148 */
149 struct GNUNET_JSONAPI_Error *err_list_tail;
150
151 /**
152 * num errors
153 */
154 int err_count;
155
156 /**
157 * Meta info
158 */
159 json_t *meta;
160};
161
162
diff --git a/src/jsonapi/jsonapi_relationship.c b/src/jsonapi/jsonapi_relationship.c
new file mode 100644
index 000000000..b88e74cc9
--- /dev/null
+++ b/src/jsonapi/jsonapi_relationship.c
@@ -0,0 +1,17 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3
4
5/**
6 * Delete a JSON API relationship TODO
7 *
8 * @param res the JSON relationship
9 */
10void
11GNUNET_JSONAPI_relationship_delete (struct GNUNET_JSONAPI_Relationship *relationship)
12{
13 GNUNET_assert (NULL != relationship);
14 GNUNET_free (relationship);
15}
16
17
diff --git a/src/jsonapi/jsonapi_resource.c b/src/jsonapi/jsonapi_resource.c
new file mode 100644
index 000000000..09217279a
--- /dev/null
+++ b/src/jsonapi/jsonapi_resource.c
@@ -0,0 +1,367 @@
1#include "platform.h"
2#include "gnunet_jsonapi_lib.h"
3#include "jsonapi_objects.h"
4
5/**
6 * String serialze jsonapi resources
7 *
8 * @param data the JSON API resource
9 * @param result where to store the result
10 * @return GNUNET_SYSERR on error else GNUNET_OK
11 */
12int
13GNUNET_JSONAPI_resource_to_json (const struct GNUNET_JSONAPI_Resource *res,
14 json_t **result)
15{
16 struct GNUNET_JSONAPI_Resource *rel_res;
17 json_t *relationship;
18 json_t *res_json_tmp;
19 *result = json_object ();
20
21 if (0 != json_object_set_new (*result,
22 GNUNET_JSONAPI_KEY_ID,
23 json_string (res->id)))
24 return GNUNET_SYSERR;
25 if (0 != json_object_set_new (*result,
26 GNUNET_JSONAPI_KEY_TYPE,
27 json_string (res->type)))
28 return GNUNET_SYSERR;
29 if ((NULL != res->attr_obj) &&
30 (0 != json_object_set (*result,
31 GNUNET_JSONAPI_KEY_ATTRIBUTES,
32 res->attr_obj)))
33 return GNUNET_SYSERR;
34
35 //Relationships
36 if (NULL != res->relationship)
37 {
38 relationship = json_object ();
39 if (0 != res->relationship->res_count)
40 {
41 json_t *res_json;
42 switch (res->relationship->res_count)
43 {
44 case 0:
45 res_json = json_null();
46 break;
47 case 1:
48 GNUNET_assert (GNUNET_OK ==
49 GNUNET_JSONAPI_resource_to_json (res->relationship->res_list_head,
50 &res_json));
51 break;
52 default:
53 res_json = json_array ();
54 rel_res = NULL;
55 for (rel_res = rel_res->relationship->res_list_head;
56 rel_res != NULL;
57 rel_res = rel_res->next)
58 {
59 GNUNET_assert (GNUNET_OK ==
60 GNUNET_JSONAPI_resource_to_json (rel_res,
61 &res_json_tmp));
62 json_array_append_new (res_json, res_json_tmp);
63 }
64 break;
65 }
66 json_object_set_new (relationship,
67 GNUNET_JSONAPI_KEY_DATA,
68 res_json);
69 }
70 if ((NULL != res->relationship->meta) &&
71 (0 != json_object_set_new (relationship,
72 GNUNET_JSONAPI_KEY_META,
73 res->relationship->meta)))
74 return GNUNET_SYSERR;
75 //TODO link
76 }
77
78
79 return GNUNET_OK;
80}
81
82
83/**
84 * Create a JSON API resource
85 *
86 * @param type the JSON API resource type
87 * @param id the JSON API resource id
88 * @return a new JSON API resource or NULL on error.
89 */
90struct GNUNET_JSONAPI_Resource*
91GNUNET_JSONAPI_resource_new (const char *type, const char *id)
92{
93 struct GNUNET_JSONAPI_Resource *res;
94
95 if ( (NULL == type) || (0 == strlen (type)) )
96 return NULL;
97 if ( (NULL == id) || (0 == strlen (id)) )
98 return NULL;
99
100 res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
101 res->prev = NULL;
102 res->next = NULL;
103 res->attr_obj = NULL;
104 res->relationship = NULL;
105 res->id = GNUNET_strdup (id);
106 res->type = GNUNET_strdup (type);
107 return res;
108}
109
110/**
111 * Add a jsonapi relationship
112 * @param res the resource to add to
113 * @param rel the relationship to add
114 * @return #GNUNETOK if added successfully
115 */
116int
117GNUNET_JSONAPI_resource_set_relationship (struct GNUNET_JSONAPI_Resource *res,
118 struct GNUNET_JSONAPI_Relationship *rel)
119{
120 GNUNET_assert (NULL != res);
121 GNUNET_assert (NULL != rel);
122 if (NULL != res->relationship)
123 return GNUNET_SYSERR;
124 res->relationship = rel;
125 return GNUNET_OK;
126}
127
128/**
129 * Add a JSON API attribute
130 *
131 * @param res the JSON resource
132 * @param key the key for the attribute
133 * @param json the json_t attribute to add
134 * @return #GNUNET_OK if added successfully
135 * #GNUNET_SYSERR if not
136 */
137int
138GNUNET_JSONAPI_resource_add_attr (struct GNUNET_JSONAPI_Resource *resource,
139 const char* key,
140 json_t *json)
141{
142 if ( (NULL == resource) ||
143 (NULL == key) ||
144 (NULL == json) )
145 return GNUNET_SYSERR;
146 if (NULL == resource->attr_obj)
147 resource->attr_obj = json_object ();
148 json_object_set (resource->attr_obj, key, json);
149 return GNUNET_OK;
150}
151
152/**
153 * Read a JSON API attribute
154 *
155 * @param res the JSON resource
156 * @param key the key for the attribute
157 * @return the json_t object
158 */
159json_t*
160GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource,
161 const char* key)
162{
163 if ( (NULL == resource) ||
164 (NULL == key) ||
165 (NULL == resource->attr_obj))
166 return NULL;
167 return json_object_get (resource->attr_obj, key);
168}
169
170int
171check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource,
172 const char* key,
173 const char* attr)
174{
175 json_t *value;
176 if ( (NULL == resource) ||
177 (NULL == key) ||
178 (NULL == attr) ||
179 (NULL == resource->attr_obj))
180 return GNUNET_NO;
181 value = json_object_get (resource->attr_obj, key);
182 if (NULL == value)
183 return GNUNET_NO;
184 if (!json_is_string (value) ||
185 (0 != strcmp (attr, json_string_value(value))))
186 {
187 return GNUNET_NO;
188 }
189 return GNUNET_YES;
190}
191
192/**
193 * Check a JSON API resource type
194 *
195 * @param res the JSON resource
196 * @param type the expected type
197 * @return GNUNET_YES if id matches
198 */
199int
200GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource,
201 const char* type)
202{
203 return (0 == memcmp (type, resource->type,
204 strlen (resource->type))) ? GNUNET_YES : GNUNET_NO;
205}
206
207
208/**
209 * Delete a JSON API resource
210 *
211 * @param res the JSON resource
212 * @param result Pointer where the resource should be stored
213 */
214void
215GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource)
216{
217 GNUNET_free (resource->id);
218 GNUNET_free (resource->type);
219 if (NULL != resource->attr_obj)
220 json_decref (resource->attr_obj);
221 if (NULL != resource->relationship)
222 GNUNET_JSONAPI_relationship_delete (resource->relationship);
223 GNUNET_free (resource);
224 resource = NULL;
225}
226
227
228/**
229 * Check a JSON API resource id
230 *
231 * @param res the JSON resource
232 * @param id the expected id
233 * @return GNUNET_YES if id matches
234 */
235int
236GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource,
237 const char* id)
238{
239 return (0 == memcmp (resource->id, id, strlen (id))) ? GNUNET_YES : GNUNET_NO;
240}
241
242/**
243 * Check a JSON API resource id
244 *
245 * @param res the JSON resource
246 * @return the resource id
247 */
248char*
249GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource)
250{
251 return resource->id;
252}
253
254/**
255 * Parse json to resource object
256 *
257 * @param res_json JSON object
258 * @param[out] res resource object
259 * @return GNUNET_OK on success
260 */
261int
262GNUNET_JSONAPI_json_to_resource (json_t *res_json,
263 struct GNUNET_JSONAPI_Resource **res)
264{
265 struct GNUNET_JSON_Specification jsonapispecresource[] = {
266 GNUNET_JSON_spec_jsonapi_resource (res),
267 GNUNET_JSON_spec_end()
268 };
269 return GNUNET_JSON_parse (res_json, jsonapispecresource,
270 NULL, NULL);
271}
272
273/**
274 * Parse given JSON object to jsonapi document.
275 *
276 * @param cls closure, NULL
277 * @param root the json object representing data
278 * @param[out] spec where to write the data
279 * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error
280 */
281static int
282parse_jsonapiresource (void *cls,
283 json_t *root,
284 struct GNUNET_JSON_Specification *spec)
285{
286 struct GNUNET_JSONAPI_Resource *res;
287 const char *type;
288 const char *id;
289 json_t *attrs;
290
291 struct GNUNET_JSON_Specification dspec[] = {
292 GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type),
293 GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_ID, &id),
294 GNUNET_JSON_spec_end()
295 };
296
297 if (GNUNET_OK !=
298 GNUNET_JSON_parse (root, dspec,
299 NULL, NULL))
300 {
301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse resource\n");
302 return GNUNET_SYSERR;
303 }
304 res = GNUNET_JSONAPI_resource_new (type, id);
305 GNUNET_JSON_parse_free (dspec);
306
307 struct GNUNET_JSON_Specification attrspec[] = {
308 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ATTRIBUTES, &attrs),
309 GNUNET_JSON_spec_end()
310 };
311 if (GNUNET_OK !=
312 GNUNET_JSON_parse (root, attrspec,
313 NULL, NULL))
314 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resource does not contain attributes\n");
315 if (NULL != attrs)
316 res->attr_obj = json_deep_copy (attrs);
317
318 //TODO relationship
319 GNUNET_JSON_parse_free (attrspec);
320 *(struct GNUNET_JSONAPI_Resource **) spec->ptr = res;
321 return GNUNET_OK;
322}
323
324
325/**
326 * Cleanup data left from parsing resource.
327 *
328 * @param cls closure, NULL
329 * @param[out] spec where to free the data
330 */
331static void
332clean_jsonapiresource (void *cls,
333 struct GNUNET_JSON_Specification *spec)
334{
335 struct GNUNET_JSONAPI_Resource **jsonapi_obj;
336 jsonapi_obj = (struct GNUNET_JSONAPI_Resource **) spec->ptr;
337 if (NULL != *jsonapi_obj)
338 {
339 GNUNET_JSONAPI_resource_delete (*jsonapi_obj);
340 *jsonapi_obj = NULL;
341 }
342}
343
344
345/**
346 * JSON object.
347 *
348 * @param name name of the JSON field
349 * @param[out] jsonp where to store the JSON found under @a name
350 */
351struct GNUNET_JSON_Specification
352GNUNET_JSON_spec_jsonapi_resource (struct GNUNET_JSONAPI_Resource **jsonapi_object)
353{
354 struct GNUNET_JSON_Specification ret = {
355 .parser = &parse_jsonapiresource,
356 .cleaner = &clean_jsonapiresource,
357 .cls = NULL,
358 .field = NULL,
359 .ptr = jsonapi_object,
360 .ptr_size = 0,
361 .size_ptr = NULL
362 };
363 *jsonapi_object = NULL;
364 return ret;
365}
366
367
diff --git a/src/jsonapi/test_jsonapi.c b/src/jsonapi/test_jsonapi.c
index e9c85eaf6..8b0b13566 100644
--- a/src/jsonapi/test_jsonapi.c
+++ b/src/jsonapi/test_jsonapi.c
@@ -27,14 +27,14 @@
27static int 27static int
28test_serialize () 28test_serialize ()
29{ 29{
30 struct GNUNET_JSONAPI_Object *obj; 30 struct GNUNET_JSONAPI_Document *obj;
31 char* data = "{\"data\":[{\"id\":\"1\", \"type\":\"test\"}]}"; 31 char* data = "{\"data\":{\"id\":\"1\",\"type\":\"bar\", \"attributes\":{\"foo\":\"bar\"}}}";
32 char* tmp_data; 32 char* tmp_data;
33 json_t* data_js; 33 json_t* data_js;
34 json_t* tmp_data_js; 34 json_t* tmp_data_js;
35 json_error_t err; 35 json_error_t err;
36 struct GNUNET_JSON_Specification jsonapispec[] = { 36 struct GNUNET_JSON_Specification jsonapispec[] = {
37 GNUNET_JSON_spec_jsonapi (&obj), 37 GNUNET_JSON_spec_jsonapi_document (&obj),
38 GNUNET_JSON_spec_end() 38 GNUNET_JSON_spec_end()
39 }; 39 };
40 data_js = json_loads (data, JSON_DECODE_ANY, &err); 40 data_js = json_loads (data, JSON_DECODE_ANY, &err);
@@ -42,8 +42,8 @@ test_serialize ()
42 GNUNET_assert (GNUNET_OK == 42 GNUNET_assert (GNUNET_OK ==
43 GNUNET_JSON_parse (data_js, jsonapispec, 43 GNUNET_JSON_parse (data_js, jsonapispec,
44 NULL, NULL)); 44 NULL, NULL));
45 GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_data_serialize (obj, 45 GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_serialize (obj,
46 &tmp_data)); 46 &tmp_data));
47 GNUNET_JSON_parse_free (jsonapispec); 47 GNUNET_JSON_parse_free (jsonapispec);
48 tmp_data_js = json_loads (tmp_data, JSON_DECODE_ANY, &err); 48 tmp_data_js = json_loads (tmp_data, JSON_DECODE_ANY, &err);
49 GNUNET_assert (NULL != tmp_data_js); 49 GNUNET_assert (NULL != tmp_data_js);
@@ -62,14 +62,14 @@ test_serialize ()
62static int 62static int
63test_spec_jsonapi () 63test_spec_jsonapi ()
64{ 64{
65 struct GNUNET_JSONAPI_Object *obj; 65 struct GNUNET_JSONAPI_Document *obj;
66 struct GNUNET_JSONAPI_Resource *res; 66 struct GNUNET_JSONAPI_Resource *res;
67 const char* data = "{\"data\":{\"id\":\"1\", \"type\":\"test\"}}"; 67 const char* data = "{\"data\":{\"id\":\"1\", \"type\":\"test\"}}";
68 json_t* data_js; 68 json_t* data_js;
69 json_error_t err; 69 json_error_t err;
70 70
71 struct GNUNET_JSON_Specification jsonapispec[] = { 71 struct GNUNET_JSON_Specification jsonapispec[] = {
72 GNUNET_JSON_spec_jsonapi (&obj), 72 GNUNET_JSON_spec_jsonapi_document (&obj),
73 GNUNET_JSON_spec_end() 73 GNUNET_JSON_spec_end()
74 }; 74 };
75 data_js = json_loads (data, JSON_DECODE_ANY, &err); 75 data_js = json_loads (data, JSON_DECODE_ANY, &err);
@@ -78,10 +78,10 @@ test_spec_jsonapi ()
78 GNUNET_JSON_parse (data_js, jsonapispec, 78 GNUNET_JSON_parse (data_js, jsonapispec,
79 NULL, NULL)); 79 NULL, NULL));
80 json_decref (data_js); 80 json_decref (data_js);
81 res = GNUNET_JSONAPI_object_get_resource (obj, 0); 81 res = GNUNET_JSONAPI_document_get_resource (obj, 0);
82 GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_id (res, "1")); 82 GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_id (res, "1"));
83 GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_type (res, "test")); 83 GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_type (res, "test"));
84 GNUNET_assert (1 == GNUNET_JSONAPI_object_resource_count (obj)); 84 GNUNET_assert (1 == GNUNET_JSONAPI_document_resource_count (obj));
85 GNUNET_JSON_parse_free (jsonapispec); 85 GNUNET_JSON_parse_free (jsonapispec);
86 return 0; 86 return 0;
87} 87}