Skip to content

Commit 23922e7

Browse files
committed
FlexBuffers: JSON output supports indentation
1 parent f8fe811 commit 23922e7

File tree

2 files changed

+59
-13
lines changed

2 files changed

+59
-13
lines changed

include/flatbuffers/flexbuffers.h

Lines changed: 53 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -360,16 +360,40 @@ class Map : public Vector {
360360
bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; }
361361
};
362362

363+
inline void IndentString(std::string &s, int indent,
364+
const char *indent_string) {
365+
for (int i = 0; i < indent; i++) s += indent_string;
366+
}
367+
363368
template<typename T>
364-
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
365-
s += "[ ";
369+
void AppendToString(std::string &s, T &&v, bool keys_quoted, bool indented,
370+
int cur_indent, const char *indent_string) {
371+
s += "[";
372+
s += indented ? "\n" : " ";
366373
for (size_t i = 0; i < v.size(); i++) {
367-
if (i) s += ", ";
368-
v[i].ToString(true, keys_quoted, s);
374+
if (i) {
375+
s += ",";
376+
s += indented ? "\n" : " ";
377+
}
378+
if (indented) IndentString(s, cur_indent, indent_string);
379+
v[i].ToString(true, keys_quoted, s, indented, cur_indent,
380+
indent_string);
369381
}
370-
s += " ]";
382+
if (indented) {
383+
s += "\n";
384+
IndentString(s, cur_indent - 1, indent_string);
385+
} else {
386+
s += " ";
387+
}
388+
s += "]";
371389
}
372390

391+
template<typename T>
392+
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
393+
AppendToString(s, v, keys_quoted);
394+
}
395+
396+
373397
class Reference {
374398
public:
375399
Reference()
@@ -542,8 +566,13 @@ class Reference {
542566
// Convert any type to a JSON-like string. strings_quoted determines if
543567
// string values at the top level receive "" quotes (inside other values
544568
// they always do). keys_quoted determines if keys are quoted, at any level.
545-
// TODO(wvo): add further options to have indentation/newlines.
546569
void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const {
570+
ToString(strings_quoted, keys_quoted, s, false, 0, "");
571+
}
572+
573+
// This version additionally allow you to specify if you want indentation.
574+
void ToString(bool strings_quoted, bool keys_quoted, std::string &s,
575+
bool indented, int cur_indent, const char *indent_string) const {
547576
if (type_ == FBT_STRING) {
548577
String str(Indirect(), byte_width_);
549578
if (strings_quoted) {
@@ -569,7 +598,8 @@ class Reference {
569598
} else if (IsBool()) {
570599
s += AsBool() ? "true" : "false";
571600
} else if (IsMap()) {
572-
s += "{ ";
601+
s += "{";
602+
s += indented ? "\n" : " ";
573603
auto m = AsMap();
574604
auto keys = m.Keys();
575605
auto vals = m.Values();
@@ -590,18 +620,28 @@ class Reference {
590620
}
591621
}
592622
}
623+
if (indented) IndentString(s, cur_indent + 1, indent_string);
593624
keys[i].ToString(true, kq, s);
594625
s += ": ";
595-
vals[i].ToString(true, keys_quoted, s);
596-
if (i < keys.size() - 1) s += ", ";
626+
vals[i].ToString(true, keys_quoted, s, indented, cur_indent + 1, indent_string);
627+
if (i < keys.size() - 1) {
628+
s += ",";
629+
if (!indented) s += " ";
630+
}
631+
if (indented) s += "\n";
597632
}
598-
s += " }";
633+
if (!indented) s += " ";
634+
if (indented) IndentString(s, cur_indent, indent_string);
635+
s += "}";
599636
} else if (IsVector()) {
600-
AppendToString<Vector>(s, AsVector(), keys_quoted);
637+
AppendToString<Vector>(s, AsVector(), keys_quoted, indented,
638+
cur_indent + 1, indent_string);
601639
} else if (IsTypedVector()) {
602-
AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted);
640+
AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted, indented,
641+
cur_indent + 1, indent_string);
603642
} else if (IsFixedTypedVector()) {
604-
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
643+
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted,
644+
indented, cur_indent + 1, indent_string);
605645
} else if (IsBlob()) {
606646
auto blob = AsBlob();
607647
flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),

tests/flexbuffers_test.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@ void FlexBuffersTest() {
132132
// And from FlexBuffer back to JSON:
133133
auto jsonback = jroot.ToString();
134134
TEST_EQ_STR(jsontest, jsonback.c_str());
135+
// With indentation:
136+
std::string jsonback_indented;
137+
jroot.ToString(true, false, jsonback_indented, true, 0, " ");
138+
auto jsontest_indented =
139+
"{\n a: [\n 123,\n 456.0\n ],\n b: \"hello\",\n c: true,\n d: false\n}";
140+
TEST_EQ_STR(jsontest_indented, jsonback_indented.c_str());
135141

136142
slb.Clear();
137143
slb.Vector([&]() {

0 commit comments

Comments
 (0)