Fix JSON parsing to handle very long ints better. Should still

do something better about them on output.
This commit is contained in:
jef 2012-10-27 16:43:04 -07:00
parent ff3c7fba24
commit d23d944f12

View File

@ -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;
} }