blobmsg_json: support indenting of output data

This commit is contained in:
Felix Fietkau 2011-07-18 13:04:23 +02:00
parent bdf6363777
commit ed9b5c986b
2 changed files with 51 additions and 8 deletions

View file

@ -98,6 +98,8 @@ struct strbuf {
blobmsg_json_format_t custom_format; blobmsg_json_format_t custom_format;
void *priv; void *priv;
bool indent;
int indent_level;
}; };
static bool blobmsg_puts(struct strbuf *s, const char *c, int len) static bool blobmsg_puts(struct strbuf *s, const char *c, int len)
@ -116,6 +118,29 @@ static bool blobmsg_puts(struct strbuf *s, const char *c, int len)
return true; return true;
} }
static void add_separator(struct strbuf *s)
{
static char indent_chars[17] = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t";
static const char indent_space = ' ';
int indent;
char *start;
if (!s->indent) {
blobmsg_puts(s, &indent_space, 1);
return;
}
indent = s->indent_level;
if (indent > 16)
indent = 16;
start = &indent_chars[sizeof(indent_chars) - indent - 1];
*start = '\n';
blobmsg_puts(s, start, indent + 1);
*start = '\t';
}
static void blobmsg_format_string(struct strbuf *s, const char *str) static void blobmsg_format_string(struct strbuf *s, const char *str)
{ {
const char *p, *last = str, *end = str + strlen(str); const char *p, *last = str, *end = str + strlen(str);
@ -185,7 +210,7 @@ static void blobmsg_format_element(struct strbuf *s, struct blob_attr *attr, boo
if (!array && blobmsg_name(attr)[0]) { if (!array && blobmsg_name(attr)[0]) {
blobmsg_format_string(s, blobmsg_name(attr)); blobmsg_format_string(s, blobmsg_name(attr));
blobmsg_puts(s, ":", 1); blobmsg_puts(s, ": ", 2);
} }
if (head) { if (head) {
data = blob_data(attr); data = blob_data(attr);
@ -233,18 +258,24 @@ static void blobmsg_format_json_list(struct strbuf *s, struct blob_attr *attr, i
bool first = true; bool first = true;
int rem = len; int rem = len;
blobmsg_puts(s, (array ? "[ " : "{ "), 2); blobmsg_puts(s, (array ? "[" : "{" ), 1);
s->indent_level++;
add_separator(s);
__blob_for_each_attr(pos, attr, rem) { __blob_for_each_attr(pos, attr, rem) {
if (!first) if (!first) {
blobmsg_puts(s, ", ", 2); blobmsg_puts(s, ",", 1);
add_separator(s);
}
blobmsg_format_element(s, pos, array, false); blobmsg_format_element(s, pos, array, false);
first = false; first = false;
} }
blobmsg_puts(s, (array ? " ]" : " }"), 2); s->indent_level--;
add_separator(s);
blobmsg_puts(s, (array ? "]" : "}"), 1);
} }
char *blobmsg_format_json_with_cb(struct blob_attr *attr, bool list, blobmsg_json_format_t cb, void *priv) char *blobmsg_format_json_with_cb(struct blob_attr *attr, bool list, blobmsg_json_format_t cb, void *priv, int indent)
{ {
struct strbuf s; struct strbuf s;
@ -253,6 +284,12 @@ char *blobmsg_format_json_with_cb(struct blob_attr *attr, bool list, blobmsg_jso
s.pos = 0; s.pos = 0;
s.custom_format = cb; s.custom_format = cb;
s.priv = priv; s.priv = priv;
s.indent = false;
if (indent >= 0) {
s.indent = true;
s.indent_level = indent;
}
if (list) if (list)
blobmsg_format_json_list(&s, blob_data(attr), blob_len(attr), false); blobmsg_format_json_list(&s, blob_data(attr), blob_len(attr), false);

View file

@ -26,11 +26,17 @@ bool blobmsg_add_json_from_string(struct blob_buf *b, const char *str);
typedef const char *(*blobmsg_json_format_t)(void *priv, struct blob_attr *attr); typedef const char *(*blobmsg_json_format_t)(void *priv, struct blob_attr *attr);
char *blobmsg_format_json_with_cb(struct blob_attr *attr, bool list, char *blobmsg_format_json_with_cb(struct blob_attr *attr, bool list,
blobmsg_json_format_t cb, void *priv); blobmsg_json_format_t cb, void *priv,
int indent);
static inline char *blobmsg_format_json(struct blob_attr *attr, bool list) static inline char *blobmsg_format_json(struct blob_attr *attr, bool list)
{ {
return blobmsg_format_json_with_cb(attr, list, NULL, NULL); return blobmsg_format_json_with_cb(attr, list, NULL, NULL, -1);
}
static inline char *blobmsg_format_json_indent(struct blob_attr *attr, bool list, int indent)
{
return blobmsg_format_json_with_cb(attr, list, NULL, NULL, indent);
} }
#endif #endif