mirror of
https://github.com/cesanta/mongoose.git
synced 2025-08-06 13:37:34 +08:00
Add more comments in json code
This commit is contained in:
parent
5d2c977029
commit
cf1566e116
51
mongoose.c
51
mongoose.c
@ -2475,26 +2475,17 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
int len = (int) json.len;
|
||||
enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
|
||||
unsigned char nesting[MG_JSON_MAX_DEPTH];
|
||||
int i, j = 0, depth = 0;
|
||||
int pos = 1; // Current position in path
|
||||
int i = 0; // Current offset in `s`
|
||||
int j = 0; // Offset in `s` we're looking for (return value)
|
||||
int depth = 0; // Current depth (nesting level)
|
||||
int ed = 0; // Expected depth
|
||||
int pos = 1; // Current position in `path`
|
||||
int ci = -1, ei = -1; // Current and expected index in array
|
||||
|
||||
if (path[0] != '$') return MG_JSON_INVALID;
|
||||
|
||||
#if 0
|
||||
#define MG_DBGP(x) \
|
||||
do { \
|
||||
printf("%c %.*s j=%d i=%d pos=%d depth=%d ed=%d ci=%d ei=%d\n", x, len, s, \
|
||||
j, i, pos, depth, ed, ci, ei); \
|
||||
} while (0)
|
||||
#else
|
||||
#define MG_DBGP(x)
|
||||
#endif
|
||||
|
||||
#define MG_CHECKRET(x) \
|
||||
do { \
|
||||
MG_DBGP(x); \
|
||||
if (depth == ed && path[pos] == '\0' && ci == ei) { \
|
||||
if (toklen) *toklen = i - j + 1; \
|
||||
return j; \
|
||||
@ -2514,17 +2505,18 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
for (i = 0; i < len; i++) {
|
||||
unsigned char c = ((unsigned char *) s)[i];
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
|
||||
MG_DBGP('-');
|
||||
switch (expecting) {
|
||||
case S_VALUE:
|
||||
if ( depth == ed && ei == ci && c != '[' && path[pos] == '[' ) return MG_JSON_NOT_FOUND;
|
||||
if (depth == ed && ei == ci && c != '[' && path[pos] == '[') {
|
||||
// Expecting array start, but got something else
|
||||
return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
if (depth == ed) j = i;
|
||||
if (c == '{') {
|
||||
if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
|
||||
if (depth == ed && (ci == ei || ci < 0) && path[pos] == '.') {
|
||||
ed++, pos++;
|
||||
ci = -1;
|
||||
ei = -1;
|
||||
if (depth == ed && path[pos] == '.' && (ci == ei || ci < 0)) {
|
||||
// If we start the object, reset array indices
|
||||
ed++, pos++, ci = ei = -1;
|
||||
}
|
||||
nesting[depth++] = c;
|
||||
expecting = S_KEY;
|
||||
@ -2542,7 +2534,7 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
nesting[depth++] = c;
|
||||
break;
|
||||
} else if (c == ']' && depth > 0) { // Empty array
|
||||
if (depth == ed) ci = -1;
|
||||
if (depth == ed) ci = -1; // Array ends. Reset current index
|
||||
MG_EOO(']');
|
||||
} else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
|
||||
i += 3;
|
||||
@ -2566,20 +2558,20 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
ci++;
|
||||
if (ci > ei) return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
|
||||
expecting = S_COMMA_OR_EOO;
|
||||
break;
|
||||
|
||||
case S_KEY:
|
||||
if (c == '"') {
|
||||
int n = mg_pass_string(&s[i + 1], len - i - 1);
|
||||
// printf("K %s %d %d %d [%.*s]\n", path, pos, n, i, n + 2, s + i);
|
||||
// printf("K1 %s %d %d %d [%.*s]\n", path, pos, n, i, n + 2, s + i);
|
||||
if (n < 0) return n;
|
||||
if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
|
||||
// printf("K %s [%.*s] %d %d %d\n", path, n, &s[i + 1], n, depth, ed);
|
||||
// NOTE(cpq): in the check sequence below is important.
|
||||
// strncmp() must go first: it fails fast if the remaining length of
|
||||
// the path is smaller than `n`.
|
||||
// printf("K2 %s [%.*s] %d %d %d\n", path, n, &s[i + 1], n, depth,
|
||||
// ed);
|
||||
// NOTE(cpq): in the check sequence below is important.
|
||||
// strncmp() must go first: it fails fast if the remaining length of
|
||||
// the path is smaller than `n`.
|
||||
if (depth == ed && path[pos - 1] == '.' &&
|
||||
strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
|
||||
(path[pos + n] == '\0' || path[pos + n] == '.' ||
|
||||
@ -2609,19 +2601,14 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
return MG_JSON_INVALID;
|
||||
} else if (c == ',') {
|
||||
expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
|
||||
// MG_CHECKRET('C');
|
||||
} else if (c == ']' || c == '}') {
|
||||
MG_EOO('O');
|
||||
if (depth == ed && ei >= 0) {
|
||||
ci++;
|
||||
if (ci > ei) return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
if (depth == ed && ei >= 0) ci++;
|
||||
} else {
|
||||
return MG_JSON_INVALID;
|
||||
}
|
||||
break;
|
||||
}
|
||||
MG_DBGP('E');
|
||||
}
|
||||
return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
|
46
src/json.c
46
src/json.c
@ -79,26 +79,17 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
int len = (int) json.len;
|
||||
enum { S_VALUE, S_KEY, S_COLON, S_COMMA_OR_EOO } expecting = S_VALUE;
|
||||
unsigned char nesting[MG_JSON_MAX_DEPTH];
|
||||
int i, j = 0, depth = 0;
|
||||
int pos = 1; // Current position in path
|
||||
int i = 0; // Current offset in `s`
|
||||
int j = 0; // Offset in `s` we're looking for (return value)
|
||||
int depth = 0; // Current depth (nesting level)
|
||||
int ed = 0; // Expected depth
|
||||
int pos = 1; // Current position in `path`
|
||||
int ci = -1, ei = -1; // Current and expected index in array
|
||||
|
||||
if (path[0] != '$') return MG_JSON_INVALID;
|
||||
|
||||
#if 0
|
||||
#define MG_DBGP(x) \
|
||||
do { \
|
||||
printf("%c %.*s j=%d i=%d pos=%d depth=%d ed=%d ci=%d ei=%d\n", x, len, s, \
|
||||
j, i, pos, depth, ed, ci, ei); \
|
||||
} while (0)
|
||||
#else
|
||||
#define MG_DBGP(x)
|
||||
#endif
|
||||
|
||||
#define MG_CHECKRET(x) \
|
||||
do { \
|
||||
MG_DBGP(x); \
|
||||
if (depth == ed && path[pos] == '\0' && ci == ei) { \
|
||||
if (toklen) *toklen = i - j + 1; \
|
||||
return j; \
|
||||
@ -118,13 +109,19 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
for (i = 0; i < len; i++) {
|
||||
unsigned char c = ((unsigned char *) s)[i];
|
||||
if (c == ' ' || c == '\t' || c == '\n' || c == '\r') continue;
|
||||
MG_DBGP('-');
|
||||
switch (expecting) {
|
||||
case S_VALUE:
|
||||
if (depth == ed && ei == ci && c != '[' && path[pos] == '[') {
|
||||
// Expecting array start, but got something else
|
||||
return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
if (depth == ed) j = i;
|
||||
if (c == '{') {
|
||||
if (depth >= (int) sizeof(nesting)) return MG_JSON_TOO_DEEP;
|
||||
if (depth == ed && path[pos] == '.') ed++, pos++;
|
||||
if (depth == ed && path[pos] == '.' && (ci == ei || ci < 0)) {
|
||||
// If we start the object, reset array indices
|
||||
ed++, pos++, ci = ei = -1;
|
||||
}
|
||||
nesting[depth++] = c;
|
||||
expecting = S_KEY;
|
||||
break;
|
||||
@ -141,6 +138,7 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
nesting[depth++] = c;
|
||||
break;
|
||||
} else if (c == ']' && depth > 0) { // Empty array
|
||||
if (depth == ed) ci = -1; // Array ends. Reset current index
|
||||
MG_EOO(']');
|
||||
} else if (c == 't' && i + 3 < len && memcmp(&s[i], "true", 4) == 0) {
|
||||
i += 3;
|
||||
@ -160,20 +158,24 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
return MG_JSON_INVALID;
|
||||
}
|
||||
MG_CHECKRET('V');
|
||||
if (depth == ed && ei >= 0) ci++;
|
||||
if (depth == ed && ei >= 0) {
|
||||
ci++;
|
||||
if (ci > ei) return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
expecting = S_COMMA_OR_EOO;
|
||||
break;
|
||||
|
||||
case S_KEY:
|
||||
if (c == '"') {
|
||||
int n = mg_pass_string(&s[i + 1], len - i - 1);
|
||||
// printf("K %s %d %d %d [%.*s]\n", path, pos, n, i, n + 2, s + i);
|
||||
// printf("K1 %s %d %d %d [%.*s]\n", path, pos, n, i, n + 2, s + i);
|
||||
if (n < 0) return n;
|
||||
if (i + 1 + n >= len) return MG_JSON_NOT_FOUND;
|
||||
// printf("K %s [%.*s] %d %d %d\n", path, n, &s[i + 1], n, depth, ed);
|
||||
// NOTE(cpq): in the check sequence below is important.
|
||||
// strncmp() must go first: it fails fast if the remaining length of
|
||||
// the path is smaller than `n`.
|
||||
// printf("K2 %s [%.*s] %d %d %d\n", path, n, &s[i + 1], n, depth,
|
||||
// ed);
|
||||
// NOTE(cpq): in the check sequence below is important.
|
||||
// strncmp() must go first: it fails fast if the remaining length of
|
||||
// the path is smaller than `n`.
|
||||
if (depth == ed && path[pos - 1] == '.' &&
|
||||
strncmp(&s[i + 1], &path[pos], (size_t) n) == 0 &&
|
||||
(path[pos + n] == '\0' || path[pos + n] == '.' ||
|
||||
@ -203,7 +205,6 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
return MG_JSON_INVALID;
|
||||
} else if (c == ',') {
|
||||
expecting = (nesting[depth - 1] == '{') ? S_KEY : S_VALUE;
|
||||
// MG_CHECKRET('C');
|
||||
} else if (c == ']' || c == '}') {
|
||||
MG_EOO('O');
|
||||
if (depth == ed && ei >= 0) ci++;
|
||||
@ -212,7 +213,6 @@ int mg_json_get(struct mg_str json, const char *path, int *toklen) {
|
||||
}
|
||||
break;
|
||||
}
|
||||
MG_DBGP('E');
|
||||
}
|
||||
return MG_JSON_NOT_FOUND;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user