+/*
+ * Alternate format, JSON
+ */
+
+static void json_print_header(void)
+{
+ avio_printf(probe_out, "{");
+}
+static void json_print_footer(void)
+{
+ avio_printf(probe_out, "}\n");
+}
+
+static void json_print_array_header(const char *name)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "\"%s\" : ", name);
+ avio_printf(probe_out, "[\n");
+}
+
+static void json_print_array_footer(const char *name)
+{
+ avio_printf(probe_out, "\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "]");
+}
+
+static void json_print_object_header(const char *name)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ if (octx.prefix[octx.level -1].type == OBJECT)
+ avio_printf(probe_out, "\"%s\" : ", name);
+ avio_printf(probe_out, "{\n");
+}
+
+static void json_print_object_footer(const char *name)
+{
+ avio_printf(probe_out, "\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "}");
+}
+
+static void json_print_integer(const char *key, int64_t value)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ avio_printf(probe_out, "\"%s\" : %"PRId64"", key, value);
+}
+
+static void json_escape_print(const char *s)
+{
+ int i = 0;
+ char c = 0;
+
+ while (c = s[i++]) {
+ switch (c) {
+ case '\r': avio_printf(probe_out, "%s", "\\r"); break;
+ case '\n': avio_printf(probe_out, "%s", "\\n"); break;
+ case '\f': avio_printf(probe_out, "%s", "\\f"); break;
+ case '\b': avio_printf(probe_out, "%s", "\\b"); break;
+ case '\t': avio_printf(probe_out, "%s", "\\t"); break;
+ case '\\':
+ case '"' : avio_w8(probe_out, '\\');
+ default:
+ if ((unsigned char)c < 32)
+ avio_printf(probe_out, "\\u00%02x", c & 0xff);
+ else
+ avio_w8(probe_out, c);
+ break;
+ }
+ }
+}
+
+static void json_print_string(const char *key, const char *value)
+{
+ if (octx.prefix[octx.level -1].nb_elems)
+ avio_printf(probe_out, ",\n");
+ AVP_INDENT();
+ avio_w8(probe_out, '\"');
+ json_escape_print(key);
+ avio_printf(probe_out, "\" : \"");
+ json_escape_print(value);
+ avio_w8(probe_out, '\"');
+}
+
+/*
+ * old-style pseudo-INI
+ */
+static void old_print_object_header(const char *name)
+{
+ char *str, *p;
+
+ if (!strcmp(name, "tags"))
+ return;
+
+ str = p = av_strdup(name);
+ while (*p) {
+ *p = toupper(*p);
+ p++;
+ }
+
+ avio_printf(probe_out, "[%s]\n", str);
+ av_freep(&str);
+}
+
+static void old_print_object_footer(const char *name)
+{
+ char *str, *p;
+
+ if (!strcmp(name, "tags"))
+ return;
+
+ str = p = av_strdup(name);
+ while (*p) {
+ *p = toupper(*p);
+ p++;
+ }
+
+ avio_printf(probe_out, "[/%s]\n", str);
+ av_freep(&str);
+}
+
+static void old_print_string(const char *key, const char *value)
+{
+ if (!strcmp(octx.prefix[octx.level - 1].name, "tags"))
+ avio_printf(probe_out, "TAG:");
+ ini_print_string(key, value);
+}
+