json: format slightly nicer escape sequences

Make use the escape sequences allowed by JSON.

Also update the linked RFC to the newest one.
This commit is contained in:
wm4 2018-05-17 15:51:47 +02:00
parent 711858377c
commit 76bff1a000
2 changed files with 20 additions and 6 deletions

View File

@ -24,7 +24,7 @@
*
* Does not support extensions like unquoted string literals.
*
* Also see: http://tools.ietf.org/html/rfc4627
* Also see: http://tools.ietf.org/html/rfc8259
*
* JSON writer:
*
@ -34,9 +34,6 @@
* to deal with somehow: either by using byte-strings for JSON, or by running
* a "fixup" pass on the input data. The latter could for example change
* invalid UTF-8 sequences to replacement characters.
*
* Currently, will insert \u literals for characters 0-31, '"', '\', and write
* everything else literally.
*/
#include <stdlib.h>
@ -218,6 +215,14 @@ int json_parse(void *ta_parent, struct mpv_node *dst, char **src, int max_depth)
#define APPEND(b, s) bstr_xappend(NULL, (b), bstr0(s))
static const char special_escape[] = {
['\b'] = 'b',
['\f'] = 'f',
['\n'] = 'n',
['\r'] = 'r',
['\t'] = 't',
};
static void write_json_str(bstr *b, unsigned char *str)
{
APPEND(b, "\"");
@ -228,7 +233,15 @@ static void write_json_str(bstr *b, unsigned char *str)
if (!cur[0])
break;
bstr_xappend(NULL, b, (bstr){str, cur - str});
bstr_xappend_asprintf(NULL, b, "\\u%04x", (unsigned char)cur[0]);
if (cur[0] == '\"') {
bstr_xappend(NULL, b, (bstr){"\\\"", 2});
} else if (cur[0] == '\\') {
bstr_xappend(NULL, b, (bstr){"\\\\", 2});
} else if (cur[0] < sizeof(special_escape) && special_escape[cur[0]]) {
bstr_xappend_asprintf(NULL, b, "\\%c", special_escape[cur[0]]);
} else {
bstr_xappend_asprintf(NULL, b, "\\u%04x", (unsigned char)cur[0]);
}
str = cur + 1;
}
APPEND(b, str);

View File

@ -40,7 +40,8 @@ static const struct entry entries[] = {
{ "abc", .expect_fail = true},
{ " 123 ", "123", NODE_INT64(123)},
{ "123.25", "123.250000", NODE_FLOAT(123.25)},
{ TEXT("a\n\\"), TEXT("a\u000a\u005c"), NODE_STR("a\n\\")},
{ TEXT("a\n\\\/\\\""), TEXT("a\n\\/\\\""), NODE_STR("a\n\\/\\\"")},
{ TEXT("a\u2c29"), TEXT("aⰩ"), NODE_STR("a\342\260\251")},
{ "[1,2,3]", "[1,2,3]",
NODE_ARRAY(NODE_INT64(1), NODE_INT64(2), NODE_INT64(3))},
{ "[ ]", "[]", NODE_ARRAY()},