mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-25 04:16:11 +00:00
[C++ ] Correctly serialize bit_flags enums to JSON with output_enum_identifiers option (#5454)
* Support output_enum_identifiers for enums with multiple bit values * Cast bit_flag enum val to uint64_t instead of int64_t
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
a4e3ad808e
commit
7de1a5e347
@@ -51,11 +51,22 @@ bool Print(T val, Type type, int /*indent*/, Type * /*union_type*/,
|
|||||||
const IDLOptions &opts, std::string *_text) {
|
const IDLOptions &opts, std::string *_text) {
|
||||||
std::string &text = *_text;
|
std::string &text = *_text;
|
||||||
if (type.enum_def && opts.output_enum_identifiers) {
|
if (type.enum_def && opts.output_enum_identifiers) {
|
||||||
auto ev = type.enum_def->ReverseLookup(static_cast<int64_t>(val));
|
std::vector<EnumVal const *> enum_values;
|
||||||
if (ev) {
|
if (auto ev = type.enum_def->ReverseLookup(static_cast<int64_t>(val))) {
|
||||||
text += "\"";
|
enum_values.push_back(ev);
|
||||||
text += ev->name;
|
} else if (val && type.enum_def->attributes.Lookup("bit_flags")) {
|
||||||
text += "\"";
|
for (auto it = type.enum_def->Vals().begin(),
|
||||||
|
e = type.enum_def->Vals().end();
|
||||||
|
it != e; ++it) {
|
||||||
|
if ((*it)->GetAsUInt64() & static_cast<uint64_t>(val))
|
||||||
|
enum_values.push_back(*it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!enum_values.empty()) {
|
||||||
|
text += '\"';
|
||||||
|
for (auto it = enum_values.begin(), e = enum_values.end(); it != e; ++it)
|
||||||
|
text += (*it)->name + ' ';
|
||||||
|
text[text.length() - 1] = '\"';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -620,6 +620,32 @@ void JsonDefaultTest() {
|
|||||||
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
|
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void JsonEnumsTest() {
|
||||||
|
// load FlatBuffer schema (.fbs) from disk
|
||||||
|
std::string schemafile;
|
||||||
|
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
|
||||||
|
false, &schemafile),
|
||||||
|
true);
|
||||||
|
// parse schema first, so we can use it to parse the data after
|
||||||
|
flatbuffers::Parser parser;
|
||||||
|
auto include_test_path =
|
||||||
|
flatbuffers::ConCatPathFileName(test_data_path, "include_test");
|
||||||
|
const char *include_directories[] = { test_data_path.c_str(),
|
||||||
|
include_test_path.c_str(), nullptr };
|
||||||
|
parser.opts.output_enum_identifiers = true;
|
||||||
|
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
||||||
|
flatbuffers::FlatBufferBuilder builder;
|
||||||
|
auto name = builder.CreateString("bitflag_enum");
|
||||||
|
MonsterBuilder color_monster(builder);
|
||||||
|
color_monster.add_name(name);
|
||||||
|
color_monster.add_color(Color(Color_Blue | Color_Red));
|
||||||
|
FinishMonsterBuffer(builder, color_monster.Finish());
|
||||||
|
std::string jsongen;
|
||||||
|
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
|
TEST_EQ(std::string::npos != jsongen.find("color: \"Red Blue\""), true);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
||||||
// The IEEE-754 quiet_NaN is not simple binary constant.
|
// The IEEE-754 quiet_NaN is not simple binary constant.
|
||||||
// All binary NaN bit strings have all the bits of the biased exponent field E
|
// All binary NaN bit strings have all the bits of the biased exponent field E
|
||||||
@@ -2975,6 +3001,7 @@ int FlatBufferTests() {
|
|||||||
EndianSwapTest();
|
EndianSwapTest();
|
||||||
CreateSharedStringTest();
|
CreateSharedStringTest();
|
||||||
JsonDefaultTest();
|
JsonDefaultTest();
|
||||||
|
JsonEnumsTest();
|
||||||
FlexBuffersTest();
|
FlexBuffersTest();
|
||||||
UninitializedVectorTest();
|
UninitializedVectorTest();
|
||||||
EqualOperatorTest();
|
EqualOperatorTest();
|
||||||
|
|||||||
Reference in New Issue
Block a user