Skip to content

Commit d1bb99d

Browse files
committed
Optimize parsing JSON number.
1 parent a169ebf commit d1bb99d

File tree

1 file changed

+58
-28
lines changed

1 file changed

+58
-28
lines changed

json_parser.c

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ static int __json_isspace(char c)
6161

6262
static int __json_isdigit(char c)
6363
{
64-
return c >= '0' && c <= '9';
64+
return (unsigned int)(c - '0') <= 9;
6565
}
6666

6767
#define isspace(c) __json_isspace(c)
@@ -338,35 +338,47 @@ static int __parse_json_number(const char *cursor, const char **end,
338338
double *num)
339339
{
340340
const char *integer = cursor;
341-
long long mant = 0;
342-
int figures = 0;
341+
unsigned int digit;
342+
long long mant;
343+
int figures;
343344
int exp = 0;
344345
double n;
345346

346347
if (*cursor == '-')
347348
cursor++;
348349

349-
if (*cursor >= '1' && *cursor <= '9')
350+
mant = *cursor - '0';
351+
if (mant >= 1 && mant <= 9)
350352
{
351-
mant = *cursor - '0';
352353
figures = 1;
353354
cursor++;
354-
while (isdigit(*cursor) && figures < 18)
355+
while (1)
355356
{
356-
mant *= 10;
357-
mant += *cursor - '0';
358-
figures++;
359-
cursor++;
357+
digit = (unsigned int)(*cursor - '0');
358+
if (digit <= 9 && figures < 18)
359+
{
360+
mant = 10 * mant + digit;
361+
figures++;
362+
cursor++;
363+
}
364+
else
365+
break;
360366
}
361367

362-
while (isdigit(*cursor))
368+
if (digit <= 9)
363369
{
364-
exp++;
365-
cursor++;
370+
do
371+
{
372+
exp++;
373+
cursor++;
374+
} while (isdigit(*cursor));
366375
}
367376
}
368-
else if (*cursor == '0')
377+
else if (mant == 0)
378+
{
379+
figures = 0;
369380
cursor++;
381+
}
370382
else
371383
return -2;
372384

@@ -385,17 +397,26 @@ static int __parse_json_number(const char *cursor, const char **end,
385397
}
386398
}
387399

388-
while (isdigit(*cursor) && figures < 18)
400+
while (1)
389401
{
390-
mant *= 10;
391-
mant += *cursor - '0';
392-
figures++;
393-
exp--;
394-
cursor++;
402+
digit = (unsigned int)(*cursor - '0');
403+
if (digit <= 9 && figures < 18)
404+
{
405+
mant = 10 * mant + digit;
406+
figures++;
407+
exp--;
408+
cursor++;
409+
}
410+
else
411+
break;
395412
}
396413

397-
while (isdigit(*cursor))
398-
cursor++;
414+
if (digit <= 9)
415+
{
416+
do
417+
cursor++;
418+
while (isdigit(*cursor));
419+
}
399420
}
400421

401422
if (cursor - integer > 1000000)
@@ -416,15 +437,24 @@ static int __parse_json_number(const char *cursor, const char **end,
416437

417438
e = *cursor - '0';
418439
cursor++;
419-
while (isdigit(*cursor) && e < 2000000)
440+
while (1)
420441
{
421-
e *= 10;
422-
e += *cursor - '0';
423-
cursor++;
442+
digit = (unsigned int)(*cursor - '0');
443+
if (digit <= 9 && e < 2000000)
444+
{
445+
e = 10 * e + digit;
446+
cursor++;
447+
}
448+
else
449+
break;
424450
}
425451

426-
while (isdigit(*cursor))
427-
cursor++;
452+
if (digit <= 9)
453+
{
454+
do
455+
cursor++;
456+
while (isdigit(*cursor));
457+
}
428458

429459
if (neg)
430460
e = -e;

0 commit comments

Comments
 (0)