"struct json_atom" with strbuf helper functions

This commit is contained in:
Andrew Bettison 2014-02-07 15:59:34 +10:30
parent 5dd9ea7a6b
commit 116389b589
2 changed files with 98 additions and 0 deletions

View File

@ -459,6 +459,31 @@ strbuf strbuf_append_quoted_string(strbuf sb, const char *str)
return sb;
}
static void _html_char(strbuf sb, char c)
{
if (c == '&')
strbuf_puts(sb, "&");
else if (c == '<')
strbuf_puts(sb, "&lt;");
else if (c == '>')
strbuf_puts(sb, "&gt;");
else if (c == '"')
strbuf_puts(sb, "&quot;");
else if (c == '\'')
strbuf_puts(sb, "&apos;");
else if (iscntrl(c))
strbuf_sprintf(sb, "&#%u;", (unsigned char) c);
else
strbuf_putc(sb, c);
}
strbuf strbuf_html_escape(strbuf sb, const char *str, size_t strlen)
{
for (; strlen; --strlen, ++str)
_html_char(sb, *str);
return sb;
}
strbuf strbuf_json_null(strbuf sb)
{
strbuf_puts(sb, "null");
@ -529,6 +554,60 @@ strbuf strbuf_json_hex(strbuf sb, const unsigned char *buf, size_t len)
return sb;
}
strbuf strbuf_json_atom(strbuf sb, const struct json_atom *atom)
{
switch (atom->type) {
case JSON_NULL:
return strbuf_json_null(sb);
case JSON_BOOLEAN:
return strbuf_json_boolean(sb, atom->u.boolean);
case JSON_INTEGER:
strbuf_sprintf(sb, "%"PRId64, atom->u.integer);
return sb;
case JSON_STRING_NULTERM:
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);
}
abort();
}
strbuf strbuf_json_atom_as_text(strbuf sb, const struct json_atom *atom)
{
switch (atom->type) {
case JSON_NULL:
return strbuf_json_null(sb);
case JSON_BOOLEAN:
return strbuf_puts(sb, atom->u.boolean ? "True" : "False");
case JSON_INTEGER:
strbuf_sprintf(sb, "%"PRId64, atom->u.integer);
return sb;
case JSON_STRING_NULTERM:
return strbuf_puts(sb, atom->u.string.content);
case JSON_STRING_LENGTH:
return strbuf_ncat(sb, atom->u.string.content, atom->u.string.length);
}
abort();
}
strbuf strbuf_json_atom_as_html(strbuf sb, const struct json_atom *atom)
{
switch (atom->type) {
case JSON_NULL:
return strbuf_json_null(sb);
case JSON_BOOLEAN:
return strbuf_json_boolean(sb, atom->u.boolean);
case JSON_INTEGER:
strbuf_sprintf(sb, "%"PRId64, atom->u.integer);
return sb;
case JSON_STRING_NULTERM:
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);
}
abort();
}
strbuf strbuf_append_http_ranges(strbuf sb, const struct http_range *ranges, unsigned nels)
{
unsigned i;

View File

@ -162,6 +162,11 @@ strbuf strbuf_append_iovec(strbuf sb, const struct iovec *iov, int iovcnt);
*/
strbuf strbuf_append_quoted_string(strbuf sb, const char *str);
/* Escape HTML entities.
* @author Andrew Bettison <andrew@servalproject.com>
*/
strbuf strbuf_html_escape(strbuf sb, const char *, size_t);
/* Append various JSON elements.
* @author Andrew Bettison <andrew@servalproject.com>
*/
@ -170,6 +175,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_atom {
enum json_atomic_type { JSON_NULL, JSON_BOOLEAN, JSON_INTEGER, JSON_STRING_NULTERM, JSON_STRING_LENGTH } type;
union {
int boolean;
int64_t integer;
struct {
const char *content;
size_t length;
} string;
} 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 *);
/* Append a representation of a struct http_range[] array.
* @author Andrew Bettison <andrew@servalproject.com>