Skip to content

Commit d88e0b8

Browse files
committed
Use character map to optimize parsing string.
1 parent 88b2be6 commit d88e0b8

File tree

1 file changed

+74
-44
lines changed

1 file changed

+74
-44
lines changed

json_parser.c

Lines changed: 74 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -67,19 +67,46 @@ 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
{
76-
if (*cursor == '\\')
95+
if (__character_map[(unsigned char)*cursor])
7796
{
7897
cursor++;
79-
if (*cursor == '\0')
80-
return -2;
98+
n++;
99+
continue;
81100
}
82-
else if ((unsigned char)*cursor < 0x20)
101+
102+
if (*cursor == '\"')
103+
break;
104+
105+
if (*cursor != '\\')
106+
return -2;
107+
108+
cursor++;
109+
if (*cursor == '\0')
83110
return -2;
84111

85112
cursor++;
@@ -187,50 +214,53 @@ static int __parse_json_string(const char *cursor, const char **end,
187214

188215
while (*cursor != '\"')
189216
{
190-
if (*cursor == '\\')
217+
if (*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+
continue;
223+
}
224224

225-
str += ret;
226-
continue;
225+
cursor++;
226+
switch (*cursor)
227+
{
228+
case '\"':
229+
*str = '\"';
230+
break;
231+
case '\\':
232+
*str = '\\';
233+
break;
234+
case '/':
235+
*str = '/';
236+
break;
237+
case 'b':
238+
*str = '\b';
239+
break;
240+
case 'f':
241+
*str = '\f';
242+
break;
243+
case 'n':
244+
*str = '\n';
245+
break;
246+
case 'r':
247+
*str = '\r';
248+
break;
249+
case 't':
250+
*str = '\t';
251+
break;
252+
case 'u':
253+
cursor++;
254+
ret = __parse_json_unicode(cursor, &cursor, str);
255+
if (ret < 0)
256+
return ret;
227257

228-
default:
229-
return -2;
230-
}
258+
str += ret;
259+
continue;
260+
261+
default:
262+
return -2;
231263
}
232-
else
233-
*str = *cursor;
234264

235265
cursor++;
236266
str++;

0 commit comments

Comments
 (0)