2 #include "gnunet_jsonapi_lib.h"
3 #include "jsonapi_objects.h"
6 * String serialze jsonapi resources
8 * @param data the JSON API resource
9 * @param result where to store the result
10 * @return GNUNET_SYSERR on error else GNUNET_OK
13 GNUNET_JSONAPI_resource_to_json (const struct GNUNET_JSONAPI_Resource *res,
16 struct GNUNET_JSONAPI_Resource *rel_res;
19 *result = json_object ();
21 if (0 != json_object_set_new (*result,
22 GNUNET_JSONAPI_KEY_ID,
23 json_string (res->id)))
25 if (0 != json_object_set_new (*result,
26 GNUNET_JSONAPI_KEY_TYPE,
27 json_string (res->type)))
29 if ((NULL != res->attr_obj) &&
30 (0 != json_object_set (*result,
31 GNUNET_JSONAPI_KEY_ATTRIBUTES,
36 if (NULL != res->relationship)
38 relationship = json_object ();
39 if (0 != res->relationship->res_count)
42 switch (res->relationship->res_count)
45 res_json = json_null();
48 GNUNET_assert (GNUNET_OK ==
49 GNUNET_JSONAPI_resource_to_json (res->relationship->res_list_head,
53 res_json = json_array ();
55 for (rel_res = res->relationship->res_list_head;
57 rel_res = rel_res->next)
59 GNUNET_assert (GNUNET_OK ==
60 GNUNET_JSONAPI_resource_to_json (rel_res,
62 json_array_append_new (res_json, res_json_tmp);
66 json_object_set_new (relationship,
67 GNUNET_JSONAPI_KEY_DATA,
70 if ((NULL != res->relationship->meta) &&
71 (0 != json_object_set_new (relationship,
72 GNUNET_JSONAPI_KEY_META,
73 res->relationship->meta)))
84 * Create a JSON API resource
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.
90 struct GNUNET_JSONAPI_Resource*
91 GNUNET_JSONAPI_resource_new (const char *type, const char *id)
93 struct GNUNET_JSONAPI_Resource *res;
95 if ( (NULL == type) || (0 == strlen (type)) )
97 if ( (NULL == id) || (0 == strlen (id)) )
100 res = GNUNET_new (struct GNUNET_JSONAPI_Resource);
103 res->attr_obj = NULL;
104 res->relationship = NULL;
105 res->id = GNUNET_strdup (id);
106 res->type = GNUNET_strdup (type);
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
117 GNUNET_JSONAPI_resource_set_relationship (struct GNUNET_JSONAPI_Resource *res,
118 struct GNUNET_JSONAPI_Relationship *rel)
120 GNUNET_assert (NULL != res);
121 GNUNET_assert (NULL != rel);
122 if (NULL != res->relationship)
123 return GNUNET_SYSERR;
124 res->relationship = rel;
129 * Add a JSON API attribute
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
138 GNUNET_JSONAPI_resource_add_attr (struct GNUNET_JSONAPI_Resource *resource,
142 if ( (NULL == resource) ||
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);
153 * Read a JSON API attribute
155 * @param res the JSON resource
156 * @param key the key for the attribute
157 * @return the json_t object
160 GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource,
163 if ( (NULL == resource) ||
165 (NULL == resource->attr_obj))
167 return json_object_get (resource->attr_obj, key);
171 check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource,
176 if ( (NULL == resource) ||
179 (NULL == resource->attr_obj))
181 value = json_object_get (resource->attr_obj, key);
184 if (!json_is_string (value) ||
185 (0 != strcmp (attr, json_string_value(value))))
193 * Check a JSON API resource type
195 * @param res the JSON resource
196 * @param type the expected type
197 * @return GNUNET_YES if id matches
200 GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource,
203 return (0 == memcmp (type, resource->type,
204 strlen (resource->type))) ? GNUNET_YES : GNUNET_NO;
209 * Delete a JSON API resource
211 * @param res the JSON resource
212 * @param result Pointer where the resource should be stored
215 GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource)
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);
229 * Check a JSON API resource id
231 * @param res the JSON resource
232 * @param id the expected id
233 * @return GNUNET_YES if id matches
236 GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource,
239 return (0 == memcmp (resource->id, id, strlen (id))) ? GNUNET_YES : GNUNET_NO;
243 * Check a JSON API resource id
245 * @param res the JSON resource
246 * @return the resource id
249 GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource)
255 * Parse json to resource object
257 * @param res_json JSON object
258 * @param[out] res resource object
259 * @return GNUNET_OK on success
262 GNUNET_JSONAPI_json_to_resource (json_t *res_json,
263 struct GNUNET_JSONAPI_Resource **res)
265 struct GNUNET_JSON_Specification jsonapispecresource[] = {
266 GNUNET_JSON_spec_jsonapi_resource (res),
267 GNUNET_JSON_spec_end()
269 return GNUNET_JSON_parse (res_json, jsonapispecresource,
274 * Parse given JSON object to jsonapi document.
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
282 parse_jsonapiresource (void *cls,
284 struct GNUNET_JSON_Specification *spec)
286 struct GNUNET_JSONAPI_Resource *res;
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()
298 GNUNET_JSON_parse (root, dspec,
301 GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse resource\n");
302 return GNUNET_SYSERR;
304 res = GNUNET_JSONAPI_resource_new (type, id);
305 GNUNET_JSON_parse_free (dspec);
307 struct GNUNET_JSON_Specification attrspec[] = {
308 GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ATTRIBUTES, &attrs),
309 GNUNET_JSON_spec_end()
312 GNUNET_JSON_parse (root, attrspec,
314 GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resource does not contain attributes\n");
316 res->attr_obj = json_deep_copy (attrs);
319 GNUNET_JSON_parse_free (attrspec);
320 *(struct GNUNET_JSONAPI_Resource **) spec->ptr = res;
326 * Cleanup data left from parsing resource.
328 * @param cls closure, NULL
329 * @param[out] spec where to free the data
332 clean_jsonapiresource (void *cls,
333 struct GNUNET_JSON_Specification *spec)
335 struct GNUNET_JSONAPI_Resource **jsonapi_obj;
336 jsonapi_obj = (struct GNUNET_JSONAPI_Resource **) spec->ptr;
337 if (NULL != *jsonapi_obj)
339 GNUNET_JSONAPI_resource_delete (*jsonapi_obj);
348 * @param name name of the JSON field
349 * @param[out] jsonp where to store the JSON found under @a name
351 struct GNUNET_JSON_Specification
352 GNUNET_JSON_spec_jsonapi_resource (struct GNUNET_JSONAPI_Resource **jsonapi_object)
354 struct GNUNET_JSON_Specification ret = {
355 .parser = &parse_jsonapiresource,
356 .cleaner = &clean_jsonapiresource,
359 .ptr = jsonapi_object,
363 *jsonapi_object = NULL;