deduplicate code with util/json.c, do use consistently /time/ encoding

This commit is contained in:
Christian Grothoff 2015-06-20 22:53:01 +02:00
parent 61752e0334
commit 3bb26bcf47
3 changed files with 86 additions and 147 deletions

View File

@ -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,

View File

@ -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", &currency))
{
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
};

View File

@ -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", &currency,
"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", &currency))
{
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
*