mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-23 19:31:48 +00:00
GenerateText generate a text string for default identifier of enum and float scalar. An enum identifier printed as the strictly quoted string. (#4527)
This commit is contained in:
committed by
Wouter van Oortmerssen
parent
a056402f56
commit
70f345012d
@@ -53,7 +53,9 @@ bool Print(T val, Type type, int /*indent*/, Type * /*union_type*/,
|
|||||||
if (type.enum_def && opts.output_enum_identifiers) {
|
if (type.enum_def && opts.output_enum_identifiers) {
|
||||||
auto enum_val = type.enum_def->ReverseLookup(static_cast<int>(val));
|
auto enum_val = type.enum_def->ReverseLookup(static_cast<int>(val));
|
||||||
if (enum_val) {
|
if (enum_val) {
|
||||||
OutputIdentifier(enum_val->name, opts, _text);
|
text += "\"";
|
||||||
|
text += enum_val->name;
|
||||||
|
text += "\"";
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,13 +149,18 @@ bool Print<const void *>(const void *val, Type type, int indent,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for a scalar field.
|
// Generate text for a scalar field.
|
||||||
template<typename T>
|
template<typename T> static bool GenField(const FieldDef &fd,
|
||||||
static bool GenField(const FieldDef &fd, const Table *table, bool fixed,
|
const Table *table, bool fixed,
|
||||||
const IDLOptions &opts, int indent, std::string *_text) {
|
const IDLOptions &opts,
|
||||||
return Print(fixed ? reinterpret_cast<const Struct *>(table)->GetField<T>(
|
int indent,
|
||||||
fd.value.offset)
|
std::string *_text) {
|
||||||
: table->GetField<T>(fd.value.offset, 0),
|
return Print(fixed ?
|
||||||
fd.value.type, indent, nullptr, opts, _text);
|
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset) :
|
||||||
|
table->GetField<T>(fd.value.offset,
|
||||||
|
IsFloat(fd.value.type.base_type) ?
|
||||||
|
static_cast<T>(strtod(fd.value.constant.c_str(), nullptr)) :
|
||||||
|
static_cast<T>(StringToInt(fd.value.constant.c_str()))),
|
||||||
|
fd.value.type, indent, nullptr, opts, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||||
@@ -212,8 +219,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
fd.value.type.base_type != BASE_TYPE_VECTOR))
|
fd.value.type.base_type != BASE_TYPE_VECTOR))
|
||||||
text += ":";
|
text += ":";
|
||||||
text += " ";
|
text += " ";
|
||||||
if (is_present) {
|
switch (fd.value.type.base_type) {
|
||||||
switch (fd.value.type.base_type) {
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
@@ -223,29 +229,25 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
return false; \
|
return false; \
|
||||||
} \
|
} \
|
||||||
break;
|
break;
|
||||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
// Generate drop-thru case statements for all pointer types:
|
// Generate drop-thru case statements for all pointer types:
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
case BASE_TYPE_ ## ENUM:
|
case BASE_TYPE_ ## ENUM:
|
||||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
||||||
union_type, opts, _text)) {
|
union_type, opts, _text)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
|
if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
|
||||||
auto enum_val = fd.value.type.enum_def->ReverseLookup(
|
auto enum_val = fd.value.type.enum_def->ReverseLookup(
|
||||||
table->GetField<uint8_t>(fd.value.offset, 0));
|
table->GetField<uint8_t>(fd.value.offset, 0));
|
||||||
assert(enum_val);
|
union_type = enum_val ? &enum_val->union_type : nullptr;
|
||||||
union_type = &enum_val->union_type;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
text += fd.value.constant;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
y: 2.0,
|
y: 2.0,
|
||||||
z: 3.0,
|
z: 3.0,
|
||||||
test1: 3.0,
|
test1: 3.0,
|
||||||
test2: Green,
|
test2: "Green",
|
||||||
test3: {
|
test3: {
|
||||||
a: 10,
|
a: 10,
|
||||||
b: 20
|
b: 20
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
8,
|
8,
|
||||||
9
|
9
|
||||||
],
|
],
|
||||||
test_type: Monster,
|
test_type: "Monster",
|
||||||
test: {
|
test: {
|
||||||
name: "Fred"
|
name: "Fred"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -541,6 +541,37 @@ void TriviallyCopyableTest() {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check stringify of an default enum value to json
|
||||||
|
void JsonDefaultTest() {
|
||||||
|
// 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 };
|
||||||
|
|
||||||
|
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
||||||
|
// create incomplete monster and store to json
|
||||||
|
parser.opts.output_default_scalars_in_json = true;
|
||||||
|
parser.opts.output_enum_identifiers = true;
|
||||||
|
flatbuffers::FlatBufferBuilder builder;
|
||||||
|
auto name = builder.CreateString("default_enum");
|
||||||
|
MonsterBuilder color_monster(builder);
|
||||||
|
color_monster.add_name(name);
|
||||||
|
FinishMonsterBuffer(builder, color_monster.Finish());
|
||||||
|
std::string jsongen;
|
||||||
|
auto result = GenerateText(parser, builder.GetBufferPointer(), &jsongen);
|
||||||
|
TEST_EQ(result, true);
|
||||||
|
// default value of the "color" field is Blue
|
||||||
|
TEST_EQ(std::string::npos != jsongen.find("color: \"Blue\""), true);
|
||||||
|
// default value of the "testf" field is 3.14159
|
||||||
|
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
|
||||||
|
}
|
||||||
|
|
||||||
// example of parsing text straight into a buffer, and generating
|
// example of parsing text straight into a buffer, and generating
|
||||||
// text back from it:
|
// text back from it:
|
||||||
void ParseAndGenerateTextTest() {
|
void ParseAndGenerateTextTest() {
|
||||||
@@ -1936,6 +1967,8 @@ int main(int /*argc*/, const char * /*argv*/ []) {
|
|||||||
TypeAliasesTest();
|
TypeAliasesTest();
|
||||||
EndianSwapTest();
|
EndianSwapTest();
|
||||||
|
|
||||||
|
JsonDefaultTest();
|
||||||
|
|
||||||
FlexBuffersTest();
|
FlexBuffersTest();
|
||||||
|
|
||||||
if (!testing_fails) {
|
if (!testing_fails) {
|
||||||
|
|||||||
Reference in New Issue
Block a user