Fix JSON parsing to handle very long ints better. Should still
do something better about them on output.
This commit is contained in:
parent
ff3c7fba24
commit
d23d944f12
42
src/cjson.c
42
src/cjson.c
@ -132,51 +132,65 @@ static double ipow( double n, int exp )
|
|||||||
/* Parse the input text to generate a number, and populate the result into item. */
|
/* Parse the input text to generate a number, and populate the result into item. */
|
||||||
static const char *parse_number( cJSON *item, const char *num )
|
static const char *parse_number( cJSON *item, const char *num )
|
||||||
{
|
{
|
||||||
double n = 0;
|
long long i = 0;
|
||||||
|
double f = 0;
|
||||||
|
int isint = 1;
|
||||||
int sign = 1, scale = 0, subscale = 0, signsubscale = 1;
|
int sign = 1, scale = 0, subscale = 0, signsubscale = 1;
|
||||||
|
|
||||||
/* Could use sscanf for this? */
|
/* Could use sscanf for this? */
|
||||||
if ( *num == '-' ) {
|
if ( *num == '-' ) {
|
||||||
/* Has sign. */
|
/* Has sign. */
|
||||||
sign = -1;
|
sign = -1;
|
||||||
num++;
|
++num;
|
||||||
}
|
}
|
||||||
if ( *num == '0' )
|
if ( *num == '0' )
|
||||||
/* Is zero. */
|
/* Is zero. */
|
||||||
num++;
|
++num;
|
||||||
if ( *num >= '1' && *num<='9' ) {
|
if ( *num >= '1' && *num<='9' ) {
|
||||||
/* Number. */
|
/* Number. */
|
||||||
do {
|
do {
|
||||||
n = ( n * 10.0 ) + ( *num++ - '0' );
|
i = ( i * 10 ) + ( *num - '0' );
|
||||||
|
f = ( f * 10.0 ) + ( *num - '0' );
|
||||||
|
++num;
|
||||||
} while ( *num >= '0' && *num <= '9' );
|
} while ( *num >= '0' && *num <= '9' );
|
||||||
}
|
}
|
||||||
if ( *num == '.' && num[1] >= '0' && num[1] <= '9' ) {
|
if ( *num == '.' && num[1] >= '0' && num[1] <= '9' ) {
|
||||||
/* Fractional part. */
|
/* Fractional part. */
|
||||||
num++;
|
isint = 0;
|
||||||
|
++num;
|
||||||
do {
|
do {
|
||||||
n = ( n * 10.0 ) + ( *num++ - '0' );
|
f = ( f * 10.0 ) + ( *num++ - '0' );
|
||||||
scale--;
|
scale--;
|
||||||
} while ( *num >= '0' && *num <= '9' );
|
} while ( *num >= '0' && *num <= '9' );
|
||||||
}
|
}
|
||||||
if ( *num == 'e' || *num == 'E' ) {
|
if ( *num == 'e' || *num == 'E' ) {
|
||||||
/* Exponent. */
|
/* Exponent. */
|
||||||
num++;
|
isint = 0;
|
||||||
|
++num;
|
||||||
if ( *num == '+' )
|
if ( *num == '+' )
|
||||||
num++;
|
++num;
|
||||||
else if ( *num == '-' ) {
|
else if ( *num == '-' ) {
|
||||||
/* With sign. */
|
/* With sign. */
|
||||||
signsubscale = -1;
|
signsubscale = -1;
|
||||||
num++;
|
++num;
|
||||||
}
|
}
|
||||||
while ( *num >= '0' && *num <= '9' )
|
while ( *num >= '0' && *num <= '9' )
|
||||||
subscale = ( subscale * 10 ) + ( *num++ - '0' );
|
subscale = ( subscale * 10 ) + ( *num++ - '0' );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Put it together: number = +/- number.fraction * 10^+/- exponent */
|
/* Put it together. */
|
||||||
n = sign * n * ipow( 10.0, scale + subscale * signsubscale );
|
if ( isint ) {
|
||||||
|
/* Int: number = +/- number */
|
||||||
item->valuefloat = n;
|
i = sign * i;
|
||||||
item->valueint = n;
|
item->valueint = i;
|
||||||
|
item->valuefloat = i;
|
||||||
|
} else {
|
||||||
|
/* Float: number = +/- number.fraction * 10^+/- exponent */
|
||||||
|
f = sign * f * ipow( 10.0, scale + subscale * signsubscale );
|
||||||
|
item->valueint = f;
|
||||||
|
item->valuefloat = f;
|
||||||
|
}
|
||||||
|
|
||||||
item->type = cJSON_Number;
|
item->type = cJSON_Number;
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user