Skip to content

Commit 149d0bf

Browse files
committed
Optimize parsing JSON string.
1 parent 88b2be6 commit 149d0bf

File tree

1 file changed

+77
-45
lines changed

1 file changed

+77
-45
lines changed

json_parser.c

Lines changed: 77 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -67,23 +67,50 @@ static int __json_isdigit(char c)
6767
#define isspace(c) __json_isspace(c)
6868
#define isdigit(c) __json_isdigit(c)
6969

70+
static const int __character_map[256] = {
71+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
72+
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
73+
1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
74+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
75+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
76+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1,
77+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
78+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
79+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
80+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
81+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
82+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
83+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
84+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
85+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
86+
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
87+
};
88+
7089
static int __json_string_length(const char *cursor, size_t *len)
7190
{
7291
size_t n = 0;
7392

74-
while (*cursor != '\"')
93+
while (1)
7594
{
95+
while (__character_map[(unsigned char)*cursor])
96+
{
97+
cursor++;
98+
n++;
99+
}
100+
76101
if (*cursor == '\\')
77102
{
78103
cursor++;
79104
if (*cursor == '\0')
80105
return -2;
106+
107+
cursor++;
108+
n++;
81109
}
82-
else if ((unsigned char)*cursor < 0x20)
110+
else if (*cursor == '\"')
111+
break;
112+
else
83113
return -2;
84-
85-
cursor++;
86-
n++;
87114
}
88115

89116
*len = n;
@@ -185,52 +212,57 @@ static int __parse_json_string(const char *cursor, const char **end,
185212
{
186213
int ret;
187214

188-
while (*cursor != '\"')
215+
while (1)
189216
{
190-
if (*cursor == '\\')
217+
while (*cursor != '\\' && *cursor != '\"')
191218
{
219+
*str = *cursor;
192220
cursor++;
193-
switch (*cursor)
194-
{
195-
case '\"':
196-
*str = '\"';
197-
break;
198-
case '\\':
199-
*str = '\\';
200-
break;
201-
case '/':
202-
*str = '/';
203-
break;
204-
case 'b':
205-
*str = '\b';
206-
break;
207-
case 'f':
208-
*str = '\f';
209-
break;
210-
case 'n':
211-
*str = '\n';
212-
break;
213-
case 'r':
214-
*str = '\r';
215-
break;
216-
case 't':
217-
*str = '\t';
218-
break;
219-
case 'u':
220-
cursor++;
221-
ret = __parse_json_unicode(cursor, &cursor, str);
222-
if (ret < 0)
223-
return ret;
221+
str++;
222+
}
224223

225-
str += ret;
226-
continue;
224+
if (*cursor == '\"')
225+
break;
227226

228-
default:
229-
return -2;
230-
}
227+
cursor++;
228+
switch (*cursor)
229+
{
230+
case '\"':
231+
*str = '\"';
232+
break;
233+
case '\\':
234+
*str = '\\';
235+
break;
236+
case '/':
237+
*str = '/';
238+
break;
239+
case 'b':
240+
*str = '\b';
241+
break;
242+
case 'f':
243+
*str = '\f';
244+
break;
245+
case 'n':
246+
*str = '\n';
247+
break;
248+
case 'r':
249+
*str = '\r';
250+
break;
251+
case 't':
252+
*str = '\t';
253+
break;
254+
case 'u':
255+
cursor++;
256+
ret = __parse_json_unicode(cursor, &cursor, str);
257+
if (ret < 0)
258+
return ret;
259+
260+
str += ret;
261+
continue;
262+
263+
default:
264+
return -2;
231265
}
232-
else
233-
*str = *cursor;
234266

235267
cursor++;
236268
str++;

0 commit comments

Comments
 (0)