mirror of
https://github.com/servalproject/serval-dna.git
synced 2025-01-18 02:39:44 +00:00
strbuf_json_atom() supports JSON objects and arrays
This commit is contained in:
parent
edc8aba100
commit
71c7a4f870
@ -1937,7 +1937,7 @@ static strbuf strbuf_status_body(strbuf sb, struct http_response *hr, const char
|
||||
strbuf_puts(sb, "\r\n");
|
||||
strbuf_puts(sb, hr->result_extra[i].label);
|
||||
strbuf_puts(sb, "=");
|
||||
strbuf_json_atom_as_text(sb, &hr->result_extra[i].value);
|
||||
strbuf_json_atom_as_text(sb, &hr->result_extra[i].value, "\r\n");
|
||||
}
|
||||
strbuf_puts(sb, "\r\n");
|
||||
}
|
||||
|
@ -777,11 +777,43 @@ strbuf strbuf_json_atom(strbuf sb, const struct json_atom *atom)
|
||||
return strbuf_json_string(sb, atom->u.string.content);
|
||||
case JSON_STRING_LENGTH:
|
||||
return strbuf_json_string_len(sb, atom->u.string.content, atom->u.string.length);
|
||||
case JSON_OBJECT: {
|
||||
strbuf_putc(sb, '{');
|
||||
size_t i;
|
||||
for (i = 0; i != atom->u.object.itemc; ++i) {
|
||||
if (i)
|
||||
strbuf_putc(sb, ',');
|
||||
strbuf_json_string(sb, atom->u.object.itemv[i].key);
|
||||
strbuf_putc(sb, ':');
|
||||
strbuf_json_atom(sb, atom->u.object.itemv[i].value);
|
||||
}
|
||||
strbuf_putc(sb, '}');
|
||||
return sb;
|
||||
}
|
||||
case JSON_ARRAY: {
|
||||
strbuf_putc(sb, '[');
|
||||
size_t i;
|
||||
for (i = 0; i != atom->u.array.itemc; ++i) {
|
||||
if (i)
|
||||
strbuf_putc(sb, ',');
|
||||
strbuf_json_atom(sb, atom->u.array.itemv[i]);
|
||||
}
|
||||
strbuf_putc(sb, ']');
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
strbuf strbuf_json_atom_as_text(strbuf sb, const struct json_atom *atom)
|
||||
static strbuf strbuf_puts_repeat(strbuf sb, const char *text, size_t repeat)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i != repeat; ++i)
|
||||
strbuf_puts(sb, text);
|
||||
return sb;
|
||||
}
|
||||
|
||||
static strbuf strbuf_json_atom_as_text_indented(strbuf sb, const struct json_atom *atom, const char *eol, const char *tab, unsigned indent)
|
||||
{
|
||||
switch (atom->type) {
|
||||
case JSON_NULL:
|
||||
@ -795,10 +827,43 @@ strbuf strbuf_json_atom_as_text(strbuf sb, const struct json_atom *atom)
|
||||
return strbuf_puts(sb, atom->u.string.content);
|
||||
case JSON_STRING_LENGTH:
|
||||
return strbuf_ncat(sb, atom->u.string.content, atom->u.string.length);
|
||||
case JSON_OBJECT: {
|
||||
strbuf_puts(sb, "{");
|
||||
size_t i;
|
||||
for (i = 0; i != atom->u.object.itemc; ++i) {
|
||||
strbuf_puts(sb, eol);
|
||||
strbuf_puts_repeat(sb, tab, indent);
|
||||
strbuf_puts(sb, atom->u.object.itemv[i].key);
|
||||
strbuf_puts(sb, ": ");
|
||||
strbuf_json_atom_as_text_indented(sb, atom->u.object.itemv[i].value, eol, tab, indent + 1);
|
||||
}
|
||||
if (i) {
|
||||
strbuf_puts(sb, eol);
|
||||
strbuf_puts_repeat(sb, tab, indent);
|
||||
}
|
||||
strbuf_puts(sb, "}");
|
||||
return sb;
|
||||
}
|
||||
case JSON_ARRAY: {
|
||||
strbuf_puts(sb, "[");
|
||||
size_t i;
|
||||
for (i = 0; i != atom->u.array.itemc; ++i) {
|
||||
if (i)
|
||||
strbuf_puts(sb, ", ");
|
||||
strbuf_json_atom_as_text_indented(sb, atom->u.array.itemv[i], eol, tab, indent + 1);
|
||||
}
|
||||
strbuf_puts(sb, "]");
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
||||
strbuf strbuf_json_atom_as_text(strbuf sb, const struct json_atom *atom, const char *eol)
|
||||
{
|
||||
return strbuf_json_atom_as_text_indented(sb, atom, eol, " ", 0);
|
||||
}
|
||||
|
||||
strbuf strbuf_json_atom_as_html(strbuf sb, const struct json_atom *atom)
|
||||
{
|
||||
switch (atom->type) {
|
||||
@ -813,6 +878,30 @@ strbuf strbuf_json_atom_as_html(strbuf sb, const struct json_atom *atom)
|
||||
return strbuf_html_escape(sb, atom->u.string.content, strlen(atom->u.string.content));
|
||||
case JSON_STRING_LENGTH:
|
||||
return strbuf_html_escape(sb, atom->u.string.content, atom->u.string.length);
|
||||
case JSON_OBJECT: {
|
||||
strbuf_puts(sb, "<dl>");
|
||||
size_t i;
|
||||
for (i = 0; i != atom->u.object.itemc; ++i) {
|
||||
strbuf_puts(sb, "\n<dt>");
|
||||
strbuf_html_escape(sb, atom->u.object.itemv[i].key, strlen(atom->u.object.itemv[i].key));
|
||||
strbuf_puts(sb, "</dt><dd>");
|
||||
strbuf_json_atom_as_html(sb, atom->u.object.itemv[i].value);
|
||||
strbuf_puts(sb, "</dd>");
|
||||
}
|
||||
strbuf_puts(sb, "\n</dl>");
|
||||
return sb;
|
||||
}
|
||||
case JSON_ARRAY: {
|
||||
strbuf_puts(sb, "<ol>");
|
||||
size_t i;
|
||||
for (i = 0; i != atom->u.array.itemc; ++i) {
|
||||
strbuf_puts(sb, "\n<li>");
|
||||
strbuf_json_atom_as_html(sb, atom->u.array.itemv[i]);
|
||||
strbuf_puts(sb, "</li>");
|
||||
}
|
||||
strbuf_puts(sb, "\n</ol>");
|
||||
return sb;
|
||||
}
|
||||
}
|
||||
abort();
|
||||
}
|
||||
|
@ -226,8 +226,20 @@ strbuf strbuf_json_boolean(strbuf sb, int boolean);
|
||||
strbuf strbuf_json_string(strbuf sb, const char *str); // str can be NULL
|
||||
strbuf strbuf_json_string_len(strbuf sb, const char *str, size_t strlen); // str cannot be NULL
|
||||
strbuf strbuf_json_hex(strbuf sb, const unsigned char *buf, size_t len);
|
||||
struct json_key_value {
|
||||
const char *key;
|
||||
struct json_atom *value;
|
||||
};
|
||||
struct json_atom {
|
||||
enum json_atomic_type { JSON_NULL, JSON_BOOLEAN, JSON_INTEGER, JSON_STRING_NULTERM, JSON_STRING_LENGTH } type;
|
||||
enum json_atomic_type {
|
||||
JSON_NULL,
|
||||
JSON_BOOLEAN, // u.boolean
|
||||
JSON_INTEGER, // u.integer
|
||||
JSON_STRING_NULTERM, // u.string.content (nul terminated)
|
||||
JSON_STRING_LENGTH, // u.string.content[0 .. u.string.length-1]
|
||||
JSON_OBJECT, // u.object.itemv[0 .. u.object.itemc].key .value
|
||||
JSON_ARRAY, // u.array.itemv[0 .. u.object.itemc]
|
||||
} type;
|
||||
union {
|
||||
int boolean;
|
||||
int64_t integer;
|
||||
@ -235,11 +247,19 @@ struct json_atom {
|
||||
const char *content;
|
||||
size_t length;
|
||||
} string;
|
||||
struct {
|
||||
size_t itemc;
|
||||
struct json_key_value *itemv;
|
||||
} object;
|
||||
struct {
|
||||
size_t itemc;
|
||||
struct json_atom **itemv;
|
||||
} array;
|
||||
} u;
|
||||
};
|
||||
strbuf strbuf_json_atom(strbuf sb, const struct json_atom *);
|
||||
strbuf strbuf_json_atom_as_html(strbuf sb, const struct json_atom *);
|
||||
strbuf strbuf_json_atom_as_text(strbuf sb, const struct json_atom *);
|
||||
strbuf strbuf_json_atom_as_text(strbuf sb, const struct json_atom *, const char *eol);
|
||||
|
||||
/* Append a representation of a struct http_range[] array.
|
||||
* @author Andrew Bettison <andrew@servalproject.com>
|
||||
|
Loading…
Reference in New Issue
Block a user