Skip to content

Commit 319f2f1

Browse files
committed
Parsing JSON number in one turn.
1 parent 8c85006 commit 319f2f1

File tree

1 file changed

+89
-107
lines changed

1 file changed

+89
-107
lines changed

json_parser.c

Lines changed: 89 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -288,159 +288,143 @@ static const double __power_of_10[309] = {
288288
1e305, 1e306, 1e307, 1e308
289289
};
290290

291-
static double __evaluate_json_number(const char *integer,
292-
const char *fraction,
293-
int exp)
291+
static int __parse_json_number(const char *cursor, const char **end,
292+
double *num)
294293
{
294+
const char *integer = cursor;
295295
long long mant = 0;
296296
int figures = 0;
297-
double num;
298-
int sign;
297+
int exp = 0;
298+
double n;
299299

300-
sign = (*integer == '-');
301-
if (sign)
302-
integer++;
300+
if (*cursor == '-')
301+
cursor++;
303302

304-
if (*integer != '0')
303+
if (*cursor == '0')
304+
cursor++;
305+
else if (isdigit(*cursor))
305306
{
306-
mant = *integer - '0';
307-
integer++;
308-
figures++;
309-
while (isdigit(*integer) && figures < 18)
307+
mant = *cursor - '0';
308+
figures = 1;
309+
cursor++;
310+
while (isdigit(*cursor) && figures < 18)
310311
{
311312
mant *= 10;
312-
mant += *integer - '0';
313-
integer++;
313+
mant += *cursor - '0';
314314
figures++;
315+
cursor++;
315316
}
316317

317-
while (isdigit(*integer))
318+
while (isdigit(*cursor))
318319
{
319320
exp++;
320-
integer++;
321+
cursor++;
321322
}
322323
}
323324
else
325+
return -2;
326+
327+
if (*cursor == '.')
324328
{
325-
while (*fraction == '0')
329+
cursor++;
330+
if (!isdigit(*cursor))
331+
return -2;
332+
333+
if (figures == 0)
334+
{
335+
while (*cursor == '0')
336+
{
337+
exp--;
338+
cursor++;
339+
}
340+
}
341+
342+
while (isdigit(*cursor) && figures < 18)
326343
{
344+
mant *= 10;
345+
mant += *cursor - '0';
346+
figures++;
327347
exp--;
328-
fraction++;
348+
cursor++;
329349
}
350+
351+
while (isdigit(*cursor))
352+
cursor++;
330353
}
331354

332-
while (isdigit(*fraction) && figures < 18)
355+
if (cursor - integer > 1000000)
356+
return -2;
357+
358+
if (*cursor == 'E' || *cursor == 'e')
333359
{
334-
mant *= 10;
335-
mant += *fraction - '0';
336-
exp--;
337-
fraction++;
338-
figures++;
360+
int neg;
361+
int e;
362+
363+
cursor++;
364+
neg = (*cursor == '-');
365+
if (neg || *cursor == '+')
366+
cursor++;
367+
368+
if (!isdigit(*cursor))
369+
return -2;
370+
371+
e = *cursor - '0';
372+
cursor++;
373+
while (isdigit(*cursor) && e < 2000000)
374+
{
375+
e *= 10;
376+
e += *cursor - '0';
377+
cursor++;
378+
}
379+
380+
while (isdigit(*cursor))
381+
cursor++;
382+
383+
if (neg)
384+
e = -e;
385+
386+
exp += e;
339387
}
340388

341389
if (exp != 0 && figures != 0)
342390
{
343391
while (exp > 0 && figures < 18)
344392
{
345393
mant *= 10;
346-
exp--;
347394
figures++;
395+
exp--;
348396
}
349397

350398
while (exp < 0 && mant % 10 == 0)
351399
{
352400
mant /= 10;
353-
exp++;
354401
figures--;
402+
exp++;
355403
}
356404
}
357405

358-
num = mant;
406+
n = mant;
359407
if (exp != 0 && figures != 0)
360408
{
361409
if (exp > 291)
362-
num = INFINITY;
410+
n = INFINITY;
363411
else if (exp > 0)
364-
num *= __power_of_10[exp];
412+
n *= __power_of_10[exp];
365413
else if (exp > -309)
366-
num /= __power_of_10[-exp];
414+
n /= __power_of_10[-exp];
367415
else if (exp > -324 - figures)
368416
{
369-
num /= __power_of_10[-exp - 308];
370-
num /= __power_of_10[308];
417+
n /= __power_of_10[-exp - 308];
418+
n /= __power_of_10[308];
371419
}
372420
else
373-
num = 0.0;
421+
n = 0.0;
374422
}
375423

376-
return sign ? -num : num;
377-
}
424+
if (*integer == '-')
425+
n = -n;
378426

379-
static int __parse_json_number(const char *cursor, const char **end,
380-
double *num)
381-
{
382-
const char *integer = cursor;
383-
const char *fraction = "";
384-
int exp = 0;
385-
int sign;
386-
387-
if (*cursor == '-')
388-
cursor++;
389-
390-
if (*cursor == '0')
391-
{
392-
if (isdigit(cursor[1]))
393-
return -2;
394-
}
395-
else if (!isdigit(*cursor))
396-
return -2;
397-
398-
cursor++;
399-
while (isdigit(*cursor))
400-
cursor++;
401-
402-
if (*cursor == '.')
403-
{
404-
cursor++;
405-
fraction = cursor;
406-
if (!isdigit(*cursor))
407-
return -2;
408-
409-
cursor++;
410-
while (isdigit(*cursor))
411-
cursor++;
412-
}
413-
414-
if (*cursor == 'E' || *cursor == 'e')
415-
{
416-
cursor++;
417-
sign = (*cursor == '-');
418-
if (sign || *cursor == '+')
419-
cursor++;
420-
421-
if (!isdigit(*cursor))
422-
return -2;
423-
424-
exp = *cursor - '0';
425-
cursor++;
426-
while (isdigit(*cursor) && exp < 2000000)
427-
{
428-
exp *= 10;
429-
exp += *cursor - '0';
430-
cursor++;
431-
}
432-
433-
while (isdigit(*cursor))
434-
cursor++;
435-
436-
if (sign)
437-
exp = -exp;
438-
}
439-
440-
if (cursor - integer > 1000000)
441-
return -2;
442-
443-
*num = __evaluate_json_number(integer, fraction, exp);
427+
*num = n;
444428
*end = cursor;
445429
return 0;
446430
}
@@ -875,13 +859,11 @@ json_value_t *json_value_create(int type, ...)
875859
va_start(ap, type);
876860
ret = __set_json_value(type, ap, val);
877861
va_end(ap);
878-
if (ret < 0)
879-
{
880-
free(val);
881-
return NULL;
882-
}
862+
if (ret >= 0)
863+
return val;
883864

884-
return val;
865+
free(val);
866+
return NULL;
885867
}
886868

887869
static int __copy_json_value(const json_value_t *src, json_value_t *dest);

0 commit comments

Comments
 (0)