Skip to content

Commit df5843b

Browse files
authored
Merge pull request #7 from recp/value_bugfix
fix value if comma appears and improve parsing (fix #6)
2 parents 56dbc37 + 44b74ff commit df5843b

File tree

1 file changed

+94
-99
lines changed

1 file changed

+94
-99
lines changed

include/json/impl/impl_json.h

Lines changed: 94 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -11,90 +11,23 @@
1111
#include "../json.h"
1212
#include "impl_mem.h"
1313

14-
JSON_INLINE
15-
const void*
16-
json__impl_key(const char ** __restrict ptr, int * __restrict keysize) {
17-
const char *pi, *end, *start;
18-
char c;
19-
20-
pi = *ptr;
21-
c = *pi;
22-
23-
while (c == '\"' || c == '\'' || c == ' ' || c == ',')
24-
c = *++pi;
25-
26-
start = end = pi;
27-
28-
while (c != ':' && c != '\"' && c != '\'' && c != '\0') {
29-
if (c != ' '
30-
&& c != '\r'
31-
&& c != '\n'
32-
&& c != '\t')
33-
end = pi + 1;
34-
35-
c = *++pi;
36-
}
37-
38-
*keysize = (int)(end - start);
39-
*ptr = pi;
40-
41-
return start;
42-
}
43-
44-
JSON_INLINE
45-
void*
46-
json__impl_value(const char ** __restrict ptr, int * __restrict valuesize) {
47-
const char *pi, *end, *start;
48-
char c;
49-
50-
pi = *ptr;
51-
c = *pi;
52-
53-
while (c == ':' || c == '\"' || c == '\'' || c == ' ')
54-
c = *++pi;
55-
56-
start = end = pi;
57-
58-
while (c != '\"'
59-
&& c != '\''
60-
&& c != ','
61-
&& c != '{'
62-
&& c != '}'
63-
&& c != '['
64-
&& c != ']'
65-
&& c != '\0') {
66-
if (c != ' '
67-
&& c != '\r'
68-
&& c != '\n'
69-
&& c != '\t')
70-
end = pi + 1;
71-
72-
c = *++pi;
73-
}
74-
75-
*valuesize = (int)(end - start);
76-
*ptr = pi;
77-
78-
return (void *)start;
79-
}
80-
8114
JSON_INLINE
8215
json_doc_t*
8316
json_parse(const char * __restrict contents, bool reverse) {
8417
json_doc_t *doc;
8518
json_t *obj, *val, *parent;
86-
const char *key;
19+
const char *key, *p, *end;
8720
json_t tmproot;
8821
int keysize;
89-
char c;
90-
bool lookingForKey;
22+
char c, quote;
23+
bool lookingForKey, foundQuote;
9124

9225
if (!contents || (c = *contents) == '\0')
9326
return NULL;
9427

9528
doc = calloc(1, sizeof(*doc));
9629
doc->memroot = calloc(1, sizeof(json_mem_t) + JSON_MEM_PAGE);
97-
doc->ptr = contents;
30+
p = contents;
9831

9932
memset(&tmproot, 0, sizeof(tmproot));
10033
tmproot.type = JSON_OBJECT;
@@ -106,18 +39,18 @@ json_parse(const char * __restrict contents, bool reverse) {
10639
lookingForKey = false;
10740

10841
((json_mem_t *)doc->memroot)->capacity = JSON_MEM_PAGE;
42+
43+
quote = '"';
10944

11045
do {
11146
again:
11247
/* child */
11348
switch (c) {
114-
/* trim */
49+
/* trim */
11550
case ' ':
11651
case '\r':
11752
case '\n':
11853
case '\t':
119-
case '\'':
120-
case '"':
12154
break;
12255
case '{':
12356
case '[': {
@@ -178,35 +111,59 @@ json_parse(const char * __restrict contents, bool reverse) {
178111
lookingForKey = obj->type == JSON_OBJECT;
179112
break;
180113
}
114+
case ':': {
115+
c = *++p;
116+
break;
117+
}
181118
default: {
182119
/* looking for key */
183120
if (lookingForKey) {
184-
key = json__impl_key(&doc->ptr, &keysize);
185-
if (key == NULL || ((c = *key) == '\0'))
186-
goto err;
121+
if ((foundQuote = (c == '"' || c == '\'' || c == '`'))) {
122+
quote = c;
123+
c = *++p;
124+
}
125+
126+
key = end = p;
127+
128+
if (foundQuote) {
129+
while (c != quote) {
130+
if (c == '\0')
131+
goto err;
132+
133+
/* espace */
134+
if (c != '\\') {
135+
if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
136+
end = p + 1;
137+
} else {
138+
c = *++p;
139+
}
140+
141+
c = *++p;
142+
}
187143

188-
lookingForKey = false;
189-
c = *doc->ptr;
190-
191-
/* jump to value */
192-
for (;;) {
193-
switch (c) {
194-
case ' ':
195-
case '\t':
196-
case '\n':
197-
case '\r':
198-
case '"':
199-
case '\'':
200-
case ':':
201-
c = *++doc->ptr;
202-
continue;
203-
default:
204-
goto val;
144+
/* skip trailing quote */
145+
c = *++p;
146+
} else {
147+
while (c != ':') {
148+
if (c == '\0')
149+
goto err;
150+
151+
if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
152+
end = p + 1;
153+
154+
c = *++p;
205155
}
156+
157+
/* skip trailing column */
158+
c = *++p;
206159
}
207160

208-
val:
209-
goto again;
161+
keysize = (int)(end - key);
162+
163+
if (key == NULL || c == '\0')
164+
goto err;
165+
166+
lookingForKey = false;
210167
}
211168

212169
/* looking for value */
@@ -236,15 +193,53 @@ json_parse(const char * __restrict contents, bool reverse) {
236193
val->keySize = keysize;
237194
key = NULL;
238195
}
196+
197+
if ((foundQuote = (c == '"' || c == '\'' || c == '`'))) {
198+
quote = c;
199+
c = *++p;
200+
}
239201

240-
val->value = json__impl_value(&doc->ptr, &val->valSize);
241-
c = *doc->ptr;
202+
end = p;
203+
val->value = (void *)end;
204+
205+
if (foundQuote) {
206+
while (c != quote) {
207+
if (c == '\0')
208+
goto err;
209+
210+
/* espace */
211+
if (c != '\\') {
212+
if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
213+
end = p + 1;
214+
} else {
215+
c = *++p;
216+
}
217+
218+
c = *++p;
219+
}
220+
221+
/* skip trailing quote */
222+
c = *++p;
223+
} else {
224+
while (c != ',' && c != '{' && c != '}' && c != '[' && c != ']') {
225+
if (c == '\0')
226+
goto err;
227+
228+
if (c != ' ' && c != '\r' && c != '\n' && c != '\t')
229+
end = p + 1;
230+
231+
c = *++p;
232+
}
233+
}
234+
235+
val->valSize = (int)(end - (char *)val->value);
236+
c = *p;
242237

243238
goto again;
244239
} /* if lookingForKey */
245240
} /* switch->default */
246241
} /* switch */
247-
} while ((c = *doc->ptr) != '\0' && (c = *++doc->ptr) != '\0');
242+
} while ((c = *p) != '\0' && (c = *++p) != '\0');
248243

249244
err:
250245
if (tmproot.value)

0 commit comments

Comments
 (0)