deduplicate code with util/json.c, do use consistently /time/ encoding
This commit is contained in:
parent
61752e0334
commit
3bb26bcf47
@ -355,7 +355,10 @@ parse_json_denomkey (struct TALER_MINT_DenomPublicKey *denom_key,
|
||||
if (GNUNET_OK !=
|
||||
MAJ_parse_json (denom_key_obj,
|
||||
spec))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
memset (&denom_key_issue, 0, sizeof (denom_key_issue));
|
||||
GNUNET_CRYPTO_rsa_public_key_hash (pk,
|
||||
|
@ -24,116 +24,6 @@
|
||||
#include "mint_api_json.h"
|
||||
|
||||
|
||||
/**
|
||||
* Parse absolute time specified in JSON format. The JSON format is
|
||||
* "/TIMEVAL/" where TIMEVAL is in milliseconds. Additionally, we
|
||||
* support "/forever/" to represent the end of time.
|
||||
*
|
||||
* @param f json specification of the amount
|
||||
* @param[out] time set to the time specified in @a f
|
||||
* @return
|
||||
* #GNUNET_YES if parsing was successful
|
||||
* #GNUNET_SYSERR on errors
|
||||
*/
|
||||
static int
|
||||
parse_time_abs (json_t *f,
|
||||
struct GNUNET_TIME_Absolute *time)
|
||||
{
|
||||
const char *val;
|
||||
size_t slen;
|
||||
unsigned long long int tval;
|
||||
char *endp;
|
||||
|
||||
val = json_string_value (f);
|
||||
if (NULL == val)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
slen = strlen (val);
|
||||
if ( (slen <= 2) ||
|
||||
('/' != val[0]) ||
|
||||
('/' != val[slen - 1]) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (0 == strcasecmp (val,
|
||||
"/forever/"))
|
||||
{
|
||||
*time = GNUNET_TIME_UNIT_FOREVER_ABS;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
tval = strtoull (&val[1],
|
||||
&endp,
|
||||
10);
|
||||
if (&val[slen - 1] != endp)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
/* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
|
||||
time->abs_value_us = tval * 1000LL * 1000LL;
|
||||
if ( (time->abs_value_us) / 1000LL / 1000LL != tval)
|
||||
{
|
||||
/* Integer overflow */
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse amount specified in JSON format.
|
||||
*
|
||||
* @param f json specification of the amount
|
||||
* @param[out] amount set to the amount specified in @a f
|
||||
* @return
|
||||
* #GNUNET_OK if parsing was successful
|
||||
* #GNUNET_SYSERR on error
|
||||
*/
|
||||
static int
|
||||
parse_amount (json_t *f,
|
||||
struct TALER_Amount *amount)
|
||||
{
|
||||
json_int_t value;
|
||||
json_int_t fraction;
|
||||
const char *currency;
|
||||
|
||||
memset (amount,
|
||||
0,
|
||||
sizeof (struct TALER_Amount));
|
||||
if (-1 == json_unpack (f,
|
||||
"{s:I, s:I, s:s}",
|
||||
"value", &value,
|
||||
"fraction", &fraction,
|
||||
"currency", ¤cy))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (value < 0) ||
|
||||
(fraction < 0) ||
|
||||
(value > UINT64_MAX) ||
|
||||
(fraction > UINT32_MAX) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (strlen (currency) >= TALER_CURRENCY_LEN)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
amount->value = (uint64_t) value;
|
||||
amount->fraction = (uint32_t) fraction;
|
||||
strcpy (amount->currency, currency);
|
||||
(void) TALER_amount_normalize (amount);
|
||||
return GNUNET_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Navigate and parse data in a JSON tree.
|
||||
*
|
||||
@ -165,15 +55,21 @@ parse_json (json_t *root,
|
||||
return i;
|
||||
case MAJ_CMD_AMOUNT:
|
||||
if (GNUNET_OK !=
|
||||
parse_amount (pos,
|
||||
spec[i].details.amount))
|
||||
TALER_json_to_amount (pos,
|
||||
spec[i].details.amount))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
case MAJ_CMD_TIME_ABSOLUTE:
|
||||
if (GNUNET_OK !=
|
||||
parse_time_abs (pos,
|
||||
spec[i].details.abs_time))
|
||||
TALER_json_to_abs (pos,
|
||||
spec[i].details.abs_time))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return i;
|
||||
}
|
||||
break;
|
||||
|
||||
case MAJ_CMD_BINARY_FIXED:
|
||||
@ -240,7 +136,7 @@ parse_json (json_t *root,
|
||||
int res;
|
||||
void *buf;
|
||||
|
||||
str = json_string_value (root);
|
||||
str = json_string_value (pos);
|
||||
if (NULL == str)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -277,7 +173,7 @@ parse_json (json_t *root,
|
||||
int res;
|
||||
void *buf;
|
||||
|
||||
str = json_string_value (root);
|
||||
str = json_string_value (pos);
|
||||
if (NULL == str)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
@ -454,7 +350,7 @@ MAJ_spec_rsa_public_key (const char *name,
|
||||
{
|
||||
struct MAJ_Specification ret =
|
||||
{
|
||||
.cmd = MAJ_CMD_AMOUNT,
|
||||
.cmd = MAJ_CMD_RSA_PUBLIC_KEY,
|
||||
.field = name,
|
||||
.details.rsa_public_key = pk
|
||||
};
|
||||
@ -474,7 +370,7 @@ MAJ_spec_rsa_signature (const char *name,
|
||||
{
|
||||
struct MAJ_Specification ret =
|
||||
{
|
||||
.cmd = MAJ_CMD_AMOUNT,
|
||||
.cmd = MAJ_CMD_RSA_SIGNATURE,
|
||||
.field = name,
|
||||
.details.rsa_signature = sig
|
||||
};
|
||||
|
@ -90,7 +90,7 @@ TALER_json_from_abs (struct GNUNET_TIME_Absolute stamp)
|
||||
int ret;
|
||||
|
||||
if (stamp.abs_value_us == GNUNET_TIME_UNIT_FOREVER_ABS.abs_value_us)
|
||||
return json_string ("never");
|
||||
return json_string ("/never/");
|
||||
ret = GNUNET_asprintf (&mystr,
|
||||
"/%llu/",
|
||||
(long long) (stamp.abs_value_us / (1000LL * 1000LL)));
|
||||
@ -282,28 +282,40 @@ int
|
||||
TALER_json_to_amount (json_t *json,
|
||||
struct TALER_Amount *r_amount)
|
||||
{
|
||||
char *currency;
|
||||
json_int_t value;
|
||||
json_int_t fraction;
|
||||
json_error_t error;
|
||||
const char *currency;
|
||||
|
||||
UNPACK_EXITIF (0 != json_unpack_ex (json,
|
||||
&error,
|
||||
JSON_STRICT,
|
||||
"{s:s, s:I, s:I}",
|
||||
"currency", ¤cy,
|
||||
"value", &value,
|
||||
"fraction", &fraction));
|
||||
EXITIF (3 < strlen (currency));
|
||||
EXITIF (TALER_CURRENCY_LEN <= strlen (currency));
|
||||
strcpy (r_amount->currency,
|
||||
currency);
|
||||
r_amount->value = (uint32_t) value;
|
||||
memset (r_amount,
|
||||
0,
|
||||
sizeof (struct TALER_Amount));
|
||||
if (-1 == json_unpack (json,
|
||||
"{s:I, s:I, s:s}",
|
||||
"value", &value,
|
||||
"fraction", &fraction,
|
||||
"currency", ¤cy))
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (value < 0) ||
|
||||
(fraction < 0) ||
|
||||
(value > UINT64_MAX) ||
|
||||
(fraction > UINT32_MAX) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if (strlen (currency) >= TALER_CURRENCY_LEN)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
r_amount->value = (uint64_t) value;
|
||||
r_amount->fraction = (uint32_t) fraction;
|
||||
strcpy (r_amount->currency, currency);
|
||||
(void) TALER_amount_normalize (r_amount);
|
||||
return GNUNET_OK;
|
||||
|
||||
EXITIF_exit:
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
|
||||
@ -318,25 +330,53 @@ int
|
||||
TALER_json_to_abs (json_t *json,
|
||||
struct GNUNET_TIME_Absolute *abs)
|
||||
{
|
||||
const char *str;
|
||||
unsigned long long abs_value_s;
|
||||
const char *val;
|
||||
size_t slen;
|
||||
unsigned long long int tval;
|
||||
char *endp;
|
||||
|
||||
GNUNET_assert (NULL != abs);
|
||||
EXITIF (NULL == (str = json_string_value (json)));
|
||||
if (0 == strcasecmp (str,
|
||||
"never"))
|
||||
val = json_string_value (json);
|
||||
if (NULL == val)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
slen = strlen (val);
|
||||
if ( (slen <= 2) ||
|
||||
('/' != val[0]) ||
|
||||
('/' != val[slen - 1]) )
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
if ( (0 == strcasecmp (val,
|
||||
"/forever/")) ||
|
||||
(0 == strcasecmp (val,
|
||||
"/never/")) )
|
||||
{
|
||||
*abs = GNUNET_TIME_UNIT_FOREVER_ABS;
|
||||
return GNUNET_OK;
|
||||
}
|
||||
EXITIF (1 > sscanf (str, "%llu", &abs_value_s));
|
||||
abs->abs_value_us = abs_value_s * 1000LL * 1000LL;
|
||||
tval = strtoull (&val[1],
|
||||
&endp,
|
||||
10);
|
||||
if (&val[slen - 1] != endp)
|
||||
{
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
/* Time is in seconds in JSON, but in microseconds in GNUNET_TIME_Absolute */
|
||||
abs->abs_value_us = tval * 1000LL * 1000LL;
|
||||
if ( (abs->abs_value_us) / 1000LL / 1000LL != tval)
|
||||
{
|
||||
/* Integer overflow */
|
||||
GNUNET_break_op (0);
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
return GNUNET_OK;
|
||||
|
||||
EXITIF_exit:
|
||||
return GNUNET_SYSERR;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parse given JSON object to data
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user