diff options
author | Thomas Haller <thaller@redhat.com> | 2019-05-09 14:25:10 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-05-22 21:24:56 +0200 |
commit | dccaea0755ef0e2f42e25bce99da7ecbd6ff4fca (patch) | |
tree | 7ec54b62810dbcf5fc4cdc45b6955672e77d87b6 | |
parent | a0de3fdcaa5d76d4118a105653c6e1f46c51878c (diff) | |
download | NetworkManager-dccaea0755ef0e2f42e25bce99da7ecbd6ff4fca.tar.gz |
shared: add nm_json_aux_gstr_append_*() helper
-rw-r--r-- | shared/nm-glib-aux/nm-json-aux.c | 127 | ||||
-rw-r--r-- | shared/nm-glib-aux/nm-json-aux.h | 36 |
2 files changed, 163 insertions, 0 deletions
diff --git a/shared/nm-glib-aux/nm-json-aux.c b/shared/nm-glib-aux/nm-json-aux.c index f7ec100df0..6f04ef2b44 100644 --- a/shared/nm-glib-aux/nm-json-aux.c +++ b/shared/nm-glib-aux/nm-json-aux.c @@ -20,3 +20,130 @@ #include "nm-default.h" #include "nm-json-aux.h" + +/*****************************************************************************/ + +static void +_gstr_append_string_len (GString *gstr, + const char *str, + gsize len) +{ + g_string_append_c (gstr, '\"'); + + while (len > 0) { + gsize n; + const char *end; + gboolean valid; + + nm_assert (len > 0); + + valid = g_utf8_validate (str, len, &end); + + nm_assert ( end + && end >= str + && end <= &str[len]); + + if (end > str) { + const char *s; + + for (s = str; s < end; s++) { + nm_assert (s[0] != '\0'); + + if (s[0] < 0x20) { + const char *text; + + switch (s[0]) { + case '\\': text = "\\\\"; break; + case '\"': text = "\\\""; break; + case '\b': text = "\\b"; break; + case '\f': text = "\\f"; break; + case '\n': text = "\\n"; break; + case '\r': text = "\\r"; break; + case '\t': text = "\\t"; break; + default: + g_string_append_printf (gstr, "\\u%04X", (guint) s[0]); + continue; + } + g_string_append (gstr, text); + continue; + } + + if (NM_IN_SET (s[0], '\\', '\"')) + g_string_append_c (gstr, '\\'); + g_string_append_c (gstr, s[0]); + } + } else + nm_assert (!valid); + + if (valid) { + nm_assert (end == &str[len]); + break; + } + + nm_assert (end < &str[len]); + + if (end[0] == '\0') { + /* there is a NUL byte in the string. Technically this is valid UTF-8, so we + * encode it there. However, this will likely result in a truncated string when + * parsing. */ + g_string_append (gstr, "\\u0000"); + } else { + /* the character is not valid UTF-8. There is nothing we can do about it, because + * JSON can only contain UTF-8 and even the escape sequences can only escape Unicode + * codepoints (but not binary). + * + * The argument is not a a string (in any known encoding), hence we cannot represent + * it as a JSON string (which are unicode strings). + * + * Print an underscore instead of the invalid char :) */ + g_string_append_c (gstr, '_'); + } + + n = str - end; + nm_assert (n < len); + n++; + str += n; + len -= n; + } + + g_string_append_c (gstr, '\"'); +} + +void +nm_json_aux_gstr_append_string_len (GString *gstr, + const char *str, + gsize n) +{ + g_return_if_fail (gstr); + + _gstr_append_string_len (gstr, str, n); +} + +void +nm_json_aux_gstr_append_string (GString *gstr, + const char *str) +{ + g_return_if_fail (gstr); + + if (!str) + g_string_append (gstr, "null"); + else + _gstr_append_string_len (gstr, str, strlen (str)); +} + +void +nm_json_aux_gstr_append_obj_name (GString *gstr, + const char *key, + char start_container) +{ + g_return_if_fail (gstr); + g_return_if_fail (key); + + nm_json_aux_gstr_append_string (gstr, key); + + if (start_container != '\0') { + nm_assert (NM_IN_SET (start_container, '[', '{')); + g_string_append_printf (gstr, ": %c ", start_container); + } else + g_string_append (gstr, ": "); +} diff --git a/shared/nm-glib-aux/nm-json-aux.h b/shared/nm-glib-aux/nm-json-aux.h index 0a3496c4db..8d6c2c4f46 100644 --- a/shared/nm-glib-aux/nm-json-aux.h +++ b/shared/nm-glib-aux/nm-json-aux.h @@ -20,4 +20,40 @@ #ifndef __NM_JSON_AUX_H__ #define __NM_JSON_AUX_H__ +/*****************************************************************************/ + +static inline GString * +nm_json_aux_gstr_append_delimiter (GString *gstr) +{ + g_string_append (gstr, ", "); + return gstr; +} + +void nm_json_aux_gstr_append_string_len (GString *gstr, + const char *str, + gsize n); + +void nm_json_aux_gstr_append_string (GString *gstr, + const char *str); + +static inline void +nm_json_aux_gstr_append_bool (GString *gstr, + gboolean v) +{ + g_string_append (gstr, v ? "true" : "false"); +} + +static inline void +nm_json_aux_gstr_append_int64 (GString *gstr, + gint64 v) +{ + g_string_append_printf (gstr, "%"G_GINT64_FORMAT, v); +} + +void nm_json_aux_gstr_append_obj_name (GString *gstr, + const char *key, + char start_container); + +/*****************************************************************************/ + #endif /* __NM_JSON_AUX_H__ */ |