Skip to content

Commit 604bf0e

Browse files
committed
Optimize parsjing JSON string.
1 parent 794aae2 commit 604bf0e

File tree

1 file changed

+65
-19
lines changed

1 file changed

+65
-19
lines changed

json_parser.c

Lines changed: 65 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,15 @@ static const int __character_map[256] = {
8686
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
8787
};
8888

89-
static int __json_string_length(const char *cursor, size_t *len)
89+
static int __json_string_length(const char *cursor, size_t *escape, size_t *len)
9090
{
91+
size_t esc = 0;
9192
size_t n = 0;
9293

9394
while (1)
9495
{
95-
if (__character_map[(unsigned char)cursor[n]])
96-
{
96+
while (__character_map[(unsigned char)cursor[n]])
9797
n++;
98-
continue;
99-
}
10098

10199
if (cursor[n] == '\"')
102100
break;
@@ -108,9 +106,11 @@ static int __json_string_length(const char *cursor, size_t *len)
108106
if (cursor[n] == '\0')
109107
return -2;
110108

109+
esc++;
111110
n++;
112111
}
113112

113+
*escape = esc;
114114
*len = n;
115115
return 0;
116116
}
@@ -208,20 +208,20 @@ static int __parse_json_unicode(const char *cursor, const char **end,
208208
}
209209

210210
static int __parse_json_string(const char *cursor, const char **end,
211-
char *str)
211+
size_t escape, char *str)
212212
{
213213
int ret;
214214

215-
while (*cursor != '\"')
215+
while (escape > 0)
216216
{
217-
if (*cursor != '\\')
217+
while (*cursor != '\\')
218218
{
219219
*str = *cursor;
220220
cursor++;
221221
str++;
222-
continue;
223222
}
224223

224+
escape--;
225225
cursor++;
226226
switch (*cursor)
227227
{
@@ -255,6 +255,9 @@ static int __parse_json_string(const char *cursor, const char **end,
255255
if (ret < 0)
256256
return ret;
257257

258+
if (ret == 4)
259+
escape--;
260+
258261
str += ret;
259262
continue;
260263

@@ -266,6 +269,28 @@ static int __parse_json_string(const char *cursor, const char **end,
266269
str++;
267270
}
268271

272+
while (cursor[0] != '\"' && cursor[1] != '\"' &&
273+
cursor[2] != '\"' && cursor[3] != '\"')
274+
{
275+
memcpy(str, cursor, 4);
276+
cursor += 4;
277+
str += 4;
278+
}
279+
280+
if (cursor[0] != '\"' && cursor[1] != '\"')
281+
{
282+
memcpy(str, cursor, 2);
283+
cursor += 2;
284+
str += 2;
285+
}
286+
287+
if (*cursor != '\"')
288+
{
289+
*str = *cursor;
290+
cursor++;
291+
str++;
292+
}
293+
269294
*str = '\0';
270295
*end = cursor + 1;
271296
return 0;
@@ -500,13 +525,23 @@ static int __parse_json_value(const char *cursor, const char **end,
500525
static void __destroy_json_value(json_value_t *val);
501526

502527
static int __parse_json_member(const char *cursor, const char **end,
528+
size_t escape, size_t len,
503529
int depth, json_member_t *memb)
504530
{
505531
int ret;
506532

507-
ret = __parse_json_string(cursor, &cursor, memb->name);
508-
if (ret < 0)
509-
return ret;
533+
if (escape != 0)
534+
{
535+
ret = __parse_json_string(cursor, &cursor, escape, memb->name);
536+
if (ret < 0)
537+
return ret;
538+
}
539+
else
540+
{
541+
memcpy(memb->name, cursor, len);
542+
memb->name[len] = '\0';
543+
cursor += len + 1;
544+
}
510545

511546
while (isspace(*cursor))
512547
cursor++;
@@ -530,6 +565,7 @@ static int __parse_json_members(const char *cursor, const char **end,
530565
int depth, json_object_t *obj)
531566
{
532567
json_member_t *memb;
568+
size_t escape;
533569
size_t len;
534570
int ret;
535571

@@ -548,15 +584,15 @@ static int __parse_json_members(const char *cursor, const char **end,
548584
return -2;
549585

550586
cursor++;
551-
ret = __json_string_length(cursor, &len);
587+
ret = __json_string_length(cursor, &escape, &len);
552588
if (ret < 0)
553589
return ret;
554590

555591
memb = (json_member_t *)malloc(offsetof(json_member_t, name) + len + 1);
556592
if (!memb)
557593
return -1;
558594

559-
ret = __parse_json_member(cursor, &cursor, depth, memb);
595+
ret = __parse_json_member(cursor, &cursor, escape, len, depth, memb);
560596
if (ret < 0)
561597
{
562598
free(memb);
@@ -704,26 +740,36 @@ static int __parse_json_array(const char *cursor, const char **end,
704740
static int __parse_json_value(const char *cursor, const char **end,
705741
int depth, json_value_t *val)
706742
{
743+
size_t escape;
707744
size_t len;
708745
int ret;
709746

710747
switch (*cursor)
711748
{
712749
case '\"':
713750
cursor++;
714-
ret = __json_string_length(cursor, &len);
751+
ret = __json_string_length(cursor, &escape, &len);
715752
if (ret < 0)
716753
return ret;
717754

718755
val->value.string = (char *)malloc(len + 1);
719756
if (!val->value.string)
720757
return -1;
721758

722-
ret = __parse_json_string(cursor, end, val->value.string);
723-
if (ret < 0)
759+
if (escape != 0)
724760
{
725-
free(val->value.string);
726-
return ret;
761+
ret = __parse_json_string(cursor, end, escape, val->value.string);
762+
if (ret < 0)
763+
{
764+
free(val->value.string);
765+
return ret;
766+
}
767+
}
768+
else
769+
{
770+
memcpy(val->value.string, cursor, len);
771+
val->value.string[len] = '\0';
772+
*end = cursor + len + 1;
727773
}
728774

729775
val->type = JSON_VALUE_STRING;

0 commit comments

Comments
 (0)