mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 12:41:00 +02:00
MINOR: mjson: reintroduce mjson_next()
The lack of mjson_next() prevents to iterate easily and need to hack by iterating on a loop of snprintf + $.field[XXX] combined with mjson_find(). This reintroduce mjson_next() so we could iterate without having to build the string. The patch does not reintroduce MJSON_ENABLE_NEXT so it could be used without having to define it.
This commit is contained in:
parent
cf72132f22
commit
3415abe56d
@ -54,4 +54,7 @@ int mjson_get_bool(const char *s, int len, const char *path, int *v);
|
||||
int mjson_get_string(const char *s, int len, const char *path, char *to, int n);
|
||||
int mjson_get_hex(const char *s, int len, const char *path, char *to, int n);
|
||||
|
||||
int mjson_next(const char *s, int n, int off, int *koff, int *klen, int *voff,
|
||||
int *vlen, int *vtype);
|
||||
|
||||
#endif // MJSON_H
|
||||
|
||||
70
src/mjson.c
70
src/mjson.c
@ -338,6 +338,76 @@ int mjson_get_hex(const char *s, int len, const char *x, char *to, int n) {
|
||||
return j;
|
||||
}
|
||||
|
||||
struct nextdata {
|
||||
int off, len, depth, t, vo, arrayindex;
|
||||
int *koff, *klen, *voff, *vlen, *vtype;
|
||||
};
|
||||
|
||||
static int next_cb(int tok, const char *s, int off, int len, void *ud) {
|
||||
struct nextdata *d = (struct nextdata *) ud;
|
||||
// int i;
|
||||
switch (tok) {
|
||||
case '{':
|
||||
case '[':
|
||||
if (d->depth == 0 && tok == '[') d->arrayindex = 0;
|
||||
if (d->depth == 1 && off > d->off) {
|
||||
d->vo = off;
|
||||
d->t = tok == '{' ? MJSON_TOK_OBJECT : MJSON_TOK_ARRAY;
|
||||
if (d->voff) *d->voff = off;
|
||||
if (d->vtype) *d->vtype = d->t;
|
||||
}
|
||||
d->depth++;
|
||||
break;
|
||||
case '}':
|
||||
case ']':
|
||||
d->depth--;
|
||||
if (d->depth == 1 && d->vo) {
|
||||
d->len = off + len;
|
||||
if (d->vlen) *d->vlen = d->len - d->vo;
|
||||
if (d->arrayindex >= 0) {
|
||||
if (d->koff) *d->koff = d->arrayindex; // koff holds array index
|
||||
if (d->klen) *d->klen = 0; // klen holds 0
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (d->depth == 1 && d->arrayindex >= 0) d->arrayindex++;
|
||||
break;
|
||||
case ',':
|
||||
case ':':
|
||||
break;
|
||||
case MJSON_TOK_KEY:
|
||||
if (d->depth == 1 && d->off < off) {
|
||||
if (d->koff) *d->koff = off; // And report back to the user
|
||||
if (d->klen) *d->klen = len; // If we have to
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (d->depth != 1) break;
|
||||
// If we're iterating over the array
|
||||
if (off > d->off) {
|
||||
d->len = off + len;
|
||||
if (d->vlen) *d->vlen = len; // value length
|
||||
if (d->voff) *d->voff = off; // value offset
|
||||
if (d->vtype) *d->vtype = tok; // value type
|
||||
if (d->arrayindex >= 0) {
|
||||
if (d->koff) *d->koff = d->arrayindex; // koff holds array index
|
||||
if (d->klen) *d->klen = 0; // klen holds 0
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
if (d->arrayindex >= 0) d->arrayindex++;
|
||||
break;
|
||||
}
|
||||
(void) s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mjson_next(const char *s, int n, int off, int *koff, int *klen, int *voff,
|
||||
int *vlen, int *vtype) {
|
||||
struct nextdata d = {off, 0, 0, 0, 0, -1, koff, klen, voff, vlen, vtype};
|
||||
mjson(s, n, next_cb, &d);
|
||||
return d.len;
|
||||
}
|
||||
static int is_digit(int c) {
|
||||
return c >= '0' && c <= '9';
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user