Skip to content

Commit

Permalink
qobject: Factor quoted_str() out of to_json()
Browse files Browse the repository at this point in the history
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <20201211171152.146877-15-armbru@redhat.com>
  • Loading branch information
Markus Armbruster committed Dec 19, 2020
1 parent b3119b0 commit 91f54d9
Showing 1 changed file with 54 additions and 56 deletions.
110 changes: 54 additions & 56 deletions qobject/qjson.c
Expand Up @@ -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)) {
Expand All @@ -170,64 +222,14 @@ 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: {
QDict *val = qobject_to(QDict, obj);
const char *comma = pretty ? "," : ", ";
const char *sep = "";
const QDictEntry *entry;
QString *qkey;

g_string_append_c(accu, '{');

Expand All @@ -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;
Expand Down

0 comments on commit 91f54d9

Please sign in to comment.