From a44744499d8f3df64cc1d15cd6b40b4b0e4a3683 Mon Sep 17 00:00:00 2001 From: Martin Schanzenbach Date: Wed, 4 May 2016 17:18:02 +0000 Subject: [PATCH] Update jsonapi to current specs, refactor --- src/gns/plugin_rest_gns.c | 12 +- .../gnunet-service-identity-provider.c | 3 +- .../plugin_rest_identity_provider.c | 20 +- src/identity/plugin_rest_identity.c | 66 +-- src/include/gnunet_jsonapi_lib.h | 169 ++++++- src/jsonapi/Makefile.am | 6 +- src/jsonapi/jsonapi.c | 454 +----------------- src/jsonapi/jsonapi_document.c | 374 +++++++++++++++ src/jsonapi/jsonapi_error.c | 205 ++++++++ src/jsonapi/jsonapi_objects.h | 162 +++++++ src/jsonapi/jsonapi_relationship.c | 17 + src/jsonapi/jsonapi_resource.c | 367 ++++++++++++++ src/jsonapi/test_jsonapi.c | 18 +- src/namestore/plugin_rest_namestore.c | 62 +-- src/rest/gnunet-rest-server.c | 2 +- 15 files changed, 1364 insertions(+), 573 deletions(-) create mode 100644 src/jsonapi/jsonapi_document.c create mode 100644 src/jsonapi/jsonapi_error.c create mode 100644 src/jsonapi/jsonapi_objects.h create mode 100644 src/jsonapi/jsonapi_relationship.c create mode 100644 src/jsonapi/jsonapi_resource.c diff --git a/src/gns/plugin_rest_gns.c b/src/gns/plugin_rest_gns.c index 718a9b29b..b2034c8ce 100644 --- a/src/gns/plugin_rest_gns.c +++ b/src/gns/plugin_rest_gns.c @@ -258,7 +258,7 @@ gnsrecord_to_json (const struct GNUNET_GNSRECORD_Data *rd) (int) rd->record_type); return NULL; } - record_obj = json_object(); + record_obj = json_object (); json_object_set_new (record_obj, "type", json_string (typename)); json_object_set_new (record_obj, "value", json_string (string_val)); GNUNET_free (string_val); @@ -295,7 +295,7 @@ process_lookup_result (void *cls, uint32_t rd_count, { struct LookupHandle *handle = cls; struct MHD_Response *resp; - struct GNUNET_JSONAPI_Object *json_object; + struct GNUNET_JSONAPI_Document *json_document; struct GNUNET_JSONAPI_Resource *json_resource; uint32_t i; char *result; @@ -303,7 +303,7 @@ process_lookup_result (void *cls, uint32_t rd_count, json_t *record_obj; result_array = json_array(); - json_object = GNUNET_JSONAPI_object_new (); + json_document = GNUNET_JSONAPI_document_new (); json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_GNS_TYPEINFO, handle->name); handle->lookup_request = NULL; for (i=0; iproc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_free (result); diff --git a/src/identity-provider/gnunet-service-identity-provider.c b/src/identity-provider/gnunet-service-identity-provider.c index 0bb400e07..0a690e2d3 100644 --- a/src/identity-provider/gnunet-service-identity-provider.c +++ b/src/identity-provider/gnunet-service-identity-provider.c @@ -481,7 +481,6 @@ handle_token_update (void *cls) token_record, &store_token_cont, ego_entry); - GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, ">>> Updating Token w/ %s\n", new_token); token_destroy (new_token); token_destroy (token); GNUNET_free (new_ecdhe_privkey); @@ -725,7 +724,7 @@ update_identities(void *cls) if (min_rel_exp.rel_value_us < MIN_WAIT_TIME.rel_value_us) min_rel_exp = MIN_WAIT_TIME; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - ">>> Finished. Rescheduling in %d\n", + ">>> Finished. Rescheduling in %lu\n", min_rel_exp.rel_value_us); ns_it = NULL; //finished -> reschedule diff --git a/src/identity-provider/plugin_rest_identity_provider.c b/src/identity-provider/plugin_rest_identity_provider.c index 1e1878cad..b039255b5 100644 --- a/src/identity-provider/plugin_rest_identity_provider.c +++ b/src/identity-provider/plugin_rest_identity_provider.c @@ -279,7 +279,7 @@ struct RequestHandle /** * Response object */ - struct GNUNET_JSONAPI_Object *resp_object; + struct GNUNET_JSONAPI_Document *resp_object; }; @@ -296,7 +296,7 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->resp_object) - GNUNET_JSONAPI_object_delete (handle->resp_object); + GNUNET_JSONAPI_document_delete (handle->resp_object); if (NULL != handle->timeout_task) GNUNET_SCHEDULER_cancel (handle->timeout_task); if (NULL != handle->identity_handle) @@ -403,7 +403,7 @@ token_creat_cont (void *cls, return; } - handle->resp_object = GNUNET_JSONAPI_object_new (); + handle->resp_object = GNUNET_JSONAPI_document_new (); json_resource = GNUNET_JSONAPI_resource_new (GNUNET_REST_JSONAPI_IDENTITY_PROVIDER_TICKET, label); ticket_str = GNUNET_IDENTITY_PROVIDER_ticket_to_string (ticket); @@ -420,9 +420,9 @@ token_creat_cont (void *cls, GNUNET_free (token_str); json_decref (ticket_json); json_decref (token_json); - GNUNET_JSONAPI_object_resource_add (handle->resp_object, json_resource); + GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); - GNUNET_JSONAPI_data_serialize (handle->resp_object, &result_str); + GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); resp = GNUNET_REST_create_json_response (result_str); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); @@ -638,7 +638,7 @@ return_token_list (void *cls) struct RequestHandle *handle = cls; struct MHD_Response *resp; - GNUNET_JSONAPI_data_serialize (handle->resp_object, &result_str); + GNUNET_JSONAPI_document_serialize (handle->resp_object, &result_str); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); resp = GNUNET_REST_create_json_response (result_str); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); @@ -717,7 +717,7 @@ token_collect (void *cls, token); json_decref (token); - GNUNET_JSONAPI_object_resource_add (handle->resp_object, json_resource); + GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); GNUNET_free (data); } } @@ -776,7 +776,7 @@ list_token_cont (struct GNUNET_REST_RequestHandle *con_handle, GNUNET_free (ego_tmp); } } - handle->resp_object = GNUNET_JSONAPI_object_new (); + handle->resp_object = GNUNET_JSONAPI_document_new (); if (NULL == handle->ego_head) { //Done @@ -1045,7 +1045,7 @@ list_ego (void *cls, ego_entry->keystring = GNUNET_CRYPTO_ecdsa_public_key_to_string (&pk); ego_entry->ego = ego; - GNUNET_asprintf (&ego_entry->identifier, "%s", identifier); + ego_entry->identifier = GNUNET_strdup (identifier); GNUNET_CONTAINER_DLL_insert_tail(handle->ego_head,handle->ego_tail, ego_entry); } @@ -1076,7 +1076,7 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *conndata_handle, handle->conndata_handle = conndata_handle; - GNUNET_asprintf (&handle->url, "%s", conndata_handle->url); + handle->url = GNUNET_strdup (conndata_handle->url); if (handle->url[strlen (handle->url)-1] == '/') handle->url[strlen (handle->url)-1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/identity/plugin_rest_identity.c b/src/identity/plugin_rest_identity.c index 4a2429a9c..50d13713a 100644 --- a/src/identity/plugin_rest_identity.c +++ b/src/identity/plugin_rest_identity.c @@ -302,14 +302,14 @@ get_ego_for_subsys (void *cls, const char *name) { struct RequestHandle *handle = cls; - struct GNUNET_JSONAPI_Object *json_object; + struct GNUNET_JSONAPI_Document *json_document; struct GNUNET_JSONAPI_Resource *json_resource; struct EgoEntry *ego_entry; struct MHD_Response *resp; json_t *name_json; char *result_str; - json_object = GNUNET_JSONAPI_object_new (); + json_document = GNUNET_JSONAPI_document_new (); for (ego_entry = handle->ego_head; NULL != ego_entry; @@ -326,20 +326,20 @@ get_ego_for_subsys (void *cls, GNUNET_REST_JSONAPI_IDENTITY_NAME, name_json); json_decref (name_json); - GNUNET_JSONAPI_object_resource_add (json_object, json_resource); + GNUNET_JSONAPI_document_resource_add (json_document, json_resource); break; } - if (0 == GNUNET_JSONAPI_object_resource_count (json_object)) + if (0 == GNUNET_JSONAPI_document_resource_count (json_document)) { - GNUNET_JSONAPI_object_delete (json_object); + GNUNET_JSONAPI_document_delete (json_document); handle->emsg = GNUNET_strdup("No identity matches results!"); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - GNUNET_JSONAPI_data_serialize (json_object, &result_str); + GNUNET_JSONAPI_document_serialize (json_document, &result_str); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); resp = GNUNET_REST_create_json_response (result_str); - GNUNET_JSONAPI_object_delete (json_object); + GNUNET_JSONAPI_document_delete (json_document); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_free (result_str); cleanup_handle (handle); @@ -365,7 +365,7 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con, struct EgoEntry *ego_entry; struct GNUNET_HashCode key; struct MHD_Response *resp; - struct GNUNET_JSONAPI_Object *json_object; + struct GNUNET_JSONAPI_Document *json_document; struct GNUNET_JSONAPI_Resource *json_resource; json_t *name_str; @@ -415,7 +415,7 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con, } } - json_object = GNUNET_JSONAPI_object_new (); + json_document = GNUNET_JSONAPI_document_new (); //Return all egos for (ego_entry = handle->ego_head; @@ -432,19 +432,19 @@ ego_info_response (struct GNUNET_REST_RequestHandle *con, GNUNET_REST_JSONAPI_IDENTITY_NAME, name_str); json_decref (name_str); - GNUNET_JSONAPI_object_resource_add (json_object, json_resource); + GNUNET_JSONAPI_document_resource_add (json_document, json_resource); } - if (0 == GNUNET_JSONAPI_object_resource_count (json_object)) + if (0 == GNUNET_JSONAPI_document_resource_count (json_document)) { - GNUNET_JSONAPI_object_delete (json_object); + GNUNET_JSONAPI_document_delete (json_document); handle->emsg = GNUNET_strdup ("No identities found!"); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - GNUNET_JSONAPI_data_serialize (json_object, &result_str); + GNUNET_JSONAPI_document_serialize (json_document, &result_str); GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Result %s\n", result_str); resp = GNUNET_REST_create_json_response (result_str); - GNUNET_JSONAPI_object_delete (json_object); + GNUNET_JSONAPI_document_delete (json_document); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); GNUNET_free (result_str); cleanup_handle (handle); @@ -489,7 +489,7 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con, struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; struct MHD_Response *resp; - struct GNUNET_JSONAPI_Object *json_obj; + struct GNUNET_JSONAPI_Document *json_obj; struct GNUNET_JSONAPI_Resource *json_res; json_t *egoname_json; const char* egoname; @@ -509,24 +509,24 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con, } term_data[handle->data_size] = '\0'; memcpy (term_data, handle->data, handle->data_size); - GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_object_parse (term_data, + GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_parse (term_data, &json_obj)); if (NULL == json_obj) { GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - if (1 != GNUNET_JSONAPI_object_resource_count (json_obj)) + if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->emsg = GNUNET_strdup ("Provided resource count invalid"); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - json_res = GNUNET_JSONAPI_object_get_resource (json_obj, 0); + json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); resp = GNUNET_REST_create_json_response (NULL); handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); cleanup_handle (handle); @@ -535,7 +535,7 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con, egoname_json = GNUNET_JSONAPI_resource_read_attr (json_res, GNUNET_REST_JSONAPI_IDENTITY_NAME); if (!json_is_string (egoname_json)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->emsg = GNUNET_strdup ("No name provided"); GNUNET_SCHEDULER_add_now (&do_error, handle); return; @@ -547,7 +547,7 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con, { if (0 == strcasecmp (egoname, ego_entry->identifier)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); resp = GNUNET_REST_create_json_response (NULL); handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); cleanup_handle (handle); @@ -555,7 +555,7 @@ ego_create_cont (struct GNUNET_REST_RequestHandle *con, } } GNUNET_asprintf (&handle->name, "%s", egoname); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->op = GNUNET_IDENTITY_create (handle->identity_handle, handle->name, &do_finished, @@ -575,7 +575,7 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, const char *url, void *cls) { - struct GNUNET_JSONAPI_Object *json_obj; + struct GNUNET_JSONAPI_Document *json_obj; struct GNUNET_JSONAPI_Resource *json_res; struct RequestHandle *handle = cls; struct EgoEntry *ego_entry; @@ -624,7 +624,7 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, term_data[handle->data_size] = '\0'; memcpy (term_data, handle->data, handle->data_size); - GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_object_parse (term_data, + GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_parse (term_data, &json_obj)); if (NULL == json_obj) @@ -634,18 +634,18 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, return; } - if (1 != GNUNET_JSONAPI_object_resource_count (json_obj)) + if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->emsg = GNUNET_strdup ("Resource amount invalid"); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - json_res = GNUNET_JSONAPI_object_get_resource (json_obj, 0); + json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_IDENTITY_EGO)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->emsg = GNUNET_strdup ("Resource type invalid"); GNUNET_SCHEDULER_add_now (&do_error, handle); return; @@ -665,7 +665,7 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, 0 != strcasecmp (keystring, ego_entry->keystring)) { //Ego with same name not allowed - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); resp = GNUNET_REST_create_json_response (NULL); handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); cleanup_handle (handle); @@ -677,7 +677,7 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, newname, &do_finished, handle); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); return; } @@ -687,7 +687,7 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, { subsys = json_string_value (subsys_json); GNUNET_asprintf (&handle->subsys, "%s", subsys); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->op = GNUNET_IDENTITY_set (handle->identity_handle, handle->subsys, ego_entry->ego, @@ -695,7 +695,7 @@ ego_edit_cont (struct GNUNET_REST_RequestHandle *con, handle); return; } - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->emsg = GNUNET_strdup ("Subsystem not provided"); GNUNET_SCHEDULER_add_now (&do_error, handle); } diff --git a/src/include/gnunet_jsonapi_lib.h b/src/include/gnunet_jsonapi_lib.h index d4556c174..5535cb2aa 100644 --- a/src/include/gnunet_jsonapi_lib.h +++ b/src/include/gnunet_jsonapi_lib.h @@ -25,12 +25,63 @@ #include "gnunet_rest_lib.h" #include "gnunet_json_lib.h" +#define GNUNET_JSONAPI_KEY_DATA "data" + +#define GNUNET_JSONAPI_KEY_ID "id" + +#define GNUNET_JSONAPI_KEY_TYPE "type" + +#define GNUNET_JSONAPI_KEY_META "meta" + +#define GNUNET_JSONAPI_KEY_ATTRIBUTES "attributes" + +#define GNUNET_JSONAPI_KEY_CODE "code" + +#define GNUNET_JSONAPI_KEY_TITLE "title" + +#define GNUNET_JSONAPI_KEY_DETAIL "detail" + +#define GNUNET_JSONAPI_KEY_SOURCE "source" + +#define GNUNET_JSONAPI_KEY_LINKS "links" + +#define GNUNET_JSONAPI_KEY_STATUS "status" + +#define GNUNET_JSONAPI_KEY_ERRORS "errors" /* ****************** JSONAPI parsing ******************* */ +struct GNUNET_JSONAPI_Relationship; + +struct GNUNET_JSONAPI_Error; + struct GNUNET_JSONAPI_Resource; -struct GNUNET_JSONAPI_Object; +struct GNUNET_JSONAPI_Document; + +/** + * Specification for parsing a jsonapi relationship. + * + * @param jsonapi_obj where to store the jsonapi relationship + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_jsonapi_relationship (struct GNUNET_JSONAPI_Relationship **jsonapi_obj); + +/** + * Specification for parsing a jsonapi error. + * + * @param jsonapi_obj where to store the jsonapi error + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_jsonapi_error (struct GNUNET_JSONAPI_Error **jsonapi_obj); + +/** + * Specification for parsing a jsonapi resource. + * + * @param jsonapi_obj where to store the jsonapi resource + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_jsonapi_resource (struct GNUNET_JSONAPI_Resource **jsonapi_obj); /** * Specification for parsing a jsonapi object. @@ -38,7 +89,58 @@ struct GNUNET_JSONAPI_Object; * @param jsonapi_obj where to store the jsonapi object */ struct GNUNET_JSON_Specification -GNUNET_JSON_spec_jsonapi (struct GNUNET_JSONAPI_Object **jsonapi_obj); +GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_obj); + +/** + * Delete a JSON API relationship + * + * @param res the JSON resource + * @param result Pointer where the resource should be stored + */ +void +GNUNET_JSONAPI_relationship_delete (struct GNUNET_JSONAPI_Relationship *rel); + + +/** + * Add a JSON API error to document + * + * @param data The JSON API document to add to + * @param res the JSON API error to add + * @return the new number of resources + */ +void +GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc, + struct GNUNET_JSONAPI_Error *err); + +/** + * String serialze jsonapi error to json + * + * @param data the JSON API error + * @param result where to store the result + * @return GNUNET_SYSERR on error else GNUNET_OK + */ +int +GNUNET_JSONAPI_error_to_json (const struct GNUNET_JSONAPI_Error *err, + json_t **result); + +/** + * Parse json to error object + * + * @param err_json JSON object + * @param[out] err error object + * @return GNUNET_OK on success + */ +int +GNUNET_JSONAPI_json_to_error (json_t *err_json, + struct GNUNET_JSONAPI_Error **err); + +/** + * Delete a JSON API error + * + * @param res the JSON error + */ +void +GNUNET_JSONAPI_error_delete (struct GNUNET_JSONAPI_Error *error); /** * Create a JSON API resource @@ -50,6 +152,29 @@ GNUNET_JSON_spec_jsonapi (struct GNUNET_JSONAPI_Object **jsonapi_obj); struct GNUNET_JSONAPI_Resource* GNUNET_JSONAPI_resource_new (const char *type, const char *id); + +/** + * String serialze jsonapi to json + * + * @param data the JSON API resource + * @param result where to store the result + * @return GNUNET_SYSERR on error else GNUNET_OK + */ +int +GNUNET_JSONAPI_resource_to_json (const struct GNUNET_JSONAPI_Resource *res, + json_t **result); + +/** + * Parse json to resource object + * + * @param res_json JSON object + * @param[out] res resource object + * @return GNUNET_OK on success + */ +int +GNUNET_JSONAPI_json_to_resource (json_t *res_json, + struct GNUNET_JSONAPI_Resource **res); + /** * Delete a JSON API resource * @@ -69,9 +194,9 @@ GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource); * #GNUNET_SYSERR if not */ int -GNUNET_JSONAPI_resource_add_attr (const struct GNUNET_JSONAPI_Resource *resource, - const char* key, - json_t *json); +GNUNET_JSONAPI_resource_add_attr (struct GNUNET_JSONAPI_Resource *resource, + const char* key, + json_t *json); /** * Read a JSON API attribute * @@ -81,7 +206,7 @@ GNUNET_JSONAPI_resource_add_attr (const struct GNUNET_JSONAPI_Resource *resource */ json_t* GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource, - const char* key); + const char* key); /** @@ -93,7 +218,7 @@ GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resourc */ int GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource, - const char* id); + const char* id); /** @@ -105,7 +230,7 @@ GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource */ int GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource, - const char* type); + const char* type); /** @@ -115,8 +240,8 @@ GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resour * @param id the JSON API resource id * @return a new JSON API resource or NULL on error. */ -struct GNUNET_JSONAPI_Object* -GNUNET_JSONAPI_object_new (); +struct GNUNET_JSONAPI_Document* +GNUNET_JSONAPI_document_new (); /** @@ -127,8 +252,8 @@ GNUNET_JSONAPI_object_new (); * @return GNUNET_OK on success */ int -GNUNET_JSONAPI_object_parse (const char* data, - struct GNUNET_JSONAPI_Object** obj); +GNUNET_JSONAPI_document_parse (const char* data, + struct GNUNET_JSONAPI_Document** obj); /** @@ -139,7 +264,7 @@ GNUNET_JSONAPI_object_parse (const char* data, * @return a new JSON API resource or NULL on error. */ void -GNUNET_JSONAPI_object_delete (struct GNUNET_JSONAPI_Object *resp); +GNUNET_JSONAPI_document_delete (struct GNUNET_JSONAPI_Document *resp); /** * Add a JSON API resource to primary data @@ -149,8 +274,8 @@ GNUNET_JSONAPI_object_delete (struct GNUNET_JSONAPI_Object *resp); * @return the new number of resources */ void -GNUNET_JSONAPI_object_resource_add (struct GNUNET_JSONAPI_Object *resp, - struct GNUNET_JSONAPI_Resource *res); +GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *resp, + struct GNUNET_JSONAPI_Resource *res); /** * Get a JSON API object resource count * @@ -158,7 +283,7 @@ GNUNET_JSONAPI_object_resource_add (struct GNUNET_JSONAPI_Object *resp, * @return the number of resources */ int -GNUNET_JSONAPI_object_resource_count (struct GNUNET_JSONAPI_Object *resp); +GNUNET_JSONAPI_document_resource_count (struct GNUNET_JSONAPI_Document *resp); /** * Get a JSON API object resource num @@ -168,7 +293,7 @@ GNUNET_JSONAPI_object_resource_count (struct GNUNET_JSONAPI_Object *resp); * @return the resource */ struct GNUNET_JSONAPI_Resource* -GNUNET_JSONAPI_object_get_resource (struct GNUNET_JSONAPI_Object *resp, int num); +GNUNET_JSONAPI_document_get_resource (struct GNUNET_JSONAPI_Document *resp, int num); /** @@ -179,8 +304,8 @@ GNUNET_JSONAPI_object_get_resource (struct GNUNET_JSONAPI_Object *resp, int num) * @return the new number of resources */ void -GNUNET_JSONAPI_data_resource_remove (struct GNUNET_JSONAPI_Object *resp, - struct GNUNET_JSONAPI_Resource *res); +GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp, + struct GNUNET_JSONAPI_Resource *res); /** * String serialze jsonapi primary data @@ -190,8 +315,8 @@ GNUNET_JSONAPI_data_resource_remove (struct GNUNET_JSONAPI_Object *resp, * @return GNUNET_SYSERR on error else GNUNET_OK */ int -GNUNET_JSONAPI_data_serialize (const struct GNUNET_JSONAPI_Object *resp, - char **result); +GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *resp, + char **result); /** * Check a JSON API resource id @@ -199,7 +324,7 @@ GNUNET_JSONAPI_data_serialize (const struct GNUNET_JSONAPI_Object *resp, * @param res the JSON resource * @return the resource id */ -json_t* +char* GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource); 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 = \ -version-info 0:0:0 \ -no-undefined libgnunetjsonapi_la_SOURCES = \ - jsonapi.c + jsonapi.c \ + jsonapi_document.c \ + jsonapi_resource.c \ + jsonapi_error.c \ + jsonapi_relationship.c libgnunetjsonapi_la_LIBADD = \ $(top_builddir)/src/util/libgnunetutil.la \ $(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 @@ #include "gnunet_json_lib.h" #include "gnunet_rest_lib.h" -#define GNUNET_JSONAPI_KEY_DATA "data" - -#define GNUNET_JSONAPI_KEY_ID "id" - -#define GNUNET_JSONAPI_KEY_TYPE "type" - -struct GNUNET_JSONAPI_Resource -{ - /** - * DLL - */ - struct GNUNET_JSONAPI_Resource *next; - - /** - * DLL - */ - struct GNUNET_JSONAPI_Resource *prev; - - /** - * Resource content - */ - json_t *res_obj; -}; - - -struct GNUNET_JSONAPI_Object -{ - /** - * DLL Resource - */ - struct GNUNET_JSONAPI_Resource *res_list_head; - - /** - * DLL Resource - */ - struct GNUNET_JSONAPI_Resource *res_list_tail; - - /** - * num resources - */ - int res_count; -}; - - /** - * JSON API + * TODO move this to jsonapi-utils */ - -/** - * Create a JSON API resource - * - * @param type the JSON API resource type - * @param id the JSON API resource id - * @return a new JSON API resource or NULL on error. - */ -struct GNUNET_JSONAPI_Resource* -GNUNET_JSONAPI_resource_new (const char *type, const char *id) -{ - struct GNUNET_JSONAPI_Resource *res; - - if ( (NULL == type) || (0 == strlen (type)) ) - return NULL; - if ( (NULL == id) || (0 == strlen (id)) ) - return NULL; - - res = GNUNET_new (struct GNUNET_JSONAPI_Resource); - res->prev = NULL; - res->next = NULL; - - res->res_obj = json_object (); - - json_object_set_new (res->res_obj, GNUNET_JSONAPI_KEY_ID, json_string (id)); - json_object_set_new (res->res_obj, GNUNET_JSONAPI_KEY_TYPE, json_string (type)); - - return res; -} - - - -/** - * Add a JSON API attribute - * - * @param res the JSON resource - * @param key the key for the attribute - * @param json the json_t attribute to add - * @return #GNUNET_OK if added successfully - * #GNUNET_SYSERR if not - */ -int -GNUNET_JSONAPI_resource_add_attr (const struct GNUNET_JSONAPI_Resource *resource, - const char* key, - json_t *json) -{ - if ( (NULL == resource) || - (NULL == key) || - (NULL == json) ) - return GNUNET_SYSERR; - json_object_set (resource->res_obj, key, json); - return GNUNET_OK; -} - -/** - * Read a JSON API attribute - * - * @param res the JSON resource - * @param key the key for the attribute - * @return the json_t object - */ -json_t* -GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource, - const char* key) -{ - if ( (NULL == resource) || - (NULL == key)) - return NULL; - return json_object_get (resource->res_obj, key); -} - -int -check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource, - const char* key, - const char* attr) -{ - json_t *value; - if ( (NULL == resource) || - (NULL == key) || - (NULL == attr)) - return GNUNET_NO; - value = json_object_get (resource->res_obj, key); - if (NULL == value) - return GNUNET_NO; - if (!json_is_string (value) || - (0 != strcmp (attr, json_string_value(value)))) - { - return GNUNET_NO; - } - return GNUNET_YES; -} - -/** - * Check a JSON API resource id - * - * @param res the JSON resource - * @param id the expected id - * @return GNUNET_YES if id matches - */ -int -GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource, - const char* id) -{ - return check_resource_attr_str (resource, GNUNET_JSONAPI_KEY_ID, id); -} - -/** - * Check a JSON API resource id - * - * @param res the JSON resource - * @return the resource id - */ -json_t* -GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource) -{ - return GNUNET_JSONAPI_resource_read_attr (resource, GNUNET_JSONAPI_KEY_ID); -} - -/** - * Check a JSON API resource type - * - * @param res the JSON resource - * @param type the expected type - * @return GNUNET_YES if id matches - */ -int -GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource, - const char* type) -{ - return check_resource_attr_str (resource, GNUNET_JSONAPI_KEY_TYPE, type); -} - -/** - * Get a JSON API object resource count - * - * @param resp the JSON API object - * @return the number of resources - */ -int -GNUNET_JSONAPI_object_resource_count (struct GNUNET_JSONAPI_Object *resp) -{ - return resp->res_count; -} - -/** - * Get a JSON API object resource by index - * - * @param resp the JSON API object - * @param num the number of the resource - * @return the resource - */ -struct GNUNET_JSONAPI_Resource* -GNUNET_JSONAPI_object_get_resource (struct GNUNET_JSONAPI_Object *resp, - int num) -{ - struct GNUNET_JSONAPI_Resource *res; - int i; - - if ((0 == resp->res_count) || - (num >= resp->res_count)) - return NULL; - res = resp->res_list_head; - for (i = 0; i < num; i++) - { - res = res->next; - } - return res; -} - -/** - * Delete a JSON API resource - * - * @param res the JSON resource - * @param result Pointer where the resource should be stored - */ -void -GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource) -{ - json_decref (resource->res_obj); - GNUNET_free (resource); - resource = NULL; -} - -/** - * Delete a JSON API primary data - * - * @param type the JSON API resource type - * @param id the JSON API resource id - * @return a new JSON API resource or NULL on error. - */ -void -GNUNET_JSONAPI_object_delete (struct GNUNET_JSONAPI_Object *resp) -{ - struct GNUNET_JSONAPI_Resource *res; - struct GNUNET_JSONAPI_Resource *res_next; - - for (res = resp->res_list_head; - res != NULL;) - { - res_next = res->next; - GNUNET_CONTAINER_DLL_remove (resp->res_list_head, - resp->res_list_tail, - res); - GNUNET_JSONAPI_resource_delete (res); - res = res_next; - } - GNUNET_free (resp); - resp = NULL; -} - -/** - * Create a JSON API primary data - * - * @return a new JSON API resource or NULL on error. - */ -struct GNUNET_JSONAPI_Object* -GNUNET_JSONAPI_object_new () -{ - struct GNUNET_JSONAPI_Object *result; - - result = GNUNET_new (struct GNUNET_JSONAPI_Object); - result->res_count = 0; - return result; -} - -/** - * Add a JSON API object to primary data - * - * @param data The JSON API data to add to - * @param res the JSON API resource to add - * @return the new number of resources - */ -void -GNUNET_JSONAPI_object_resource_add (struct GNUNET_JSONAPI_Object *resp, - struct GNUNET_JSONAPI_Resource *res) -{ - GNUNET_CONTAINER_DLL_insert (resp->res_list_head, - resp->res_list_tail, - res); - - resp->res_count++; -} - -static void -add_json_resource (struct GNUNET_JSONAPI_Object *obj, - const json_t *res_json) -{ - struct GNUNET_JSONAPI_Resource *res; - const char *type_json; - - struct GNUNET_JSON_Specification dspec[] = { - GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type_json), - GNUNET_JSON_spec_end() - }; - - GNUNET_assert (GNUNET_OK == - GNUNET_JSON_parse (res_json, dspec, - NULL, NULL)); - GNUNET_JSON_parse_free (dspec); - res = GNUNET_new (struct GNUNET_JSONAPI_Resource); - res->next = NULL; - res->prev = NULL; - res->res_obj = json_deep_copy (res_json); - GNUNET_JSONAPI_object_resource_add (obj, res); -} - -/** - * Parse given JSON object to RSA public key. - * - * @param cls closure, NULL - * @param root the json object representing data - * @param[out] spec where to write the data - * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error - */ -static int -parse_jsonapiobject (void *cls, - json_t *root, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Object *result; - json_t *data_json; - int res_count = 0; - int i; - - struct GNUNET_JSON_Specification jsonapispec[] = { - GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &data_json), - GNUNET_JSON_spec_end() - }; - if (GNUNET_OK != - GNUNET_JSON_parse (root, jsonapispec, - NULL, NULL) || (NULL == data_json)) - { - return GNUNET_SYSERR; - } - - result = GNUNET_new (struct GNUNET_JSONAPI_Object); - result->res_count = 0; - if (json_is_object (data_json)) - add_json_resource (result, data_json); - else if (json_is_array (data_json)) - { - res_count = json_array_size (data_json); - for (i = 0; i < res_count; i++) - add_json_resource (result, json_array_get (data_json, i)); - } - if (0 == result->res_count) - { - GNUNET_free (result); - GNUNET_JSON_parse_free (jsonapispec); - return GNUNET_SYSERR; - } - *(struct GNUNET_JSONAPI_Object **) spec->ptr = result; - GNUNET_JSON_parse_free (jsonapispec); - return GNUNET_OK; -} - - -/** - * Cleanup data left from parsing RSA public key. - * - * @param cls closure, NULL - * @param[out] spec where to free the data - */ -static void -clean_jsonapiobject (void *cls, - struct GNUNET_JSON_Specification *spec) -{ - struct GNUNET_JSONAPI_Object **jsonapi_obj; - jsonapi_obj = (struct GNUNET_JSONAPI_Object **) spec->ptr; - if (NULL != *jsonapi_obj) - { - GNUNET_JSONAPI_object_delete (*jsonapi_obj); - *jsonapi_obj = NULL; - } -} - -/** - * Add a JSON API resource to primary data - * - * @param data The JSON API data to add to - * @param res the JSON API resource to add - * @return the new number of resources - */ -void -GNUNET_JSONAPI_data_resource_remove (struct GNUNET_JSONAPI_Object *resp, - struct GNUNET_JSONAPI_Resource *res) -{ - GNUNET_CONTAINER_DLL_remove (resp->res_list_head, - resp->res_list_tail, - res); - resp->res_count--; -} - -/** - * String serialze jsonapi primary data - * - * @param data the JSON API primary data - * @param result where to store the result - * @return GNUNET_SYSERR on error else GNUNET_OK - */ -int -GNUNET_JSONAPI_data_serialize (const struct GNUNET_JSONAPI_Object *resp, - char **result) -{ - struct GNUNET_JSONAPI_Resource *res; - json_t *root_json; - json_t *res_arr; - - if ((NULL == resp)) - return GNUNET_SYSERR; - - root_json = json_object (); - res_arr = json_array (); - for (res = resp->res_list_head; - res != NULL; - res = res->next) - { - json_array_append (res_arr, res->res_obj); - } - json_object_set (root_json, GNUNET_JSONAPI_KEY_DATA, res_arr); - *result = json_dumps (root_json, JSON_INDENT(2)); - json_decref (root_json); - json_decref (res_arr); - return GNUNET_OK; -} - -/** - * JSON object. - * - * @param name name of the JSON field - * @param[out] jsonp where to store the JSON found under @a name - */ -struct GNUNET_JSON_Specification -GNUNET_JSON_spec_jsonapi (struct GNUNET_JSONAPI_Object **jsonapi_object) -{ - struct GNUNET_JSON_Specification ret = { - .parser = &parse_jsonapiobject, - .cleaner = &clean_jsonapiobject, - .cls = NULL, - .field = NULL, - .ptr = jsonapi_object, - .ptr_size = 0, - .size_ptr = NULL - }; - *jsonapi_object = NULL; - return ret; -} - /** * Check rest request for validity * 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 @@ + +#include "platform.h" +#include "gnunet_util_lib.h" +#include "gnunet_json_lib.h" +#include "jsonapi_objects.h" + +/** + * Get a JSON API object resource count + * + * @param resp the JSON API object + * @return the number of resources + */ +int +GNUNET_JSONAPI_document_resource_count (struct GNUNET_JSONAPI_Document *doc) +{ + return doc->res_count; +} + +/** + * Get a JSON API object resource by index + * + * @param resp the JSON API object + * @param idx index of the resource + * @return the resource + */ +struct GNUNET_JSONAPI_Resource* +GNUNET_JSONAPI_document_get_resource (struct GNUNET_JSONAPI_Document *doc, + int idx) +{ + struct GNUNET_JSONAPI_Resource *res; + int i; + + if ((0 == doc->res_count) || + (idx >= doc->res_count)) + return NULL; + res = doc->res_list_head; + for (i = 0; i < idx; i++) + { + res = res->next; + } + return res; +} + +/** + * Delete a JSON API primary data + * + * @param type the JSON API resource type + * @param id the JSON API resource id + * @return a new JSON API resource or NULL on error. + */ +void +GNUNET_JSONAPI_document_delete (struct GNUNET_JSONAPI_Document *doc) +{ + struct GNUNET_JSONAPI_Resource *res; + struct GNUNET_JSONAPI_Resource *res_next; + + + for (res = doc->res_list_head; + res != NULL;) + { + res_next = res->next; + GNUNET_CONTAINER_DLL_remove (doc->res_list_head, + doc->res_list_tail, + res); + GNUNET_JSONAPI_resource_delete (res); + res = res_next; + } + GNUNET_free (doc); + doc = NULL; +} + +/** + * Create a JSON API primary data + * + * @return a new JSON API resource or NULL on error. + */ +struct GNUNET_JSONAPI_Document* +GNUNET_JSONAPI_document_new () +{ + struct GNUNET_JSONAPI_Document *result; + + result = GNUNET_new (struct GNUNET_JSONAPI_Document); + result->res_count = 0; + result->err_count = 0; + result->meta = 0; + return result; +} + +/** + * Add a JSON API error to document + * + * @param data The JSON API document to add to + * @param res the JSON API error to add + * @return the new number of resources + */ +void +GNUNET_JSONAPI_document_error_add (struct GNUNET_JSONAPI_Document *doc, + struct GNUNET_JSONAPI_Error *err) +{ + GNUNET_CONTAINER_DLL_insert (doc->err_list_head, + doc->err_list_tail, + err); + + doc->err_count++; +} + +/** + * Add a JSON API resource to primary data + * + * @param data The JSON API data to add to + * @param res the JSON API resource to add + * @return the new number of resources + */ +void +GNUNET_JSONAPI_document_resource_add (struct GNUNET_JSONAPI_Document *doc, + struct GNUNET_JSONAPI_Resource *res) +{ + GNUNET_CONTAINER_DLL_insert (doc->res_list_head, + doc->res_list_tail, + res); + + doc->res_count++; +} + + +/** + * Parse given JSON object to jsonapi document. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_jsonapiobject (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_JSONAPI_Document *result; + struct GNUNET_JSONAPI_Error *error; + struct GNUNET_JSONAPI_Resource *resource; + json_t *meta_json; + json_t *resource_json; + json_t *errors_json; + json_t *value; + size_t index; + + struct GNUNET_JSON_Specification jsonapispecerrors[] = { + GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ERRORS, &errors_json), + GNUNET_JSON_spec_end() + }; + if (GNUNET_OK != + GNUNET_JSON_parse (root, jsonapispecerrors, + NULL, NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "JSONAPI document does not contain error objects\n"); + } else if (!json_is_array (errors_json)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "Error object is not array!\n"); + GNUNET_JSON_parse_free (jsonapispecerrors); + return GNUNET_SYSERR; + } + struct GNUNET_JSON_Specification jsonapispecmeta[] = { + GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_META, &meta_json), + GNUNET_JSON_spec_end() + }; + if (GNUNET_OK != + GNUNET_JSON_parse (root, jsonapispecmeta, + NULL, NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_INFO, + "JSONAPI document does not contain error objects\n"); + } + struct GNUNET_JSON_Specification jsonapispecresource[] = { + GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_DATA, &resource_json), + GNUNET_JSON_spec_end() + }; + if (GNUNET_OK != + GNUNET_JSON_parse (root, jsonapispecresource, + NULL, NULL)) + { + if (NULL == errors_json) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "JSONAPI document contains neither error nor data!\n"); + GNUNET_JSON_parse_free (jsonapispecerrors); + GNUNET_JSON_parse_free (jsonapispecmeta); + return GNUNET_SYSERR; + } + } else { + if (NULL != errors_json) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, + "JSONAPI document contains both error and data!\n"); + GNUNET_JSON_parse_free (jsonapispecerrors); + GNUNET_JSON_parse_free (jsonapispecmeta); + GNUNET_JSON_parse_free (jsonapispecresource); + return GNUNET_SYSERR; + } + } + + result = GNUNET_new (struct GNUNET_JSONAPI_Document); + result->res_count = 0; + result->err_count = 0; + if (NULL != meta_json) + result->meta = json_deep_copy (meta_json); + if (NULL != errors_json) { + json_array_foreach(errors_json, index, value) { + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_json_to_error (value, + &error)); + GNUNET_JSONAPI_document_error_add (result, error); + } + } + if (NULL != resource_json) { + if (0 != json_is_array (resource_json)) + { + json_array_foreach(resource_json, index, value) { + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_json_to_resource (value, + &resource)); + GNUNET_JSONAPI_document_resource_add (result, resource); + } + } else { + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_json_to_resource (resource_json, + &resource)); + GNUNET_JSONAPI_document_resource_add (result, resource); + } + } + if (NULL != errors_json) + GNUNET_JSON_parse_free (jsonapispecerrors); + if (NULL != resource) + GNUNET_JSON_parse_free (jsonapispecresource); + if (NULL != meta_json) + GNUNET_JSON_parse_free (jsonapispecmeta); + *(struct GNUNET_JSONAPI_Document **) spec->ptr = result; + return GNUNET_OK; +} + + +/** + * Cleanup data left from parsing RSA public key. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_jsonapiobject (void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_JSONAPI_Document **jsonapi_obj; + jsonapi_obj = (struct GNUNET_JSONAPI_Document **) spec->ptr; + if (NULL != *jsonapi_obj) + { + GNUNET_JSONAPI_document_delete (*jsonapi_obj); + *jsonapi_obj = NULL; + } +} + +/** + * Add a JSON API resource to primary data + * + * @param data The JSON API data to add to + * @param res the JSON API resource to add + * @return the new number of resources + */ +void +GNUNET_JSONAPI_document_resource_remove (struct GNUNET_JSONAPI_Document *resp, + struct GNUNET_JSONAPI_Resource *res) +{ + GNUNET_CONTAINER_DLL_remove (resp->res_list_head, + resp->res_list_tail, + res); + resp->res_count--; +} + + +/** + * String serialze jsonapi primary data + * + * @param data the JSON API primary data + * @param result where to store the result + * @return GNUNET_SYSERR on error else GNUNET_OK + */ +int +GNUNET_JSONAPI_document_serialize (const struct GNUNET_JSONAPI_Document *doc, + char **result) +{ + struct GNUNET_JSONAPI_Resource *res; + struct GNUNET_JSONAPI_Error *error; + json_t *root_json; + json_t *res_json; + json_t *res_json_tmp; + + if ((NULL == doc)) + return GNUNET_SYSERR; + + root_json = json_object (); + + //Check for errors first + if (doc->err_count != 0) + { + res_json = json_array (); + for (error = doc->err_list_head; + error != NULL; + error = error->next) + { + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_error_to_json (error, + &res_json_tmp)); + json_array_append (res_json, res_json_tmp); + } + json_object_set (root_json, GNUNET_JSONAPI_KEY_ERRORS, res_json); + } else { + switch (doc->res_count) + { + case 0: + res_json = json_null(); + break; + case 1: + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_resource_to_json (doc->res_list_head, + &res_json)); + break; + default: + res_json = json_array (); + for (res = doc->res_list_head; + res != NULL; + res = res->next) + { + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_resource_to_json (res, + &res_json_tmp)); + json_array_append (res_json, res_json_tmp); + } + break; + } + json_object_set (root_json, GNUNET_JSONAPI_KEY_DATA, res_json); + } + + //Add meta + json_object_set (root_json, GNUNET_JSONAPI_KEY_META, doc->meta); + *result = json_dumps (root_json, JSON_INDENT(2)); + json_decref (root_json); + json_decref (res_json); + return GNUNET_OK; +} + +/** + * JSON object. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_jsonapi_document (struct GNUNET_JSONAPI_Document **jsonapi_object) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_jsonapiobject, + .cleaner = &clean_jsonapiobject, + .cls = NULL, + .field = NULL, + .ptr = jsonapi_object, + .ptr_size = 0, + .size_ptr = NULL + }; + *jsonapi_object = NULL; + return ret; +} + + 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 @@ +#include "platform.h" +#include "gnunet_jsonapi_lib.h" +#include "jsonapi_objects.h" + +/** + * Parse json to error object + * + * @param err_json JSON object + * @param[out] err error object + * @return GNUNET_OK on success + */ +int +GNUNET_JSONAPI_json_to_error (json_t *err_json, + struct GNUNET_JSONAPI_Error **err) +{ + struct GNUNET_JSON_Specification jsonapispecerror[] = { + GNUNET_JSON_spec_jsonapi_error (err), + GNUNET_JSON_spec_end() + }; + return GNUNET_JSON_parse (err_json, jsonapispecerror, + NULL, NULL); +} + +/** + * Serialze jsonapi errors + * + * @param data the JSON API errors + * @param result where to store the result + * @return GNUNET_SYSERR on error else GNUNET_OK + */ +int +GNUNET_JSONAPI_error_to_json (const struct GNUNET_JSONAPI_Error *err, + json_t **result) +{ + *result = json_object (); + + if ((NULL != err->id) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_ID, + json_string (err->id)))) + return GNUNET_SYSERR; + if ((NULL != err->status) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_STATUS, + json_string (err->status)))) + return GNUNET_SYSERR; + if ((NULL != err->code) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_CODE, + json_string (err->code)))) + return GNUNET_SYSERR; + + if ((NULL != err->title) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_TITLE, + json_string (err->title)))) + return GNUNET_SYSERR; + if ((NULL != err->detail) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_DETAIL, + json_string (err->detail)))) + return GNUNET_SYSERR; + if ((NULL != err->source) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_SOURCE, + err->source))) + return GNUNET_SYSERR; + if ((NULL != err->links) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_LINKS, + err->links))) + return GNUNET_SYSERR; + if ((NULL != err->meta) && + (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_META, + err->meta))) + return GNUNET_SYSERR; + return GNUNET_OK; +} + + +/** + * Parse given JSON object to jsonapi document. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_jsonapierror (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_JSONAPI_Error *result; + json_t *pos; + + GNUNET_assert (NULL != root); + result = GNUNET_new (struct GNUNET_JSONAPI_Error); + pos = json_object_get (root, GNUNET_JSONAPI_KEY_ID); + if (json_is_string (pos)) + result->id = GNUNET_strdup (json_string_value (pos)); + + pos = json_object_get (root, GNUNET_JSONAPI_KEY_LINKS); + if (json_is_object (pos)) + result->links = json_deep_copy (pos); + + pos = json_object_get (root, GNUNET_JSONAPI_KEY_STATUS); + if (json_is_string (pos)) + result->status = GNUNET_strdup (json_string_value (pos)); + + pos = json_object_get (root, GNUNET_JSONAPI_KEY_CODE); + if (json_is_string (pos)) + result->code = GNUNET_strdup (json_string_value (pos)); + + pos = json_object_get (root, GNUNET_JSONAPI_KEY_TITLE); + if (json_is_string (pos)) + result->title = GNUNET_strdup (json_string_value (pos)); + + pos = json_object_get (root, GNUNET_JSONAPI_KEY_DETAIL); + if (json_is_string (pos)) + result->detail = GNUNET_strdup (json_string_value (pos)); + + pos = json_object_get (root, GNUNET_JSONAPI_KEY_SOURCE); + if (json_is_object (pos)) + result->source = json_deep_copy (pos); + pos = json_object_get (root, GNUNET_JSONAPI_KEY_META); + if (json_is_object (pos)) + result->meta = json_deep_copy (pos); + *(struct GNUNET_JSONAPI_Error **) spec->ptr = result; + return GNUNET_OK; +} + +/** + * Delete a JSON API error + * + * @param res the JSON error + */ +void +GNUNET_JSONAPI_error_delete (struct GNUNET_JSONAPI_Error *error) +{ + GNUNET_assert (NULL != error); + + if (NULL != error->id) + GNUNET_free (error->id); + if (NULL != error->status) + GNUNET_free (error->status); + if (NULL != error->code) + GNUNET_free (error->code); + if (NULL != error->title) + GNUNET_free (error->title); + if (NULL != error->detail) + GNUNET_free (error->detail); + if (NULL != error->links) + json_decref (error->links); + if (NULL != error->source) + json_decref (error->source); + if (NULL != error->meta) + json_decref (error->meta); + GNUNET_free (error); +} + + + +/** + * Cleanup data left from parsing RSA public key. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_jsonapierror (void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_JSONAPI_Error **jsonapi_obj; + jsonapi_obj = (struct GNUNET_JSONAPI_Error **) spec->ptr; + if (NULL != *jsonapi_obj) + { + GNUNET_JSONAPI_error_delete (*jsonapi_obj); + *jsonapi_obj = NULL; + } +} +/** + * JSON object. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_jsonapi_error (struct GNUNET_JSONAPI_Error **jsonapi_object) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_jsonapierror, + .cleaner = &clean_jsonapierror, + .cls = NULL, + .field = NULL, + .ptr = jsonapi_object, + .ptr_size = 0, + .size_ptr = NULL + }; + *jsonapi_object = NULL; + return ret; +} + + 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 @@ +#include "platform.h" +#include "gnunet_jsonapi_lib.h" +/** + * jsonapi error object + */ +struct GNUNET_JSONAPI_Error +{ + /** + * DLL + */ + struct GNUNET_JSONAPI_Error *next; + + /** + * DLL + */ + struct GNUNET_JSONAPI_Error *prev; + + /** + * Unique error id + */ + char *id; + + /** + * Links object + */ + json_t *links; + + /** + * HTTP status code for this error + */ + char *status; + + /** + * Application error code + */ + char *code; + + /** + * Error title + */ + char *title; + + /** + * Error details + */ + char *detail; + + /** + * Error source + */ + json_t *source; + + /** + * Meta info for the error + */ + json_t *meta; +}; + +struct GNUNET_JSONAPI_Relationship +{ + /** + * Links object + */ + struct GNUNET_JSONAPI_Link *links; + + /** + * Resource linkage data + */ + struct GNUNET_JSONAPI_Resource *res_list_head; + + /** + * DLL + */ + struct GNUNET_JSONAPI_Resource *res_list_tail; + + /** + * Number of resources in data section + */ + int res_count; + + /** + * Meta information + */ + json_t *meta; +}; + +/** + * A jsonapi resource object + */ +struct GNUNET_JSONAPI_Resource +{ + /** + * DLL + */ + struct GNUNET_JSONAPI_Resource *next; + + /** + * DLL + */ + struct GNUNET_JSONAPI_Resource *prev; + + /** + * Resource type + */ + char *type; + + /** + * Resource ID + */ + char *id; + + /** + * Attributes object + */ + json_t *attr_obj; + + /** + * Relationship + */ + struct GNUNET_JSONAPI_Relationship *relationship; +}; + + +struct GNUNET_JSONAPI_Document +{ + /** + * DLL Resource + */ + struct GNUNET_JSONAPI_Resource *res_list_head; + + /** + * DLL Resource + */ + struct GNUNET_JSONAPI_Resource *res_list_tail; + + /** + * num resources + */ + int res_count; + + /** + * DLL Error + */ + struct GNUNET_JSONAPI_Error *err_list_head; + + /** + * DLL Error + */ + struct GNUNET_JSONAPI_Error *err_list_tail; + + /** + * num errors + */ + int err_count; + + /** + * Meta info + */ + json_t *meta; +}; + + 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 @@ +#include "platform.h" +#include "gnunet_jsonapi_lib.h" + + +/** + * Delete a JSON API relationship TODO + * + * @param res the JSON relationship + */ +void +GNUNET_JSONAPI_relationship_delete (struct GNUNET_JSONAPI_Relationship *relationship) +{ + GNUNET_assert (NULL != relationship); + GNUNET_free (relationship); +} + + 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 @@ +#include "platform.h" +#include "gnunet_jsonapi_lib.h" +#include "jsonapi_objects.h" + +/** + * String serialze jsonapi resources + * + * @param data the JSON API resource + * @param result where to store the result + * @return GNUNET_SYSERR on error else GNUNET_OK + */ +int +GNUNET_JSONAPI_resource_to_json (const struct GNUNET_JSONAPI_Resource *res, + json_t **result) +{ + struct GNUNET_JSONAPI_Resource *rel_res; + json_t *relationship; + json_t *res_json_tmp; + *result = json_object (); + + if (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_ID, + json_string (res->id))) + return GNUNET_SYSERR; + if (0 != json_object_set_new (*result, + GNUNET_JSONAPI_KEY_TYPE, + json_string (res->type))) + return GNUNET_SYSERR; + if ((NULL != res->attr_obj) && + (0 != json_object_set (*result, + GNUNET_JSONAPI_KEY_ATTRIBUTES, + res->attr_obj))) + return GNUNET_SYSERR; + + //Relationships + if (NULL != res->relationship) + { + relationship = json_object (); + if (0 != res->relationship->res_count) + { + json_t *res_json; + switch (res->relationship->res_count) + { + case 0: + res_json = json_null(); + break; + case 1: + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_resource_to_json (res->relationship->res_list_head, + &res_json)); + break; + default: + res_json = json_array (); + rel_res = NULL; + for (rel_res = rel_res->relationship->res_list_head; + rel_res != NULL; + rel_res = rel_res->next) + { + GNUNET_assert (GNUNET_OK == + GNUNET_JSONAPI_resource_to_json (rel_res, + &res_json_tmp)); + json_array_append_new (res_json, res_json_tmp); + } + break; + } + json_object_set_new (relationship, + GNUNET_JSONAPI_KEY_DATA, + res_json); + } + if ((NULL != res->relationship->meta) && + (0 != json_object_set_new (relationship, + GNUNET_JSONAPI_KEY_META, + res->relationship->meta))) + return GNUNET_SYSERR; + //TODO link + } + + + return GNUNET_OK; +} + + +/** + * Create a JSON API resource + * + * @param type the JSON API resource type + * @param id the JSON API resource id + * @return a new JSON API resource or NULL on error. + */ +struct GNUNET_JSONAPI_Resource* +GNUNET_JSONAPI_resource_new (const char *type, const char *id) +{ + struct GNUNET_JSONAPI_Resource *res; + + if ( (NULL == type) || (0 == strlen (type)) ) + return NULL; + if ( (NULL == id) || (0 == strlen (id)) ) + return NULL; + + res = GNUNET_new (struct GNUNET_JSONAPI_Resource); + res->prev = NULL; + res->next = NULL; + res->attr_obj = NULL; + res->relationship = NULL; + res->id = GNUNET_strdup (id); + res->type = GNUNET_strdup (type); + return res; +} + +/** + * Add a jsonapi relationship + * @param res the resource to add to + * @param rel the relationship to add + * @return #GNUNETOK if added successfully + */ +int +GNUNET_JSONAPI_resource_set_relationship (struct GNUNET_JSONAPI_Resource *res, + struct GNUNET_JSONAPI_Relationship *rel) +{ + GNUNET_assert (NULL != res); + GNUNET_assert (NULL != rel); + if (NULL != res->relationship) + return GNUNET_SYSERR; + res->relationship = rel; + return GNUNET_OK; +} + +/** + * Add a JSON API attribute + * + * @param res the JSON resource + * @param key the key for the attribute + * @param json the json_t attribute to add + * @return #GNUNET_OK if added successfully + * #GNUNET_SYSERR if not + */ +int +GNUNET_JSONAPI_resource_add_attr (struct GNUNET_JSONAPI_Resource *resource, + const char* key, + json_t *json) +{ + if ( (NULL == resource) || + (NULL == key) || + (NULL == json) ) + return GNUNET_SYSERR; + if (NULL == resource->attr_obj) + resource->attr_obj = json_object (); + json_object_set (resource->attr_obj, key, json); + return GNUNET_OK; +} + +/** + * Read a JSON API attribute + * + * @param res the JSON resource + * @param key the key for the attribute + * @return the json_t object + */ +json_t* +GNUNET_JSONAPI_resource_read_attr (const struct GNUNET_JSONAPI_Resource *resource, + const char* key) +{ + if ( (NULL == resource) || + (NULL == key) || + (NULL == resource->attr_obj)) + return NULL; + return json_object_get (resource->attr_obj, key); +} + +int +check_resource_attr_str (const struct GNUNET_JSONAPI_Resource *resource, + const char* key, + const char* attr) +{ + json_t *value; + if ( (NULL == resource) || + (NULL == key) || + (NULL == attr) || + (NULL == resource->attr_obj)) + return GNUNET_NO; + value = json_object_get (resource->attr_obj, key); + if (NULL == value) + return GNUNET_NO; + if (!json_is_string (value) || + (0 != strcmp (attr, json_string_value(value)))) + { + return GNUNET_NO; + } + return GNUNET_YES; +} + +/** + * Check a JSON API resource type + * + * @param res the JSON resource + * @param type the expected type + * @return GNUNET_YES if id matches + */ +int +GNUNET_JSONAPI_resource_check_type (const struct GNUNET_JSONAPI_Resource *resource, + const char* type) +{ + return (0 == memcmp (type, resource->type, + strlen (resource->type))) ? GNUNET_YES : GNUNET_NO; +} + + +/** + * Delete a JSON API resource + * + * @param res the JSON resource + * @param result Pointer where the resource should be stored + */ +void +GNUNET_JSONAPI_resource_delete (struct GNUNET_JSONAPI_Resource *resource) +{ + GNUNET_free (resource->id); + GNUNET_free (resource->type); + if (NULL != resource->attr_obj) + json_decref (resource->attr_obj); + if (NULL != resource->relationship) + GNUNET_JSONAPI_relationship_delete (resource->relationship); + GNUNET_free (resource); + resource = NULL; +} + + +/** + * Check a JSON API resource id + * + * @param res the JSON resource + * @param id the expected id + * @return GNUNET_YES if id matches + */ +int +GNUNET_JSONAPI_resource_check_id (const struct GNUNET_JSONAPI_Resource *resource, + const char* id) +{ + return (0 == memcmp (resource->id, id, strlen (id))) ? GNUNET_YES : GNUNET_NO; +} + +/** + * Check a JSON API resource id + * + * @param res the JSON resource + * @return the resource id + */ +char* +GNUNET_JSONAPI_resource_get_id (const struct GNUNET_JSONAPI_Resource *resource) +{ + return resource->id; +} + +/** + * Parse json to resource object + * + * @param res_json JSON object + * @param[out] res resource object + * @return GNUNET_OK on success + */ +int +GNUNET_JSONAPI_json_to_resource (json_t *res_json, + struct GNUNET_JSONAPI_Resource **res) +{ + struct GNUNET_JSON_Specification jsonapispecresource[] = { + GNUNET_JSON_spec_jsonapi_resource (res), + GNUNET_JSON_spec_end() + }; + return GNUNET_JSON_parse (res_json, jsonapispecresource, + NULL, NULL); +} + +/** + * Parse given JSON object to jsonapi document. + * + * @param cls closure, NULL + * @param root the json object representing data + * @param[out] spec where to write the data + * @return #GNUNET_OK upon successful parsing; #GNUNET_SYSERR upon error + */ +static int +parse_jsonapiresource (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_JSONAPI_Resource *res; + const char *type; + const char *id; + json_t *attrs; + + struct GNUNET_JSON_Specification dspec[] = { + GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_TYPE, &type), + GNUNET_JSON_spec_string (GNUNET_JSONAPI_KEY_ID, &id), + GNUNET_JSON_spec_end() + }; + + if (GNUNET_OK != + GNUNET_JSON_parse (root, dspec, + NULL, NULL)) + { + GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unable to parse resource\n"); + return GNUNET_SYSERR; + } + res = GNUNET_JSONAPI_resource_new (type, id); + GNUNET_JSON_parse_free (dspec); + + struct GNUNET_JSON_Specification attrspec[] = { + GNUNET_JSON_spec_json (GNUNET_JSONAPI_KEY_ATTRIBUTES, &attrs), + GNUNET_JSON_spec_end() + }; + if (GNUNET_OK != + GNUNET_JSON_parse (root, attrspec, + NULL, NULL)) + GNUNET_log (GNUNET_ERROR_TYPE_INFO, "Resource does not contain attributes\n"); + if (NULL != attrs) + res->attr_obj = json_deep_copy (attrs); + + //TODO relationship + GNUNET_JSON_parse_free (attrspec); + *(struct GNUNET_JSONAPI_Resource **) spec->ptr = res; + return GNUNET_OK; +} + + +/** + * Cleanup data left from parsing resource. + * + * @param cls closure, NULL + * @param[out] spec where to free the data + */ +static void +clean_jsonapiresource (void *cls, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_JSONAPI_Resource **jsonapi_obj; + jsonapi_obj = (struct GNUNET_JSONAPI_Resource **) spec->ptr; + if (NULL != *jsonapi_obj) + { + GNUNET_JSONAPI_resource_delete (*jsonapi_obj); + *jsonapi_obj = NULL; + } +} + + +/** + * JSON object. + * + * @param name name of the JSON field + * @param[out] jsonp where to store the JSON found under @a name + */ +struct GNUNET_JSON_Specification +GNUNET_JSON_spec_jsonapi_resource (struct GNUNET_JSONAPI_Resource **jsonapi_object) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_jsonapiresource, + .cleaner = &clean_jsonapiresource, + .cls = NULL, + .field = NULL, + .ptr = jsonapi_object, + .ptr_size = 0, + .size_ptr = NULL + }; + *jsonapi_object = NULL; + return ret; +} + + 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 @@ static int test_serialize () { - struct GNUNET_JSONAPI_Object *obj; - char* data = "{\"data\":[{\"id\":\"1\", \"type\":\"test\"}]}"; + struct GNUNET_JSONAPI_Document *obj; + char* data = "{\"data\":{\"id\":\"1\",\"type\":\"bar\", \"attributes\":{\"foo\":\"bar\"}}}"; char* tmp_data; json_t* data_js; json_t* tmp_data_js; json_error_t err; struct GNUNET_JSON_Specification jsonapispec[] = { - GNUNET_JSON_spec_jsonapi (&obj), + GNUNET_JSON_spec_jsonapi_document (&obj), GNUNET_JSON_spec_end() }; data_js = json_loads (data, JSON_DECODE_ANY, &err); @@ -42,8 +42,8 @@ test_serialize () GNUNET_assert (GNUNET_OK == GNUNET_JSON_parse (data_js, jsonapispec, NULL, NULL)); - GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_data_serialize (obj, - &tmp_data)); + GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_serialize (obj, + &tmp_data)); GNUNET_JSON_parse_free (jsonapispec); tmp_data_js = json_loads (tmp_data, JSON_DECODE_ANY, &err); GNUNET_assert (NULL != tmp_data_js); @@ -62,14 +62,14 @@ test_serialize () static int test_spec_jsonapi () { - struct GNUNET_JSONAPI_Object *obj; + struct GNUNET_JSONAPI_Document *obj; struct GNUNET_JSONAPI_Resource *res; const char* data = "{\"data\":{\"id\":\"1\", \"type\":\"test\"}}"; json_t* data_js; json_error_t err; struct GNUNET_JSON_Specification jsonapispec[] = { - GNUNET_JSON_spec_jsonapi (&obj), + GNUNET_JSON_spec_jsonapi_document (&obj), GNUNET_JSON_spec_end() }; data_js = json_loads (data, JSON_DECODE_ANY, &err); @@ -78,10 +78,10 @@ test_spec_jsonapi () GNUNET_JSON_parse (data_js, jsonapispec, NULL, NULL)); json_decref (data_js); - res = GNUNET_JSONAPI_object_get_resource (obj, 0); + res = GNUNET_JSONAPI_document_get_resource (obj, 0); GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_id (res, "1")); GNUNET_assert (GNUNET_YES == GNUNET_JSONAPI_resource_check_type (res, "test")); - GNUNET_assert (1 == GNUNET_JSONAPI_object_resource_count (obj)); + GNUNET_assert (1 == GNUNET_JSONAPI_document_resource_count (obj)); GNUNET_JSON_parse_free (jsonapispec); return 0; } diff --git a/src/namestore/plugin_rest_namestore.c b/src/namestore/plugin_rest_namestore.c index 76a1126a5..c20ef8e8a 100644 --- a/src/namestore/plugin_rest_namestore.c +++ b/src/namestore/plugin_rest_namestore.c @@ -106,7 +106,7 @@ struct RequestHandle /** * JSON response object */ - struct GNUNET_JSONAPI_Object *resp_object; + struct GNUNET_JSONAPI_Document *resp_object; /** * Rest connection @@ -251,7 +251,7 @@ cleanup_handle (struct RequestHandle *handle) GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Cleaning up\n"); if (NULL != handle->resp_object) - GNUNET_JSONAPI_object_delete (handle->resp_object); + GNUNET_JSONAPI_document_delete (handle->resp_object); if (NULL != handle->name) GNUNET_free (handle->name); if (NULL != handle->timeout_task) @@ -407,13 +407,13 @@ namestore_list_response (void *cls, char *result; if (NULL == handle->resp_object) - handle->resp_object = GNUNET_JSONAPI_object_new (); + handle->resp_object = GNUNET_JSONAPI_document_new (); if (NULL == rname) { handle->list_it = NULL; //Handle response - if (GNUNET_SYSERR == GNUNET_JSONAPI_data_serialize (handle->resp_object, &result)) + if (GNUNET_SYSERR == GNUNET_JSONAPI_document_serialize (handle->resp_object, &result)) { GNUNET_SCHEDULER_add_now (&do_error, handle); return; @@ -456,7 +456,7 @@ namestore_list_response (void *cls, GNUNET_JSONAPI_resource_add_attr (json_resource, GNUNET_REST_JSONAPI_NAMESTORE_RECORD, result_array); - GNUNET_JSONAPI_object_resource_add (handle->resp_object, json_resource); + GNUNET_JSONAPI_document_resource_add (handle->resp_object, json_resource); } json_decref (result_array); @@ -658,7 +658,7 @@ json_to_gnsrecord (const json_t *records_json, "Value property is no string\n"); return GNUNET_SYSERR; } - GNUNET_asprintf (&value, "%s", json_string_value (value_json)); + value = GNUNET_strdup (json_string_value (value_json)); if (GNUNET_OK != GNUNET_GNSRECORD_string_to_value ((*rd)[i].record_type, value, &rdata, @@ -719,9 +719,8 @@ namestore_create_cont (struct GNUNET_REST_RequestHandle *con, { struct RequestHandle *handle = cls; struct MHD_Response *resp; - struct GNUNET_JSONAPI_Object *json_obj; + struct GNUNET_JSONAPI_Document *json_obj; struct GNUNET_JSONAPI_Resource *json_res; - json_t *name_json; json_t *records_json; char term_data[handle->rest_handle->data_size+1]; @@ -741,7 +740,7 @@ namestore_create_cont (struct GNUNET_REST_RequestHandle *con, memcpy (term_data, handle->rest_handle->data, handle->rest_handle->data_size); - GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_object_parse (term_data, + GNUNET_assert (GNUNET_OK == GNUNET_JSONAPI_document_parse (term_data, &json_obj)); if (NULL == json_obj) { @@ -751,54 +750,45 @@ namestore_create_cont (struct GNUNET_REST_RequestHandle *con, GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - if (1 != GNUNET_JSONAPI_object_resource_count (json_obj)) + if (1 != GNUNET_JSONAPI_document_resource_count (json_obj)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Cannot create more than 1 resource! (Got %d)\n", - GNUNET_JSONAPI_object_resource_count (json_obj)); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_resource_count (json_obj)); + GNUNET_JSONAPI_document_delete (json_obj); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - json_res = GNUNET_JSONAPI_object_get_resource (json_obj, 0); + json_res = GNUNET_JSONAPI_document_get_resource (json_obj, 0); if (GNUNET_NO == GNUNET_JSONAPI_resource_check_type (json_res, GNUNET_REST_JSONAPI_NAMESTORE_RECORD)) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "Unsupported JSON data type\n"); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); resp = GNUNET_REST_create_json_response (NULL); handle->proc (handle->proc_cls, resp, MHD_HTTP_CONFLICT); cleanup_handle (handle); return; } - name_json = GNUNET_JSONAPI_resource_get_id (json_res); - if (!json_is_string (name_json)) - { - GNUNET_log (GNUNET_ERROR_TYPE_ERROR, - "Name property is no string\n"); - GNUNET_JSONAPI_object_delete (json_obj); - GNUNET_SCHEDULER_add_now (&do_error, handle); - return; - } - GNUNET_asprintf (&handle->name, "%s", json_string_value (name_json)); + handle->name = GNUNET_strdup (GNUNET_JSONAPI_resource_get_id (json_res)); records_json = GNUNET_JSONAPI_resource_read_attr (json_res, GNUNET_REST_JSONAPI_NAMESTORE_RECORD); if (NULL == records_json) { GNUNET_log (GNUNET_ERROR_TYPE_ERROR, "No records given\n"); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } if (GNUNET_SYSERR == json_to_gnsrecord (records_json, &handle->rd, &handle->rd_count)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); handle->add_qe = GNUNET_NAMESTORE_records_lookup (handle->ns_handle, &handle->zone_pkey, @@ -815,13 +805,13 @@ namestore_zkey_response (void *cls, { struct RequestHandle *handle = cls; struct MHD_Response *resp; - struct GNUNET_JSONAPI_Object *json_obj; + struct GNUNET_JSONAPI_Document *json_obj; struct GNUNET_JSONAPI_Resource *json_res; json_t *name_json; char* result; handle->reverse_qe = NULL; - json_obj = GNUNET_JSONAPI_object_new (); + json_obj = GNUNET_JSONAPI_document_new (); if (NULL != label) { name_json = json_string (label); @@ -830,19 +820,19 @@ namestore_zkey_response (void *cls, GNUNET_JSONAPI_resource_add_attr (json_res, GNUNET_REST_JSONAPI_NAMESTORE_NAME, name_json); - GNUNET_JSONAPI_object_resource_add (json_obj, json_res); + GNUNET_JSONAPI_document_resource_add (json_obj, json_res); json_decref (name_json); } //Handle response - if (GNUNET_SYSERR == GNUNET_JSONAPI_data_serialize (json_obj, &result)) + if (GNUNET_SYSERR == GNUNET_JSONAPI_document_serialize (json_obj, &result)) { - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); GNUNET_SCHEDULER_add_now (&do_error, handle); return; } resp = GNUNET_REST_create_json_response (result); handle->proc (handle->proc_cls, resp, MHD_HTTP_OK); - GNUNET_JSONAPI_object_delete (json_obj); + GNUNET_JSONAPI_document_delete (json_obj); GNUNET_free (result); GNUNET_SCHEDULER_add_now (&cleanup_handle_delayed, handle); return; @@ -1105,9 +1095,9 @@ testservice_id_task (void *cls, int result) } name = get_name_from_url (handle->url); if (NULL != ego) - GNUNET_asprintf (&handle->ego_name, "%s", ego); + handle->ego_name = GNUNET_strdup (ego); if (NULL != name) - GNUNET_asprintf (&handle->name, "%s", name); + handle->name = GNUNET_strdup (name); if (NULL == handle->ego_name) { handle->identity_handle = GNUNET_IDENTITY_connect (handle->cfg, &id_connect_cb, handle); @@ -1148,7 +1138,7 @@ rest_identity_process_request(struct GNUNET_REST_RequestHandle *rest_handle, handle->proc_cls = proc_cls; handle->proc = proc; handle->rest_handle = rest_handle; - GNUNET_asprintf (&handle->url, "%s", rest_handle->url); + handle->url = GNUNET_strdup (rest_handle->url); if (handle->url[strlen (handle->url)-1] == '/') handle->url[strlen (handle->url)-1] = '\0'; GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, diff --git a/src/rest/gnunet-rest-server.c b/src/rest/gnunet-rest-server.c index 92bef1094..92d478442 100644 --- a/src/rest/gnunet-rest-server.c +++ b/src/rest/gnunet-rest-server.c @@ -757,7 +757,7 @@ run (void *cls, return; } GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, - "Service listens on port %u\n", + "Service listens on port %lu\n", port); httpd = MHD_start_daemon (MHD_USE_DEBUG | MHD_USE_NO_LISTEN_SOCKET, 0, -- 2.25.1