mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-03 04:21:13 +00:00
Allow other pointer types than unique_ptr for object API.
Change-Id: I945890ce667a2f5a6c0495e78fd5326ed33b9914 Tested: on Linux. Bug: 30135763
This commit is contained in:
@@ -159,40 +159,40 @@ class CppGenerator : public BaseGenerator {
|
||||
// The root datatype accessor:
|
||||
code += "inline const " + cpp_qualified_name + " *Get";
|
||||
code += name;
|
||||
code += "(const void *buf) { return flatbuffers::GetRoot<";
|
||||
code += cpp_qualified_name + ">(buf); }\n\n";
|
||||
code += "(const void *buf) {\n return flatbuffers::GetRoot<";
|
||||
code += cpp_qualified_name + ">(buf);\n}\n\n";
|
||||
if (parser_.opts.mutable_buffer) {
|
||||
code += "inline " + name + " *GetMutable";
|
||||
code += name;
|
||||
code += "(void *buf) { return flatbuffers::GetMutableRoot<";
|
||||
code += name + ">(buf); }\n\n";
|
||||
code += "(void *buf) {\n return flatbuffers::GetMutableRoot<";
|
||||
code += name + ">(buf);\n}\n\n";
|
||||
}
|
||||
|
||||
if (parser_.file_identifier_.length()) {
|
||||
// Return the identifier
|
||||
code += "inline const char *" + name;
|
||||
code += "Identifier() { return \"" + parser_.file_identifier_;
|
||||
code += "\"; }\n\n";
|
||||
code += "Identifier() {\n return \"" + parser_.file_identifier_;
|
||||
code += "\";\n}\n\n";
|
||||
|
||||
// Check if a buffer has the identifier.
|
||||
code += "inline bool " + name;
|
||||
code += "BufferHasIdentifier(const void *buf) { return flatbuffers::";
|
||||
code += "BufferHasIdentifier(const void *buf) {\n return flatbuffers::";
|
||||
code += "BufferHasIdentifier(buf, ";
|
||||
code += name + "Identifier()); }\n\n";
|
||||
code += name + "Identifier());\n}\n\n";
|
||||
}
|
||||
|
||||
// The root verifier:
|
||||
code += "inline bool Verify";
|
||||
code += name;
|
||||
code +=
|
||||
"Buffer(flatbuffers::Verifier &verifier) { "
|
||||
"return verifier.VerifyBuffer<";
|
||||
"Buffer(flatbuffers::Verifier &verifier) {\n"
|
||||
" return verifier.VerifyBuffer<";
|
||||
code += cpp_qualified_name + ">(";
|
||||
if (parser_.file_identifier_.length())
|
||||
code += name + "Identifier()";
|
||||
else
|
||||
code += "nullptr";
|
||||
code += "); }\n\n";
|
||||
code += ");\n}\n\n";
|
||||
|
||||
if (parser_.file_extension_.length()) {
|
||||
// Return the extension
|
||||
@@ -205,10 +205,22 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "inline void Finish" + name;
|
||||
code +=
|
||||
"Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
|
||||
code += cpp_qualified_name + "> root) { fbb.Finish(root";
|
||||
code += cpp_qualified_name + "> root) {\n fbb.Finish(root";
|
||||
if (parser_.file_identifier_.length())
|
||||
code += ", " + name + "Identifier()";
|
||||
code += "); }\n\n";
|
||||
code += ");\n}\n\n";
|
||||
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
// A convenient root unpack function.
|
||||
auto native_name =
|
||||
NativeName(WrapInNameSpace(*parser_.root_struct_def_));
|
||||
code += "inline " + GenTypeNativePtr(native_name, nullptr, false);
|
||||
code += " UnPack" + name;
|
||||
code += "(const void *buf, const flatbuffers::resolver_function_t *";
|
||||
code += "resolver = nullptr) {\n return ";
|
||||
code += GenTypeNativePtr(native_name, nullptr, true);
|
||||
code += "(Get" + name + "(buf)->UnPack(resolver));\n}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
assert(cur_name_space_);
|
||||
@@ -293,23 +305,42 @@ class CppGenerator : public BaseGenerator {
|
||||
// TODO(wvo): make this configurable.
|
||||
std::string NativeName(const std::string &name) { return name + "T"; }
|
||||
|
||||
std::string GenTypeNative(const Type &type, bool invector) {
|
||||
const std::string &PtrType(const FieldDef *field) {
|
||||
auto attr = field ? field->attributes.Lookup("cpp_ptr_type") : nullptr;
|
||||
return attr ? attr->constant : parser_.opts.cpp_object_api_pointer_type;
|
||||
}
|
||||
|
||||
std::string GenTypeNativePtr(const std::string &type, const FieldDef *field,
|
||||
bool is_constructor) {
|
||||
auto &ptr_type = PtrType(field);
|
||||
if (ptr_type == "naked") return is_constructor ? "" : type + " *";
|
||||
return ptr_type + "<" + type + ">";
|
||||
}
|
||||
|
||||
std::string GenPtrGet(const FieldDef &field) {
|
||||
auto &ptr_type = PtrType(&field);
|
||||
return ptr_type == "naked" ? "" : ".get()";
|
||||
}
|
||||
|
||||
std::string GenTypeNative(const Type &type, bool invector,
|
||||
const FieldDef &field) {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING:
|
||||
return "std::string";
|
||||
case BASE_TYPE_VECTOR:
|
||||
return "std::vector<" + GenTypeNative(type.VectorType(), true) + ">";
|
||||
return "std::vector<" + GenTypeNative(type.VectorType(), true, field) +
|
||||
">";
|
||||
case BASE_TYPE_STRUCT:
|
||||
if (IsStruct(type)) {
|
||||
if (invector) {
|
||||
return WrapInNameSpace(*type.struct_def);
|
||||
} else {
|
||||
return "std::unique_ptr<" +
|
||||
WrapInNameSpace(*type.struct_def) + ">";
|
||||
return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), &field,
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
return "std::unique_ptr<" +
|
||||
NativeName(WrapInNameSpace(*type.struct_def)) + ">";
|
||||
return GenTypeNativePtr(NativeName(WrapInNameSpace(*type.struct_def)),
|
||||
&field, false);
|
||||
}
|
||||
case BASE_TYPE_UNION:
|
||||
return type.enum_def->name + "Union";
|
||||
@@ -383,7 +414,7 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
|
||||
std::string TableUnPackSignature(StructDef &struct_def, bool inclass) {
|
||||
return "std::unique_ptr<" + NativeName(struct_def.name) + "> " +
|
||||
return NativeName(struct_def.name) + " *" +
|
||||
(inclass ? "" : struct_def.name + "::") +
|
||||
"UnPack(const flatbuffers::resolver_function_t *resolver" +
|
||||
(inclass ? " = nullptr" : "") + ") const";
|
||||
@@ -490,7 +521,7 @@ class CppGenerator : public BaseGenerator {
|
||||
}
|
||||
code += "]; }\n\n";
|
||||
}
|
||||
|
||||
|
||||
// Generate type traits for unions to map from a type to union enum value.
|
||||
if (enum_def.is_union) {
|
||||
for (auto it = enum_def.vals.vec.begin();
|
||||
@@ -507,7 +538,7 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "};\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (enum_def.is_union) {
|
||||
code += UnionVerifySignature(enum_def) + ";\n\n";
|
||||
}
|
||||
@@ -548,7 +579,7 @@ class CppGenerator : public BaseGenerator {
|
||||
} else {
|
||||
code += ": return reinterpret_cast<const ";
|
||||
code += WrapInNameSpace(*ev.struct_def);
|
||||
code += " *>(union_obj)->UnPack(resolver).release();\n";
|
||||
code += " *>(union_obj)->UnPack(resolver);\n";
|
||||
}
|
||||
}
|
||||
code += " default: return nullptr;\n }\n}\n\n";
|
||||
@@ -662,7 +693,7 @@ class CppGenerator : public BaseGenerator {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||
field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||
auto type = GenTypeNative(field.value.type, false);
|
||||
auto type = GenTypeNative(field.value.type, false, field);
|
||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
code += " " + (cpp_type ? cpp_type->constant + " *" : type+ " ") +
|
||||
field.name + ";\n";
|
||||
@@ -982,6 +1013,7 @@ class CppGenerator : public BaseGenerator {
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
// Generate the UnPack() method.
|
||||
code += "inline " + TableUnPackSignature(struct_def, false) + " {\n";
|
||||
code += " (void)resolver;\n";
|
||||
code += " auto _o = new " + NativeName(struct_def.name) + "();\n";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
@@ -993,7 +1025,8 @@ class CppGenerator : public BaseGenerator {
|
||||
auto dest = deref + field.name;
|
||||
auto assign = prefix + dest + " = ";
|
||||
auto gen_unpack_val = [&](const Type &type, const std::string &val,
|
||||
bool invector) -> std::string {
|
||||
bool invector, const FieldDef &afield)
|
||||
-> std::string {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING:
|
||||
return val + "->str()";
|
||||
@@ -1002,13 +1035,15 @@ class CppGenerator : public BaseGenerator {
|
||||
if (invector) {
|
||||
return "*" + val;
|
||||
} else {
|
||||
return "std::unique_ptr<" +
|
||||
WrapInNameSpace (*type.struct_def) +
|
||||
">(new " +
|
||||
WrapInNameSpace (*type.struct_def) + "(*" + val + "))";
|
||||
return GenTypeNativePtr(WrapInNameSpace(*type.struct_def),
|
||||
&afield, true) +
|
||||
"(new " +
|
||||
WrapInNameSpace(*type.struct_def) + "(*" + val + "))";
|
||||
}
|
||||
} else {
|
||||
return val + "->UnPack(resolver)";
|
||||
return GenTypeNativePtr(NativeName(WrapInNameSpace(
|
||||
*type.struct_def)), &afield, true) +
|
||||
"(" + val + "->UnPack(resolver))";
|
||||
}
|
||||
default:
|
||||
return val;
|
||||
@@ -1025,7 +1060,7 @@ class CppGenerator : public BaseGenerator {
|
||||
if (field.value.type.element == BASE_TYPE_BOOL)
|
||||
indexing += "!=0";
|
||||
code += gen_unpack_val(field.value.type.VectorType(),
|
||||
indexing, true);
|
||||
indexing, true, field);
|
||||
code += "); } }";
|
||||
break;
|
||||
}
|
||||
@@ -1052,7 +1087,7 @@ class CppGenerator : public BaseGenerator {
|
||||
code += dest + " = nullptr";
|
||||
} else {
|
||||
code += assign;
|
||||
code += gen_unpack_val(field.value.type, "_e", false);
|
||||
code += gen_unpack_val(field.value.type, "_e", false, field);
|
||||
}
|
||||
code += ";";
|
||||
break;
|
||||
@@ -1061,11 +1096,11 @@ class CppGenerator : public BaseGenerator {
|
||||
code += " };\n";
|
||||
}
|
||||
}
|
||||
code += " return std::unique_ptr<" + NativeName(struct_def.name);
|
||||
code += ">(_o);\n}\n\n";
|
||||
code += " return _o;\n}\n\n";
|
||||
|
||||
// Generate a CreateX method that works with an unpacked C++ object.
|
||||
code += TableCreateSignature(struct_def, false) + " {\n";
|
||||
code += " (void)rehasher;\n";
|
||||
auto before_return_statement = code.size();
|
||||
code += " return Create";
|
||||
code += struct_def.name + "(_fbb";
|
||||
@@ -1116,7 +1151,7 @@ class CppGenerator : public BaseGenerator {
|
||||
code += vector_type.struct_def->name + ">>(" + accessor;
|
||||
code += ".size(), [&](size_t i) { return Create";
|
||||
code += vector_type.struct_def->name + "(_fbb, " + accessor;
|
||||
code += "[i].get(), rehasher); })";
|
||||
code += "[i]" + GenPtrGet(field) + ", rehasher); })";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1131,11 +1166,12 @@ class CppGenerator : public BaseGenerator {
|
||||
break;
|
||||
case BASE_TYPE_STRUCT:
|
||||
if (IsStruct(field.value.type)) {
|
||||
code += ptrprefix + accessor + ".get()" + postfix;
|
||||
code += ptrprefix + accessor + GenPtrGet(field) + postfix;
|
||||
} else {
|
||||
code += ptrprefix + "Create";
|
||||
code += field.value.type.struct_def->name;
|
||||
code += "(_fbb, " + accessor + ".get(), rehasher)" + postfix;
|
||||
code += "(_fbb, " + accessor + GenPtrGet(field) + ", rehasher)";
|
||||
code += postfix;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user