From b1a925dfc2ac78508aee89029e950057405f0a0a Mon Sep 17 00:00:00 2001 From: Michael Edwards Date: Mon, 24 Sep 2018 18:29:49 +0200 Subject: [PATCH] ToStringVisitor settings to allow pretty formatted JSON (#4933) --- include/flatbuffers/minireflect.h | 45 ++++++++++++++++++++++++++----- tests/test.cpp | 32 ++++++++++++++++++++++ 2 files changed, 71 insertions(+), 6 deletions(-) diff --git a/include/flatbuffers/minireflect.h b/include/flatbuffers/minireflect.h index ff3e681b8..21cabf380 100644 --- a/include/flatbuffers/minireflect.h +++ b/include/flatbuffers/minireflect.h @@ -284,14 +284,27 @@ inline void IterateFlatBuffer(const uint8_t *buffer, struct ToStringVisitor : public IterationVisitor { std::string s; std::string d; - ToStringVisitor(std::string delimiter): d(delimiter) {} + bool q; + std::string in; + size_t indent_level; + ToStringVisitor(std::string delimiter, bool quotes, std::string indent) + : d(delimiter), q(quotes), in(indent), indent_level(0) {} + ToStringVisitor(std::string delimiter) + : d(delimiter), q(false), in(""), indent_level(0) {} + + void append_indent() { + for (size_t i = 0; i < indent_level; i++) { s += in; } + } void StartSequence() { s += "{"; s += d; + indent_level++; } void EndSequence() { s += d; + indent_level--; + append_indent(); s += "}"; } void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/, @@ -302,16 +315,22 @@ struct ToStringVisitor : public IterationVisitor { s += ","; s += d; } + append_indent(); if (name) { + if (q) s += "\""; s += name; + if (q) s += "\""; s += ": "; } } template void Named(T x, const char *name) { - if (name) + if (name) { + if (q) s += "\""; s += name; - else + if (q) s += "\""; + } else { s += NumToString(x); + } } void UType(uint8_t x, const char *name) { Named(x, name); } void Bool(bool x) { s += x ? "true" : "false"; } @@ -329,11 +348,25 @@ struct ToStringVisitor : public IterationVisitor { EscapeString(str->c_str(), str->size(), &s, true, false); } void Unknown(const uint8_t *) { s += "(?)"; } - void StartVector() { s += "[ "; } - void EndVector() { s += " ]"; } + void StartVector() { + s += "["; + s += d; + indent_level++; + append_indent(); + } + void EndVector() { + s += d; + indent_level--; + append_indent(); + s += "]"; + } void Element(size_t i, ElementaryType /*type*/, const TypeTable * /*type_table*/, const uint8_t * /*val*/) { - if (i) s += ", "; + if (i) { + s += ","; + s += d; + append_indent(); + } } }; diff --git a/tests/test.cpp b/tests/test.cpp index 7b90c568f..0aefc5dce 100644 --- a/tests/test.cpp +++ b/tests/test.cpp @@ -1727,6 +1727,38 @@ void UnionVectorTest() { "characters_type: [ Belle, MuLan, BookFan, Other, Unused ], " "characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, " "{ books_read: 2 }, \"Other\", \"Unused\" ] }"); + + + flatbuffers::ToStringVisitor visitor("\n", true, " "); + IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor); + TEST_EQ_STR( + visitor.s.c_str(), + "{\n" + " \"main_character_type\": \"Rapunzel\",\n" + " \"main_character\": {\n" + " \"hair_length\": 6\n" + " },\n" + " \"characters_type\": [\n" + " \"Belle\",\n" + " \"MuLan\",\n" + " \"BookFan\",\n" + " \"Other\",\n" + " \"Unused\"\n" + " ],\n" + " \"characters\": [\n" + " {\n" + " \"books_read\": 7\n" + " },\n" + " {\n" + " \"sword_attack_damage\": 5\n" + " },\n" + " {\n" + " \"books_read\": 2\n" + " },\n" + " \"Other\",\n" + " \"Unused\"\n" + " ]\n" + "}"); } void ConformTest() {