ffprobe: implement generic reindent logic in the JSON writer

Clarify/generalize indent logic.
This commit is contained in:
Stefano Sabatini 2012-01-08 01:20:03 +01:00
parent 4231bbbf4c
commit 48f37b1d21
1 changed files with 36 additions and 16 deletions

View File

@ -721,6 +721,7 @@ typedef struct {
char *buf; char *buf;
size_t buf_size; size_t buf_size;
int print_packets_and_frames; int print_packets_and_frames;
int indent_level;
} JSONContext; } JSONContext;
static av_cold int json_init(WriterContext *wctx, const char *args, void *opaque) static av_cold int json_init(WriterContext *wctx, const char *args, void *opaque)
@ -777,14 +778,20 @@ static const char *json_escape_str(char **dst, size_t *dst_size, const char *src
static void json_print_header(WriterContext *wctx) static void json_print_header(WriterContext *wctx)
{ {
JSONContext *json = wctx->priv;
printf("{"); printf("{");
json->indent_level++;
} }
static void json_print_footer(WriterContext *wctx) static void json_print_footer(WriterContext *wctx)
{ {
JSONContext *json = wctx->priv;
json->indent_level--;
printf("\n}\n"); printf("\n}\n");
} }
#define JSON_INDENT() printf("%*c", json->indent_level * 4, ' ')
static void json_print_chapter_header(WriterContext *wctx, const char *chapter) static void json_print_chapter_header(WriterContext *wctx, const char *chapter)
{ {
JSONContext *json = wctx->priv; JSONContext *json = wctx->priv;
@ -794,51 +801,60 @@ static void json_print_chapter_header(WriterContext *wctx, const char *chapter)
json->multiple_entries = !strcmp(chapter, "packets") || !strcmp(chapter, "frames" ) || json->multiple_entries = !strcmp(chapter, "packets") || !strcmp(chapter, "frames" ) ||
!strcmp(chapter, "packets_and_frames") || !strcmp(chapter, "packets_and_frames") ||
!strcmp(chapter, "streams"); !strcmp(chapter, "streams");
printf("\n \"%s\":%s", json_escape_str(&json->buf, &json->buf_size, chapter, wctx), printf("\n"); JSON_INDENT();
printf("\"%s\":%s", json_escape_str(&json->buf, &json->buf_size, chapter, wctx),
json->multiple_entries ? " [" : " "); json->multiple_entries ? " [" : " ");
json->print_packets_and_frames = !strcmp(chapter, "packets_and_frames"); json->print_packets_and_frames = !strcmp(chapter, "packets_and_frames");
if (json->multiple_entries)
json->indent_level++;
} }
static void json_print_chapter_footer(WriterContext *wctx, const char *chapter) static void json_print_chapter_footer(WriterContext *wctx, const char *chapter)
{ {
JSONContext *json = wctx->priv; JSONContext *json = wctx->priv;
if (json->multiple_entries) if (json->multiple_entries) {
printf("]"); printf("]");
json->indent_level--;
}
} }
#define INDENT " "
static void json_print_section_header(WriterContext *wctx, const char *section) static void json_print_section_header(WriterContext *wctx, const char *section)
{ {
JSONContext *json = wctx->priv; JSONContext *json = wctx->priv;
if (wctx->nb_section) printf(","); if (wctx->nb_section) printf(",");
printf("{\n"); printf("{\n");
json->indent_level++;
/* this is required so the parser can distinguish between packets and frames */ /* this is required so the parser can distinguish between packets and frames */
if (json->print_packets_and_frames) if (json->print_packets_and_frames) {
printf(INDENT "\"type\": \"%s\",\n", section); JSON_INDENT(); printf("\"type\": \"%s\",\n", section);
}
} }
static void json_print_section_footer(WriterContext *wctx, const char *section) static void json_print_section_footer(WriterContext *wctx, const char *section)
{ {
printf("\n }"); JSONContext *json = wctx->priv;
printf("\n");
json->indent_level--;
JSON_INDENT(); printf("}");
} }
static inline void json_print_item_str(WriterContext *wctx, static inline void json_print_item_str(WriterContext *wctx,
const char *key, const char *value, const char *key, const char *value)
const char *indent)
{ {
JSONContext *json = wctx->priv; JSONContext *json = wctx->priv;
printf("%s\"%s\":", indent, json_escape_str(&json->buf, &json->buf_size, key, wctx)); JSON_INDENT();
printf(" \"%s\"", json_escape_str(&json->buf, &json->buf_size, value, wctx)); printf("\"%s\":", json_escape_str(&json->buf, &json->buf_size, key, wctx));
printf(" \"%s\"", json_escape_str(&json->buf, &json->buf_size, value, wctx));
} }
static void json_print_str(WriterContext *wctx, const char *key, const char *value) static void json_print_str(WriterContext *wctx, const char *key, const char *value)
{ {
if (wctx->nb_item) printf(",\n"); if (wctx->nb_item) printf(",\n");
json_print_item_str(wctx, key, value, INDENT); json_print_item_str(wctx, key, value);
} }
static void json_print_int(WriterContext *wctx, const char *key, long long int value) static void json_print_int(WriterContext *wctx, const char *key, long long int value)
@ -846,23 +862,27 @@ static void json_print_int(WriterContext *wctx, const char *key, long long int v
JSONContext *json = wctx->priv; JSONContext *json = wctx->priv;
if (wctx->nb_item) printf(",\n"); if (wctx->nb_item) printf(",\n");
printf(INDENT "\"%s\": %lld", JSON_INDENT();
printf("\"%s\": %lld",
json_escape_str(&json->buf, &json->buf_size, key, wctx), value); json_escape_str(&json->buf, &json->buf_size, key, wctx), value);
} }
static void json_show_tags(WriterContext *wctx, AVDictionary *dict) static void json_show_tags(WriterContext *wctx, AVDictionary *dict)
{ {
JSONContext *json = wctx->priv;
AVDictionaryEntry *tag = NULL; AVDictionaryEntry *tag = NULL;
int is_first = 1; int is_first = 1;
if (!dict) if (!dict)
return; return;
printf(",\n" INDENT "\"tags\": {\n"); printf(",\n"); JSON_INDENT(); printf("\"tags\": {\n");
json->indent_level++;
while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) { while ((tag = av_dict_get(dict, "", tag, AV_DICT_IGNORE_SUFFIX))) {
if (is_first) is_first = 0; if (is_first) is_first = 0;
else printf(",\n"); else printf(",\n");
json_print_item_str(wctx, tag->key, tag->value, INDENT INDENT); json_print_item_str(wctx, tag->key, tag->value);
} }
printf("\n }"); json->indent_level--;
printf("\n"); JSON_INDENT(); printf("}");
} }
static const Writer json_writer = { static const Writer json_writer = {