diff options
-rw-r--r-- | src/include/taler_json_lib.h | 12 | ||||
-rw-r--r-- | src/json/json_helper.c | 89 | ||||
-rw-r--r-- | src/lib/exchange_api_handle.c | 6 |
3 files changed, 101 insertions, 6 deletions
diff --git a/src/include/taler_json_lib.h b/src/include/taler_json_lib.h index fbc8785d0..5a16d40a5 100644 --- a/src/include/taler_json_lib.h +++ b/src/include/taler_json_lib.h @@ -106,6 +106,18 @@ TALER_JSON_spec_absolute_time_nbo (const char *name, /** + * Provide specification to parse given JSON object to a relative time. + * The absolute time value is expected to be already rounded. + * + * @param name name of the time field in the JSON + * @param[out] r_time where the time has to be written + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_relative_time (const char *name, + struct GNUNET_TIME_Relative *r_time); + + +/** * Generate line in parser specification for denomination public key. * * @param field name of the field diff --git a/src/json/json_helper.c b/src/json/json_helper.c index 44eeb87bf..c30e82894 100644 --- a/src/json/json_helper.c +++ b/src/json/json_helper.c @@ -251,7 +251,7 @@ TALER_JSON_spec_absolute_time (const char *name, .cls = NULL, .field = name, .ptr = r_time, - .ptr_size = sizeof(uint64_t), + .ptr_size = sizeof(struct GNUNET_TIME_Absolute), .size_ptr = NULL }; @@ -307,7 +307,92 @@ TALER_JSON_spec_absolute_time_nbo (const char *name, .cls = NULL, .field = name, .ptr = r_time, - .ptr_size = sizeof(uint64_t), + .ptr_size = sizeof(struct GNUNET_TIME_AbsoluteNBO), + .size_ptr = NULL + }; + + return ret; +} + + +/** + * Parse given JSON object to relative time. + * + * @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_rel_time (void *cls, + json_t *root, + struct GNUNET_JSON_Specification *spec) +{ + struct GNUNET_TIME_Relative *rel = spec->ptr; + json_t *json_d_ms; + unsigned long long int tval; + + if (! json_is_object (root)) + { + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + json_d_ms = json_object_get (root, "d_ms"); + if (json_is_integer (json_d_ms)) + { + tval = json_integer_value (json_d_ms); + /* Time is in milliseconds in JSON, but in microseconds in GNUNET_TIME_Absolute */ + rel->rel_value_us = tval * 1000LL; + if ((rel->rel_value_us) / 1000LL != tval) + { + /* Integer overflow */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + if (GNUNET_OK != + GNUNET_TIME_round_rel (rel)) + { + /* time not rounded */ + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + return GNUNET_OK; + } + if (json_is_string (json_d_ms)) + { + const char *val; + val = json_string_value (json_d_ms); + if ((0 == strcasecmp (val, "forever"))) + { + *rel = GNUNET_TIME_UNIT_FOREVER_REL; + return GNUNET_OK; + } + GNUNET_break_op (0); + return GNUNET_SYSERR; + } + GNUNET_break_op (0); + return GNUNET_SYSERR; +} + + +/** + * Provide specification to parse given JSON object to a relative time. + * The absolute time value is expected to be already rounded. + * + * @param name name of the time field in the JSON + * @param[out] r_time where the time has to be written + */ +struct GNUNET_JSON_Specification +TALER_JSON_spec_relative_time (const char *name, + struct GNUNET_TIME_Relative *r_time) +{ + struct GNUNET_JSON_Specification ret = { + .parser = &parse_rel_time, + .cleaner = NULL, + .cls = NULL, + .field = name, + .ptr = r_time, + .ptr_size = sizeof(struct GNUNET_TIME_Relative), .size_ptr = NULL }; diff --git a/src/lib/exchange_api_handle.c b/src/lib/exchange_api_handle.c index ab4af8ae8..374312a1b 100644 --- a/src/lib/exchange_api_handle.c +++ b/src/lib/exchange_api_handle.c @@ -827,8 +827,8 @@ decode_keys_json (const json_t *resp_obj, &key_data->master_pub), TALER_JSON_spec_absolute_time ("list_issue_date", &key_data->list_issue_date), - GNUNET_JSON_spec_relative_time ("reserve_closing_delay", - &key_data->reserve_closing_delay), + TALER_JSON_spec_relative_time ("reserve_closing_delay", + &key_data->reserve_closing_delay), GNUNET_JSON_spec_end () }; @@ -887,8 +887,6 @@ decode_keys_json (const json_t *resp_obj, GNUNET_JSON_parse (resp_obj, (check_sig) ? mspec : &mspec[2], NULL, NULL)); - EXITIF (GNUNET_OK != - GNUNET_TIME_round_rel (&key_data->reserve_closing_delay)); /* parse the master public key and issue date of the response */ if (check_sig) hash_context = GNUNET_CRYPTO_hash_context_start (); |