#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; } /** * Create a JSON API error * * @param res the JSON error */ struct GNUNET_JSONAPI_Error* GNUNET_JSONAPI_error_new (const char *id, const char *status, const char *code, const char *title, const char *detail, json_t *links, json_t *source, json_t *meta) { struct GNUNET_JSONAPI_Error *error; error = GNUNET_new (struct GNUNET_JSONAPI_Error); if (NULL != id) error->id = GNUNET_strdup (id); if (NULL != status) error->status = GNUNET_strdup (status); if (NULL != code) error->code = GNUNET_strdup (code); if (NULL != title) error->title = GNUNET_strdup (title); if (NULL != detail) error->detail = GNUNET_strdup (detail); if (NULL != links) error->links = json_deep_copy (links); if (NULL != source) error->source = json_deep_copy (source); if (NULL != meta) error->meta = json_deep_copy (meta); return error; } /** * 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; }