diff --git a/qobject/qjson.c b/qobject/qjson.c index 2f690c1816..962214f5a7 100644 --- a/qobject/qjson.c +++ b/qobject/qjson.c @@ -156,6 +156,58 @@ static void json_pretty_newline(GString *accu, bool pretty, int indent) } } +static void quoted_str(const char *str, GString *accu) +{ + const char *ptr; + int cp; + char *end; + + g_string_append_c(accu, '"'); + + for (ptr = str; *ptr; ptr = end) { + cp = mod_utf8_codepoint(ptr, 6, &end); + switch (cp) { + case '\"': + g_string_append(accu, "\\\""); + break; + case '\\': + g_string_append(accu, "\\\\"); + break; + case '\b': + g_string_append(accu, "\\b"); + break; + case '\f': + g_string_append(accu, "\\f"); + break; + case '\n': + g_string_append(accu, "\\n"); + break; + case '\r': + g_string_append(accu, "\\r"); + break; + case '\t': + g_string_append(accu, "\\t"); + break; + default: + if (cp < 0) { + cp = 0xFFFD; /* replacement character */ + } + if (cp > 0xFFFF) { + /* beyond BMP; need a surrogate pair */ + g_string_append_printf(accu, "\\u%04X\\u%04X", + 0xD800 + ((cp - 0x10000) >> 10), + 0xDC00 + ((cp - 0x10000) & 0x3FF)); + } else if (cp < 0x20 || cp >= 0x7F) { + g_string_append_printf(accu, "\\u%04X", cp); + } else { + g_string_append_c(accu, cp); + } + } + }; + + g_string_append_c(accu, '"'); +} + static void to_json(const QObject *obj, GString *accu, bool pretty, int indent) { switch (qobject_type(obj)) { @@ -170,56 +222,7 @@ static void to_json(const QObject *obj, GString *accu, bool pretty, int indent) break; } case QTYPE_QSTRING: { - QString *val = qobject_to(QString, obj); - const char *ptr; - int cp; - char *end; - - ptr = qstring_get_str(val); - g_string_append_c(accu, '"'); - - for (; *ptr; ptr = end) { - cp = mod_utf8_codepoint(ptr, 6, &end); - switch (cp) { - case '\"': - g_string_append(accu, "\\\""); - break; - case '\\': - g_string_append(accu, "\\\\"); - break; - case '\b': - g_string_append(accu, "\\b"); - break; - case '\f': - g_string_append(accu, "\\f"); - break; - case '\n': - g_string_append(accu, "\\n"); - break; - case '\r': - g_string_append(accu, "\\r"); - break; - case '\t': - g_string_append(accu, "\\t"); - break; - default: - if (cp < 0) { - cp = 0xFFFD; /* replacement character */ - } - if (cp > 0xFFFF) { - /* beyond BMP; need a surrogate pair */ - g_string_append_printf(accu, "\\u%04X\\u%04X", - 0xD800 + ((cp - 0x10000) >> 10), - 0xDC00 + ((cp - 0x10000) & 0x3FF)); - } else if (cp < 0x20 || cp >= 0x7F) { - g_string_append_printf(accu, "\\u%04X", cp); - } else { - g_string_append_c(accu, cp); - } - } - }; - - g_string_append_c(accu, '"'); + quoted_str(qstring_get_str(qobject_to(QString, obj)), accu); break; } case QTYPE_QDICT: { @@ -227,7 +230,6 @@ static void to_json(const QObject *obj, GString *accu, bool pretty, int indent) const char *comma = pretty ? "," : ", "; const char *sep = ""; const QDictEntry *entry; - QString *qkey; g_string_append_c(accu, '{'); @@ -236,11 +238,7 @@ static void to_json(const QObject *obj, GString *accu, bool pretty, int indent) entry = qdict_next(val, entry)) { g_string_append(accu, sep); json_pretty_newline(accu, pretty, indent + 1); - - qkey = qstring_from_str(qdict_entry_key(entry)); - to_json(QOBJECT(qkey), accu, pretty, indent + 1); - qobject_unref(qkey); - + quoted_str(qdict_entry_key(entry), accu); g_string_append(accu, ": "); to_json(qdict_entry_value(entry), accu, pretty, indent + 1); sep = comma;