forked from BigfootDev/flatbuffers
Use the Google Style for clang-format without exceptions (#8706)
This reduces the friction when merging from github and google repos by using the exact same clang style guide. MARKDOWN=true
This commit is contained in:
@@ -1,13 +1,5 @@
|
|||||||
---
|
---
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
BasedOnStyle: Google
|
BasedOnStyle: Google
|
||||||
DerivePointerAlignment: false
|
|
||||||
PointerAlignment: Right
|
|
||||||
IndentPPDirectives: AfterHash
|
|
||||||
Cpp11BracedListStyle: false
|
|
||||||
AlwaysBreakTemplateDeclarations: false
|
|
||||||
AllowShortCaseLabelsOnASingleLine: true
|
|
||||||
SpaceAfterTemplateKeyword: false
|
|
||||||
AllowShortBlocksOnASingleLine: true
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,10 @@
|
|||||||
// swiftlint:disable all
|
// swiftlint:disable all
|
||||||
// swiftformat:disable all
|
// swiftformat:disable all
|
||||||
|
|
||||||
|
#if canImport(Common)
|
||||||
|
import Common
|
||||||
|
#endif
|
||||||
|
|
||||||
import FlatBuffers
|
import FlatBuffers
|
||||||
|
|
||||||
public struct flatbuffers_goldens_Galaxy: FlatBufferObject, Verifiable {
|
public struct flatbuffers_goldens_Galaxy: FlatBufferObject, Verifiable {
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifndef GRPC_CUSTOM_STRING
|
#ifndef GRPC_CUSTOM_STRING
|
||||||
# include <string>
|
#include <string>
|
||||||
# define GRPC_CUSTOM_STRING std::string
|
#define GRPC_CUSTOM_STRING std::string
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace grpc {
|
namespace grpc {
|
||||||
@@ -55,10 +55,10 @@ struct Method : public CommentHolder {
|
|||||||
virtual grpc::string output_type_name() const = 0;
|
virtual grpc::string output_type_name() const = 0;
|
||||||
|
|
||||||
virtual bool get_module_and_message_path_input(
|
virtual bool get_module_and_message_path_input(
|
||||||
grpc::string *str, grpc::string generator_file_name,
|
grpc::string* str, grpc::string generator_file_name,
|
||||||
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
|
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
|
||||||
virtual bool get_module_and_message_path_output(
|
virtual bool get_module_and_message_path_output(
|
||||||
grpc::string *str, grpc::string generator_file_name,
|
grpc::string* str, grpc::string generator_file_name,
|
||||||
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
|
bool generate_in_pb2_grpc, grpc::string import_prefix) const = 0;
|
||||||
|
|
||||||
virtual std::vector<grpc::string> get_input_namespace_parts() const = 0;
|
virtual std::vector<grpc::string> get_input_namespace_parts() const = 0;
|
||||||
@@ -89,9 +89,9 @@ struct Service : public CommentHolder {
|
|||||||
struct Printer {
|
struct Printer {
|
||||||
virtual ~Printer() {}
|
virtual ~Printer() {}
|
||||||
|
|
||||||
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
virtual void Print(const std::map<grpc::string, grpc::string>& vars,
|
||||||
const char *template_string) = 0;
|
const char* template_string) = 0;
|
||||||
virtual void Print(const char *string) = 0;
|
virtual void Print(const char* string) = 0;
|
||||||
virtual void SetIndentationSize(const size_t size) = 0;
|
virtual void SetIndentationSize(const size_t size) = 0;
|
||||||
virtual void Indent() = 0;
|
virtual void Indent() = 0;
|
||||||
virtual void Outdent() = 0;
|
virtual void Outdent() = 0;
|
||||||
@@ -112,7 +112,7 @@ struct File : public CommentHolder {
|
|||||||
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
||||||
|
|
||||||
virtual std::unique_ptr<Printer> CreatePrinter(
|
virtual std::unique_ptr<Printer> CreatePrinter(
|
||||||
grpc::string *str, const char indentation_type = ' ') const = 0;
|
grpc::string* str, const char indentation_type = ' ') const = 0;
|
||||||
};
|
};
|
||||||
} // namespace grpc_generator
|
} // namespace grpc_generator
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,9 @@ void message_builder_tests();
|
|||||||
// code. It implements all rpcs specified in the FlatBuffers schema.
|
// code. It implements all rpcs specified in the FlatBuffers schema.
|
||||||
class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
||||||
virtual ::grpc::Status Store(
|
virtual ::grpc::Status Store(
|
||||||
::grpc::ServerContext *context,
|
::grpc::ServerContext* context,
|
||||||
const flatbuffers::grpc::Message<Monster> *request,
|
const flatbuffers::grpc::Message<Monster>* request,
|
||||||
flatbuffers::grpc::Message<Stat> *response) override {
|
flatbuffers::grpc::Message<Stat>* response) override {
|
||||||
// Create a response from the incoming request name.
|
// Create a response from the incoming request name.
|
||||||
fbb_.Clear();
|
fbb_.Clear();
|
||||||
auto stat_offset = CreateStat(
|
auto stat_offset = CreateStat(
|
||||||
@@ -46,9 +46,9 @@ class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
|||||||
return grpc::Status::OK;
|
return grpc::Status::OK;
|
||||||
}
|
}
|
||||||
virtual ::grpc::Status Retrieve(
|
virtual ::grpc::Status Retrieve(
|
||||||
::grpc::ServerContext *context,
|
::grpc::ServerContext* context,
|
||||||
const flatbuffers::grpc::Message<Stat> *request,
|
const flatbuffers::grpc::Message<Stat>* request,
|
||||||
::grpc::ServerWriter<flatbuffers::grpc::Message<Monster>> *writer)
|
::grpc::ServerWriter<flatbuffers::grpc::Message<Monster>>* writer)
|
||||||
override {
|
override {
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
fbb_.Clear();
|
fbb_.Clear();
|
||||||
@@ -73,7 +73,7 @@ class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Track the server instance, so we can terminate it later.
|
// Track the server instance, so we can terminate it later.
|
||||||
grpc::Server *server_instance = nullptr;
|
grpc::Server* server_instance = nullptr;
|
||||||
// Mutex to protec this variable.
|
// Mutex to protec this variable.
|
||||||
std::mutex wait_for_server;
|
std::mutex wait_for_server;
|
||||||
std::condition_variable server_instance_cv;
|
std::condition_variable server_instance_cv;
|
||||||
@@ -98,7 +98,8 @@ void RunServer() {
|
|||||||
server_instance->Wait();
|
server_instance->Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
|
template <class Builder>
|
||||||
|
void StoreRPC(MonsterStorage::Stub* stub) {
|
||||||
Builder fbb;
|
Builder fbb;
|
||||||
grpc::ClientContext context;
|
grpc::ClientContext context;
|
||||||
// Build a request with the name set.
|
// Build a request with the name set.
|
||||||
@@ -119,7 +120,8 @@ template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class Builder> void RetrieveRPC(MonsterStorage::Stub *stub) {
|
template <class Builder>
|
||||||
|
void RetrieveRPC(MonsterStorage::Stub* stub) {
|
||||||
Builder fbb;
|
Builder fbb;
|
||||||
grpc::ClientContext context;
|
grpc::ClientContext context;
|
||||||
fbb.Clear();
|
fbb.Clear();
|
||||||
@@ -179,7 +181,7 @@ int grpc_server_test() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
int main(int /*argc*/, const char* /*argv*/[]) {
|
||||||
message_builder_tests();
|
message_builder_tests();
|
||||||
grpc_server_test();
|
grpc_server_test();
|
||||||
|
|
||||||
|
|||||||
@@ -15,44 +15,43 @@ using namespace MyGame::Example; // NOLINT
|
|||||||
// Unary async overloads
|
// Unary async overloads
|
||||||
static_assert(std::is_member_function_pointer<
|
static_assert(std::is_member_function_pointer<
|
||||||
decltype(static_cast<void (Stub::*)(
|
decltype(static_cast<void (Stub::*)(
|
||||||
::grpc::ClientContext *,
|
::grpc::ClientContext*,
|
||||||
const flatbuffers::grpc::Message<Monster> &,
|
const flatbuffers::grpc::Message<Monster>&,
|
||||||
flatbuffers::grpc::Message<Stat> *,
|
flatbuffers::grpc::Message<Stat>*,
|
||||||
std::function<void(::grpc::Status)>)>(
|
std::function<void(::grpc::Status)>)>(
|
||||||
&Stub::async_Store))>::value,
|
&Stub::async_Store))>::value,
|
||||||
"Function-form unary async_Store missing");
|
"Function-form unary async_Store missing");
|
||||||
static_assert(std::is_member_function_pointer<
|
static_assert(
|
||||||
|
std::is_member_function_pointer<
|
||||||
decltype(static_cast<void (Stub::*)(
|
decltype(static_cast<void (Stub::*)(
|
||||||
::grpc::ClientContext *,
|
::grpc::ClientContext*,
|
||||||
const flatbuffers::grpc::Message<Monster> &,
|
const flatbuffers::grpc::Message<Monster>&,
|
||||||
flatbuffers::grpc::Message<Stat> *,
|
flatbuffers::grpc::Message<Stat>*,
|
||||||
::grpc::ClientUnaryReactor *)>(
|
::grpc::ClientUnaryReactor*)>(&Stub::async_Store))>::value,
|
||||||
&Stub::async_Store))>::value,
|
|
||||||
"Reactor-form unary async_Store missing");
|
"Reactor-form unary async_Store missing");
|
||||||
|
|
||||||
// Streaming reactor entry points
|
// Streaming reactor entry points
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_member_function_pointer<
|
std::is_member_function_pointer<
|
||||||
decltype(static_cast<void (Stub::*)(
|
decltype(static_cast<void (Stub::*)(
|
||||||
::grpc::ClientContext *,
|
::grpc::ClientContext*,
|
||||||
const flatbuffers::grpc::Message<Stat> &,
|
const flatbuffers::grpc::Message<Stat>&,
|
||||||
::grpc::ClientReadReactor<flatbuffers::grpc::Message<
|
::grpc::ClientReadReactor<flatbuffers::grpc::Message<
|
||||||
Monster> > *)>(&Stub::async_Retrieve))>::value,
|
Monster> >*)>(&Stub::async_Retrieve))>::value,
|
||||||
"Server streaming reactor async_Retrieve missing");
|
"Server streaming reactor async_Retrieve missing");
|
||||||
static_assert(
|
static_assert(
|
||||||
std::is_member_function_pointer<
|
std::is_member_function_pointer<
|
||||||
decltype(static_cast<void (Stub::*)(
|
decltype(static_cast<void (Stub::*)(
|
||||||
::grpc::ClientContext *,
|
::grpc::ClientContext*, flatbuffers::grpc::Message<Stat>*,
|
||||||
flatbuffers::grpc::Message<Stat> *,
|
|
||||||
::grpc::ClientWriteReactor<flatbuffers::grpc::Message<
|
::grpc::ClientWriteReactor<flatbuffers::grpc::Message<
|
||||||
Monster> > *)>(&Stub::async_GetMaxHitPoint))>::value,
|
Monster> >*)>(&Stub::async_GetMaxHitPoint))>::value,
|
||||||
"Client streaming reactor async_GetMaxHitPoint missing");
|
"Client streaming reactor async_GetMaxHitPoint missing");
|
||||||
static_assert(std::is_member_function_pointer<
|
static_assert(std::is_member_function_pointer<
|
||||||
decltype(static_cast<void (Stub::*)(
|
decltype(static_cast<void (Stub::*)(
|
||||||
::grpc::ClientContext *,
|
::grpc::ClientContext*,
|
||||||
::grpc::ClientBidiReactor<
|
::grpc::ClientBidiReactor<
|
||||||
flatbuffers::grpc::Message<Monster>,
|
flatbuffers::grpc::Message<Monster>,
|
||||||
flatbuffers::grpc::Message<Stat> > *)>(
|
flatbuffers::grpc::Message<Stat> >*)>(
|
||||||
&Stub::async_GetMinMaxHitPoints))>::value,
|
&Stub::async_GetMinMaxHitPoints))>::value,
|
||||||
"Bidi streaming reactor async_GetMinMaxHitPoints missing");
|
"Bidi streaming reactor async_GetMinMaxHitPoints missing");
|
||||||
#endif // FLATBUFFERS_GENERATED_GRPC_CALLBACK_API &&
|
#endif // FLATBUFFERS_GENERATED_GRPC_CALLBACK_API &&
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ using MyGame::Example::Any_NONE;
|
|||||||
using MyGame::Example::CreateStat;
|
using MyGame::Example::CreateStat;
|
||||||
using MyGame::Example::Vec3;
|
using MyGame::Example::Vec3;
|
||||||
|
|
||||||
bool verify(flatbuffers::grpc::Message<Monster> &msg,
|
bool verify(flatbuffers::grpc::Message<Monster>& msg,
|
||||||
const std::string &expected_name, Color expected_color) {
|
const std::string& expected_name, Color expected_color) {
|
||||||
const Monster *monster = msg.GetRoot();
|
const Monster* monster = msg.GetRoot();
|
||||||
const auto name = monster->name()->str();
|
const auto name = monster->name()->str();
|
||||||
const auto color = monster->color();
|
const auto color = monster->color();
|
||||||
TEST_EQ(name, expected_name);
|
TEST_EQ(name, expected_name);
|
||||||
@@ -17,8 +17,8 @@ bool verify(flatbuffers::grpc::Message<Monster> &msg,
|
|||||||
return (name == expected_name) && (color == expected_color);
|
return (name == expected_name) && (color == expected_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
|
bool release_n_verify(flatbuffers::grpc::MessageBuilder& mbb,
|
||||||
const std::string &expected_name, Color expected_color) {
|
const std::string& expected_name, Color expected_color) {
|
||||||
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
|
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
|
||||||
return verify(msg, expected_name, expected_color);
|
return verify(msg, expected_name, expected_color);
|
||||||
}
|
}
|
||||||
@@ -41,11 +41,13 @@ void builder_move_assign_after_releaseraw_test(
|
|||||||
TEST_EQ(src.GetSize(), 0);
|
TEST_EQ(src.GetSize(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class SrcBuilder>
|
template <class SrcBuilder>
|
||||||
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
||||||
static void builder_reusable_after_release_message_test(
|
static void builder_reusable_after_release_message_test(
|
||||||
TestSelector selector) {
|
TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { return; }
|
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
|
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
|
||||||
@@ -58,7 +60,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_release_test(TestSelector selector) {
|
static void builder_reusable_after_release_test(TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
|
if (!selector.count(REUSABLE_AFTER_RELEASE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
|
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
|
||||||
// SliceAllocator::allocate in the second iteration.
|
// SliceAllocator::allocate in the second iteration.
|
||||||
@@ -74,7 +78,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
|
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
|
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
@@ -82,14 +88,16 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
mb.Finish(root_offset1);
|
mb.Finish(root_offset1);
|
||||||
size_t size, offset;
|
size_t size, offset;
|
||||||
::grpc::Slice slice;
|
::grpc::Slice slice;
|
||||||
const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
|
const uint8_t* buf = mb.ReleaseRaw(size, offset, slice);
|
||||||
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
|
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_release_and_move_assign_test(
|
static void builder_reusable_after_release_and_move_assign_test(
|
||||||
TestSelector selector) {
|
TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
|
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// FIXME: Release-move_assign loop fails assert(p ==
|
// FIXME: Release-move_assign loop fails assert(p ==
|
||||||
// GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
|
// GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
|
||||||
@@ -137,7 +145,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
|
|
||||||
static void builder_reusable_after_releaseraw_and_move_assign_test(
|
static void builder_reusable_after_releaseraw_and_move_assign_test(
|
||||||
TestSelector selector) {
|
TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
|
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder dst;
|
flatbuffers::grpc::MessageBuilder dst;
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
@@ -145,7 +155,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
dst.Finish(root_offset1);
|
dst.Finish(root_offset1);
|
||||||
size_t size, offset;
|
size_t size, offset;
|
||||||
::grpc::Slice slice;
|
::grpc::Slice slice;
|
||||||
const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
|
const uint8_t* buf = dst.ReleaseRaw(size, offset, slice);
|
||||||
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
|
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
|
||||||
|
|
||||||
SrcBuilder src;
|
SrcBuilder src;
|
||||||
@@ -170,7 +180,7 @@ void slice_allocator_tests() {
|
|||||||
{
|
{
|
||||||
size_t size = 2048;
|
size_t size = 2048;
|
||||||
flatbuffers::grpc::SliceAllocator sa1;
|
flatbuffers::grpc::SliceAllocator sa1;
|
||||||
uint8_t *buf = sa1.allocate(size);
|
uint8_t* buf = sa1.allocate(size);
|
||||||
TEST_ASSERT_FUNC(buf != 0);
|
TEST_ASSERT_FUNC(buf != 0);
|
||||||
buf[0] = 100;
|
buf[0] = 100;
|
||||||
buf[size - 1] = 200;
|
buf[size - 1] = 200;
|
||||||
@@ -184,7 +194,7 @@ void slice_allocator_tests() {
|
|||||||
// move-assign test
|
// move-assign test
|
||||||
{
|
{
|
||||||
flatbuffers::grpc::SliceAllocator sa1, sa2;
|
flatbuffers::grpc::SliceAllocator sa1, sa2;
|
||||||
uint8_t *buf = sa1.allocate(2048);
|
uint8_t* buf = sa1.allocate(2048);
|
||||||
sa1 = std::move(sa2);
|
sa1 = std::move(sa2);
|
||||||
// sa1 deletes previously allocated memory in move-assign.
|
// sa1 deletes previously allocated memory in move-assign.
|
||||||
// So buf is no longer usable here.
|
// So buf is no longer usable here.
|
||||||
@@ -194,7 +204,7 @@ void slice_allocator_tests() {
|
|||||||
|
|
||||||
/// This function does not populate exactly the first half of the table. But it
|
/// This function does not populate exactly the first half of the table. But it
|
||||||
/// could.
|
/// could.
|
||||||
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
|
void populate_first_half(MyGame::Example::MonsterBuilder& wrapper,
|
||||||
flatbuffers::Offset<flatbuffers::String> name_offset) {
|
flatbuffers::Offset<flatbuffers::String> name_offset) {
|
||||||
wrapper.add_name(name_offset);
|
wrapper.add_name(name_offset);
|
||||||
wrapper.add_color(m1_color());
|
wrapper.add_color(m1_color());
|
||||||
@@ -202,7 +212,7 @@ void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
|
|||||||
|
|
||||||
/// This function does not populate exactly the second half of the table. But it
|
/// This function does not populate exactly the second half of the table. But it
|
||||||
/// could.
|
/// could.
|
||||||
void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
|
void populate_second_half(MyGame::Example::MonsterBuilder& wrapper) {
|
||||||
wrapper.add_hp(77);
|
wrapper.add_hp(77);
|
||||||
wrapper.add_mana(88);
|
wrapper.add_mana(88);
|
||||||
Vec3 vec3;
|
Vec3 vec3;
|
||||||
@@ -216,9 +226,9 @@ void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
|
|||||||
/// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
|
/// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
|
||||||
/// would be unnecessary. That involves a code-generator change though.
|
/// would be unnecessary. That involves a code-generator change though.
|
||||||
void test_only_hack_update_fbb_reference(
|
void test_only_hack_update_fbb_reference(
|
||||||
MyGame::Example::MonsterBuilder &monsterBuilder,
|
MyGame::Example::MonsterBuilder& monsterBuilder,
|
||||||
flatbuffers::grpc::MessageBuilder &mb) {
|
flatbuffers::grpc::MessageBuilder& mb) {
|
||||||
*reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
|
*reinterpret_cast<flatbuffers::FlatBufferBuilder**>(&monsterBuilder) = &mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test validates correctness of move conversion of FlatBufferBuilder to a
|
/// This test validates correctness of move conversion of FlatBufferBuilder to a
|
||||||
@@ -358,8 +368,7 @@ void message_builder_tests() {
|
|||||||
|
|
||||||
REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
|
REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
|
||||||
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
|
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
|
||||||
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
|
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN};
|
||||||
};
|
|
||||||
|
|
||||||
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
|
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
|
||||||
TestSelector(tests, tests + 6));
|
TestSelector(tests, tests + 6));
|
||||||
|
|||||||
@@ -28,21 +28,21 @@ class Allocator {
|
|||||||
virtual ~Allocator() {}
|
virtual ~Allocator() {}
|
||||||
|
|
||||||
// Allocate `size` bytes of memory.
|
// Allocate `size` bytes of memory.
|
||||||
virtual uint8_t *allocate(size_t size) = 0;
|
virtual uint8_t* allocate(size_t size) = 0;
|
||||||
|
|
||||||
// Deallocate `size` bytes of memory at `p` allocated by this allocator.
|
// Deallocate `size` bytes of memory at `p` allocated by this allocator.
|
||||||
virtual void deallocate(uint8_t *p, size_t size) = 0;
|
virtual void deallocate(uint8_t* p, size_t size) = 0;
|
||||||
|
|
||||||
// Reallocate `new_size` bytes of memory, replacing the old region of size
|
// Reallocate `new_size` bytes of memory, replacing the old region of size
|
||||||
// `old_size` at `p`. In contrast to a normal realloc, this grows downwards,
|
// `old_size` at `p`. In contrast to a normal realloc, this grows downwards,
|
||||||
// and is intended specifcally for `vector_downward` use.
|
// and is intended specifcally for `vector_downward` use.
|
||||||
// `in_use_back` and `in_use_front` indicate how much of `old_size` is
|
// `in_use_back` and `in_use_front` indicate how much of `old_size` is
|
||||||
// actually in use at each end, and needs to be copied.
|
// actually in use at each end, and needs to be copied.
|
||||||
virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
|
virtual uint8_t* reallocate_downward(uint8_t* old_p, size_t old_size,
|
||||||
size_t new_size, size_t in_use_back,
|
size_t new_size, size_t in_use_back,
|
||||||
size_t in_use_front) {
|
size_t in_use_front) {
|
||||||
FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows
|
FLATBUFFERS_ASSERT(new_size > old_size); // vector_downward only grows
|
||||||
uint8_t *new_p = allocate(new_size);
|
uint8_t* new_p = allocate(new_size);
|
||||||
memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
|
memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
|
||||||
in_use_front);
|
in_use_front);
|
||||||
deallocate(old_p, old_size);
|
deallocate(old_p, old_size);
|
||||||
@@ -54,7 +54,7 @@ class Allocator {
|
|||||||
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
|
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
|
||||||
// `in_use_back` will be copied from the front and back of the old memory
|
// `in_use_back` will be copied from the front and back of the old memory
|
||||||
// allocation.
|
// allocation.
|
||||||
void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
|
void memcpy_downward(uint8_t* old_p, size_t old_size, uint8_t* new_p,
|
||||||
size_t new_size, size_t in_use_back,
|
size_t new_size, size_t in_use_back,
|
||||||
size_t in_use_front) {
|
size_t in_use_front) {
|
||||||
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
|
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
|
||||||
|
|||||||
@@ -27,7 +27,8 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
// This is used as a helper type for accessing arrays.
|
// This is used as a helper type for accessing arrays.
|
||||||
template<typename T, uint16_t length> class Array {
|
template <typename T, uint16_t length>
|
||||||
|
class Array {
|
||||||
// Array<T> can carry only POD data types (scalars or structs).
|
// Array<T> can carry only POD data types (scalars or structs).
|
||||||
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
|
typedef typename flatbuffers::bool_constant<flatbuffers::is_scalar<T>::value>
|
||||||
scalar_tag;
|
scalar_tag;
|
||||||
@@ -55,7 +56,8 @@ template<typename T, uint16_t length> class Array {
|
|||||||
// If this is a Vector of enums, T will be its storage type, not the enum
|
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||||
// type. This function makes it convenient to retrieve value with enum
|
// type. This function makes it convenient to retrieve value with enum
|
||||||
// type E.
|
// type E.
|
||||||
template<typename E> E GetEnum(uoffset_t i) const {
|
template <typename E>
|
||||||
|
E GetEnum(uoffset_t i) const {
|
||||||
return static_cast<E>(Get(i));
|
return static_cast<E>(Get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,28 +82,28 @@ template<typename T, uint16_t length> class Array {
|
|||||||
// operation. For primitive types use @p Mutate directly.
|
// operation. For primitive types use @p Mutate directly.
|
||||||
// @warning Assignments and reads to/from the dereferenced pointer are not
|
// @warning Assignments and reads to/from the dereferenced pointer are not
|
||||||
// automatically converted to the correct endianness.
|
// automatically converted to the correct endianness.
|
||||||
typename flatbuffers::conditional<scalar_tag::value, void, T *>::type
|
typename flatbuffers::conditional<scalar_tag::value, void, T*>::type
|
||||||
GetMutablePointer(uoffset_t i) const {
|
GetMutablePointer(uoffset_t i) const {
|
||||||
FLATBUFFERS_ASSERT(i < size());
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
return const_cast<T *>(&data()[i]);
|
return const_cast<T*>(&data()[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Change elements if you have a non-const pointer to this object.
|
// Change elements if you have a non-const pointer to this object.
|
||||||
void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
|
void Mutate(uoffset_t i, const T& val) { MutateImpl(scalar_tag(), i, val); }
|
||||||
|
|
||||||
// The raw data in little endian format. Use with care.
|
// The raw data in little endian format. Use with care.
|
||||||
const uint8_t *Data() const { return data_; }
|
const uint8_t* Data() const { return data_; }
|
||||||
|
|
||||||
uint8_t *Data() { return data_; }
|
uint8_t* Data() { return data_; }
|
||||||
|
|
||||||
// Similarly, but typed, much like std::vector::data
|
// Similarly, but typed, much like std::vector::data
|
||||||
const T *data() const { return reinterpret_cast<const T *>(Data()); }
|
const T* data() const { return reinterpret_cast<const T*>(Data()); }
|
||||||
T *data() { return reinterpret_cast<T *>(Data()); }
|
T* data() { return reinterpret_cast<T*>(Data()); }
|
||||||
|
|
||||||
// Copy data from a span with endian conversion.
|
// Copy data from a span with endian conversion.
|
||||||
// If this Array and the span overlap, the behavior is undefined.
|
// If this Array and the span overlap, the behavior is undefined.
|
||||||
void CopyFromSpan(flatbuffers::span<const T, length> src) {
|
void CopyFromSpan(flatbuffers::span<const T, length> src) {
|
||||||
const auto p1 = reinterpret_cast<const uint8_t *>(src.data());
|
const auto p1 = reinterpret_cast<const uint8_t*>(src.data());
|
||||||
const auto p2 = Data();
|
const auto p2 = Data();
|
||||||
FLATBUFFERS_ASSERT(!(p1 >= p2 && p1 < (p2 + length)) &&
|
FLATBUFFERS_ASSERT(!(p1 >= p2 && p1 < (p2 + length)) &&
|
||||||
!(p2 >= p1 && p2 < (p1 + length)));
|
!(p2 >= p1 && p2 < (p1 + length)));
|
||||||
@@ -111,12 +113,12 @@ template<typename T, uint16_t length> class Array {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void MutateImpl(flatbuffers::true_type, uoffset_t i, const T &val) {
|
void MutateImpl(flatbuffers::true_type, uoffset_t i, const T& val) {
|
||||||
FLATBUFFERS_ASSERT(i < size());
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
WriteScalar(data() + i, val);
|
WriteScalar(data() + i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MutateImpl(flatbuffers::false_type, uoffset_t i, const T &val) {
|
void MutateImpl(flatbuffers::false_type, uoffset_t i, const T& val) {
|
||||||
*(GetMutablePointer(i)) = val;
|
*(GetMutablePointer(i)) = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,7 +133,9 @@ template<typename T, uint16_t length> class Array {
|
|||||||
// Copy data from flatbuffers::span with endian conversion.
|
// Copy data from flatbuffers::span with endian conversion.
|
||||||
void CopyFromSpanImpl(flatbuffers::false_type,
|
void CopyFromSpanImpl(flatbuffers::false_type,
|
||||||
flatbuffers::span<const T, length> src) {
|
flatbuffers::span<const T, length> src) {
|
||||||
for (size_type k = 0; k < length; k++) { Mutate(k, src[k]); }
|
for (size_type k = 0; k < length; k++) {
|
||||||
|
Mutate(k, src[k]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This class is only used to access pre-existing data. Don't ever
|
// This class is only used to access pre-existing data. Don't ever
|
||||||
@@ -150,21 +154,21 @@ template<typename T, uint16_t length> class Array {
|
|||||||
private:
|
private:
|
||||||
// This class is a pointer. Copying will therefore create an invalid object.
|
// This class is a pointer. Copying will therefore create an invalid object.
|
||||||
// Private and unimplemented copy constructor.
|
// Private and unimplemented copy constructor.
|
||||||
Array(const Array &);
|
Array(const Array&);
|
||||||
Array &operator=(const Array &);
|
Array& operator=(const Array&);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specialization for Array[struct] with access using Offset<void> pointer.
|
// Specialization for Array[struct] with access using Offset<void> pointer.
|
||||||
// This specialization used by idl_gen_text.cpp.
|
// This specialization used by idl_gen_text.cpp.
|
||||||
template<typename T, uint16_t length, template<typename> class OffsetT>
|
template <typename T, uint16_t length, template <typename> class OffsetT>
|
||||||
class Array<OffsetT<T>, length> {
|
class Array<OffsetT<T>, length> {
|
||||||
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
|
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef const void *return_type;
|
typedef const void* return_type;
|
||||||
typedef uint16_t size_type;
|
typedef uint16_t size_type;
|
||||||
|
|
||||||
const uint8_t *Data() const { return data_; }
|
const uint8_t* Data() const { return data_; }
|
||||||
|
|
||||||
// Make idl_gen_text.cpp::PrintContainer happy.
|
// Make idl_gen_text.cpp::PrintContainer happy.
|
||||||
return_type operator[](uoffset_t) const {
|
return_type operator[](uoffset_t) const {
|
||||||
@@ -175,14 +179,14 @@ class Array<OffsetT<T>, length> {
|
|||||||
private:
|
private:
|
||||||
// This class is only used to access pre-existing data.
|
// This class is only used to access pre-existing data.
|
||||||
Array();
|
Array();
|
||||||
Array(const Array &);
|
Array(const Array&);
|
||||||
Array &operator=(const Array &);
|
Array& operator=(const Array&);
|
||||||
|
|
||||||
uint8_t data_[1];
|
uint8_t data_[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
template<class U, uint16_t N>
|
template <class U, uint16_t N>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U, N> make_span(Array<U, N> &arr)
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U, N> make_span(Array<U, N>& arr)
|
||||||
FLATBUFFERS_NOEXCEPT {
|
FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(
|
static_assert(
|
||||||
Array<U, N>::is_span_observable,
|
Array<U, N>::is_span_observable,
|
||||||
@@ -190,26 +194,26 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U, N> make_span(Array<U, N> &arr)
|
|||||||
return span<U, N>(arr.data(), N);
|
return span<U, N>(arr.data(), N);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U, uint16_t N>
|
template <class U, uint16_t N>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U, N> make_span(
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U, N> make_span(
|
||||||
const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
const Array<U, N>& arr) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(
|
static_assert(
|
||||||
Array<U, N>::is_span_observable,
|
Array<U, N>::is_span_observable,
|
||||||
"wrong type U, only plain struct, LE-scalar, or byte types are allowed");
|
"wrong type U, only plain struct, LE-scalar, or byte types are allowed");
|
||||||
return span<const U, N>(arr.data(), N);
|
return span<const U, N>(arr.data(), N);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U, uint16_t N>
|
template <class U, uint16_t N>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t, sizeof(U) * N>
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t, sizeof(U) * N>
|
||||||
make_bytes_span(Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
make_bytes_span(Array<U, N>& arr) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Array<U, N>::is_span_observable,
|
static_assert(Array<U, N>::is_span_observable,
|
||||||
"internal error, Array<T> might hold only scalars or structs");
|
"internal error, Array<T> might hold only scalars or structs");
|
||||||
return span<uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
|
return span<uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U, uint16_t N>
|
template <class U, uint16_t N>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t, sizeof(U) * N>
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t, sizeof(U) * N>
|
||||||
make_bytes_span(const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
make_bytes_span(const Array<U, N>& arr) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Array<U, N>::is_span_observable,
|
static_assert(Array<U, N>::is_span_observable,
|
||||||
"internal error, Array<T> might hold only scalars or structs");
|
"internal error, Array<T> might hold only scalars or structs");
|
||||||
return span<const uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
|
return span<const uint8_t, sizeof(U) * N>(arr.Data(), sizeof(U) * N);
|
||||||
@@ -218,31 +222,31 @@ make_bytes_span(const Array<U, N> &arr) FLATBUFFERS_NOEXCEPT {
|
|||||||
// Cast a raw T[length] to a raw flatbuffers::Array<T, length>
|
// Cast a raw T[length] to a raw flatbuffers::Array<T, length>
|
||||||
// without endian conversion. Use with care.
|
// without endian conversion. Use with care.
|
||||||
// TODO: move these Cast-methods to `internal` namespace.
|
// TODO: move these Cast-methods to `internal` namespace.
|
||||||
template<typename T, uint16_t length>
|
template <typename T, uint16_t length>
|
||||||
Array<T, length> &CastToArray(T (&arr)[length]) {
|
Array<T, length>& CastToArray(T (&arr)[length]) {
|
||||||
return *reinterpret_cast<Array<T, length> *>(arr);
|
return *reinterpret_cast<Array<T, length>*>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t length>
|
template <typename T, uint16_t length>
|
||||||
const Array<T, length> &CastToArray(const T (&arr)[length]) {
|
const Array<T, length>& CastToArray(const T (&arr)[length]) {
|
||||||
return *reinterpret_cast<const Array<T, length> *>(arr);
|
return *reinterpret_cast<const Array<T, length>*>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, typename T, uint16_t length>
|
template <typename E, typename T, uint16_t length>
|
||||||
Array<E, length> &CastToArrayOfEnum(T (&arr)[length]) {
|
Array<E, length>& CastToArrayOfEnum(T (&arr)[length]) {
|
||||||
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
|
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
|
||||||
return *reinterpret_cast<Array<E, length> *>(arr);
|
return *reinterpret_cast<Array<E, length>*>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, typename T, uint16_t length>
|
template <typename E, typename T, uint16_t length>
|
||||||
const Array<E, length> &CastToArrayOfEnum(const T (&arr)[length]) {
|
const Array<E, length>& CastToArrayOfEnum(const T (&arr)[length]) {
|
||||||
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
|
static_assert(sizeof(E) == sizeof(T), "invalid enum type E");
|
||||||
return *reinterpret_cast<const Array<E, length> *>(arr);
|
return *reinterpret_cast<const Array<E, length>*>(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, uint16_t length>
|
template <typename T, uint16_t length>
|
||||||
bool operator==(const Array<T, length> &lhs,
|
bool operator==(const Array<T, length>& lhs,
|
||||||
const Array<T, length> &rhs) noexcept {
|
const Array<T, length>& rhs) noexcept {
|
||||||
return std::addressof(lhs) == std::addressof(rhs) ||
|
return std::addressof(lhs) == std::addressof(rhs) ||
|
||||||
(lhs.size() == rhs.size() &&
|
(lhs.size() == rhs.size() &&
|
||||||
std::memcmp(lhs.Data(), rhs.Data(), rhs.size() * sizeof(T)) == 0);
|
std::memcmp(lhs.Data(), rhs.Data(), rhs.size() * sizeof(T)) == 0);
|
||||||
|
|||||||
@@ -26,7 +26,8 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
// Wrapper for uoffset_t to allow safe template specialization.
|
// Wrapper for uoffset_t to allow safe template specialization.
|
||||||
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
|
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
|
||||||
template<typename T = void> struct Offset {
|
template <typename T = void>
|
||||||
|
struct Offset {
|
||||||
// The type of offset to use.
|
// The type of offset to use.
|
||||||
typedef uoffset_t offset_type;
|
typedef uoffset_t offset_type;
|
||||||
|
|
||||||
@@ -37,12 +38,14 @@ template<typename T = void> struct Offset {
|
|||||||
bool IsNull() const { return !o; }
|
bool IsNull() const { return !o; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct is_specialisation_of_Offset : false_type {};
|
template <typename T>
|
||||||
template<typename T>
|
struct is_specialisation_of_Offset : false_type {};
|
||||||
|
template <typename T>
|
||||||
struct is_specialisation_of_Offset<Offset<T>> : true_type {};
|
struct is_specialisation_of_Offset<Offset<T>> : true_type {};
|
||||||
|
|
||||||
// Wrapper for uoffset64_t Offsets.
|
// Wrapper for uoffset64_t Offsets.
|
||||||
template<typename T = void> struct Offset64 {
|
template <typename T = void>
|
||||||
|
struct Offset64 {
|
||||||
// The type of offset to use.
|
// The type of offset to use.
|
||||||
typedef uoffset64_t offset_type;
|
typedef uoffset64_t offset_type;
|
||||||
|
|
||||||
@@ -53,8 +56,9 @@ template<typename T = void> struct Offset64 {
|
|||||||
bool IsNull() const { return !o; }
|
bool IsNull() const { return !o; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> struct is_specialisation_of_Offset64 : false_type {};
|
template <typename T>
|
||||||
template<typename T>
|
struct is_specialisation_of_Offset64 : false_type {};
|
||||||
|
template <typename T>
|
||||||
struct is_specialisation_of_Offset64<Offset64<T>> : true_type {};
|
struct is_specialisation_of_Offset64<Offset64<T>> : true_type {};
|
||||||
|
|
||||||
// Litmus check for ensuring the Offsets are the expected size.
|
// Litmus check for ensuring the Offsets are the expected size.
|
||||||
@@ -64,12 +68,13 @@ static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size");
|
|||||||
inline void EndianCheck() {
|
inline void EndianCheck() {
|
||||||
int endiantest = 1;
|
int endiantest = 1;
|
||||||
// If this fails, see FLATBUFFERS_LITTLEENDIAN above.
|
// If this fails, see FLATBUFFERS_LITTLEENDIAN above.
|
||||||
FLATBUFFERS_ASSERT(*reinterpret_cast<char *>(&endiantest) ==
|
FLATBUFFERS_ASSERT(*reinterpret_cast<char*>(&endiantest) ==
|
||||||
FLATBUFFERS_LITTLEENDIAN);
|
FLATBUFFERS_LITTLEENDIAN);
|
||||||
(void)endiantest;
|
(void)endiantest;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
|
template <typename T>
|
||||||
|
FLATBUFFERS_CONSTEXPR size_t AlignOf() {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return __alignof(T);
|
return __alignof(T);
|
||||||
@@ -85,8 +90,8 @@ template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
|
|||||||
|
|
||||||
// Lexicographically compare two strings (possibly containing nulls), and
|
// Lexicographically compare two strings (possibly containing nulls), and
|
||||||
// return true if the first is less than the second.
|
// return true if the first is less than the second.
|
||||||
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
|
static inline bool StringLessThan(const char* a_data, uoffset_t a_size,
|
||||||
const char *b_data, uoffset_t b_size) {
|
const char* b_data, uoffset_t b_size) {
|
||||||
const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
|
const auto cmp = memcmp(a_data, b_data, (std::min)(a_size, b_size));
|
||||||
return cmp == 0 ? a_size < b_size : cmp < 0;
|
return cmp == 0 ? a_size < b_size : cmp < 0;
|
||||||
}
|
}
|
||||||
@@ -99,42 +104,43 @@ static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
|
|||||||
// return type like this.
|
// return type like this.
|
||||||
// The typedef is for the convenience of callers of this function
|
// The typedef is for the convenience of callers of this function
|
||||||
// (avoiding the need for a trailing return decltype)
|
// (avoiding the need for a trailing return decltype)
|
||||||
template<typename T, typename Enable = void> struct IndirectHelper {
|
template <typename T, typename Enable = void>
|
||||||
|
struct IndirectHelper {
|
||||||
typedef T return_type;
|
typedef T return_type;
|
||||||
typedef T mutable_return_type;
|
typedef T mutable_return_type;
|
||||||
static const size_t element_stride = sizeof(T);
|
static const size_t element_stride = sizeof(T);
|
||||||
|
|
||||||
static return_type Read(const uint8_t *p, const size_t i) {
|
static return_type Read(const uint8_t* p, const size_t i) {
|
||||||
return EndianScalar((reinterpret_cast<const T *>(p))[i]);
|
return EndianScalar((reinterpret_cast<const T*>(p))[i]);
|
||||||
}
|
}
|
||||||
static mutable_return_type Read(uint8_t *p, const size_t i) {
|
static mutable_return_type Read(uint8_t* p, const size_t i) {
|
||||||
return reinterpret_cast<mutable_return_type>(
|
return reinterpret_cast<mutable_return_type>(
|
||||||
Read(const_cast<const uint8_t *>(p), i));
|
Read(const_cast<const uint8_t*>(p), i));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// For vector of Offsets.
|
// For vector of Offsets.
|
||||||
template<typename T, template<typename> class OffsetT>
|
template <typename T, template <typename> class OffsetT>
|
||||||
struct IndirectHelper<OffsetT<T>> {
|
struct IndirectHelper<OffsetT<T>> {
|
||||||
typedef const T *return_type;
|
typedef const T* return_type;
|
||||||
typedef T *mutable_return_type;
|
typedef T* mutable_return_type;
|
||||||
typedef typename OffsetT<T>::offset_type offset_type;
|
typedef typename OffsetT<T>::offset_type offset_type;
|
||||||
static const offset_type element_stride = sizeof(offset_type);
|
static const offset_type element_stride = sizeof(offset_type);
|
||||||
|
|
||||||
static return_type Read(const uint8_t *const p, const offset_type i) {
|
static return_type Read(const uint8_t* const p, const offset_type i) {
|
||||||
// Offsets are relative to themselves, so first update the pointer to
|
// Offsets are relative to themselves, so first update the pointer to
|
||||||
// point to the offset location.
|
// point to the offset location.
|
||||||
const uint8_t *const offset_location = p + i * element_stride;
|
const uint8_t* const offset_location = p + i * element_stride;
|
||||||
|
|
||||||
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
||||||
// then determine the relative location from the offset location.
|
// then determine the relative location from the offset location.
|
||||||
return reinterpret_cast<return_type>(
|
return reinterpret_cast<return_type>(
|
||||||
offset_location + ReadScalar<offset_type>(offset_location));
|
offset_location + ReadScalar<offset_type>(offset_location));
|
||||||
}
|
}
|
||||||
static mutable_return_type Read(uint8_t *const p, const offset_type i) {
|
static mutable_return_type Read(uint8_t* const p, const offset_type i) {
|
||||||
// Offsets are relative to themselves, so first update the pointer to
|
// Offsets are relative to themselves, so first update the pointer to
|
||||||
// point to the offset location.
|
// point to the offset location.
|
||||||
uint8_t *const offset_location = p + i * element_stride;
|
uint8_t* const offset_location = p + i * element_stride;
|
||||||
|
|
||||||
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
||||||
// then determine the relative location from the offset location.
|
// then determine the relative location from the offset location.
|
||||||
@@ -144,7 +150,7 @@ struct IndirectHelper<OffsetT<T>> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// For vector of structs.
|
// For vector of structs.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
struct IndirectHelper<
|
struct IndirectHelper<
|
||||||
T, typename std::enable_if<
|
T, typename std::enable_if<
|
||||||
!std::is_scalar<typename std::remove_pointer<T>::type>::value &&
|
!std::is_scalar<typename std::remove_pointer<T>::type>::value &&
|
||||||
@@ -155,15 +161,15 @@ struct IndirectHelper<
|
|||||||
pointee_type;
|
pointee_type;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef const pointee_type *return_type;
|
typedef const pointee_type* return_type;
|
||||||
typedef pointee_type *mutable_return_type;
|
typedef pointee_type* mutable_return_type;
|
||||||
static const size_t element_stride = sizeof(pointee_type);
|
static const size_t element_stride = sizeof(pointee_type);
|
||||||
|
|
||||||
static return_type Read(const uint8_t *const p, const size_t i) {
|
static return_type Read(const uint8_t* const p, const size_t i) {
|
||||||
// Structs are stored inline, relative to the first struct pointer.
|
// Structs are stored inline, relative to the first struct pointer.
|
||||||
return reinterpret_cast<return_type>(p + i * element_stride);
|
return reinterpret_cast<return_type>(p + i * element_stride);
|
||||||
}
|
}
|
||||||
static mutable_return_type Read(uint8_t *const p, const size_t i) {
|
static mutable_return_type Read(uint8_t* const p, const size_t i) {
|
||||||
// Structs are stored inline, relative to the first struct pointer.
|
// Structs are stored inline, relative to the first struct pointer.
|
||||||
return reinterpret_cast<mutable_return_type>(p + i * element_stride);
|
return reinterpret_cast<mutable_return_type>(p + i * element_stride);
|
||||||
}
|
}
|
||||||
@@ -176,14 +182,14 @@ struct IndirectHelper<
|
|||||||
/// This function is UNDEFINED for FlatBuffers whose schema does not include
|
/// This function is UNDEFINED for FlatBuffers whose schema does not include
|
||||||
/// a file_identifier (likely points at padding or the start of a the root
|
/// a file_identifier (likely points at padding or the start of a the root
|
||||||
/// vtable).
|
/// vtable).
|
||||||
inline const char *GetBufferIdentifier(const void *buf,
|
inline const char* GetBufferIdentifier(const void* buf,
|
||||||
bool size_prefixed = false) {
|
bool size_prefixed = false) {
|
||||||
return reinterpret_cast<const char *>(buf) +
|
return reinterpret_cast<const char*>(buf) +
|
||||||
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
|
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to see if the identifier in a buffer has the expected value.
|
// Helper to see if the identifier in a buffer has the expected value.
|
||||||
inline bool BufferHasIdentifier(const void *buf, const char *identifier,
|
inline bool BufferHasIdentifier(const void* buf, const char* identifier,
|
||||||
bool size_prefixed = false) {
|
bool size_prefixed = false) {
|
||||||
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
|
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
|
||||||
flatbuffers::kFileIdentifierLength) == 0;
|
flatbuffers::kFileIdentifierLength) == 0;
|
||||||
@@ -191,26 +197,27 @@ inline bool BufferHasIdentifier(const void *buf, const char *identifier,
|
|||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
// Helpers to get a typed pointer to the root object contained in the buffer.
|
// Helpers to get a typed pointer to the root object contained in the buffer.
|
||||||
template<typename T> T *GetMutableRoot(void *buf) {
|
template <typename T>
|
||||||
|
T* GetMutableRoot(void* buf) {
|
||||||
if (!buf) return nullptr;
|
if (!buf) return nullptr;
|
||||||
EndianCheck();
|
EndianCheck();
|
||||||
return reinterpret_cast<T *>(
|
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(buf) +
|
||||||
reinterpret_cast<uint8_t *>(buf) +
|
EndianScalar(*reinterpret_cast<uoffset_t*>(buf)));
|
||||||
EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename SizeT = uoffset_t>
|
template <typename T, typename SizeT = uoffset_t>
|
||||||
T *GetMutableSizePrefixedRoot(void *buf) {
|
T* GetMutableSizePrefixedRoot(void* buf) {
|
||||||
return GetMutableRoot<T>(reinterpret_cast<uint8_t *>(buf) + sizeof(SizeT));
|
return GetMutableRoot<T>(reinterpret_cast<uint8_t*>(buf) + sizeof(SizeT));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> const T *GetRoot(const void *buf) {
|
template <typename T>
|
||||||
return GetMutableRoot<T>(const_cast<void *>(buf));
|
const T* GetRoot(const void* buf) {
|
||||||
|
return GetMutableRoot<T>(const_cast<void*>(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename SizeT = uoffset_t>
|
template <typename T, typename SizeT = uoffset_t>
|
||||||
const T *GetSizePrefixedRoot(const void *buf) {
|
const T* GetSizePrefixedRoot(const void* buf) {
|
||||||
return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(SizeT));
|
return GetRoot<T>(reinterpret_cast<const uint8_t*>(buf) + sizeof(SizeT));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -27,23 +27,24 @@ namespace flatbuffers {
|
|||||||
// A BufferRef does not own its buffer.
|
// A BufferRef does not own its buffer.
|
||||||
struct BufferRefBase {}; // for std::is_base_of
|
struct BufferRefBase {}; // for std::is_base_of
|
||||||
|
|
||||||
template<typename T> struct BufferRef : BufferRefBase {
|
template <typename T>
|
||||||
|
struct BufferRef : BufferRefBase {
|
||||||
BufferRef() : buf(nullptr), len(0), must_free(false) {}
|
BufferRef() : buf(nullptr), len(0), must_free(false) {}
|
||||||
BufferRef(uint8_t *_buf, uoffset_t _len)
|
BufferRef(uint8_t* _buf, uoffset_t _len)
|
||||||
: buf(_buf), len(_len), must_free(false) {}
|
: buf(_buf), len(_len), must_free(false) {}
|
||||||
|
|
||||||
~BufferRef() {
|
~BufferRef() {
|
||||||
if (must_free) free(buf);
|
if (must_free) free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
const T *GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
|
const T* GetRoot() const { return flatbuffers::GetRoot<T>(buf); }
|
||||||
|
|
||||||
bool Verify() {
|
bool Verify() {
|
||||||
Verifier verifier(buf, len);
|
Verifier verifier(buf, len);
|
||||||
return verifier.VerifyBuffer<T>(nullptr);
|
return verifier.VerifyBuffer<T>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *buf;
|
uint8_t* buf;
|
||||||
uoffset_t len;
|
uoffset_t len;
|
||||||
bool must_free;
|
bool must_free;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -45,13 +45,13 @@ class CodeGenerator {
|
|||||||
// Generate code from the provided `parser`.
|
// Generate code from the provided `parser`.
|
||||||
//
|
//
|
||||||
// DEPRECATED: prefer using the other overload of GenerateCode for bfbs.
|
// DEPRECATED: prefer using the other overload of GenerateCode for bfbs.
|
||||||
virtual Status GenerateCode(const Parser &parser, const std::string &path,
|
virtual Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) = 0;
|
const std::string& filename) = 0;
|
||||||
|
|
||||||
// Generate code from the provided `parser` and place it in the output.
|
// Generate code from the provided `parser` and place it in the output.
|
||||||
virtual Status GenerateCodeString(const Parser &parser,
|
virtual Status GenerateCodeString(const Parser& parser,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) {
|
std::string& output) {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
(void)output;
|
(void)output;
|
||||||
@@ -60,18 +60,18 @@ class CodeGenerator {
|
|||||||
|
|
||||||
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
||||||
// serialized reflection.fbs.
|
// serialized reflection.fbs.
|
||||||
virtual Status GenerateCode(const uint8_t *buffer, int64_t length,
|
virtual Status GenerateCode(const uint8_t* buffer, int64_t length,
|
||||||
const CodeGenOptions &options) = 0;
|
const CodeGenOptions& options) = 0;
|
||||||
|
|
||||||
virtual Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
virtual Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) = 0;
|
std::string& output) = 0;
|
||||||
|
|
||||||
virtual Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
virtual Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) = 0;
|
const std::string& filename) = 0;
|
||||||
|
|
||||||
virtual Status GenerateRootFile(const Parser &parser,
|
virtual Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) = 0;
|
const std::string& path) = 0;
|
||||||
|
|
||||||
virtual bool IsSchemaOnly() const = 0;
|
virtual bool IsSchemaOnly() const = 0;
|
||||||
|
|
||||||
@@ -88,8 +88,8 @@ class CodeGenerator {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// Copying is not supported.
|
// Copying is not supported.
|
||||||
CodeGenerator(const CodeGenerator &) = delete;
|
CodeGenerator(const CodeGenerator&) = delete;
|
||||||
CodeGenerator &operator=(const CodeGenerator &) = delete;
|
CodeGenerator& operator=(const CodeGenerator&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -51,11 +51,11 @@ class CodeWriter {
|
|||||||
// Associates a key with a value. All subsequent calls to operator+=, where
|
// Associates a key with a value. All subsequent calls to operator+=, where
|
||||||
// the specified key is contained in {{ and }} delimiters will be replaced by
|
// the specified key is contained in {{ and }} delimiters will be replaced by
|
||||||
// the given value.
|
// the given value.
|
||||||
void SetValue(const std::string &key, const std::string &value) {
|
void SetValue(const std::string& key, const std::string& value) {
|
||||||
value_map_[key] = value;
|
value_map_[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetValue(const std::string &key) const {
|
std::string GetValue(const std::string& key) const {
|
||||||
const auto it = value_map_.find(key);
|
const auto it = value_map_.find(key);
|
||||||
return it == value_map_.end() ? "" : it->second;
|
return it == value_map_.end() ? "" : it->second;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ class CodeWriter {
|
|||||||
if (cur_ident_lvl_) cur_ident_lvl_--;
|
if (cur_ident_lvl_) cur_ident_lvl_--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetPadding(const std::string &padding) { pad_ = padding; }
|
void SetPadding(const std::string& padding) { pad_ = padding; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> value_map_;
|
std::map<std::string, std::string> value_map_;
|
||||||
@@ -86,24 +86,24 @@ class CodeWriter {
|
|||||||
bool ignore_ident_;
|
bool ignore_ident_;
|
||||||
|
|
||||||
// Add ident padding (tab or space) based on ident level
|
// Add ident padding (tab or space) based on ident level
|
||||||
void AppendIdent(std::stringstream &stream);
|
void AppendIdent(std::stringstream& stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BaseGenerator {
|
class BaseGenerator {
|
||||||
public:
|
public:
|
||||||
virtual bool generate() = 0;
|
virtual bool generate() = 0;
|
||||||
|
|
||||||
static std::string NamespaceDir(const Parser &parser, const std::string &path,
|
static std::string NamespaceDir(const Parser& parser, const std::string& path,
|
||||||
const Namespace &ns,
|
const Namespace& ns,
|
||||||
const bool dasherize = false);
|
const bool dasherize = false);
|
||||||
|
|
||||||
std::string GeneratedFileName(const std::string &path,
|
std::string GeneratedFileName(const std::string& path,
|
||||||
const std::string &file_name,
|
const std::string& file_name,
|
||||||
const IDLOptions &options) const;
|
const IDLOptions& options) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseGenerator(const Parser &parser, const std::string &path,
|
BaseGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name, std::string qualifying_start,
|
const std::string& file_name, std::string qualifying_start,
|
||||||
std::string qualifying_separator, std::string default_extension)
|
std::string qualifying_separator, std::string default_extension)
|
||||||
: parser_(parser),
|
: parser_(parser),
|
||||||
path_(path),
|
path_(path),
|
||||||
@@ -114,84 +114,84 @@ class BaseGenerator {
|
|||||||
virtual ~BaseGenerator() {}
|
virtual ~BaseGenerator() {}
|
||||||
|
|
||||||
// No copy/assign.
|
// No copy/assign.
|
||||||
BaseGenerator &operator=(const BaseGenerator &);
|
BaseGenerator& operator=(const BaseGenerator&);
|
||||||
BaseGenerator(const BaseGenerator &);
|
BaseGenerator(const BaseGenerator&);
|
||||||
|
|
||||||
std::string NamespaceDir(const Namespace &ns,
|
std::string NamespaceDir(const Namespace& ns,
|
||||||
const bool dasherize = false) const;
|
const bool dasherize = false) const;
|
||||||
|
|
||||||
static const char *FlatBuffersGeneratedWarning();
|
static const char* FlatBuffersGeneratedWarning();
|
||||||
|
|
||||||
static std::string FullNamespace(const char *separator, const Namespace &ns);
|
static std::string FullNamespace(const char* separator, const Namespace& ns);
|
||||||
|
|
||||||
static std::string LastNamespacePart(const Namespace &ns);
|
static std::string LastNamespacePart(const Namespace& ns);
|
||||||
|
|
||||||
// tracks the current namespace for early exit in WrapInNameSpace
|
// tracks the current namespace for early exit in WrapInNameSpace
|
||||||
// c++, java and csharp returns a different namespace from
|
// c++, java and csharp returns a different namespace from
|
||||||
// the following default (no early exit, always fully qualify),
|
// the following default (no early exit, always fully qualify),
|
||||||
// which works for js and php
|
// which works for js and php
|
||||||
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
|
virtual const Namespace* CurrentNameSpace() const { return nullptr; }
|
||||||
|
|
||||||
// Ensure that a type is prefixed with its namespace even within
|
// Ensure that a type is prefixed with its namespace even within
|
||||||
// its own namespace to avoid conflict between generated method
|
// its own namespace to avoid conflict between generated method
|
||||||
// names and similarly named classes or structs
|
// names and similarly named classes or structs
|
||||||
std::string WrapInNameSpace(const Namespace *ns,
|
std::string WrapInNameSpace(const Namespace* ns,
|
||||||
const std::string &name) const;
|
const std::string& name) const;
|
||||||
|
|
||||||
std::string WrapInNameSpace(const Definition &def,
|
std::string WrapInNameSpace(const Definition& def,
|
||||||
const std::string &suffix = "") const;
|
const std::string& suffix = "") const;
|
||||||
|
|
||||||
std::string GetNameSpace(const Definition &def) const;
|
std::string GetNameSpace(const Definition& def) const;
|
||||||
|
|
||||||
const Parser &parser_;
|
const Parser& parser_;
|
||||||
const std::string &path_;
|
const std::string& path_;
|
||||||
const std::string &file_name_;
|
const std::string& file_name_;
|
||||||
const std::string qualifying_start_;
|
const std::string qualifying_start_;
|
||||||
const std::string qualifying_separator_;
|
const std::string qualifying_separator_;
|
||||||
const std::string default_extension_;
|
const std::string default_extension_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommentConfig {
|
struct CommentConfig {
|
||||||
const char *first_line;
|
const char* first_line;
|
||||||
const char *content_line_prefix;
|
const char* content_line_prefix;
|
||||||
const char *last_line;
|
const char* last_line;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern void GenComment(const std::vector<std::string> &dc,
|
extern void GenComment(const std::vector<std::string>& dc,
|
||||||
std::string *code_ptr, const CommentConfig *config,
|
std::string* code_ptr, const CommentConfig* config,
|
||||||
const char *prefix = "");
|
const char* prefix = "");
|
||||||
|
|
||||||
class FloatConstantGenerator {
|
class FloatConstantGenerator {
|
||||||
public:
|
public:
|
||||||
virtual ~FloatConstantGenerator() {}
|
virtual ~FloatConstantGenerator() {}
|
||||||
std::string GenFloatConstant(const FieldDef &field) const;
|
std::string GenFloatConstant(const FieldDef& field) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual std::string Value(double v, const std::string &src) const = 0;
|
virtual std::string Value(double v, const std::string& src) const = 0;
|
||||||
virtual std::string Inf(double v) const = 0;
|
virtual std::string Inf(double v) const = 0;
|
||||||
virtual std::string NaN(double v) const = 0;
|
virtual std::string NaN(double v) const = 0;
|
||||||
|
|
||||||
virtual std::string Value(float v, const std::string &src) const = 0;
|
virtual std::string Value(float v, const std::string& src) const = 0;
|
||||||
virtual std::string Inf(float v) const = 0;
|
virtual std::string Inf(float v) const = 0;
|
||||||
virtual std::string NaN(float v) const = 0;
|
virtual std::string NaN(float v) const = 0;
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
std::string GenFloatConstantImpl(const FieldDef &field) const;
|
std::string GenFloatConstantImpl(const FieldDef& field) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SimpleFloatConstantGenerator : public FloatConstantGenerator {
|
class SimpleFloatConstantGenerator : public FloatConstantGenerator {
|
||||||
public:
|
public:
|
||||||
SimpleFloatConstantGenerator(const char *nan_number,
|
SimpleFloatConstantGenerator(const char* nan_number,
|
||||||
const char *pos_inf_number,
|
const char* pos_inf_number,
|
||||||
const char *neg_inf_number);
|
const char* neg_inf_number);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Value(double v,
|
std::string Value(double v,
|
||||||
const std::string &src) const FLATBUFFERS_OVERRIDE;
|
const std::string& src) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
|
std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
|
std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
|
||||||
|
|
||||||
std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
|
std::string Value(float v, const std::string& src) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
|
std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
|
std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
|
||||||
|
|
||||||
@@ -203,24 +203,24 @@ class SimpleFloatConstantGenerator : public FloatConstantGenerator {
|
|||||||
// C++, C#, Java like generator.
|
// C++, C#, Java like generator.
|
||||||
class TypedFloatConstantGenerator : public FloatConstantGenerator {
|
class TypedFloatConstantGenerator : public FloatConstantGenerator {
|
||||||
public:
|
public:
|
||||||
TypedFloatConstantGenerator(const char *double_prefix,
|
TypedFloatConstantGenerator(const char* double_prefix,
|
||||||
const char *single_prefix, const char *nan_number,
|
const char* single_prefix, const char* nan_number,
|
||||||
const char *pos_inf_number,
|
const char* pos_inf_number,
|
||||||
const char *neg_inf_number = "");
|
const char* neg_inf_number = "");
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Value(double v,
|
std::string Value(double v,
|
||||||
const std::string &src) const FLATBUFFERS_OVERRIDE;
|
const std::string& src) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
|
std::string Inf(double v) const FLATBUFFERS_OVERRIDE;
|
||||||
|
|
||||||
std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
|
std::string NaN(double v) const FLATBUFFERS_OVERRIDE;
|
||||||
|
|
||||||
std::string Value(float v, const std::string &src) const FLATBUFFERS_OVERRIDE;
|
std::string Value(float v, const std::string& src) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
|
std::string Inf(float v) const FLATBUFFERS_OVERRIDE;
|
||||||
std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
|
std::string NaN(float v) const FLATBUFFERS_OVERRIDE;
|
||||||
|
|
||||||
std::string MakeNaN(const std::string &prefix) const;
|
std::string MakeNaN(const std::string& prefix) const;
|
||||||
std::string MakeInf(bool neg, const std::string &prefix) const;
|
std::string MakeInf(bool neg, const std::string& prefix) const;
|
||||||
|
|
||||||
const std::string double_prefix_;
|
const std::string double_prefix_;
|
||||||
const std::string single_prefix_;
|
const std::string single_prefix_;
|
||||||
@@ -229,9 +229,9 @@ class TypedFloatConstantGenerator : public FloatConstantGenerator {
|
|||||||
const std::string neg_inf_number_;
|
const std::string neg_inf_number_;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::string JavaCSharpMakeRule(const bool java, const Parser &parser,
|
std::string JavaCSharpMakeRule(const bool java, const Parser& parser,
|
||||||
const std::string &path,
|
const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
|||||||
@@ -25,32 +25,32 @@ namespace flatbuffers {
|
|||||||
// DefaultAllocator uses new/delete to allocate memory regions
|
// DefaultAllocator uses new/delete to allocate memory regions
|
||||||
class DefaultAllocator : public Allocator {
|
class DefaultAllocator : public Allocator {
|
||||||
public:
|
public:
|
||||||
uint8_t *allocate(size_t size) FLATBUFFERS_OVERRIDE {
|
uint8_t* allocate(size_t size) FLATBUFFERS_OVERRIDE {
|
||||||
return new uint8_t[size];
|
return new uint8_t[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
|
void deallocate(uint8_t* p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
|
||||||
|
|
||||||
static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
|
static void dealloc(void* p, size_t) { delete[] static_cast<uint8_t*>(p); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// These functions allow for a null allocator to mean use the default allocator,
|
// These functions allow for a null allocator to mean use the default allocator,
|
||||||
// as used by DetachedBuffer and vector_downward below.
|
// as used by DetachedBuffer and vector_downward below.
|
||||||
// This is to avoid having a statically or dynamically allocated default
|
// This is to avoid having a statically or dynamically allocated default
|
||||||
// allocator, or having to move it between the classes that may own it.
|
// allocator, or having to move it between the classes that may own it.
|
||||||
inline uint8_t *Allocate(Allocator *allocator, size_t size) {
|
inline uint8_t* Allocate(Allocator* allocator, size_t size) {
|
||||||
return allocator ? allocator->allocate(size)
|
return allocator ? allocator->allocate(size)
|
||||||
: DefaultAllocator().allocate(size);
|
: DefaultAllocator().allocate(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
|
inline void Deallocate(Allocator* allocator, uint8_t* p, size_t size) {
|
||||||
if (allocator)
|
if (allocator)
|
||||||
allocator->deallocate(p, size);
|
allocator->deallocate(p, size);
|
||||||
else
|
else
|
||||||
DefaultAllocator().deallocate(p, size);
|
DefaultAllocator().deallocate(p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
|
inline uint8_t* ReallocateDownward(Allocator* allocator, uint8_t* old_p,
|
||||||
size_t old_size, size_t new_size,
|
size_t old_size, size_t new_size,
|
||||||
size_t in_use_back, size_t in_use_front) {
|
size_t in_use_back, size_t in_use_front) {
|
||||||
return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
|
return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ class DetachedBuffer {
|
|||||||
cur_(nullptr),
|
cur_(nullptr),
|
||||||
size_(0) {}
|
size_(0) {}
|
||||||
|
|
||||||
DetachedBuffer(Allocator *allocator, bool own_allocator, uint8_t *buf,
|
DetachedBuffer(Allocator* allocator, bool own_allocator, uint8_t* buf,
|
||||||
size_t reserved, uint8_t *cur, size_t sz)
|
size_t reserved, uint8_t* cur, size_t sz)
|
||||||
: allocator_(allocator),
|
: allocator_(allocator),
|
||||||
own_allocator_(own_allocator),
|
own_allocator_(own_allocator),
|
||||||
buf_(buf),
|
buf_(buf),
|
||||||
@@ -45,7 +45,7 @@ class DetachedBuffer {
|
|||||||
cur_(cur),
|
cur_(cur),
|
||||||
size_(sz) {}
|
size_(sz) {}
|
||||||
|
|
||||||
DetachedBuffer(DetachedBuffer &&other) noexcept
|
DetachedBuffer(DetachedBuffer&& other) noexcept
|
||||||
: allocator_(other.allocator_),
|
: allocator_(other.allocator_),
|
||||||
own_allocator_(other.own_allocator_),
|
own_allocator_(other.own_allocator_),
|
||||||
buf_(other.buf_),
|
buf_(other.buf_),
|
||||||
@@ -55,7 +55,7 @@ class DetachedBuffer {
|
|||||||
other.reset();
|
other.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedBuffer &operator=(DetachedBuffer &&other) noexcept {
|
DetachedBuffer& operator=(DetachedBuffer&& other) noexcept {
|
||||||
if (this == &other) return *this;
|
if (this == &other) return *this;
|
||||||
|
|
||||||
destroy();
|
destroy();
|
||||||
@@ -74,33 +74,35 @@ class DetachedBuffer {
|
|||||||
|
|
||||||
~DetachedBuffer() { destroy(); }
|
~DetachedBuffer() { destroy(); }
|
||||||
|
|
||||||
const uint8_t *data() const { return cur_; }
|
const uint8_t* data() const { return cur_; }
|
||||||
|
|
||||||
uint8_t *data() { return cur_; }
|
uint8_t* data() { return cur_; }
|
||||||
|
|
||||||
size_t size() const { return size_; }
|
size_t size() const { return size_; }
|
||||||
|
|
||||||
uint8_t *begin() { return data(); }
|
uint8_t* begin() { return data(); }
|
||||||
const uint8_t *begin() const { return data(); }
|
const uint8_t* begin() const { return data(); }
|
||||||
uint8_t *end() { return data() + size(); }
|
uint8_t* end() { return data() + size(); }
|
||||||
const uint8_t *end() const { return data() + size(); }
|
const uint8_t* end() const { return data() + size(); }
|
||||||
|
|
||||||
// These may change access mode, leave these at end of public section
|
// These may change access mode, leave these at end of public section
|
||||||
FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer &other));
|
FLATBUFFERS_DELETE_FUNC(DetachedBuffer(const DetachedBuffer& other));
|
||||||
FLATBUFFERS_DELETE_FUNC(
|
FLATBUFFERS_DELETE_FUNC(
|
||||||
DetachedBuffer &operator=(const DetachedBuffer &other));
|
DetachedBuffer& operator=(const DetachedBuffer& other));
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Allocator *allocator_;
|
Allocator* allocator_;
|
||||||
bool own_allocator_;
|
bool own_allocator_;
|
||||||
uint8_t *buf_;
|
uint8_t* buf_;
|
||||||
size_t reserved_;
|
size_t reserved_;
|
||||||
uint8_t *cur_;
|
uint8_t* cur_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
|
|
||||||
inline void destroy() {
|
inline void destroy() {
|
||||||
if (buf_) Deallocate(allocator_, buf_, reserved_);
|
if (buf_) Deallocate(allocator_, buf_, reserved_);
|
||||||
if (own_allocator_ && allocator_) { delete allocator_; }
|
if (own_allocator_ && allocator_) {
|
||||||
|
delete allocator_;
|
||||||
|
}
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,16 +31,16 @@ class FileManager {
|
|||||||
FileManager() = default;
|
FileManager() = default;
|
||||||
virtual ~FileManager() = default;
|
virtual ~FileManager() = default;
|
||||||
|
|
||||||
virtual bool SaveFile(const std::string &absolute_file_name,
|
virtual bool SaveFile(const std::string& absolute_file_name,
|
||||||
const std::string &content) = 0;
|
const std::string& content) = 0;
|
||||||
|
|
||||||
virtual bool LoadFile(const std::string &absolute_file_name,
|
virtual bool LoadFile(const std::string& absolute_file_name,
|
||||||
std::string *buf) = 0;
|
std::string* buf) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Copying is not supported.
|
// Copying is not supported.
|
||||||
FileManager(const FileManager &) = delete;
|
FileManager(const FileManager&) = delete;
|
||||||
FileManager &operator=(const FileManager &) = delete;
|
FileManager& operator=(const FileManager&) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -50,19 +50,19 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
|
|||||||
return static_cast<voffset_t>(offset);
|
return static_cast<voffset_t>(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename Alloc = std::allocator<T>>
|
template <typename T, typename Alloc = std::allocator<T>>
|
||||||
const T *data(const std::vector<T, Alloc> &v) {
|
const T* data(const std::vector<T, Alloc>& v) {
|
||||||
// Eventually the returned pointer gets passed down to memcpy, so
|
// Eventually the returned pointer gets passed down to memcpy, so
|
||||||
// we need it to be non-null to avoid undefined behavior.
|
// we need it to be non-null to avoid undefined behavior.
|
||||||
static uint8_t t;
|
static uint8_t t;
|
||||||
return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
|
return v.empty() ? reinterpret_cast<const T*>(&t) : &v.front();
|
||||||
}
|
}
|
||||||
template<typename T, typename Alloc = std::allocator<T>>
|
template <typename T, typename Alloc = std::allocator<T>>
|
||||||
T *data(std::vector<T, Alloc> &v) {
|
T* data(std::vector<T, Alloc>& v) {
|
||||||
// Eventually the returned pointer gets passed down to memcpy, so
|
// Eventually the returned pointer gets passed down to memcpy, so
|
||||||
// we need it to be non-null to avoid undefined behavior.
|
// we need it to be non-null to avoid undefined behavior.
|
||||||
static uint8_t t;
|
static uint8_t t;
|
||||||
return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
|
return v.empty() ? reinterpret_cast<T*>(&t) : &v.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @addtogroup flatbuffers_cpp_api
|
/// @addtogroup flatbuffers_cpp_api
|
||||||
@@ -74,7 +74,8 @@ T *data(std::vector<T, Alloc> &v) {
|
|||||||
/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
|
/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
|
||||||
/// `CreateVector` functions. Do this is depth-first order to build up a tree to
|
/// `CreateVector` functions. Do this is depth-first order to build up a tree to
|
||||||
/// the root. `Finish()` wraps up the buffer ready for transport.
|
/// the root. `Finish()` wraps up the buffer ready for transport.
|
||||||
template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
template <bool Is64Aware = false>
|
||||||
|
class FlatBufferBuilderImpl {
|
||||||
public:
|
public:
|
||||||
// This switches the size type of the builder, based on if its 64-bit aware
|
// This switches the size type of the builder, based on if its 64-bit aware
|
||||||
// (uoffset64_t) or not (uoffset_t).
|
// (uoffset64_t) or not (uoffset_t).
|
||||||
@@ -93,7 +94,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// types with custom alignment AND you wish to read the buffer in-place
|
/// types with custom alignment AND you wish to read the buffer in-place
|
||||||
/// directly after creation.
|
/// directly after creation.
|
||||||
explicit FlatBufferBuilderImpl(
|
explicit FlatBufferBuilderImpl(
|
||||||
size_t initial_size = 1024, Allocator *allocator = nullptr,
|
size_t initial_size = 1024, Allocator* allocator = nullptr,
|
||||||
bool own_allocator = false,
|
bool own_allocator = false,
|
||||||
size_t buffer_minalign = AlignOf<largest_scalar_t>())
|
size_t buffer_minalign = AlignOf<largest_scalar_t>())
|
||||||
: buf_(initial_size, allocator, own_allocator, buffer_minalign,
|
: buf_(initial_size, allocator, own_allocator, buffer_minalign,
|
||||||
@@ -112,7 +113,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Move constructor for FlatBufferBuilder.
|
/// @brief Move constructor for FlatBufferBuilder.
|
||||||
FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept
|
FlatBufferBuilderImpl(FlatBufferBuilderImpl&& other) noexcept
|
||||||
: buf_(1024, nullptr, false, AlignOf<largest_scalar_t>(),
|
: buf_(1024, nullptr, false, AlignOf<largest_scalar_t>(),
|
||||||
static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
|
static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
|
||||||
: FLATBUFFERS_MAX_BUFFER_SIZE)),
|
: FLATBUFFERS_MAX_BUFFER_SIZE)),
|
||||||
@@ -133,14 +134,14 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Move assignment operator for FlatBufferBuilder.
|
/// @brief Move assignment operator for FlatBufferBuilder.
|
||||||
FlatBufferBuilderImpl &operator=(FlatBufferBuilderImpl &&other) noexcept {
|
FlatBufferBuilderImpl& operator=(FlatBufferBuilderImpl&& other) noexcept {
|
||||||
// Move construct a temporary and swap idiom
|
// Move construct a temporary and swap idiom
|
||||||
FlatBufferBuilderImpl temp(std::move(other));
|
FlatBufferBuilderImpl temp(std::move(other));
|
||||||
Swap(temp);
|
Swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swap(FlatBufferBuilderImpl &other) {
|
void Swap(FlatBufferBuilderImpl& other) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
buf_.swap(other.buf_);
|
buf_.swap(other.buf_);
|
||||||
swap(num_field_loc, other.num_field_loc);
|
swap(num_field_loc, other.num_field_loc);
|
||||||
@@ -182,7 +183,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @brief The current size of the serialized buffer relative to the end of
|
/// @brief The current size of the serialized buffer relative to the end of
|
||||||
/// the 32-bit region.
|
/// the 32-bit region.
|
||||||
/// @return Returns an `uoffset_t` with the current size of the buffer.
|
/// @return Returns an `uoffset_t` with the current size of the buffer.
|
||||||
template<bool is_64 = Is64Aware>
|
template <bool is_64 = Is64Aware>
|
||||||
// Only enable this method for the 64-bit builder, as only that builder is
|
// Only enable this method for the 64-bit builder, as only that builder is
|
||||||
// concerned with the 32/64-bit boundary, and should be the one to bare any
|
// concerned with the 32/64-bit boundary, and should be the one to bare any
|
||||||
// run time costs.
|
// run time costs.
|
||||||
@@ -195,7 +196,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
return static_cast<uoffset_t>(GetSize() - length_of_64_bit_region_);
|
return static_cast<uoffset_t>(GetSize() - length_of_64_bit_region_);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool is_64 = Is64Aware>
|
template <bool is_64 = Is64Aware>
|
||||||
// Only enable this method for the 32-bit builder.
|
// Only enable this method for the 32-bit builder.
|
||||||
typename std::enable_if<!is_64, uoffset_t>::type GetSizeRelative32BitRegion()
|
typename std::enable_if<!is_64, uoffset_t>::type GetSizeRelative32BitRegion()
|
||||||
const {
|
const {
|
||||||
@@ -205,7 +206,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @brief Get the serialized buffer (after you call `Finish()`).
|
/// @brief Get the serialized buffer (after you call `Finish()`).
|
||||||
/// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the
|
/// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the
|
||||||
/// buffer.
|
/// buffer.
|
||||||
uint8_t *GetBufferPointer() const {
|
uint8_t* GetBufferPointer() const {
|
||||||
Finished();
|
Finished();
|
||||||
return buf_.data();
|
return buf_.data();
|
||||||
}
|
}
|
||||||
@@ -220,7 +221,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
/// @brief Get a pointer to an unfinished buffer.
|
/// @brief Get a pointer to an unfinished buffer.
|
||||||
/// @return Returns a `uint8_t` pointer to the unfinished buffer.
|
/// @return Returns a `uint8_t` pointer to the unfinished buffer.
|
||||||
uint8_t *GetCurrentBufferPointer() const { return buf_.data(); }
|
uint8_t* GetCurrentBufferPointer() const { return buf_.data(); }
|
||||||
|
|
||||||
/// @brief Get the released DetachedBuffer.
|
/// @brief Get the released DetachedBuffer.
|
||||||
/// @return A `DetachedBuffer` that owns the buffer and its allocator.
|
/// @return A `DetachedBuffer` that owns the buffer and its allocator.
|
||||||
@@ -240,9 +241,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// the serialized `FlatBuffer`.
|
/// the serialized `FlatBuffer`.
|
||||||
/// @remark If the allocator is owned, it gets deleted when the destructor is
|
/// @remark If the allocator is owned, it gets deleted when the destructor is
|
||||||
/// called.
|
/// called.
|
||||||
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
|
uint8_t* ReleaseRaw(size_t& size, size_t& offset) {
|
||||||
Finished();
|
Finished();
|
||||||
uint8_t *raw = buf_.release_raw(size, offset);
|
uint8_t* raw = buf_.release_raw(size, offset);
|
||||||
Clear();
|
Clear();
|
||||||
return raw;
|
return raw;
|
||||||
}
|
}
|
||||||
@@ -291,22 +292,23 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
buf_.fill(PaddingBytes(buf_.size(), elem_size));
|
buf_.fill(PaddingBytes(buf_.size(), elem_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushFlatBuffer(const uint8_t *bytes, size_t size) {
|
void PushFlatBuffer(const uint8_t* bytes, size_t size) {
|
||||||
PushBytes(bytes, size);
|
PushBytes(bytes, size);
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PushBytes(const uint8_t *bytes, size_t size) { buf_.push(bytes, size); }
|
void PushBytes(const uint8_t* bytes, size_t size) { buf_.push(bytes, size); }
|
||||||
|
|
||||||
void PopBytes(size_t amount) { buf_.pop(amount); }
|
void PopBytes(size_t amount) { buf_.pop(amount); }
|
||||||
|
|
||||||
template<typename T> void AssertScalarT() {
|
template <typename T>
|
||||||
|
void AssertScalarT() {
|
||||||
// The code assumes power of 2 sizes and endian-swap-ability.
|
// The code assumes power of 2 sizes and endian-swap-ability.
|
||||||
static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
|
static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a single aligned scalar to the buffer
|
// Write a single aligned scalar to the buffer
|
||||||
template<typename T, typename ReturnT = uoffset_t>
|
template <typename T, typename ReturnT = uoffset_t>
|
||||||
ReturnT PushElement(T element) {
|
ReturnT PushElement(T element) {
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
Align(sizeof(T));
|
Align(sizeof(T));
|
||||||
@@ -314,7 +316,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
return CalculateOffset<ReturnT>();
|
return CalculateOffset<ReturnT>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, template<typename> class OffsetT = Offset>
|
template <typename T, template <typename> class OffsetT = Offset>
|
||||||
uoffset_t PushElement(OffsetT<T> off) {
|
uoffset_t PushElement(OffsetT<T> off) {
|
||||||
// Special case for offsets: see ReferTo below.
|
// Special case for offsets: see ReferTo below.
|
||||||
return PushElement(ReferTo(off.o));
|
return PushElement(ReferTo(off.o));
|
||||||
@@ -323,34 +325,41 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
// When writing fields, we track where they are, so we can create correct
|
// When writing fields, we track where they are, so we can create correct
|
||||||
// vtables later.
|
// vtables later.
|
||||||
void TrackField(voffset_t field, uoffset_t off) {
|
void TrackField(voffset_t field, uoffset_t off) {
|
||||||
FieldLoc fl = { off, field };
|
FieldLoc fl = {off, field};
|
||||||
buf_.scratch_push_small(fl);
|
buf_.scratch_push_small(fl);
|
||||||
num_field_loc++;
|
num_field_loc++;
|
||||||
if (field > max_voffset_) { max_voffset_ = field; }
|
if (field > max_voffset_) {
|
||||||
|
max_voffset_ = field;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like PushElement, but additionally tracks the field this represents.
|
// Like PushElement, but additionally tracks the field this represents.
|
||||||
template<typename T> void AddElement(voffset_t field, T e, T def) {
|
template <typename T>
|
||||||
|
void AddElement(voffset_t field, T e, T def) {
|
||||||
// We don't serialize values equal to the default.
|
// We don't serialize values equal to the default.
|
||||||
if (IsTheSameAs(e, def) && !force_defaults_) return;
|
if (IsTheSameAs(e, def) && !force_defaults_) return;
|
||||||
TrackField(field, PushElement(e));
|
TrackField(field, PushElement(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void AddElement(voffset_t field, T e) {
|
template <typename T>
|
||||||
|
void AddElement(voffset_t field, T e) {
|
||||||
TrackField(field, PushElement(e));
|
TrackField(field, PushElement(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void AddOffset(voffset_t field, Offset<T> off) {
|
template <typename T>
|
||||||
|
void AddOffset(voffset_t field, Offset<T> off) {
|
||||||
if (off.IsNull()) return; // Don't store.
|
if (off.IsNull()) return; // Don't store.
|
||||||
AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
|
AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void AddOffset(voffset_t field, Offset64<T> off) {
|
template <typename T>
|
||||||
|
void AddOffset(voffset_t field, Offset64<T> off) {
|
||||||
if (off.IsNull()) return; // Don't store.
|
if (off.IsNull()) return; // Don't store.
|
||||||
AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0));
|
AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void AddStruct(voffset_t field, const T *structptr) {
|
template <typename T>
|
||||||
|
void AddStruct(voffset_t field, const T* structptr) {
|
||||||
if (!structptr) return; // Default, don't store.
|
if (!structptr) return; // Default, don't store.
|
||||||
Align(AlignOf<T>());
|
Align(AlignOf<T>());
|
||||||
buf_.push_small(*structptr);
|
buf_.push_small(*structptr);
|
||||||
@@ -380,12 +389,14 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
return ReferTo(off, GetSize());
|
return ReferTo(off, GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename T2> T ReferTo(const T off, const T2 size) {
|
template <typename T, typename T2>
|
||||||
|
T ReferTo(const T off, const T2 size) {
|
||||||
FLATBUFFERS_ASSERT(off && off <= size);
|
FLATBUFFERS_ASSERT(off && off <= size);
|
||||||
return size - off + static_cast<T>(sizeof(T));
|
return size - off + static_cast<T>(sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> T ReferTo(const T off, const T size) {
|
template <typename T>
|
||||||
|
T ReferTo(const T off, const T size) {
|
||||||
FLATBUFFERS_ASSERT(off && off <= size);
|
FLATBUFFERS_ASSERT(off && off <= size);
|
||||||
return size - off + static_cast<T>(sizeof(T));
|
return size - off + static_cast<T>(sizeof(T));
|
||||||
}
|
}
|
||||||
@@ -441,7 +452,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
// Write the offsets into the table
|
// Write the offsets into the table
|
||||||
for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
|
for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
|
||||||
it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
|
it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
|
||||||
auto field_location = reinterpret_cast<FieldLoc *>(it);
|
auto field_location = reinterpret_cast<FieldLoc*>(it);
|
||||||
const voffset_t pos =
|
const voffset_t pos =
|
||||||
static_cast<voffset_t>(vtable_offset_loc - field_location->off);
|
static_cast<voffset_t>(vtable_offset_loc - field_location->off);
|
||||||
// If this asserts, it means you've set a field twice.
|
// If this asserts, it means you've set a field twice.
|
||||||
@@ -450,7 +461,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
|
WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
|
||||||
}
|
}
|
||||||
ClearOffsets();
|
ClearOffsets();
|
||||||
auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
|
auto vt1 = reinterpret_cast<voffset_t*>(buf_.data());
|
||||||
auto vt1_size = ReadScalar<voffset_t>(vt1);
|
auto vt1_size = ReadScalar<voffset_t>(vt1);
|
||||||
auto vt_use = GetSizeRelative32BitRegion();
|
auto vt_use = GetSizeRelative32BitRegion();
|
||||||
// See if we already have generated a vtable with this exact same
|
// See if we already have generated a vtable with this exact same
|
||||||
@@ -458,8 +469,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
if (dedup_vtables_) {
|
if (dedup_vtables_) {
|
||||||
for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
|
for (auto it = buf_.scratch_data(); it < buf_.scratch_end();
|
||||||
it += sizeof(uoffset_t)) {
|
it += sizeof(uoffset_t)) {
|
||||||
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
|
auto vt_offset_ptr = reinterpret_cast<uoffset_t*>(it);
|
||||||
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
|
auto vt2 = reinterpret_cast<voffset_t*>(buf_.data_at(*vt_offset_ptr));
|
||||||
auto vt2_size = ReadScalar<voffset_t>(vt2);
|
auto vt2_size = ReadScalar<voffset_t>(vt2);
|
||||||
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
|
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
|
||||||
vt_use = *vt_offset_ptr;
|
vt_use = *vt_offset_ptr;
|
||||||
@@ -490,8 +501,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
// This checks a required field has been set in a given table that has
|
// This checks a required field has been set in a given table that has
|
||||||
// just been constructed.
|
// just been constructed.
|
||||||
template<typename T> void Required(Offset<T> table, voffset_t field) {
|
template <typename T>
|
||||||
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
|
void Required(Offset<T> table, voffset_t field) {
|
||||||
|
auto table_ptr = reinterpret_cast<const Table*>(buf_.data_at(table.o));
|
||||||
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
|
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
|
||||||
// If this fails, the caller will show what field needs to be set.
|
// If this fails, the caller will show what field needs to be set.
|
||||||
FLATBUFFERS_ASSERT(ok);
|
FLATBUFFERS_ASSERT(ok);
|
||||||
@@ -521,7 +533,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
// Aligns such than when "len" bytes are written, an object of type `AlignT`
|
// Aligns such than when "len" bytes are written, an object of type `AlignT`
|
||||||
// can be written after it (forward in the buffer) without padding.
|
// can be written after it (forward in the buffer) without padding.
|
||||||
template<typename AlignT> void PreAlign(size_t len) {
|
template <typename AlignT>
|
||||||
|
void PreAlign(size_t len) {
|
||||||
AssertScalarT<AlignT>();
|
AssertScalarT<AlignT>();
|
||||||
PreAlign(len, AlignOf<AlignT>());
|
PreAlign(len, AlignOf<AlignT>());
|
||||||
}
|
}
|
||||||
@@ -531,8 +544,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] str A const char pointer to the data to be stored as a string.
|
/// @param[in] str A const char pointer to the data to be stored as a string.
|
||||||
/// @param[in] len The number of bytes that should be stored from `str`.
|
/// @param[in] len The number of bytes that should be stored from `str`.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
template<template<typename> class OffsetT = Offset>
|
template <template <typename> class OffsetT = Offset>
|
||||||
OffsetT<String> CreateString(const char *str, size_t len) {
|
OffsetT<String> CreateString(const char* str, size_t len) {
|
||||||
CreateStringImpl(str, len);
|
CreateStringImpl(str, len);
|
||||||
return OffsetT<String>(
|
return OffsetT<String>(
|
||||||
CalculateOffset<typename OffsetT<String>::offset_type>());
|
CalculateOffset<typename OffsetT<String>::offset_type>());
|
||||||
@@ -541,24 +554,24 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @brief Store a string in the buffer, which is null-terminated.
|
/// @brief Store a string in the buffer, which is null-terminated.
|
||||||
/// @param[in] str A const char pointer to a C-string to add to the buffer.
|
/// @param[in] str A const char pointer to a C-string to add to the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
template<template<typename> class OffsetT = Offset>
|
template <template <typename> class OffsetT = Offset>
|
||||||
OffsetT<String> CreateString(const char *str) {
|
OffsetT<String> CreateString(const char* str) {
|
||||||
return CreateString<OffsetT>(str, strlen(str));
|
return CreateString<OffsetT>(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Store a string in the buffer, which is null-terminated.
|
/// @brief Store a string in the buffer, which is null-terminated.
|
||||||
/// @param[in] str A char pointer to a C-string to add to the buffer.
|
/// @param[in] str A char pointer to a C-string to add to the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
template<template<typename> class OffsetT = Offset>
|
template <template <typename> class OffsetT = Offset>
|
||||||
OffsetT<String> CreateString(char *str) {
|
OffsetT<String> CreateString(char* str) {
|
||||||
return CreateString<OffsetT>(str, strlen(str));
|
return CreateString<OffsetT>(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||||
/// @param[in] str A const reference to a std::string to store in the buffer.
|
/// @param[in] str A const reference to a std::string to store in the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
template<template<typename> class OffsetT = Offset>
|
template <template <typename> class OffsetT = Offset>
|
||||||
OffsetT<String> CreateString(const std::string &str) {
|
OffsetT<String> CreateString(const std::string& str) {
|
||||||
return CreateString<OffsetT>(str.c_str(), str.length());
|
return CreateString<OffsetT>(str.c_str(), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -577,8 +590,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||||
/// @param[in] str A const pointer to a `String` struct to add to the buffer.
|
/// @param[in] str A const pointer to a `String` struct to add to the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts
|
/// @return Returns the offset in the buffer where the string starts
|
||||||
template<template<typename> class OffsetT = Offset>
|
template <template <typename> class OffsetT = Offset>
|
||||||
OffsetT<String> CreateString(const String *str) {
|
OffsetT<String> CreateString(const String* str) {
|
||||||
return str ? CreateString<OffsetT>(str->c_str(), str->size()) : 0;
|
return str ? CreateString<OffsetT>(str->c_str(), str->size()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -586,11 +599,11 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] str A const reference to a std::string like type with support
|
/// @param[in] str A const reference to a std::string like type with support
|
||||||
/// of T::data() and T::length() to store in the buffer.
|
/// of T::data() and T::length() to store in the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
template<template<typename> class OffsetT = Offset,
|
template <template <typename> class OffsetT = Offset,
|
||||||
// No need to explicitly declare the T type, let the compiler deduce
|
// No need to explicitly declare the T type, let the compiler deduce
|
||||||
// it.
|
// it.
|
||||||
int &...ExplicitArgumentBarrier, typename T>
|
int&... ExplicitArgumentBarrier, typename T>
|
||||||
OffsetT<String> CreateString(const T &str) {
|
OffsetT<String> CreateString(const T& str) {
|
||||||
return CreateString<OffsetT>(str.data(), str.length());
|
return CreateString<OffsetT>(str.data(), str.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -601,7 +614,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] str A const char pointer to the data to be stored as a string.
|
/// @param[in] str A const char pointer to the data to be stored as a string.
|
||||||
/// @param[in] len The number of bytes that should be stored from `str`.
|
/// @param[in] len The number of bytes that should be stored from `str`.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
Offset<String> CreateSharedString(const char *str, size_t len) {
|
Offset<String> CreateSharedString(const char* str, size_t len) {
|
||||||
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
||||||
if (!string_pool) {
|
if (!string_pool) {
|
||||||
string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
|
string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
|
||||||
@@ -640,7 +653,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// stored on the heap, but only stores the numerical offsets.
|
/// stored on the heap, but only stores the numerical offsets.
|
||||||
/// @param[in] str A const char pointer to a C-string to add to the buffer.
|
/// @param[in] str A const char pointer to a C-string to add to the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
Offset<String> CreateSharedString(const char *str) {
|
Offset<String> CreateSharedString(const char* str) {
|
||||||
return CreateSharedString(str, strlen(str));
|
return CreateSharedString(str, strlen(str));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -650,7 +663,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// stored on the heap, but only stores the numerical offsets.
|
/// stored on the heap, but only stores the numerical offsets.
|
||||||
/// @param[in] str A const reference to a std::string to store in the buffer.
|
/// @param[in] str A const reference to a std::string to store in the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
Offset<String> CreateSharedString(const std::string &str) {
|
Offset<String> CreateSharedString(const std::string& str) {
|
||||||
return CreateSharedString(str.c_str(), str.length());
|
return CreateSharedString(str.c_str(), str.length());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -661,19 +674,20 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// stored on the heap, but only stores the numerical offsets.
|
/// stored on the heap, but only stores the numerical offsets.
|
||||||
/// @param[in] str A const pointer to a `String` struct to add to the buffer.
|
/// @param[in] str A const pointer to a `String` struct to add to the buffer.
|
||||||
/// @return Returns the offset in the buffer where the string starts
|
/// @return Returns the offset in the buffer where the string starts
|
||||||
Offset<String> CreateSharedString(const String *str) {
|
Offset<String> CreateSharedString(const String* str) {
|
||||||
return str ? CreateSharedString(str->c_str(), str->size()) : 0;
|
return str ? CreateSharedString(str->c_str(), str->size()) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
template<typename LenT = uoffset_t, typename ReturnT = uoffset_t>
|
template <typename LenT = uoffset_t, typename ReturnT = uoffset_t>
|
||||||
ReturnT EndVector(size_t len) {
|
ReturnT EndVector(size_t len) {
|
||||||
FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector.
|
FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector.
|
||||||
nested = false;
|
nested = false;
|
||||||
return PushElement<LenT, ReturnT>(static_cast<LenT>(len));
|
return PushElement<LenT, ReturnT>(static_cast<LenT>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<template<typename> class OffsetT = Offset, typename LenT = uint32_t>
|
template <template <typename> class OffsetT = Offset,
|
||||||
|
typename LenT = uint32_t>
|
||||||
void StartVector(size_t len, size_t elemsize, size_t alignment) {
|
void StartVector(size_t len, size_t elemsize, size_t alignment) {
|
||||||
NotNested();
|
NotNested();
|
||||||
nested = true;
|
nested = true;
|
||||||
@@ -683,7 +697,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
PreAlign(len * elemsize, alignment); // Just in case elemsize > uoffset_t.
|
PreAlign(len * elemsize, alignment); // Just in case elemsize > uoffset_t.
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, template<typename> class OffsetT = Offset,
|
template <typename T, template <typename> class OffsetT = Offset,
|
||||||
typename LenT = uint32_t>
|
typename LenT = uint32_t>
|
||||||
void StartVector(size_t len) {
|
void StartVector(size_t len) {
|
||||||
return StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
|
return StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
|
||||||
@@ -701,7 +715,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
PreAlign(len * elemsize, alignment);
|
PreAlign(len * elemsize, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<bool is_64 = Is64Aware>
|
template <bool is_64 = Is64Aware>
|
||||||
typename std::enable_if<is_64, void>::type ForceVectorAlignment64(
|
typename std::enable_if<is_64, void>::type ForceVectorAlignment64(
|
||||||
const size_t len, const size_t elemsize, const size_t alignment) {
|
const size_t len, const size_t elemsize, const size_t alignment) {
|
||||||
// If you hit this assertion, you are trying to force alignment on a
|
// If you hit this assertion, you are trying to force alignment on a
|
||||||
@@ -733,9 +747,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] len The number of elements to serialize.
|
/// @param[in] len The number of elements to serialize.
|
||||||
/// @return Returns a typed `TOffset` into the serialized data indicating
|
/// @return Returns a typed `TOffset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, template<typename...> class OffsetT = Offset,
|
template <typename T, template <typename...> class OffsetT = Offset,
|
||||||
template<typename...> class VectorT = Vector>
|
template <typename...> class VectorT = Vector>
|
||||||
OffsetT<VectorT<T>> CreateVector(const T *v, size_t len) {
|
OffsetT<VectorT<T>> CreateVector(const T* v, size_t len) {
|
||||||
// The type of the length field in the vector.
|
// The type of the length field in the vector.
|
||||||
typedef typename VectorT<T>::size_type LenT;
|
typedef typename VectorT<T>::size_type LenT;
|
||||||
typedef typename OffsetT<VectorT<T>>::offset_type offset_type;
|
typedef typename OffsetT<VectorT<T>>::offset_type offset_type;
|
||||||
@@ -768,7 +782,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, class C> Offset<Vector<T>> CreateVector(const C &array) {
|
template <typename T, class C>
|
||||||
|
Offset<Vector<T>> CreateVector(const C& array) {
|
||||||
return CreateVector(array.data(), array.size());
|
return CreateVector(array.data(), array.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -777,15 +792,17 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] v The value of the initializer list.
|
/// @param[in] v The value of the initializer list.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<T>> CreateVector(std::initializer_list<T> v) {
|
Offset<Vector<T>> CreateVector(std::initializer_list<T> v) {
|
||||||
return CreateVector(v.begin(), v.size());
|
return CreateVector(v.begin(), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<Offset<T>>> CreateVector(const Offset<T> *v, size_t len) {
|
Offset<Vector<Offset<T>>> CreateVector(const Offset<T>* v, size_t len) {
|
||||||
StartVector<Offset<T>>(len);
|
StartVector<Offset<T>>(len);
|
||||||
for (auto i = len; i > 0;) { PushElement(v[--i]); }
|
for (auto i = len; i > 0;) {
|
||||||
|
PushElement(v[--i]);
|
||||||
|
}
|
||||||
return Offset<Vector<Offset<T>>>(EndVector(len));
|
return Offset<Vector<Offset<T>>>(EndVector(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -795,21 +812,21 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// buffer as a `vector`.
|
/// buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename Alloc = std::allocator<T>>
|
template <typename T, typename Alloc = std::allocator<T>>
|
||||||
Offset<Vector<T>> CreateVector(const std::vector<T, Alloc> &v) {
|
Offset<Vector<T>> CreateVector(const std::vector<T, Alloc>& v) {
|
||||||
return CreateVector(data(v), v.size());
|
return CreateVector(data(v), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<template<typename...> class VectorT = Vector64,
|
template <template <typename...> class VectorT = Vector64,
|
||||||
int &...ExplicitArgumentBarrier, typename T>
|
int&... ExplicitArgumentBarrier, typename T>
|
||||||
Offset64<VectorT<T>> CreateVector64(const std::vector<T> &v) {
|
Offset64<VectorT<T>> CreateVector64(const std::vector<T>& v) {
|
||||||
return CreateVector<T, Offset64, VectorT>(data(v), v.size());
|
return CreateVector<T, Offset64, VectorT>(data(v), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// vector<bool> may be implemented using a bit-set, so we can't access it as
|
// vector<bool> may be implemented using a bit-set, so we can't access it as
|
||||||
// an array. Instead, read elements manually.
|
// an array. Instead, read elements manually.
|
||||||
// Background: https://isocpp.org/blog/2012/11/on-vectorbool
|
// Background: https://isocpp.org/blog/2012/11/on-vectorbool
|
||||||
Offset<Vector<uint8_t>> CreateVector(const std::vector<bool> &v) {
|
Offset<Vector<uint8_t>> CreateVector(const std::vector<bool>& v) {
|
||||||
StartVector<uint8_t>(v.size());
|
StartVector<uint8_t>(v.size());
|
||||||
for (auto i = v.size(); i > 0;) {
|
for (auto i = v.size(); i > 0;) {
|
||||||
PushElement(static_cast<uint8_t>(v[--i]));
|
PushElement(static_cast<uint8_t>(v[--i]));
|
||||||
@@ -824,9 +841,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// returns any type that you can construct a FlatBuffers vector out of.
|
/// returns any type that you can construct a FlatBuffers vector out of.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<T>> CreateVector(size_t vector_size,
|
Offset<Vector<T>> CreateVector(size_t vector_size,
|
||||||
const std::function<T(size_t i)> &f) {
|
const std::function<T(size_t i)>& f) {
|
||||||
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
||||||
std::vector<T> elems(vector_size);
|
std::vector<T> elems(vector_size);
|
||||||
for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
|
for (size_t i = 0; i < vector_size; i++) elems[i] = f(i);
|
||||||
@@ -844,8 +861,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param state State passed to f.
|
/// @param state State passed to f.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename F, typename S>
|
template <typename T, typename F, typename S>
|
||||||
Offset<Vector<T>> CreateVector(size_t vector_size, F f, S *state) {
|
Offset<Vector<T>> CreateVector(size_t vector_size, F f, S* state) {
|
||||||
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
||||||
std::vector<T> elems(vector_size);
|
std::vector<T> elems(vector_size);
|
||||||
for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
|
for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
|
||||||
@@ -860,10 +877,10 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// buffer as a `vector`.
|
/// buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename StringType = std::string,
|
template <typename StringType = std::string,
|
||||||
typename Alloc = std::allocator<StringType>>
|
typename Alloc = std::allocator<StringType>>
|
||||||
Offset<Vector<Offset<String>>> CreateVectorOfStrings(
|
Offset<Vector<Offset<String>>> CreateVectorOfStrings(
|
||||||
const std::vector<StringType, Alloc> &v) {
|
const std::vector<StringType, Alloc>& v) {
|
||||||
return CreateVectorOfStrings(v.cbegin(), v.cend());
|
return CreateVectorOfStrings(v.cbegin(), v.cend());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -873,7 +890,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param end The ending iterator of the collection
|
/// @param end The ending iterator of the collection
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<class It>
|
template <class It>
|
||||||
Offset<Vector<Offset<String>>> CreateVectorOfStrings(It begin, It end) {
|
Offset<Vector<Offset<String>>> CreateVectorOfStrings(It begin, It end) {
|
||||||
auto distance = std::distance(begin, end);
|
auto distance = std::distance(begin, end);
|
||||||
FLATBUFFERS_ASSERT(distance >= 0);
|
FLATBUFFERS_ASSERT(distance >= 0);
|
||||||
@@ -890,7 +907,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
for (size_t i = 1; i <= size; i++) {
|
for (size_t i = 1; i <= size; i++) {
|
||||||
// Note we re-evaluate the buf location each iteration to account for any
|
// Note we re-evaluate the buf location each iteration to account for any
|
||||||
// underlying buffer resizing that may occur.
|
// underlying buffer resizing that may occur.
|
||||||
PushElement(*reinterpret_cast<Offset<String> *>(
|
PushElement(*reinterpret_cast<Offset<String>*>(
|
||||||
buf_.scratch_end() - i * sizeof(Offset<String>)));
|
buf_.scratch_end() - i * sizeof(Offset<String>)));
|
||||||
}
|
}
|
||||||
buf_.scratch_pop(scratch_buffer_usage);
|
buf_.scratch_pop(scratch_buffer_usage);
|
||||||
@@ -904,18 +921,18 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] len The number of elements to serialize.
|
/// @param[in] len The number of elements to serialize.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, template<typename...> class OffsetT = Offset,
|
template <typename T, template <typename...> class OffsetT = Offset,
|
||||||
template<typename...> class VectorT = Vector>
|
template <typename...> class VectorT = Vector>
|
||||||
OffsetT<VectorT<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
|
OffsetT<VectorT<const T*>> CreateVectorOfStructs(const T* v, size_t len) {
|
||||||
// The type of the length field in the vector.
|
// The type of the length field in the vector.
|
||||||
typedef typename VectorT<T>::size_type LenT;
|
typedef typename VectorT<T>::size_type LenT;
|
||||||
typedef typename OffsetT<VectorT<const T *>>::offset_type offset_type;
|
typedef typename OffsetT<VectorT<const T*>>::offset_type offset_type;
|
||||||
|
|
||||||
StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
|
StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
|
PushBytes(reinterpret_cast<const uint8_t*>(v), sizeof(T) * len);
|
||||||
}
|
}
|
||||||
return OffsetT<VectorT<const T *>>(EndVector<LenT, offset_type>(len));
|
return OffsetT<VectorT<const T*>>(EndVector<LenT, offset_type>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
||||||
@@ -926,10 +943,10 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
/// This is mostly useful when flatbuffers are generated with mutation
|
/// This is mostly useful when flatbuffers are generated with mutation
|
||||||
/// accessors.
|
/// accessors.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<const T *>> CreateVectorOfStructs(
|
Offset<Vector<const T*>> CreateVectorOfStructs(
|
||||||
size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
|
size_t vector_size, const std::function<void(size_t i, T*)>& filler) {
|
||||||
T *structs = StartVectorOfStructs<T>(vector_size);
|
T* structs = StartVectorOfStructs<T>(vector_size);
|
||||||
for (size_t i = 0; i < vector_size; i++) {
|
for (size_t i = 0; i < vector_size; i++) {
|
||||||
filler(i, structs);
|
filler(i, structs);
|
||||||
structs++;
|
structs++;
|
||||||
@@ -946,10 +963,10 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
/// This is mostly useful when flatbuffers are generated with mutation
|
/// This is mostly useful when flatbuffers are generated with mutation
|
||||||
/// accessors.
|
/// accessors.
|
||||||
template<typename T, typename F, typename S>
|
template <typename T, typename F, typename S>
|
||||||
Offset<Vector<const T *>> CreateVectorOfStructs(size_t vector_size, F f,
|
Offset<Vector<const T*>> CreateVectorOfStructs(size_t vector_size, F f,
|
||||||
S *state) {
|
S* state) {
|
||||||
T *structs = StartVectorOfStructs<T>(vector_size);
|
T* structs = StartVectorOfStructs<T>(vector_size);
|
||||||
for (size_t i = 0; i < vector_size; i++) {
|
for (size_t i = 0; i < vector_size; i++) {
|
||||||
f(i, structs, state);
|
f(i, structs, state);
|
||||||
structs++;
|
structs++;
|
||||||
@@ -963,17 +980,17 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, template<typename...> class OffsetT = Offset,
|
template <typename T, template <typename...> class OffsetT = Offset,
|
||||||
template<typename...> class VectorT = Vector,
|
template <typename...> class VectorT = Vector,
|
||||||
typename Alloc = std::allocator<T>>
|
typename Alloc = std::allocator<T>>
|
||||||
OffsetT<VectorT<const T *>> CreateVectorOfStructs(
|
OffsetT<VectorT<const T*>> CreateVectorOfStructs(
|
||||||
const std::vector<T, Alloc> &v) {
|
const std::vector<T, Alloc>& v) {
|
||||||
return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size());
|
return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<template<typename...> class VectorT = Vector64, int &..., typename T>
|
template <template <typename...> class VectorT = Vector64, int&...,
|
||||||
Offset64<VectorT<const T *>> CreateVectorOfStructs64(
|
typename T>
|
||||||
const std::vector<T> &v) {
|
Offset64<VectorT<const T*>> CreateVectorOfStructs64(const std::vector<T>& v) {
|
||||||
return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size());
|
return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -987,12 +1004,14 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// to the FlatBuffer struct.
|
/// to the FlatBuffer struct.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename S>
|
template <typename T, typename S>
|
||||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
Offset<Vector<const T*>> CreateVectorOfNativeStructs(
|
||||||
const S *v, size_t len, T (*const pack_func)(const S &)) {
|
const S* v, size_t len, T (*const pack_func)(const S&)) {
|
||||||
FLATBUFFERS_ASSERT(pack_func);
|
FLATBUFFERS_ASSERT(pack_func);
|
||||||
auto structs = StartVectorOfStructs<T>(len);
|
auto structs = StartVectorOfStructs<T>(len);
|
||||||
for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); }
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
structs[i] = pack_func(v[i]);
|
||||||
|
}
|
||||||
return EndVectorOfStructs<T>(len);
|
return EndVectorOfStructs<T>(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1004,10 +1023,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] len The number of elements to serialize.
|
/// @param[in] len The number of elements to serialize.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename S>
|
template <typename T, typename S>
|
||||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
|
Offset<Vector<const T*>> CreateVectorOfNativeStructs(const S* v, size_t len) {
|
||||||
size_t len) {
|
extern T Pack(const S&);
|
||||||
extern T Pack(const S &);
|
|
||||||
return CreateVectorOfNativeStructs(v, len, Pack);
|
return CreateVectorOfNativeStructs(v, len, Pack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1021,9 +1039,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// to the FlatBuffer struct.
|
/// to the FlatBuffer struct.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename S, typename Alloc = std::allocator<T>>
|
template <typename T, typename S, typename Alloc = std::allocator<T>>
|
||||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
Offset<Vector<const T*>> CreateVectorOfNativeStructs(
|
||||||
const std::vector<S, Alloc> &v, T (*const pack_func)(const S &)) {
|
const std::vector<S, Alloc>& v, T (*const pack_func)(const S&)) {
|
||||||
return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
|
return CreateVectorOfNativeStructs<T, S>(data(v), v.size(), pack_func);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1035,15 +1053,16 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename S, typename Alloc = std::allocator<S>>
|
template <typename T, typename S, typename Alloc = std::allocator<S>>
|
||||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
Offset<Vector<const T*>> CreateVectorOfNativeStructs(
|
||||||
const std::vector<S, Alloc> &v) {
|
const std::vector<S, Alloc>& v) {
|
||||||
return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
|
return CreateVectorOfNativeStructs<T, S>(data(v), v.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
template<typename T> struct StructKeyComparator {
|
template <typename T>
|
||||||
bool operator()(const T &a, const T &b) const {
|
struct StructKeyComparator {
|
||||||
|
bool operator()(const T& a, const T& b) const {
|
||||||
return a.KeyCompareLessThan(&b);
|
return a.KeyCompareLessThan(&b);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -1056,9 +1075,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename Alloc = std::allocator<T>>
|
template <typename T, typename Alloc = std::allocator<T>>
|
||||||
Offset<Vector<const T *>> CreateVectorOfSortedStructs(
|
Offset<Vector<const T*>> CreateVectorOfSortedStructs(
|
||||||
std::vector<T, Alloc> *v) {
|
std::vector<T, Alloc>* v) {
|
||||||
return CreateVectorOfSortedStructs(data(*v), v->size());
|
return CreateVectorOfSortedStructs(data(*v), v->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1070,9 +1089,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename S, typename Alloc = std::allocator<T>>
|
template <typename T, typename S, typename Alloc = std::allocator<T>>
|
||||||
Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(
|
Offset<Vector<const T*>> CreateVectorOfSortedNativeStructs(
|
||||||
std::vector<S, Alloc> *v) {
|
std::vector<S, Alloc>* v) {
|
||||||
return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
|
return CreateVectorOfSortedNativeStructs<T, S>(data(*v), v->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1084,8 +1103,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] len The number of elements to serialize.
|
/// @param[in] len The number of elements to serialize.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<const T *>> CreateVectorOfSortedStructs(T *v, size_t len) {
|
Offset<Vector<const T*>> CreateVectorOfSortedStructs(T* v, size_t len) {
|
||||||
std::stable_sort(v, v + len, StructKeyComparator<T>());
|
std::stable_sort(v, v + len, StructKeyComparator<T>());
|
||||||
return CreateVectorOfStructs(v, len);
|
return CreateVectorOfStructs(v, len);
|
||||||
}
|
}
|
||||||
@@ -1099,30 +1118,32 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] len The number of elements to serialize.
|
/// @param[in] len The number of elements to serialize.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename S>
|
template <typename T, typename S>
|
||||||
Offset<Vector<const T *>> CreateVectorOfSortedNativeStructs(S *v,
|
Offset<Vector<const T*>> CreateVectorOfSortedNativeStructs(S* v, size_t len) {
|
||||||
size_t len) {
|
extern T Pack(const S&);
|
||||||
extern T Pack(const S &);
|
|
||||||
auto structs = StartVectorOfStructs<T>(len);
|
auto structs = StartVectorOfStructs<T>(len);
|
||||||
for (size_t i = 0; i < len; i++) { structs[i] = Pack(v[i]); }
|
for (size_t i = 0; i < len; i++) {
|
||||||
|
structs[i] = Pack(v[i]);
|
||||||
|
}
|
||||||
std::stable_sort(structs, structs + len, StructKeyComparator<T>());
|
std::stable_sort(structs, structs + len, StructKeyComparator<T>());
|
||||||
return EndVectorOfStructs<T>(len);
|
return EndVectorOfStructs<T>(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
template<typename T> struct TableKeyComparator {
|
template <typename T>
|
||||||
explicit TableKeyComparator(vector_downward<SizeT> &buf) : buf_(buf) {}
|
struct TableKeyComparator {
|
||||||
TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
|
explicit TableKeyComparator(vector_downward<SizeT>& buf) : buf_(buf) {}
|
||||||
bool operator()(const Offset<T> &a, const Offset<T> &b) const {
|
TableKeyComparator(const TableKeyComparator& other) : buf_(other.buf_) {}
|
||||||
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
|
bool operator()(const Offset<T>& a, const Offset<T>& b) const {
|
||||||
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
|
auto table_a = reinterpret_cast<T*>(buf_.data_at(a.o));
|
||||||
|
auto table_b = reinterpret_cast<T*>(buf_.data_at(b.o));
|
||||||
return table_a->KeyCompareLessThan(table_b);
|
return table_a->KeyCompareLessThan(table_b);
|
||||||
}
|
}
|
||||||
vector_downward<SizeT> &buf_;
|
vector_downward<SizeT>& buf_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FLATBUFFERS_DELETE_FUNC(
|
FLATBUFFERS_DELETE_FUNC(
|
||||||
TableKeyComparator &operator=(const TableKeyComparator &other));
|
TableKeyComparator& operator=(const TableKeyComparator& other));
|
||||||
};
|
};
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@@ -1134,8 +1155,8 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] len The number of elements to store in the `vector`.
|
/// @param[in] len The number of elements to store in the `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T> *v,
|
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(Offset<T>* v,
|
||||||
size_t len) {
|
size_t len) {
|
||||||
std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
|
std::stable_sort(v, v + len, TableKeyComparator<T>(buf_));
|
||||||
return CreateVector(v, len);
|
return CreateVector(v, len);
|
||||||
@@ -1148,9 +1169,9 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// offsets to store in the buffer in sorted order.
|
/// offsets to store in the buffer in sorted order.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T, typename Alloc = std::allocator<T>>
|
template <typename T, typename Alloc = std::allocator<T>>
|
||||||
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
|
Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
|
||||||
std::vector<Offset<T>, Alloc> *v) {
|
std::vector<Offset<T>, Alloc>* v) {
|
||||||
return CreateVectorOfSortedTables(data(*v), v->size());
|
return CreateVectorOfSortedTables(data(*v), v->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1162,7 +1183,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// written to at a later time to serialize the data into a `vector`
|
/// written to at a later time to serialize the data into a `vector`
|
||||||
/// in the buffer.
|
/// in the buffer.
|
||||||
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
||||||
size_t alignment, uint8_t **buf) {
|
size_t alignment, uint8_t** buf) {
|
||||||
NotNested();
|
NotNested();
|
||||||
StartVector(len, elemsize, alignment);
|
StartVector(len, elemsize, alignment);
|
||||||
buf_.make_space(len * elemsize);
|
buf_.make_space(len * elemsize);
|
||||||
@@ -1174,7 +1195,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
|
FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
|
||||||
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
uoffset_t CreateUninitializedVector(size_t len, size_t elemsize,
|
||||||
uint8_t **buf) {
|
uint8_t** buf) {
|
||||||
return CreateUninitializedVector(len, elemsize, elemsize, buf);
|
return CreateUninitializedVector(len, elemsize, elemsize, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1186,46 +1207,49 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[out] buf A pointer to a pointer of type `T` that can be
|
/// @param[out] buf A pointer to a pointer of type `T` that can be
|
||||||
/// written to at a later time to serialize the data into a `vector`
|
/// written to at a later time to serialize the data into a `vector`
|
||||||
/// in the buffer.
|
/// in the buffer.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<T>> CreateUninitializedVector(size_t len, T **buf) {
|
Offset<Vector<T>> CreateUninitializedVector(size_t len, T** buf) {
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
|
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
|
||||||
reinterpret_cast<uint8_t **>(buf));
|
reinterpret_cast<uint8_t**>(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
|
Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len,
|
||||||
T **buf) {
|
T** buf) {
|
||||||
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
|
return CreateUninitializedVector(len, sizeof(T), AlignOf<T>(),
|
||||||
reinterpret_cast<uint8_t **>(buf));
|
reinterpret_cast<uint8_t**>(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
// @brief Create a vector of scalar type T given as input a vector of scalar
|
// @brief Create a vector of scalar type T given as input a vector of scalar
|
||||||
// type U, useful with e.g. pre "enum class" enums, or any existing scalar
|
// type U, useful with e.g. pre "enum class" enums, or any existing scalar
|
||||||
// data of the wrong type.
|
// data of the wrong type.
|
||||||
template<typename T, typename U>
|
template <typename T, typename U>
|
||||||
Offset<Vector<T>> CreateVectorScalarCast(const U *v, size_t len) {
|
Offset<Vector<T>> CreateVectorScalarCast(const U* v, size_t len) {
|
||||||
AssertScalarT<T>();
|
AssertScalarT<T>();
|
||||||
AssertScalarT<U>();
|
AssertScalarT<U>();
|
||||||
StartVector<T>(len);
|
StartVector<T>(len);
|
||||||
for (auto i = len; i > 0;) { PushElement(static_cast<T>(v[--i])); }
|
for (auto i = len; i > 0;) {
|
||||||
|
PushElement(static_cast<T>(v[--i]));
|
||||||
|
}
|
||||||
return Offset<Vector<T>>(EndVector(len));
|
return Offset<Vector<T>>(EndVector(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Write a struct by itself, typically to be part of a union.
|
/// @brief Write a struct by itself, typically to be part of a union.
|
||||||
template<typename T> Offset<const T *> CreateStruct(const T &structobj) {
|
template <typename T>
|
||||||
|
Offset<const T*> CreateStruct(const T& structobj) {
|
||||||
NotNested();
|
NotNested();
|
||||||
Align(AlignOf<T>());
|
Align(AlignOf<T>());
|
||||||
buf_.push_small(structobj);
|
buf_.push_small(structobj);
|
||||||
return Offset<const T *>(
|
return Offset<const T*>(
|
||||||
CalculateOffset<typename Offset<const T *>::offset_type>());
|
CalculateOffset<typename Offset<const T*>::offset_type>());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Finish serializing a buffer by writing the root offset.
|
/// @brief Finish serializing a buffer by writing the root offset.
|
||||||
/// @param[in] file_identifier If a `file_identifier` is given, the buffer
|
/// @param[in] file_identifier If a `file_identifier` is given, the buffer
|
||||||
/// will be prefixed with a standard FlatBuffers file header.
|
/// will be prefixed with a standard FlatBuffers file header.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void Finish(Offset<T> root, const char *file_identifier = nullptr) {
|
void Finish(Offset<T> root, const char* file_identifier = nullptr) {
|
||||||
Finish(root.o, file_identifier, false);
|
Finish(root.o, file_identifier, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1236,13 +1260,13 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// All >32 bit quantities in this buffer will be aligned when the whole
|
/// All >32 bit quantities in this buffer will be aligned when the whole
|
||||||
/// size pre-fixed buffer is aligned.
|
/// size pre-fixed buffer is aligned.
|
||||||
/// These kinds of buffers are useful for creating a stream of FlatBuffers.
|
/// These kinds of buffers are useful for creating a stream of FlatBuffers.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void FinishSizePrefixed(Offset<T> root,
|
void FinishSizePrefixed(Offset<T> root,
|
||||||
const char *file_identifier = nullptr) {
|
const char* file_identifier = nullptr) {
|
||||||
Finish(root.o, file_identifier, true);
|
Finish(root.o, file_identifier, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SwapBufAllocator(FlatBufferBuilderImpl &other) {
|
void SwapBufAllocator(FlatBufferBuilderImpl& other) {
|
||||||
buf_.swap_allocator(other.buf_);
|
buf_.swap_allocator(other.buf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1252,10 +1276,10 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
// You shouldn't really be copying instances of this class.
|
// You shouldn't really be copying instances of this class.
|
||||||
FlatBufferBuilderImpl(const FlatBufferBuilderImpl &);
|
FlatBufferBuilderImpl(const FlatBufferBuilderImpl&);
|
||||||
FlatBufferBuilderImpl &operator=(const FlatBufferBuilderImpl &);
|
FlatBufferBuilderImpl& operator=(const FlatBufferBuilderImpl&);
|
||||||
|
|
||||||
void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
|
void Finish(uoffset_t root, const char* file_identifier, bool size_prefix) {
|
||||||
// A buffer can only be finished once. To reuse a builder use `clear()`.
|
// A buffer can only be finished once. To reuse a builder use `clear()`.
|
||||||
FLATBUFFERS_ASSERT(!finished);
|
FLATBUFFERS_ASSERT(!finished);
|
||||||
|
|
||||||
@@ -1274,11 +1298,13 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
if (file_identifier) {
|
if (file_identifier) {
|
||||||
FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
|
FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
|
||||||
PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
|
PushBytes(reinterpret_cast<const uint8_t*>(file_identifier),
|
||||||
kFileIdentifierLength);
|
kFileIdentifierLength);
|
||||||
}
|
}
|
||||||
PushElement(ReferTo(root)); // Location of root.
|
PushElement(ReferTo(root)); // Location of root.
|
||||||
if (size_prefix) { PushElement(GetSize()); }
|
if (size_prefix) {
|
||||||
|
PushElement(GetSize());
|
||||||
|
}
|
||||||
finished = true;
|
finished = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1329,20 +1355,20 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
bool dedup_vtables_;
|
bool dedup_vtables_;
|
||||||
|
|
||||||
struct StringOffsetCompare {
|
struct StringOffsetCompare {
|
||||||
explicit StringOffsetCompare(const vector_downward<SizeT> &buf)
|
explicit StringOffsetCompare(const vector_downward<SizeT>& buf)
|
||||||
: buf_(&buf) {}
|
: buf_(&buf) {}
|
||||||
bool operator()(const Offset<String> &a, const Offset<String> &b) const {
|
bool operator()(const Offset<String>& a, const Offset<String>& b) const {
|
||||||
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
|
auto stra = reinterpret_cast<const String*>(buf_->data_at(a.o));
|
||||||
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
|
auto strb = reinterpret_cast<const String*>(buf_->data_at(b.o));
|
||||||
return StringLessThan(stra->data(), stra->size(), strb->data(),
|
return StringLessThan(stra->data(), stra->size(), strb->data(),
|
||||||
strb->size());
|
strb->size());
|
||||||
}
|
}
|
||||||
const vector_downward<SizeT> *buf_;
|
const vector_downward<SizeT>* buf_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// For use with CreateSharedString. Instantiated on first use only.
|
// For use with CreateSharedString. Instantiated on first use only.
|
||||||
typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
|
typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
|
||||||
StringOffsetMap *string_pool;
|
StringOffsetMap* string_pool;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CanAddOffset64() {
|
void CanAddOffset64() {
|
||||||
@@ -1372,33 +1398,33 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
/// @param[in] str A const char pointer to the data to be stored as a string.
|
/// @param[in] str A const char pointer to the data to be stored as a string.
|
||||||
/// @param[in] len The number of bytes that should be stored from `str`.
|
/// @param[in] len The number of bytes that should be stored from `str`.
|
||||||
/// @return Returns the offset in the buffer where the string starts.
|
/// @return Returns the offset in the buffer where the string starts.
|
||||||
void CreateStringImpl(const char *str, size_t len) {
|
void CreateStringImpl(const char* str, size_t len) {
|
||||||
NotNested();
|
NotNested();
|
||||||
PreAlign<uoffset_t>(len + 1); // Always 0-terminated.
|
PreAlign<uoffset_t>(len + 1); // Always 0-terminated.
|
||||||
buf_.fill(1);
|
buf_.fill(1);
|
||||||
PushBytes(reinterpret_cast<const uint8_t *>(str), len);
|
PushBytes(reinterpret_cast<const uint8_t*>(str), len);
|
||||||
PushElement(static_cast<uoffset_t>(len));
|
PushElement(static_cast<uoffset_t>(len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocates space for a vector of structures.
|
// Allocates space for a vector of structures.
|
||||||
// Must be completed with EndVectorOfStructs().
|
// Must be completed with EndVectorOfStructs().
|
||||||
template<typename T, template<typename> class OffsetT = Offset>
|
template <typename T, template <typename> class OffsetT = Offset>
|
||||||
T *StartVectorOfStructs(size_t vector_size) {
|
T* StartVectorOfStructs(size_t vector_size) {
|
||||||
StartVector<OffsetT>(vector_size, sizeof(T), AlignOf<T>());
|
StartVector<OffsetT>(vector_size, sizeof(T), AlignOf<T>());
|
||||||
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
return reinterpret_cast<T*>(buf_.make_space(vector_size * sizeof(T)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// End the vector of structures in the flatbuffers.
|
// End the vector of structures in the flatbuffers.
|
||||||
// Vector should have previously be started with StartVectorOfStructs().
|
// Vector should have previously be started with StartVectorOfStructs().
|
||||||
template<typename T, template<typename> class OffsetT = Offset>
|
template <typename T, template <typename> class OffsetT = Offset>
|
||||||
OffsetT<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
|
OffsetT<Vector<const T*>> EndVectorOfStructs(size_t vector_size) {
|
||||||
return OffsetT<Vector<const T *>>(
|
return OffsetT<Vector<const T*>>(
|
||||||
EndVector<typename Vector<const T *>::size_type,
|
EndVector<typename Vector<const T*>::size_type,
|
||||||
typename OffsetT<Vector<const T *>>::offset_type>(
|
typename OffsetT<Vector<const T*>>::offset_type>(
|
||||||
vector_size));
|
vector_size));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_same<T, uoffset_t>::value, T>::type
|
typename std::enable_if<std::is_same<T, uoffset_t>::value, T>::type
|
||||||
CalculateOffset() {
|
CalculateOffset() {
|
||||||
// Default to the end of the 32-bit region. This may or may not be the end
|
// Default to the end of the 32-bit region. This may or may not be the end
|
||||||
@@ -1408,7 +1434,7 @@ template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
|||||||
|
|
||||||
// Specializations to handle the 64-bit CalculateOffset, which is relative to
|
// Specializations to handle the 64-bit CalculateOffset, which is relative to
|
||||||
// end of the buffer.
|
// end of the buffer.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
typename std::enable_if<std::is_same<T, uoffset64_t>::value, T>::type
|
typename std::enable_if<std::is_same<T, uoffset64_t>::value, T>::type
|
||||||
CalculateOffset() {
|
CalculateOffset() {
|
||||||
// This should never be compiled in when not using a 64-bit builder.
|
// This should never be compiled in when not using a 64-bit builder.
|
||||||
@@ -1430,9 +1456,9 @@ using FlatBufferBuilder64 = FlatBufferBuilderImpl<true>;
|
|||||||
|
|
||||||
// These are external due to GCC not allowing them in the class.
|
// These are external due to GCC not allowing them in the class.
|
||||||
// See: https://stackoverflow.com/q/8061456/868247
|
// See: https://stackoverflow.com/q/8061456/868247
|
||||||
template<>
|
template <>
|
||||||
template<>
|
template <>
|
||||||
inline Offset64<String> FlatBufferBuilder64::CreateString(const char *str,
|
inline Offset64<String> FlatBufferBuilder64::CreateString(const char* str,
|
||||||
size_t len) {
|
size_t len) {
|
||||||
CanAddOffset64();
|
CanAddOffset64();
|
||||||
CreateStringImpl(str, len);
|
CreateStringImpl(str, len);
|
||||||
@@ -1441,19 +1467,20 @@ inline Offset64<String> FlatBufferBuilder64::CreateString(const char *str,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used to distinguish from real Offsets.
|
// Used to distinguish from real Offsets.
|
||||||
template<typename T = void> struct EmptyOffset {};
|
template <typename T = void>
|
||||||
|
struct EmptyOffset {};
|
||||||
|
|
||||||
// TODO(derekbailey): it would be nice to combine these two methods.
|
// TODO(derekbailey): it would be nice to combine these two methods.
|
||||||
template<>
|
template <>
|
||||||
template<>
|
template <>
|
||||||
inline void FlatBufferBuilder64::StartVector<Offset64, uint32_t>(
|
inline void FlatBufferBuilder64::StartVector<Offset64, uint32_t>(
|
||||||
size_t len, size_t elemsize, size_t alignment) {
|
size_t len, size_t elemsize, size_t alignment) {
|
||||||
CanAddOffset64();
|
CanAddOffset64();
|
||||||
StartVector<EmptyOffset, uint32_t>(len, elemsize, alignment);
|
StartVector<EmptyOffset, uint32_t>(len, elemsize, alignment);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
template<>
|
template <>
|
||||||
inline void FlatBufferBuilder64::StartVector<Offset64, uint64_t>(
|
inline void FlatBufferBuilder64::StartVector<Offset64, uint64_t>(
|
||||||
size_t len, size_t elemsize, size_t alignment) {
|
size_t len, size_t elemsize, size_t alignment) {
|
||||||
CanAddOffset64();
|
CanAddOffset64();
|
||||||
@@ -1463,15 +1490,15 @@ inline void FlatBufferBuilder64::StartVector<Offset64, uint64_t>(
|
|||||||
/// Helpers to get a typed pointer to objects that are currently being built.
|
/// Helpers to get a typed pointer to objects that are currently being built.
|
||||||
/// @warning Creating new objects will lead to reallocations and invalidates
|
/// @warning Creating new objects will lead to reallocations and invalidates
|
||||||
/// the pointer!
|
/// the pointer!
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
|
T* GetMutableTemporaryPointer(FlatBufferBuilder& fbb, Offset<T> offset) {
|
||||||
return reinterpret_cast<T *>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
|
return reinterpret_cast<T*>(fbb.GetCurrentBufferPointer() + fbb.GetSize() -
|
||||||
offset.o);
|
offset.o);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
const T *GetTemporaryPointer(const FlatBufferBuilder &fbb, Offset<T> offset) {
|
const T* GetTemporaryPointer(const FlatBufferBuilder& fbb, Offset<T> offset) {
|
||||||
return reinterpret_cast<const T *>(fbb.GetCurrentBufferPointer() +
|
return reinterpret_cast<const T*>(fbb.GetCurrentBufferPointer() +
|
||||||
fbb.GetSize() - offset.o);
|
fbb.GetSize() - offset.o);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -41,13 +41,13 @@ namespace flatbuffers {
|
|||||||
/// it is the opposite transformation of GetRoot().
|
/// it is the opposite transformation of GetRoot().
|
||||||
/// This may be useful if you want to pass on a root and have the recipient
|
/// This may be useful if you want to pass on a root and have the recipient
|
||||||
/// delete the buffer afterwards.
|
/// delete the buffer afterwards.
|
||||||
inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
inline const uint8_t* GetBufferStartFromRootPointer(const void* root) {
|
||||||
auto table = reinterpret_cast<const Table *>(root);
|
auto table = reinterpret_cast<const Table*>(root);
|
||||||
auto vtable = table->GetVTable();
|
auto vtable = table->GetVTable();
|
||||||
// Either the vtable is before the root or after the root.
|
// Either the vtable is before the root or after the root.
|
||||||
auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
|
auto start = (std::min)(vtable, reinterpret_cast<const uint8_t*>(root));
|
||||||
// Align to at least sizeof(uoffset_t).
|
// Align to at least sizeof(uoffset_t).
|
||||||
start = reinterpret_cast<const uint8_t *>(reinterpret_cast<uintptr_t>(start) &
|
start = reinterpret_cast<const uint8_t*>(reinterpret_cast<uintptr_t>(start) &
|
||||||
~(sizeof(uoffset_t) - 1));
|
~(sizeof(uoffset_t) - 1));
|
||||||
// Additionally, there may be a file_identifier in the buffer, and the root
|
// Additionally, there may be a file_identifier in the buffer, and the root
|
||||||
// offset. The buffer may have been aligned to any size between
|
// offset. The buffer may have been aligned to any size between
|
||||||
@@ -64,7 +64,7 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
|||||||
possible_roots; possible_roots--) {
|
possible_roots; possible_roots--) {
|
||||||
start -= sizeof(uoffset_t);
|
start -= sizeof(uoffset_t);
|
||||||
if (ReadScalar<uoffset_t>(start) + start ==
|
if (ReadScalar<uoffset_t>(start) + start ==
|
||||||
reinterpret_cast<const uint8_t *>(root))
|
reinterpret_cast<const uint8_t*>(root))
|
||||||
return start;
|
return start;
|
||||||
}
|
}
|
||||||
// We didn't find the root, either the "root" passed isn't really a root,
|
// We didn't find the root, either the "root" passed isn't really a root,
|
||||||
@@ -76,8 +76,8 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief This return the prefixed size of a FlatBuffer.
|
/// @brief This return the prefixed size of a FlatBuffer.
|
||||||
template<typename SizeT = uoffset_t>
|
template <typename SizeT = uoffset_t>
|
||||||
inline SizeT GetPrefixedSize(const uint8_t *buf) {
|
inline SizeT GetPrefixedSize(const uint8_t* buf) {
|
||||||
return ReadScalar<SizeT>(buf);
|
return ReadScalar<SizeT>(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,8 +87,8 @@ inline SizeT GetPrefixedSize(const uint8_t *buf) {
|
|||||||
//
|
//
|
||||||
// [size prefix][flatbuffer]
|
// [size prefix][flatbuffer]
|
||||||
// |---------length--------|
|
// |---------length--------|
|
||||||
template<typename SizeT = uoffset_t>
|
template <typename SizeT = uoffset_t>
|
||||||
inline SizeT GetSizePrefixedBufferLength(const uint8_t *const buf) {
|
inline SizeT GetSizePrefixedBufferLength(const uint8_t* const buf) {
|
||||||
return ReadScalar<SizeT>(buf) + sizeof(SizeT);
|
return ReadScalar<SizeT>(buf) + sizeof(SizeT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,9 +106,9 @@ struct NativeTable {};
|
|||||||
/// if you wish. The resolver does the opposite lookup, for when the object
|
/// if you wish. The resolver does the opposite lookup, for when the object
|
||||||
/// is being serialized again.
|
/// is being serialized again.
|
||||||
typedef uint64_t hash_value_t;
|
typedef uint64_t hash_value_t;
|
||||||
typedef std::function<void(void **pointer_adr, hash_value_t hash)>
|
typedef std::function<void(void** pointer_adr, hash_value_t hash)>
|
||||||
resolver_function_t;
|
resolver_function_t;
|
||||||
typedef std::function<hash_value_t(void *pointer)> rehasher_function_t;
|
typedef std::function<hash_value_t(void* pointer)> rehasher_function_t;
|
||||||
|
|
||||||
// Helper function to test if a field is present, using any of the field
|
// Helper function to test if a field is present, using any of the field
|
||||||
// enums in the generated code.
|
// enums in the generated code.
|
||||||
@@ -117,18 +117,18 @@ typedef std::function<hash_value_t(void *pointer)> rehasher_function_t;
|
|||||||
// Note: this function will return false for fields equal to the default
|
// Note: this function will return false for fields equal to the default
|
||||||
// value, since they're not stored in the buffer (unless force_defaults was
|
// value, since they're not stored in the buffer (unless force_defaults was
|
||||||
// used).
|
// used).
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool IsFieldPresent(const T *table, typename T::FlatBuffersVTableOffset field) {
|
bool IsFieldPresent(const T* table, typename T::FlatBuffersVTableOffset field) {
|
||||||
// Cast, since Table is a private baseclass of any table types.
|
// Cast, since Table is a private baseclass of any table types.
|
||||||
return reinterpret_cast<const Table *>(table)->CheckField(
|
return reinterpret_cast<const Table*>(table)->CheckField(
|
||||||
static_cast<voffset_t>(field));
|
static_cast<voffset_t>(field));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Utility function for reverse lookups on the EnumNames*() functions
|
// Utility function for reverse lookups on the EnumNames*() functions
|
||||||
// (in the generated C++ code)
|
// (in the generated C++ code)
|
||||||
// names must be NULL terminated.
|
// names must be NULL terminated.
|
||||||
inline int LookupEnum(const char **names, const char *name) {
|
inline int LookupEnum(const char** names, const char* name) {
|
||||||
for (const char **p = names; *p; p++)
|
for (const char** p = names; *p; p++)
|
||||||
if (!strcmp(*p, name)) return static_cast<int>(p - names);
|
if (!strcmp(*p, name)) return static_cast<int>(p - names);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -227,20 +227,20 @@ static_assert(sizeof(TypeCode) == 2, "TypeCode");
|
|||||||
struct TypeTable;
|
struct TypeTable;
|
||||||
|
|
||||||
// Signature of the static method present in each type.
|
// Signature of the static method present in each type.
|
||||||
typedef const TypeTable *(*TypeFunction)();
|
typedef const TypeTable* (*TypeFunction)();
|
||||||
|
|
||||||
struct TypeTable {
|
struct TypeTable {
|
||||||
SequenceType st;
|
SequenceType st;
|
||||||
size_t num_elems; // of type_codes, values, names (but not type_refs).
|
size_t num_elems; // of type_codes, values, names (but not type_refs).
|
||||||
const TypeCode *type_codes; // num_elems count
|
const TypeCode* type_codes; // num_elems count
|
||||||
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
|
const TypeFunction* type_refs; // less than num_elems entries (see TypeCode).
|
||||||
const int16_t *array_sizes; // less than num_elems entries (see TypeCode).
|
const int16_t* array_sizes; // less than num_elems entries (see TypeCode).
|
||||||
const int64_t *values; // Only set for non-consecutive enum/union or structs.
|
const int64_t* values; // Only set for non-consecutive enum/union or structs.
|
||||||
const char *const *names; // Only set if compiled with --reflect-names.
|
const char* const* names; // Only set if compiled with --reflect-names.
|
||||||
};
|
};
|
||||||
|
|
||||||
// String which identifies the current version of FlatBuffers.
|
// String which identifies the current version of FlatBuffers.
|
||||||
inline const char *flatbuffers_version_string() {
|
inline const char* flatbuffers_version_string() {
|
||||||
return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
|
return "FlatBuffers " FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MAJOR) "."
|
||||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
|
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_MINOR) "."
|
||||||
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
|
FLATBUFFERS_STRING(FLATBUFFERS_VERSION_REVISION);
|
||||||
|
|||||||
@@ -30,8 +30,8 @@
|
|||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
extern void LogCompilerWarn(const std::string &warn);
|
extern void LogCompilerWarn(const std::string& warn);
|
||||||
extern void LogCompilerError(const std::string &err);
|
extern void LogCompilerError(const std::string& err);
|
||||||
|
|
||||||
struct FlatCOptions {
|
struct FlatCOptions {
|
||||||
IDLOptions opts;
|
IDLOptions opts;
|
||||||
@@ -43,8 +43,8 @@ struct FlatCOptions {
|
|||||||
std::vector<std::string> filenames;
|
std::vector<std::string> filenames;
|
||||||
|
|
||||||
std::list<std::string> include_directories_storage;
|
std::list<std::string> include_directories_storage;
|
||||||
std::vector<const char *> include_directories;
|
std::vector<const char*> include_directories;
|
||||||
std::vector<const char *> conform_include_directories;
|
std::vector<const char*> conform_include_directories;
|
||||||
std::vector<bool> generator_enabled;
|
std::vector<bool> generator_enabled;
|
||||||
size_t binary_files_from = std::numeric_limits<size_t>::max();
|
size_t binary_files_from = std::numeric_limits<size_t>::max();
|
||||||
std::string conform_to_schema;
|
std::string conform_to_schema;
|
||||||
@@ -70,10 +70,10 @@ struct FlatCOption {
|
|||||||
|
|
||||||
class FlatCompiler {
|
class FlatCompiler {
|
||||||
public:
|
public:
|
||||||
typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
|
typedef void (*WarnFn)(const FlatCompiler* flatc, const std::string& warn,
|
||||||
bool show_exe_name);
|
bool show_exe_name);
|
||||||
|
|
||||||
typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err,
|
typedef void (*ErrorFn)(const FlatCompiler* flatc, const std::string& err,
|
||||||
bool usage, bool show_exe_name);
|
bool usage, bool show_exe_name);
|
||||||
|
|
||||||
// Parameters required to initialize the FlatCompiler.
|
// Parameters required to initialize the FlatCompiler.
|
||||||
@@ -84,42 +84,42 @@ class FlatCompiler {
|
|||||||
ErrorFn error_fn;
|
ErrorFn error_fn;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit FlatCompiler(const InitParams ¶ms) : params_(params) {}
|
explicit FlatCompiler(const InitParams& params) : params_(params) {}
|
||||||
|
|
||||||
bool RegisterCodeGenerator(const FlatCOption &option,
|
bool RegisterCodeGenerator(const FlatCOption& option,
|
||||||
std::shared_ptr<CodeGenerator> code_generator);
|
std::shared_ptr<CodeGenerator> code_generator);
|
||||||
|
|
||||||
int Compile(const FlatCOptions &options);
|
int Compile(const FlatCOptions& options);
|
||||||
|
|
||||||
std::string GetShortUsageString(const std::string &program_name) const;
|
std::string GetShortUsageString(const std::string& program_name) const;
|
||||||
std::string GetUsageString(const std::string &program_name) const;
|
std::string GetUsageString(const std::string& program_name) const;
|
||||||
|
|
||||||
// Parse the FlatC options from command line arguments.
|
// Parse the FlatC options from command line arguments.
|
||||||
FlatCOptions ParseFromCommandLineArguments(int argc, const char **argv);
|
FlatCOptions ParseFromCommandLineArguments(int argc, const char** argv);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseFile(flatbuffers::Parser &parser, const std::string &filename,
|
void ParseFile(flatbuffers::Parser& parser, const std::string& filename,
|
||||||
const std::string &contents,
|
const std::string& contents,
|
||||||
const std::vector<const char *> &include_directories) const;
|
const std::vector<const char*>& include_directories) const;
|
||||||
|
|
||||||
void LoadBinarySchema(Parser &parser, const std::string &filename,
|
void LoadBinarySchema(Parser& parser, const std::string& filename,
|
||||||
const std::string &contents);
|
const std::string& contents);
|
||||||
|
|
||||||
void Warn(const std::string &warn, bool show_exe_name = true) const;
|
void Warn(const std::string& warn, bool show_exe_name = true) const;
|
||||||
|
|
||||||
void Error(const std::string &err, bool usage = true,
|
void Error(const std::string& err, bool usage = true,
|
||||||
bool show_exe_name = true) const;
|
bool show_exe_name = true) const;
|
||||||
|
|
||||||
void AnnotateBinaries(const uint8_t *binary_schema,
|
void AnnotateBinaries(const uint8_t* binary_schema,
|
||||||
uint64_t binary_schema_size,
|
uint64_t binary_schema_size,
|
||||||
const FlatCOptions &options);
|
const FlatCOptions& options);
|
||||||
|
|
||||||
void ValidateOptions(const FlatCOptions &options);
|
void ValidateOptions(const FlatCOptions& options);
|
||||||
|
|
||||||
Parser GetConformParser(const FlatCOptions &options);
|
Parser GetConformParser(const FlatCOptions& options);
|
||||||
|
|
||||||
std::unique_ptr<Parser> GenerateCode(const FlatCOptions &options,
|
std::unique_ptr<Parser> GenerateCode(const FlatCOptions& options,
|
||||||
Parser &conform_parser);
|
Parser& conform_parser);
|
||||||
|
|
||||||
std::map<std::string, std::shared_ptr<CodeGenerator>> code_generators_;
|
std::map<std::string, std::shared_ptr<CodeGenerator>> code_generators_;
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,8 @@ namespace flexbuffers {
|
|||||||
|
|
||||||
// Verifies the `nested` flexbuffer within a flatbuffer vector is valid.
|
// Verifies the `nested` flexbuffer within a flatbuffer vector is valid.
|
||||||
inline bool VerifyNestedFlexBuffer(
|
inline bool VerifyNestedFlexBuffer(
|
||||||
const flatbuffers::Vector<uint8_t> *const nested,
|
const flatbuffers::Vector<uint8_t>* const nested,
|
||||||
flatbuffers::Verifier &verifier) {
|
flatbuffers::Verifier& verifier) {
|
||||||
if (!nested) return true;
|
if (!nested) return true;
|
||||||
return verifier.Check(flexbuffers::VerifyBuffer(
|
return verifier.Check(flexbuffers::VerifyBuffer(
|
||||||
nested->data(), nested->size(), verifier.GetFlexReuseTracker()));
|
nested->data(), nested->size(), verifier.GetFlexReuseTracker()));
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -30,23 +30,24 @@ namespace grpc {
|
|||||||
// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify`
|
// `grpc_slice` and also provides flatbuffers-specific helpers such as `Verify`
|
||||||
// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer
|
// and `GetRoot`. Since it is backed by a `grpc_slice`, the underlying buffer
|
||||||
// is refcounted and ownership is be managed automatically.
|
// is refcounted and ownership is be managed automatically.
|
||||||
template<class T> class Message {
|
template <class T>
|
||||||
|
class Message {
|
||||||
public:
|
public:
|
||||||
Message() {}
|
Message() {}
|
||||||
|
|
||||||
Message(::grpc::Slice slice) : slice_(slice) {}
|
Message(::grpc::Slice slice) : slice_(slice) {}
|
||||||
|
|
||||||
Message &operator=(const Message &other) = delete;
|
Message& operator=(const Message& other) = delete;
|
||||||
|
|
||||||
Message(Message &&other) = default;
|
Message(Message&& other) = default;
|
||||||
|
|
||||||
Message(const Message &other) = delete;
|
Message(const Message& other) = delete;
|
||||||
|
|
||||||
Message &operator=(Message &&other) = default;
|
Message& operator=(Message&& other) = default;
|
||||||
|
|
||||||
const uint8_t *mutable_data() const { return slice_.begin(); }
|
const uint8_t* mutable_data() const { return slice_.begin(); }
|
||||||
|
|
||||||
const uint8_t *data() const { return slice_.begin(); }
|
const uint8_t* data() const { return slice_.begin(); }
|
||||||
|
|
||||||
size_t size() const { return slice_.size(); }
|
size_t size() const { return slice_.size(); }
|
||||||
|
|
||||||
@@ -55,12 +56,12 @@ template<class T> class Message {
|
|||||||
return verifier.VerifyBuffer<T>(nullptr);
|
return verifier.VerifyBuffer<T>(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
T *GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); }
|
T* GetMutableRoot() { return flatbuffers::GetMutableRoot<T>(mutable_data()); }
|
||||||
|
|
||||||
const T *GetRoot() const { return flatbuffers::GetRoot<T>(data()); }
|
const T* GetRoot() const { return flatbuffers::GetRoot<T>(data()); }
|
||||||
|
|
||||||
// This is only intended for serializer use, or if you know what you're doing
|
// This is only intended for serializer use, or if you know what you're doing
|
||||||
const ::grpc::Slice &BorrowSlice() const { return slice_; }
|
const ::grpc::Slice& BorrowSlice() const { return slice_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::grpc::Slice slice_;
|
::grpc::Slice slice_;
|
||||||
@@ -75,41 +76,41 @@ class SliceAllocator : public Allocator {
|
|||||||
public:
|
public:
|
||||||
SliceAllocator() {}
|
SliceAllocator() {}
|
||||||
|
|
||||||
SliceAllocator(const SliceAllocator &other) = delete;
|
SliceAllocator(const SliceAllocator& other) = delete;
|
||||||
SliceAllocator &operator=(const SliceAllocator &other) = delete;
|
SliceAllocator& operator=(const SliceAllocator& other) = delete;
|
||||||
|
|
||||||
SliceAllocator(SliceAllocator &&other) {
|
SliceAllocator(SliceAllocator&& other) {
|
||||||
// default-construct and swap idiom
|
// default-construct and swap idiom
|
||||||
swap(other);
|
swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
SliceAllocator &operator=(SliceAllocator &&other) {
|
SliceAllocator& operator=(SliceAllocator&& other) {
|
||||||
// move-construct and swap idiom
|
// move-construct and swap idiom
|
||||||
SliceAllocator temp(std::move(other));
|
SliceAllocator temp(std::move(other));
|
||||||
swap(temp);
|
swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap(SliceAllocator &other) {
|
void swap(SliceAllocator& other) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(slice_, other.slice_);
|
swap(slice_, other.slice_);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~SliceAllocator() {}
|
virtual ~SliceAllocator() {}
|
||||||
|
|
||||||
virtual uint8_t *allocate(size_t size) override {
|
virtual uint8_t* allocate(size_t size) override {
|
||||||
FLATBUFFERS_ASSERT(slice_.size() == 0);
|
FLATBUFFERS_ASSERT(slice_.size() == 0);
|
||||||
slice_ = ::grpc::Slice(size);
|
slice_ = ::grpc::Slice(size);
|
||||||
return const_cast<uint8_t *>(slice_.begin());
|
return const_cast<uint8_t*>(slice_.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void deallocate(uint8_t *p, size_t size) override {
|
virtual void deallocate(uint8_t* p, size_t size) override {
|
||||||
FLATBUFFERS_ASSERT(p == slice_.begin());
|
FLATBUFFERS_ASSERT(p == slice_.begin());
|
||||||
FLATBUFFERS_ASSERT(size == slice_.size());
|
FLATBUFFERS_ASSERT(size == slice_.size());
|
||||||
slice_ = ::grpc::Slice();
|
slice_ = ::grpc::Slice();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual uint8_t *reallocate_downward(uint8_t *old_p, size_t old_size,
|
virtual uint8_t* reallocate_downward(uint8_t* old_p, size_t old_size,
|
||||||
size_t new_size, size_t in_use_back,
|
size_t new_size, size_t in_use_back,
|
||||||
size_t in_use_front) override {
|
size_t in_use_front) override {
|
||||||
FLATBUFFERS_ASSERT(old_p == slice_.begin());
|
FLATBUFFERS_ASSERT(old_p == slice_.begin());
|
||||||
@@ -117,15 +118,15 @@ class SliceAllocator : public Allocator {
|
|||||||
FLATBUFFERS_ASSERT(new_size > old_size);
|
FLATBUFFERS_ASSERT(new_size > old_size);
|
||||||
::grpc::Slice old_slice = slice_;
|
::grpc::Slice old_slice = slice_;
|
||||||
::grpc::Slice new_slice = ::grpc::Slice(new_size);
|
::grpc::Slice new_slice = ::grpc::Slice(new_size);
|
||||||
uint8_t *new_p = const_cast<uint8_t *>(new_slice.begin());
|
uint8_t* new_p = const_cast<uint8_t*>(new_slice.begin());
|
||||||
memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
|
memcpy_downward(old_p, old_size, new_p, new_size, in_use_back,
|
||||||
in_use_front);
|
in_use_front);
|
||||||
slice_ = new_slice;
|
slice_ = new_slice;
|
||||||
return const_cast<uint8_t *>(slice_.begin());
|
return const_cast<uint8_t*>(slice_.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
::grpc::Slice &get_slice(uint8_t *p, size_t size) {
|
::grpc::Slice& get_slice(uint8_t* p, size_t size) {
|
||||||
FLATBUFFERS_ASSERT(p == slice_.begin());
|
FLATBUFFERS_ASSERT(p == slice_.begin());
|
||||||
FLATBUFFERS_ASSERT(size == slice_.size());
|
FLATBUFFERS_ASSERT(size == slice_.size());
|
||||||
return slice_;
|
return slice_;
|
||||||
@@ -153,24 +154,24 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
||||||
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||||
|
|
||||||
MessageBuilder(const MessageBuilder &other) = delete;
|
MessageBuilder(const MessageBuilder& other) = delete;
|
||||||
MessageBuilder &operator=(const MessageBuilder &other) = delete;
|
MessageBuilder& operator=(const MessageBuilder& other) = delete;
|
||||||
|
|
||||||
MessageBuilder(MessageBuilder &&other)
|
MessageBuilder(MessageBuilder&& other)
|
||||||
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
||||||
// Default construct and swap idiom.
|
// Default construct and swap idiom.
|
||||||
Swap(other);
|
Swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a MessageBuilder from a FlatBufferBuilder.
|
/// Create a MessageBuilder from a FlatBufferBuilder.
|
||||||
explicit MessageBuilder(FlatBufferBuilder &&src,
|
explicit MessageBuilder(FlatBufferBuilder&& src,
|
||||||
void (*dealloc)(void *,
|
void (*dealloc)(void*,
|
||||||
size_t) = &DefaultAllocator::dealloc)
|
size_t) = &DefaultAllocator::dealloc)
|
||||||
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
||||||
src.Swap(*this);
|
src.Swap(*this);
|
||||||
src.SwapBufAllocator(*this);
|
src.SwapBufAllocator(*this);
|
||||||
if (buf_.capacity()) {
|
if (buf_.capacity()) {
|
||||||
uint8_t *buf = buf_.scratch_data(); // pointer to memory
|
uint8_t* buf = buf_.scratch_data(); // pointer to memory
|
||||||
size_t capacity = buf_.capacity(); // size of memory
|
size_t capacity = buf_.capacity(); // size of memory
|
||||||
slice_allocator_.slice_ = ::grpc::Slice(buf, capacity, dealloc);
|
slice_allocator_.slice_ = ::grpc::Slice(buf, capacity, dealloc);
|
||||||
} else {
|
} else {
|
||||||
@@ -181,21 +182,21 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
|
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
|
||||||
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is
|
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is
|
||||||
/// supported.
|
/// supported.
|
||||||
MessageBuilder &operator=(FlatBufferBuilder &&src) {
|
MessageBuilder& operator=(FlatBufferBuilder&& src) {
|
||||||
// Move construct a temporary and swap
|
// Move construct a temporary and swap
|
||||||
MessageBuilder temp(std::move(src));
|
MessageBuilder temp(std::move(src));
|
||||||
Swap(temp);
|
Swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageBuilder &operator=(MessageBuilder &&other) {
|
MessageBuilder& operator=(MessageBuilder&& other) {
|
||||||
// Move construct a temporary and swap
|
// Move construct a temporary and swap
|
||||||
MessageBuilder temp(std::move(other));
|
MessageBuilder temp(std::move(other));
|
||||||
Swap(temp);
|
Swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swap(MessageBuilder &other) {
|
void Swap(MessageBuilder& other) {
|
||||||
slice_allocator_.swap(other.slice_allocator_);
|
slice_allocator_.swap(other.slice_allocator_);
|
||||||
FlatBufferBuilder::Swap(other);
|
FlatBufferBuilder::Swap(other);
|
||||||
// After swapping the FlatBufferBuilder, we swap back the allocator, which
|
// After swapping the FlatBufferBuilder, we swap back the allocator, which
|
||||||
@@ -209,8 +210,8 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
// Releases the ownership of the buffer pointer.
|
// Releases the ownership of the buffer pointer.
|
||||||
// Returns the size, offset, and the original grpc_slice that
|
// Returns the size, offset, and the original grpc_slice that
|
||||||
// allocated the buffer. Also see grpc_slice_unref().
|
// allocated the buffer. Also see grpc_slice_unref().
|
||||||
uint8_t *ReleaseRaw(size_t &size, size_t &offset, ::grpc::Slice &slice) {
|
uint8_t* ReleaseRaw(size_t& size, size_t& offset, ::grpc::Slice& slice) {
|
||||||
uint8_t *buf = FlatBufferBuilder::ReleaseRaw(size, offset);
|
uint8_t* buf = FlatBufferBuilder::ReleaseRaw(size, offset);
|
||||||
slice = slice_allocator_.slice_;
|
slice = slice_allocator_.slice_;
|
||||||
slice_allocator_.slice_ = ::grpc::Slice();
|
slice_allocator_.slice_ = ::grpc::Slice();
|
||||||
return buf;
|
return buf;
|
||||||
@@ -221,7 +222,8 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
// GetMessage extracts the subslice of the buffer corresponding to the
|
// GetMessage extracts the subslice of the buffer corresponding to the
|
||||||
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
|
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
|
||||||
// ownership.
|
// ownership.
|
||||||
template<class T> Message<T> GetMessage() {
|
template <class T>
|
||||||
|
Message<T> GetMessage() {
|
||||||
auto buf_data = buf_.scratch_data(); // pointer to memory
|
auto buf_data = buf_.scratch_data(); // pointer to memory
|
||||||
auto buf_size = buf_.capacity(); // size of memory
|
auto buf_size = buf_.capacity(); // size of memory
|
||||||
auto msg_data = buf_.data(); // pointer to msg
|
auto msg_data = buf_.data(); // pointer to msg
|
||||||
@@ -243,7 +245,8 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> Message<T> ReleaseMessage() {
|
template <class T>
|
||||||
|
Message<T> ReleaseMessage() {
|
||||||
Message<T> msg = GetMessage<T>();
|
Message<T> msg = GetMessage<T>();
|
||||||
Reset();
|
Reset();
|
||||||
return msg;
|
return msg;
|
||||||
@@ -258,10 +261,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
|
|
||||||
namespace grpc {
|
namespace grpc {
|
||||||
|
|
||||||
template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
template <class T>
|
||||||
|
class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
||||||
public:
|
public:
|
||||||
static grpc::Status Serialize(const flatbuffers::grpc::Message<T> &msg,
|
static grpc::Status Serialize(const flatbuffers::grpc::Message<T>& msg,
|
||||||
ByteBuffer *buffer, bool *own_buffer) {
|
ByteBuffer* buffer, bool* own_buffer) {
|
||||||
// Package the single slice into a `ByteBuffer`,
|
// Package the single slice into a `ByteBuffer`,
|
||||||
// incrementing the refcount in the process.
|
// incrementing the refcount in the process.
|
||||||
*buffer = ByteBuffer(&msg.BorrowSlice(), 1);
|
*buffer = ByteBuffer(&msg.BorrowSlice(), 1);
|
||||||
@@ -270,8 +274,8 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Deserialize by pulling the
|
// Deserialize by pulling the
|
||||||
static grpc::Status Deserialize(ByteBuffer *buf,
|
static grpc::Status Deserialize(ByteBuffer* buf,
|
||||||
flatbuffers::grpc::Message<T> *msg) {
|
flatbuffers::grpc::Message<T>* msg) {
|
||||||
Slice slice;
|
Slice slice;
|
||||||
if (!buf->TrySingleSlice(&slice).ok()) {
|
if (!buf->TrySingleSlice(&slice).ok()) {
|
||||||
if (!buf->DumpToSingleSlice(&slice).ok()) {
|
if (!buf->DumpToSingleSlice(&slice).ok()) {
|
||||||
|
|||||||
@@ -24,73 +24,81 @@
|
|||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
template<typename T> struct FnvTraits {
|
template <typename T>
|
||||||
|
struct FnvTraits {
|
||||||
static const T kFnvPrime;
|
static const T kFnvPrime;
|
||||||
static const T kOffsetBasis;
|
static const T kOffsetBasis;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct FnvTraits<uint32_t> {
|
template <>
|
||||||
|
struct FnvTraits<uint32_t> {
|
||||||
static const uint32_t kFnvPrime = 0x01000193;
|
static const uint32_t kFnvPrime = 0x01000193;
|
||||||
static const uint32_t kOffsetBasis = 0x811C9DC5;
|
static const uint32_t kOffsetBasis = 0x811C9DC5;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<> struct FnvTraits<uint64_t> {
|
template <>
|
||||||
|
struct FnvTraits<uint64_t> {
|
||||||
static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
|
static const uint64_t kFnvPrime = 0x00000100000001b3ULL;
|
||||||
static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
|
static const uint64_t kOffsetBasis = 0xcbf29ce484222645ULL;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> T HashFnv1(const char *input) {
|
template <typename T>
|
||||||
|
T HashFnv1(const char* input) {
|
||||||
T hash = FnvTraits<T>::kOffsetBasis;
|
T hash = FnvTraits<T>::kOffsetBasis;
|
||||||
for (const char *c = input; *c; ++c) {
|
for (const char* c = input; *c; ++c) {
|
||||||
hash *= FnvTraits<T>::kFnvPrime;
|
hash *= FnvTraits<T>::kFnvPrime;
|
||||||
hash ^= static_cast<unsigned char>(*c);
|
hash ^= static_cast<unsigned char>(*c);
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> T HashFnv1a(const char *input) {
|
template <typename T>
|
||||||
|
T HashFnv1a(const char* input) {
|
||||||
T hash = FnvTraits<T>::kOffsetBasis;
|
T hash = FnvTraits<T>::kOffsetBasis;
|
||||||
for (const char *c = input; *c; ++c) {
|
for (const char* c = input; *c; ++c) {
|
||||||
hash ^= static_cast<unsigned char>(*c);
|
hash ^= static_cast<unsigned char>(*c);
|
||||||
hash *= FnvTraits<T>::kFnvPrime;
|
hash *= FnvTraits<T>::kFnvPrime;
|
||||||
}
|
}
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline uint16_t HashFnv1<uint16_t>(const char *input) {
|
template <>
|
||||||
|
inline uint16_t HashFnv1<uint16_t>(const char* input) {
|
||||||
uint32_t hash = HashFnv1<uint32_t>(input);
|
uint32_t hash = HashFnv1<uint32_t>(input);
|
||||||
return (hash >> 16) ^ (hash & 0xffff);
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
|
template <>
|
||||||
|
inline uint16_t HashFnv1a<uint16_t>(const char* input) {
|
||||||
uint32_t hash = HashFnv1a<uint32_t>(input);
|
uint32_t hash = HashFnv1a<uint32_t>(input);
|
||||||
return (hash >> 16) ^ (hash & 0xffff);
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> struct NamedHashFunction {
|
template <typename T>
|
||||||
const char *name;
|
struct NamedHashFunction {
|
||||||
|
const char* name;
|
||||||
|
|
||||||
typedef T (*HashFunction)(const char *);
|
typedef T (*HashFunction)(const char*);
|
||||||
HashFunction function;
|
HashFunction function;
|
||||||
};
|
};
|
||||||
|
|
||||||
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
|
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
|
||||||
{ "fnv1_16", HashFnv1<uint16_t> },
|
{"fnv1_16", HashFnv1<uint16_t>},
|
||||||
{ "fnv1a_16", HashFnv1a<uint16_t> },
|
{"fnv1a_16", HashFnv1a<uint16_t>},
|
||||||
};
|
};
|
||||||
|
|
||||||
const NamedHashFunction<uint32_t> kHashFunctions32[] = {
|
const NamedHashFunction<uint32_t> kHashFunctions32[] = {
|
||||||
{ "fnv1_32", HashFnv1<uint32_t> },
|
{"fnv1_32", HashFnv1<uint32_t>},
|
||||||
{ "fnv1a_32", HashFnv1a<uint32_t> },
|
{"fnv1a_32", HashFnv1a<uint32_t>},
|
||||||
};
|
};
|
||||||
|
|
||||||
const NamedHashFunction<uint64_t> kHashFunctions64[] = {
|
const NamedHashFunction<uint64_t> kHashFunctions64[] = {
|
||||||
{ "fnv1_64", HashFnv1<uint64_t> },
|
{"fnv1_64", HashFnv1<uint64_t>},
|
||||||
{ "fnv1a_64", HashFnv1a<uint64_t> },
|
{"fnv1a_64", HashFnv1a<uint64_t>},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16(
|
inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16(
|
||||||
const char *name) {
|
const char* name) {
|
||||||
std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]);
|
std::size_t size = sizeof(kHashFunctions16) / sizeof(kHashFunctions16[0]);
|
||||||
for (std::size_t i = 0; i < size; ++i) {
|
for (std::size_t i = 0; i < size; ++i) {
|
||||||
if (std::strcmp(name, kHashFunctions16[i].name) == 0) {
|
if (std::strcmp(name, kHashFunctions16[i].name) == 0) {
|
||||||
@@ -101,7 +109,7 @@ inline NamedHashFunction<uint16_t>::HashFunction FindHashFunction16(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
|
inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
|
||||||
const char *name) {
|
const char* name) {
|
||||||
std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
|
std::size_t size = sizeof(kHashFunctions32) / sizeof(kHashFunctions32[0]);
|
||||||
for (std::size_t i = 0; i < size; ++i) {
|
for (std::size_t i = 0; i < size; ++i) {
|
||||||
if (std::strcmp(name, kHashFunctions32[i].name) == 0) {
|
if (std::strcmp(name, kHashFunctions32[i].name) == 0) {
|
||||||
@@ -112,7 +120,7 @@ inline NamedHashFunction<uint32_t>::HashFunction FindHashFunction32(
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64(
|
inline NamedHashFunction<uint64_t>::HashFunction FindHashFunction64(
|
||||||
const char *name) {
|
const char* name) {
|
||||||
std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]);
|
std::size_t size = sizeof(kHashFunctions64) / sizeof(kHashFunctions64[0]);
|
||||||
for (std::size_t i = 0; i < size; ++i) {
|
for (std::size_t i = 0; i < size; ++i) {
|
||||||
if (std::strcmp(name, kHashFunctions64[i].name) == 0) {
|
if (std::strcmp(name, kHashFunctions64[i].name) == 0) {
|
||||||
|
|||||||
@@ -36,7 +36,7 @@
|
|||||||
// Limits maximum depth of nested objects.
|
// Limits maximum depth of nested objects.
|
||||||
// Prevents stack overflow while parse scheme, or json, or flexbuffer.
|
// Prevents stack overflow while parse scheme, or json, or flexbuffer.
|
||||||
#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH)
|
#if !defined(FLATBUFFERS_MAX_PARSING_DEPTH)
|
||||||
# define FLATBUFFERS_MAX_PARSING_DEPTH 64
|
#define FLATBUFFERS_MAX_PARSING_DEPTH 64
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
@@ -192,15 +192,15 @@ class Parser;
|
|||||||
// Represents any type in the IDL, which is a combination of the BaseType
|
// Represents any type in the IDL, which is a combination of the BaseType
|
||||||
// and additional information for vectors/structs_.
|
// and additional information for vectors/structs_.
|
||||||
struct Type {
|
struct Type {
|
||||||
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
|
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef* _sd = nullptr,
|
||||||
EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
|
EnumDef* _ed = nullptr, uint16_t _fixed_length = 0)
|
||||||
: base_type(_base_type),
|
: base_type(_base_type),
|
||||||
element(BASE_TYPE_NONE),
|
element(BASE_TYPE_NONE),
|
||||||
struct_def(_sd),
|
struct_def(_sd),
|
||||||
enum_def(_ed),
|
enum_def(_ed),
|
||||||
fixed_length(_fixed_length) {}
|
fixed_length(_fixed_length) {}
|
||||||
|
|
||||||
bool operator==(const Type &o) const {
|
bool operator==(const Type& o) const {
|
||||||
return base_type == o.base_type && element == o.element &&
|
return base_type == o.base_type && element == o.element &&
|
||||||
struct_def == o.struct_def && enum_def == o.enum_def;
|
struct_def == o.struct_def && enum_def == o.enum_def;
|
||||||
}
|
}
|
||||||
@@ -209,15 +209,15 @@ struct Type {
|
|||||||
return Type(element, struct_def, enum_def, fixed_length);
|
return Type(element, struct_def, enum_def, fixed_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
|
Offset<reflection::Type> Serialize(FlatBufferBuilder* builder) const;
|
||||||
|
|
||||||
bool Deserialize(const Parser &parser, const reflection::Type *type);
|
bool Deserialize(const Parser& parser, const reflection::Type* type);
|
||||||
|
|
||||||
BaseType base_type;
|
BaseType base_type;
|
||||||
BaseType element; // only set if t == BASE_TYPE_VECTOR or
|
BaseType element; // only set if t == BASE_TYPE_VECTOR or
|
||||||
// BASE_TYPE_VECTOR64
|
// BASE_TYPE_VECTOR64
|
||||||
StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT
|
StructDef* struct_def; // only set if t or element == BASE_TYPE_STRUCT
|
||||||
EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
|
EnumDef* enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
|
||||||
// or for an integral type derived from an enum.
|
// or for an integral type derived from an enum.
|
||||||
uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
|
uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
|
||||||
};
|
};
|
||||||
@@ -234,13 +234,16 @@ struct Value {
|
|||||||
|
|
||||||
// Helper class that retains the original order of a set of identifiers and
|
// Helper class that retains the original order of a set of identifiers and
|
||||||
// also provides quick lookup.
|
// also provides quick lookup.
|
||||||
template<typename T> class SymbolTable {
|
template <typename T>
|
||||||
|
class SymbolTable {
|
||||||
public:
|
public:
|
||||||
~SymbolTable() {
|
~SymbolTable() {
|
||||||
for (auto it = vec.begin(); it != vec.end(); ++it) { delete *it; }
|
for (auto it = vec.begin(); it != vec.end(); ++it) {
|
||||||
|
delete *it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Add(const std::string &name, T *e) {
|
bool Add(const std::string& name, T* e) {
|
||||||
vec.emplace_back(e);
|
vec.emplace_back(e);
|
||||||
auto it = dict.find(name);
|
auto it = dict.find(name);
|
||||||
if (it != dict.end()) return true;
|
if (it != dict.end()) return true;
|
||||||
@@ -248,7 +251,7 @@ template<typename T> class SymbolTable {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Move(const std::string &oldname, const std::string &newname) {
|
void Move(const std::string& oldname, const std::string& newname) {
|
||||||
auto it = dict.find(oldname);
|
auto it = dict.find(oldname);
|
||||||
if (it != dict.end()) {
|
if (it != dict.end()) {
|
||||||
auto obj = it->second;
|
auto obj = it->second;
|
||||||
@@ -259,14 +262,14 @@ template<typename T> class SymbolTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
T *Lookup(const std::string &name) const {
|
T* Lookup(const std::string& name) const {
|
||||||
auto it = dict.find(name);
|
auto it = dict.find(name);
|
||||||
return it == dict.end() ? nullptr : it->second;
|
return it == dict.end() ? nullptr : it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
std::map<std::string, T *> dict; // quick lookup
|
std::map<std::string, T*> dict; // quick lookup
|
||||||
std::vector<T *> vec; // Used to iterate in order of insertion
|
std::vector<T*> vec; // Used to iterate in order of insertion
|
||||||
};
|
};
|
||||||
|
|
||||||
// A name space, as set in the schema.
|
// A name space, as set in the schema.
|
||||||
@@ -277,14 +280,14 @@ struct Namespace {
|
|||||||
// which has a full namespaced descriptor.
|
// which has a full namespaced descriptor.
|
||||||
// With max_components you can request less than the number of components
|
// With max_components you can request less than the number of components
|
||||||
// the current namespace has.
|
// the current namespace has.
|
||||||
std::string GetFullyQualifiedName(const std::string &name,
|
std::string GetFullyQualifiedName(const std::string& name,
|
||||||
size_t max_components = 1000) const;
|
size_t max_components = 1000) const;
|
||||||
|
|
||||||
std::vector<std::string> components;
|
std::vector<std::string> components;
|
||||||
size_t from_table; // Part of the namespace corresponds to a message/table.
|
size_t from_table; // Part of the namespace corresponds to a message/table.
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool operator<(const Namespace &a, const Namespace &b) {
|
inline bool operator<(const Namespace& a, const Namespace& b) {
|
||||||
size_t min_size = std::min(a.components.size(), b.components.size());
|
size_t min_size = std::min(a.components.size(), b.components.size());
|
||||||
for (size_t i = 0; i < min_size; ++i) {
|
for (size_t i = 0; i < min_size; ++i) {
|
||||||
if (a.components[i] != b.components[i])
|
if (a.components[i] != b.components[i])
|
||||||
@@ -305,23 +308,23 @@ struct Definition {
|
|||||||
|
|
||||||
flatbuffers::Offset<
|
flatbuffers::Offset<
|
||||||
flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
|
flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
|
||||||
SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;
|
SerializeAttributes(FlatBufferBuilder* builder, const Parser& parser) const;
|
||||||
|
|
||||||
bool DeserializeAttributes(Parser &parser,
|
bool DeserializeAttributes(Parser& parser,
|
||||||
const Vector<Offset<reflection::KeyValue>> *attrs);
|
const Vector<Offset<reflection::KeyValue>>* attrs);
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string file;
|
std::string file;
|
||||||
std::vector<std::string> doc_comment;
|
std::vector<std::string> doc_comment;
|
||||||
SymbolTable<Value> attributes;
|
SymbolTable<Value> attributes;
|
||||||
bool generated; // did we already output code for this definition?
|
bool generated; // did we already output code for this definition?
|
||||||
Namespace *defined_namespace; // Where it was defined.
|
Namespace* defined_namespace; // Where it was defined.
|
||||||
|
|
||||||
// For use with Serialize()
|
// For use with Serialize()
|
||||||
uoffset_t serialized_location;
|
uoffset_t serialized_location;
|
||||||
int index; // Inside the vector it is stored.
|
int index; // Inside the vector it is stored.
|
||||||
int refcount;
|
int refcount;
|
||||||
const std::string *declaration_file;
|
const std::string* declaration_file;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldDef : public Definition {
|
struct FieldDef : public Definition {
|
||||||
@@ -337,15 +340,12 @@ struct FieldDef : public Definition {
|
|||||||
padding(0),
|
padding(0),
|
||||||
sibling_union_field(nullptr) {}
|
sibling_union_field(nullptr) {}
|
||||||
|
|
||||||
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
|
Offset<reflection::Field> Serialize(FlatBufferBuilder* builder, uint16_t id,
|
||||||
const Parser &parser) const;
|
const Parser& parser) const;
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::Field *field);
|
bool Deserialize(Parser& parser, const reflection::Field* field);
|
||||||
|
|
||||||
|
bool IsScalarOptional() const { return IsScalar() && IsOptional(); }
|
||||||
bool IsScalarOptional() const {
|
|
||||||
return IsScalar() && IsOptional();
|
|
||||||
}
|
|
||||||
bool IsScalar() const {
|
bool IsScalar() const {
|
||||||
return ::flatbuffers::IsScalar(value.type.base_type);
|
return ::flatbuffers::IsScalar(value.type.base_type);
|
||||||
}
|
}
|
||||||
@@ -383,14 +383,14 @@ struct FieldDef : public Definition {
|
|||||||
}
|
}
|
||||||
Presence presence;
|
Presence presence;
|
||||||
|
|
||||||
StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data.
|
StructDef* nested_flatbuffer; // This field contains nested FlatBuffer data.
|
||||||
size_t padding; // Bytes to always pad after this field.
|
size_t padding; // Bytes to always pad after this field.
|
||||||
|
|
||||||
// sibling_union_field is always set to nullptr. The only exception is
|
// sibling_union_field is always set to nullptr. The only exception is
|
||||||
// when FieldDef is a union field or an union type field. Therefore,
|
// when FieldDef is a union field or an union type field. Therefore,
|
||||||
// sibling_union_field on a union field points to the union type field
|
// sibling_union_field on a union field points to the union type field
|
||||||
// and vice-versa.
|
// and vice-versa.
|
||||||
FieldDef *sibling_union_field;
|
FieldDef* sibling_union_field;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StructDef : public Definition {
|
struct StructDef : public Definition {
|
||||||
@@ -408,10 +408,10 @@ struct StructDef : public Definition {
|
|||||||
if (fields.vec.size()) fields.vec.back()->padding = padding;
|
if (fields.vec.size()) fields.vec.back()->padding = padding;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset<reflection::Object> Serialize(FlatBufferBuilder *builder,
|
Offset<reflection::Object> Serialize(FlatBufferBuilder* builder,
|
||||||
const Parser &parser) const;
|
const Parser& parser) const;
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::Object *object);
|
bool Deserialize(Parser& parser, const reflection::Object* object);
|
||||||
|
|
||||||
SymbolTable<FieldDef> fields;
|
SymbolTable<FieldDef> fields;
|
||||||
|
|
||||||
@@ -430,17 +430,17 @@ struct EnumDef;
|
|||||||
struct EnumValBuilder;
|
struct EnumValBuilder;
|
||||||
|
|
||||||
struct EnumVal {
|
struct EnumVal {
|
||||||
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
|
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder* builder,
|
||||||
const Parser &parser) const;
|
const Parser& parser) const;
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::EnumVal *val);
|
bool Deserialize(Parser& parser, const reflection::EnumVal* val);
|
||||||
|
|
||||||
flatbuffers::Offset<
|
flatbuffers::Offset<
|
||||||
flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
|
flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>>
|
||||||
SerializeAttributes(FlatBufferBuilder *builder, const Parser &parser) const;
|
SerializeAttributes(FlatBufferBuilder* builder, const Parser& parser) const;
|
||||||
|
|
||||||
bool DeserializeAttributes(Parser &parser,
|
bool DeserializeAttributes(Parser& parser,
|
||||||
const Vector<Offset<reflection::KeyValue>> *attrs);
|
const Vector<Offset<reflection::KeyValue>>* attrs);
|
||||||
|
|
||||||
uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
|
uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
|
||||||
int64_t GetAsInt64() const { return value; }
|
int64_t GetAsInt64() const { return value; }
|
||||||
@@ -455,9 +455,9 @@ struct EnumVal {
|
|||||||
private:
|
private:
|
||||||
friend EnumDef;
|
friend EnumDef;
|
||||||
friend EnumValBuilder;
|
friend EnumValBuilder;
|
||||||
friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);
|
friend bool operator==(const EnumVal& lhs, const EnumVal& rhs);
|
||||||
|
|
||||||
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
|
EnumVal(const std::string& _name, int64_t _val) : name(_name), value(_val) {}
|
||||||
EnumVal() : value(0) {}
|
EnumVal() : value(0) {}
|
||||||
|
|
||||||
int64_t value;
|
int64_t value;
|
||||||
@@ -466,37 +466,38 @@ struct EnumVal {
|
|||||||
struct EnumDef : public Definition {
|
struct EnumDef : public Definition {
|
||||||
EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
|
EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
|
||||||
|
|
||||||
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
|
Offset<reflection::Enum> Serialize(FlatBufferBuilder* builder,
|
||||||
const Parser &parser) const;
|
const Parser& parser) const;
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::Enum *values);
|
bool Deserialize(Parser& parser, const reflection::Enum* values);
|
||||||
|
|
||||||
template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
|
template <typename T>
|
||||||
|
void ChangeEnumValue(EnumVal* ev, T new_val);
|
||||||
void SortByValue();
|
void SortByValue();
|
||||||
void RemoveDuplicates();
|
void RemoveDuplicates();
|
||||||
|
|
||||||
std::string AllFlags() const;
|
std::string AllFlags() const;
|
||||||
const EnumVal *MinValue() const;
|
const EnumVal* MinValue() const;
|
||||||
const EnumVal *MaxValue() const;
|
const EnumVal* MaxValue() const;
|
||||||
// Returns the number of integer steps from v1 to v2.
|
// Returns the number of integer steps from v1 to v2.
|
||||||
uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
|
uint64_t Distance(const EnumVal* v1, const EnumVal* v2) const;
|
||||||
// Returns the number of integer steps from Min to Max.
|
// Returns the number of integer steps from Min to Max.
|
||||||
uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
|
uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
|
||||||
|
|
||||||
EnumVal *ReverseLookup(int64_t enum_idx,
|
EnumVal* ReverseLookup(int64_t enum_idx,
|
||||||
bool skip_union_default = false) const;
|
bool skip_union_default = false) const;
|
||||||
EnumVal *FindByValue(const std::string &constant) const;
|
EnumVal* FindByValue(const std::string& constant) const;
|
||||||
|
|
||||||
std::string ToString(const EnumVal &ev) const {
|
std::string ToString(const EnumVal& ev) const {
|
||||||
return IsUInt64() ? NumToString(ev.GetAsUInt64())
|
return IsUInt64() ? NumToString(ev.GetAsUInt64())
|
||||||
: NumToString(ev.GetAsInt64());
|
: NumToString(ev.GetAsInt64());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t size() const { return vals.vec.size(); }
|
size_t size() const { return vals.vec.size(); }
|
||||||
|
|
||||||
const std::vector<EnumVal *> &Vals() const { return vals.vec; }
|
const std::vector<EnumVal*>& Vals() const { return vals.vec; }
|
||||||
|
|
||||||
const EnumVal *Lookup(const std::string &enum_name) const {
|
const EnumVal* Lookup(const std::string& enum_name) const {
|
||||||
return vals.Lookup(enum_name);
|
return vals.Lookup(enum_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,53 +516,53 @@ struct EnumDef : public Definition {
|
|||||||
SymbolTable<EnumVal> vals;
|
SymbolTable<EnumVal> vals;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsString(const Type &type) {
|
inline bool IsString(const Type& type) {
|
||||||
return type.base_type == BASE_TYPE_STRING;
|
return type.base_type == BASE_TYPE_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsStruct(const Type &type) {
|
inline bool IsStruct(const Type& type) {
|
||||||
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
|
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsIncompleteStruct(const Type &type) {
|
inline bool IsIncompleteStruct(const Type& type) {
|
||||||
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->predecl;
|
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->predecl;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsTable(const Type &type) {
|
inline bool IsTable(const Type& type) {
|
||||||
return type.base_type == BASE_TYPE_STRUCT && !type.struct_def->fixed;
|
return type.base_type == BASE_TYPE_STRUCT && !type.struct_def->fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsUnion(const Type &type) {
|
inline bool IsUnion(const Type& type) {
|
||||||
return type.enum_def != nullptr && type.enum_def->is_union;
|
return type.enum_def != nullptr && type.enum_def->is_union;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsUnionType(const Type &type) {
|
inline bool IsUnionType(const Type& type) {
|
||||||
return IsUnion(type) && IsInteger(type.base_type);
|
return IsUnion(type) && IsInteger(type.base_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsVector(const Type &type) { return IsVector(type.base_type); }
|
inline bool IsVector(const Type& type) { return IsVector(type.base_type); }
|
||||||
|
|
||||||
inline bool IsVectorOfStruct(const Type &type) {
|
inline bool IsVectorOfStruct(const Type& type) {
|
||||||
return IsVector(type) && IsStruct(type.VectorType());
|
return IsVector(type) && IsStruct(type.VectorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsVectorOfTable(const Type &type) {
|
inline bool IsVectorOfTable(const Type& type) {
|
||||||
return IsVector(type) && IsTable(type.VectorType());
|
return IsVector(type) && IsTable(type.VectorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsArray(const Type &type) {
|
inline bool IsArray(const Type& type) {
|
||||||
return type.base_type == BASE_TYPE_ARRAY;
|
return type.base_type == BASE_TYPE_ARRAY;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsSeries(const Type &type) {
|
inline bool IsSeries(const Type& type) {
|
||||||
return IsVector(type) || IsArray(type);
|
return IsVector(type) || IsArray(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsEnum(const Type &type) {
|
inline bool IsEnum(const Type& type) {
|
||||||
return type.enum_def != nullptr && IsInteger(type.base_type);
|
return type.enum_def != nullptr && IsInteger(type.base_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t InlineSize(const Type &type) {
|
inline size_t InlineSize(const Type& type) {
|
||||||
return IsStruct(type)
|
return IsStruct(type)
|
||||||
? type.struct_def->bytesize
|
? type.struct_def->bytesize
|
||||||
: (IsArray(type)
|
: (IsArray(type)
|
||||||
@@ -569,7 +570,7 @@ inline size_t InlineSize(const Type &type) {
|
|||||||
: SizeOf(type.base_type));
|
: SizeOf(type.base_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t InlineAlignment(const Type &type) {
|
inline size_t InlineAlignment(const Type& type) {
|
||||||
if (IsStruct(type)) {
|
if (IsStruct(type)) {
|
||||||
return type.struct_def->minalign;
|
return type.struct_def->minalign;
|
||||||
} else if (IsArray(type)) {
|
} else if (IsArray(type)) {
|
||||||
@@ -579,14 +580,14 @@ inline size_t InlineAlignment(const Type &type) {
|
|||||||
return SizeOf(type.base_type);
|
return SizeOf(type.base_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
|
inline bool operator==(const EnumVal& lhs, const EnumVal& rhs) {
|
||||||
return lhs.value == rhs.value;
|
return lhs.value == rhs.value;
|
||||||
}
|
}
|
||||||
inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
|
inline bool operator!=(const EnumVal& lhs, const EnumVal& rhs) {
|
||||||
return !(lhs == rhs);
|
return !(lhs == rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool EqualByName(const Type &a, const Type &b) {
|
inline bool EqualByName(const Type& a, const Type& b) {
|
||||||
return a.base_type == b.base_type && a.element == b.element &&
|
return a.base_type == b.base_type && a.element == b.element &&
|
||||||
(a.struct_def == b.struct_def ||
|
(a.struct_def == b.struct_def ||
|
||||||
(a.struct_def != nullptr && b.struct_def != nullptr &&
|
(a.struct_def != nullptr && b.struct_def != nullptr &&
|
||||||
@@ -597,18 +598,18 @@ inline bool EqualByName(const Type &a, const Type &b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RPCCall : public Definition {
|
struct RPCCall : public Definition {
|
||||||
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
|
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder* builder,
|
||||||
const Parser &parser) const;
|
const Parser& parser) const;
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::RPCCall *call);
|
bool Deserialize(Parser& parser, const reflection::RPCCall* call);
|
||||||
|
|
||||||
StructDef *request, *response;
|
StructDef *request, *response;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ServiceDef : public Definition {
|
struct ServiceDef : public Definition {
|
||||||
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
|
Offset<reflection::Service> Serialize(FlatBufferBuilder* builder,
|
||||||
const Parser &parser) const;
|
const Parser& parser) const;
|
||||||
bool Deserialize(Parser &parser, const reflection::Service *service);
|
bool Deserialize(Parser& parser, const reflection::Service* service);
|
||||||
|
|
||||||
SymbolTable<RPCCall> calls;
|
SymbolTable<RPCCall> calls;
|
||||||
};
|
};
|
||||||
@@ -627,7 +628,7 @@ struct IncludedFile {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Since IncludedFile is contained within a std::set, need to provide ordering.
|
// Since IncludedFile is contained within a std::set, need to provide ordering.
|
||||||
inline bool operator<(const IncludedFile &a, const IncludedFile &b) {
|
inline bool operator<(const IncludedFile& a, const IncludedFile& b) {
|
||||||
return a.filename < b.filename;
|
return a.filename < b.filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -711,7 +712,7 @@ struct IDLOptions {
|
|||||||
/********************************** Python **********************************/
|
/********************************** Python **********************************/
|
||||||
bool python_no_type_prefix_suffix;
|
bool python_no_type_prefix_suffix;
|
||||||
bool python_typing;
|
bool python_typing;
|
||||||
bool python_decode_obj_api_strings=false;
|
bool python_decode_obj_api_strings = false;
|
||||||
|
|
||||||
// The target Python version. Can be one of the following:
|
// The target Python version. Can be one of the following:
|
||||||
// - "0"
|
// - "0"
|
||||||
@@ -881,7 +882,7 @@ struct ParserState {
|
|||||||
attr_is_trivial_ascii_string_(true) {}
|
attr_is_trivial_ascii_string_(true) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void ResetState(const char *source) {
|
void ResetState(const char* source) {
|
||||||
prev_cursor_ = source;
|
prev_cursor_ = source;
|
||||||
cursor_ = source;
|
cursor_ = source;
|
||||||
line_ = 0;
|
line_ = 0;
|
||||||
@@ -898,9 +899,9 @@ struct ParserState {
|
|||||||
return static_cast<int64_t>(cursor_ - line_start_);
|
return static_cast<int64_t>(cursor_ - line_start_);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *prev_cursor_;
|
const char* prev_cursor_;
|
||||||
const char *cursor_;
|
const char* cursor_;
|
||||||
const char *line_start_;
|
const char* line_start_;
|
||||||
int line_; // the current line being parsed
|
int line_; // the current line being parsed
|
||||||
int token_;
|
int token_;
|
||||||
|
|
||||||
@@ -924,14 +925,14 @@ class CheckedError {
|
|||||||
explicit CheckedError(bool error)
|
explicit CheckedError(bool error)
|
||||||
: is_error_(error), has_been_checked_(false) {}
|
: is_error_(error), has_been_checked_(false) {}
|
||||||
|
|
||||||
CheckedError &operator=(const CheckedError &other) {
|
CheckedError& operator=(const CheckedError& other) {
|
||||||
is_error_ = other.is_error_;
|
is_error_ = other.is_error_;
|
||||||
has_been_checked_ = false;
|
has_been_checked_ = false;
|
||||||
other.has_been_checked_ = true;
|
other.has_been_checked_ = true;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
CheckedError(const CheckedError &other) {
|
CheckedError(const CheckedError& other) {
|
||||||
*this = other; // Use assignment operator.
|
*this = other; // Use assignment operator.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -960,7 +961,7 @@ class CheckedError {
|
|||||||
|
|
||||||
class Parser : public ParserState {
|
class Parser : public ParserState {
|
||||||
public:
|
public:
|
||||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
explicit Parser(const IDLOptions& options = IDLOptions())
|
||||||
: current_namespace_(nullptr),
|
: current_namespace_(nullptr),
|
||||||
empty_namespace_(nullptr),
|
empty_namespace_(nullptr),
|
||||||
flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
|
flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
|
||||||
@@ -972,7 +973,9 @@ class Parser : public ParserState {
|
|||||||
source_(nullptr),
|
source_(nullptr),
|
||||||
anonymous_counter_(0),
|
anonymous_counter_(0),
|
||||||
parse_depth_counter_(0) {
|
parse_depth_counter_(0) {
|
||||||
if (opts.force_defaults) { builder_.ForceDefaults(true); }
|
if (opts.force_defaults) {
|
||||||
|
builder_.ForceDefaults(true);
|
||||||
|
}
|
||||||
// Start out with the empty namespace being current.
|
// Start out with the empty namespace being current.
|
||||||
empty_namespace_ = new Namespace();
|
empty_namespace_ = new Namespace();
|
||||||
namespaces_.push_back(empty_namespace_);
|
namespaces_.push_back(empty_namespace_);
|
||||||
@@ -1012,11 +1015,11 @@ class Parser : public ParserState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Copying is not allowed
|
// Copying is not allowed
|
||||||
Parser(const Parser &) = delete;
|
Parser(const Parser&) = delete;
|
||||||
Parser &operator=(const Parser &) = delete;
|
Parser& operator=(const Parser&) = delete;
|
||||||
|
|
||||||
Parser(Parser &&) = default;
|
Parser(Parser&&) = default;
|
||||||
Parser &operator=(Parser &&) = default;
|
Parser& operator=(Parser&&) = default;
|
||||||
|
|
||||||
~Parser() {
|
~Parser() {
|
||||||
for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) {
|
for (auto it = namespaces_.begin(); it != namespaces_.end(); ++it) {
|
||||||
@@ -1035,16 +1038,16 @@ class Parser : public ParserState {
|
|||||||
// supply its name in source_filename.
|
// supply its name in source_filename.
|
||||||
// All paths specified in this call must be in posix format, if you accept
|
// All paths specified in this call must be in posix format, if you accept
|
||||||
// paths from user input, please call PosixPath on them first.
|
// paths from user input, please call PosixPath on them first.
|
||||||
bool Parse(const char *_source, const char **include_paths = nullptr,
|
bool Parse(const char* _source, const char** include_paths = nullptr,
|
||||||
const char *source_filename = nullptr);
|
const char* source_filename = nullptr);
|
||||||
|
|
||||||
bool ParseJson(const char *json, const char *json_filename = nullptr);
|
bool ParseJson(const char* json, const char* json_filename = nullptr);
|
||||||
|
|
||||||
// Returns the number of characters were consumed when parsing a JSON string.
|
// Returns the number of characters were consumed when parsing a JSON string.
|
||||||
std::ptrdiff_t BytesConsumed() const;
|
std::ptrdiff_t BytesConsumed() const;
|
||||||
|
|
||||||
// Set the root type. May override the one set in the schema.
|
// Set the root type. May override the one set in the schema.
|
||||||
bool SetRootType(const char *name);
|
bool SetRootType(const char* name);
|
||||||
|
|
||||||
// Mark all definitions as already having code generated.
|
// Mark all definitions as already having code generated.
|
||||||
void MarkGenerated();
|
void MarkGenerated();
|
||||||
@@ -1052,41 +1055,41 @@ class Parser : public ParserState {
|
|||||||
// Get the files recursively included by the given file. The returned
|
// Get the files recursively included by the given file. The returned
|
||||||
// container will have at least the given file.
|
// container will have at least the given file.
|
||||||
std::set<std::string> GetIncludedFilesRecursive(
|
std::set<std::string> GetIncludedFilesRecursive(
|
||||||
const std::string &file_name) const;
|
const std::string& file_name) const;
|
||||||
|
|
||||||
// Fills builder_ with a binary version of the schema parsed.
|
// Fills builder_ with a binary version of the schema parsed.
|
||||||
// See reflection/reflection.fbs
|
// See reflection/reflection.fbs
|
||||||
void Serialize();
|
void Serialize();
|
||||||
|
|
||||||
// Deserialize a schema buffer
|
// Deserialize a schema buffer
|
||||||
bool Deserialize(const uint8_t *buf, const size_t size);
|
bool Deserialize(const uint8_t* buf, const size_t size);
|
||||||
|
|
||||||
// Fills internal structure as if the schema passed had been loaded by parsing
|
// Fills internal structure as if the schema passed had been loaded by parsing
|
||||||
// with Parse except that included filenames will not be populated.
|
// with Parse except that included filenames will not be populated.
|
||||||
bool Deserialize(const reflection::Schema *schema);
|
bool Deserialize(const reflection::Schema* schema);
|
||||||
|
|
||||||
Type *DeserializeType(const reflection::Type *type);
|
Type* DeserializeType(const reflection::Type* type);
|
||||||
|
|
||||||
// Checks that the schema represented by this parser is a safe evolution
|
// Checks that the schema represented by this parser is a safe evolution
|
||||||
// of the schema provided. Returns non-empty error on any problems.
|
// of the schema provided. Returns non-empty error on any problems.
|
||||||
std::string ConformTo(const Parser &base);
|
std::string ConformTo(const Parser& base);
|
||||||
|
|
||||||
// Similar to Parse(), but now only accepts JSON to be parsed into a
|
// Similar to Parse(), but now only accepts JSON to be parsed into a
|
||||||
// FlexBuffer.
|
// FlexBuffer.
|
||||||
bool ParseFlexBuffer(const char *source, const char *source_filename,
|
bool ParseFlexBuffer(const char* source, const char* source_filename,
|
||||||
flexbuffers::Builder *builder);
|
flexbuffers::Builder* builder);
|
||||||
|
|
||||||
StructDef *LookupStruct(const std::string &id) const;
|
StructDef* LookupStruct(const std::string& id) const;
|
||||||
StructDef *LookupStructThruParentNamespaces(const std::string &id) const;
|
StructDef* LookupStructThruParentNamespaces(const std::string& id) const;
|
||||||
|
|
||||||
std::string UnqualifiedName(const std::string &fullQualifiedName);
|
std::string UnqualifiedName(const std::string& fullQualifiedName);
|
||||||
|
|
||||||
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
FLATBUFFERS_CHECKED_ERROR Error(const std::string& msg);
|
||||||
|
|
||||||
// @brief Verify that any of 'opts.lang_to_generate' supports Optional scalars
|
// @brief Verify that any of 'opts.lang_to_generate' supports Optional scalars
|
||||||
// in a schema.
|
// in a schema.
|
||||||
// @param opts Options used to parce a schema and generate code.
|
// @param opts Options used to parce a schema and generate code.
|
||||||
static bool SupportsOptionalScalars(const flatbuffers::IDLOptions &opts);
|
static bool SupportsOptionalScalars(const flatbuffers::IDLOptions& opts);
|
||||||
|
|
||||||
// Get the set of included files that are directly referenced by the file
|
// Get the set of included files that are directly referenced by the file
|
||||||
// being parsed. This does not include files that are transitively included by
|
// being parsed. This does not include files that are transitively included by
|
||||||
@@ -1096,101 +1099,101 @@ class Parser : public ParserState {
|
|||||||
private:
|
private:
|
||||||
class ParseDepthGuard;
|
class ParseDepthGuard;
|
||||||
|
|
||||||
void Message(const std::string &msg);
|
void Message(const std::string& msg);
|
||||||
void Warning(const std::string &msg);
|
void Warning(const std::string& msg);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
|
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t* val);
|
||||||
FLATBUFFERS_CHECKED_ERROR Next();
|
FLATBUFFERS_CHECKED_ERROR Next();
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
||||||
bool Is(int t) const;
|
bool Is(int t) const;
|
||||||
bool IsIdent(const char *id) const;
|
bool IsIdent(const char* id) const;
|
||||||
FLATBUFFERS_CHECKED_ERROR Expect(int t);
|
FLATBUFFERS_CHECKED_ERROR Expect(int t);
|
||||||
std::string TokenToStringId(int t) const;
|
std::string TokenToStringId(int t) const;
|
||||||
EnumDef *LookupEnum(const std::string &id);
|
EnumDef* LookupEnum(const std::string& id);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string *id,
|
FLATBUFFERS_CHECKED_ERROR ParseNamespacing(std::string* id,
|
||||||
std::string *last);
|
std::string* last);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type &type);
|
FLATBUFFERS_CHECKED_ERROR ParseTypeIdent(Type& type);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseType(Type &type);
|
FLATBUFFERS_CHECKED_ERROR ParseType(Type& type);
|
||||||
FLATBUFFERS_CHECKED_ERROR AddField(StructDef &struct_def,
|
FLATBUFFERS_CHECKED_ERROR AddField(StructDef& struct_def,
|
||||||
const std::string &name, const Type &type,
|
const std::string& name, const Type& type,
|
||||||
FieldDef **dest);
|
FieldDef** dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseField(StructDef &struct_def);
|
FLATBUFFERS_CHECKED_ERROR ParseField(StructDef& struct_def);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseString(Value &val, bool use_string_pooling);
|
FLATBUFFERS_CHECKED_ERROR ParseString(Value& val, bool use_string_pooling);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseComma();
|
FLATBUFFERS_CHECKED_ERROR ParseComma();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value& val, FieldDef* field,
|
||||||
size_t parent_fieldn,
|
size_t parent_fieldn,
|
||||||
const StructDef *parent_struct_def,
|
const StructDef* parent_struct_def,
|
||||||
size_t count,
|
size_t count,
|
||||||
bool inside_vector = false);
|
bool inside_vector = false);
|
||||||
template<typename F>
|
template <typename F>
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
|
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t& fieldn,
|
||||||
const StructDef *struct_def,
|
const StructDef* struct_def,
|
||||||
F body);
|
F body);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef& struct_def,
|
||||||
std::string *value, uoffset_t *ovalue);
|
std::string* value, uoffset_t* ovalue);
|
||||||
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
void SerializeStruct(const StructDef& struct_def, const Value& val);
|
||||||
void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
|
void SerializeStruct(FlatBufferBuilder& builder, const StructDef& struct_def,
|
||||||
const Value &val);
|
const Value& val);
|
||||||
template<typename F>
|
template <typename F>
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t &count, F body);
|
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t& count, F body);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
|
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type& type, uoffset_t* ovalue,
|
||||||
FieldDef *field, size_t fieldn);
|
FieldDef* field, size_t fieldn);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
|
FLATBUFFERS_CHECKED_ERROR ParseArray(Value& array);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
|
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
|
||||||
Value &val, FieldDef *field, size_t fieldn,
|
Value& val, FieldDef* field, size_t fieldn,
|
||||||
const StructDef *parent_struct_def);
|
const StructDef* parent_struct_def);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
|
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value>* attributes);
|
||||||
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
|
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string* name, int dtoken,
|
||||||
bool check, Value &e, BaseType req,
|
bool check, Value& e, BaseType req,
|
||||||
bool *destmatch);
|
bool* destmatch);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
|
FLATBUFFERS_CHECKED_ERROR ParseHash(Value& e, FieldDef* field);
|
||||||
FLATBUFFERS_CHECKED_ERROR TokenError();
|
FLATBUFFERS_CHECKED_ERROR TokenError();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
|
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string* name, Value& e,
|
||||||
bool check_now);
|
bool check_now);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string *name, Value &e);
|
FLATBUFFERS_CHECKED_ERROR ParseFunction(const std::string* name, Value& e);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
|
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type& type,
|
||||||
std::string *result);
|
std::string* result);
|
||||||
StructDef *LookupCreateStruct(const std::string &name,
|
StructDef* LookupCreateStruct(const std::string& name,
|
||||||
bool create_if_new = true,
|
bool create_if_new = true,
|
||||||
bool definition = false);
|
bool definition = false);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef **dest,
|
FLATBUFFERS_CHECKED_ERROR ParseEnum(bool is_union, EnumDef** dest,
|
||||||
const char *filename);
|
const char* filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
|
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
|
||||||
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
|
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string& name,
|
||||||
StructDef **dest);
|
StructDef** dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
|
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string& name, bool is_union,
|
||||||
EnumDef **dest);
|
EnumDef** dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseDecl(const char *filename);
|
FLATBUFFERS_CHECKED_ERROR ParseDecl(const char* filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseService(const char *filename);
|
FLATBUFFERS_CHECKED_ERROR ParseService(const char* filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef *struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseProtoFields(StructDef* struct_def,
|
||||||
bool isextend, bool inside_oneof);
|
bool isextend, bool inside_oneof);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoMapField(StructDef *struct_def);
|
FLATBUFFERS_CHECKED_ERROR ParseProtoMapField(StructDef* struct_def);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoOption();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoKey();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoDecl();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
|
FLATBUFFERS_CHECKED_ERROR ParseProtoCurliesOrIdent();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type *type);
|
FLATBUFFERS_CHECKED_ERROR ParseTypeFromProtoType(Type* type);
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
|
FLATBUFFERS_CHECKED_ERROR SkipAnyJsonValue();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant(
|
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferNumericConstant(
|
||||||
flexbuffers::Builder *builder);
|
flexbuffers::Builder* builder);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
|
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder* builder);
|
||||||
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char* source,
|
||||||
const char *source_filename);
|
const char* source_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
|
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char* _source,
|
||||||
const char **include_paths,
|
const char** include_paths,
|
||||||
const char *source_filename);
|
const char* source_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckPrivateLeak();
|
FLATBUFFERS_CHECKED_ERROR CheckPrivateLeak();
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckPrivatelyLeakedFields(
|
FLATBUFFERS_CHECKED_ERROR CheckPrivatelyLeakedFields(
|
||||||
const Definition &def, const Definition &value_type);
|
const Definition& def, const Definition& value_type);
|
||||||
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
FLATBUFFERS_CHECKED_ERROR DoParse(const char* _source,
|
||||||
const char **include_paths,
|
const char** include_paths,
|
||||||
const char *source_filename,
|
const char* source_filename,
|
||||||
const char *include_filename);
|
const char* include_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR DoParseJson();
|
FLATBUFFERS_CHECKED_ERROR DoParseJson();
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
|
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*>& fields,
|
||||||
StructDef *struct_def,
|
StructDef* struct_def,
|
||||||
const char *suffix, BaseType baseType);
|
const char* suffix, BaseType baseType);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute(
|
FLATBUFFERS_CHECKED_ERROR ParseAlignAttribute(
|
||||||
const std::string &align_constant, size_t min_align, size_t *align);
|
const std::string& align_constant, size_t min_align, size_t* align);
|
||||||
|
|
||||||
bool SupportsAdvancedUnionFeatures() const;
|
bool SupportsAdvancedUnionFeatures() const;
|
||||||
bool SupportsAdvancedArrayFeatures() const;
|
bool SupportsAdvancedArrayFeatures() const;
|
||||||
@@ -1198,27 +1201,28 @@ class Parser : public ParserState {
|
|||||||
bool SupportsDefaultVectorsAndStrings() const;
|
bool SupportsDefaultVectorsAndStrings() const;
|
||||||
bool Supports64BitOffsets() const;
|
bool Supports64BitOffsets() const;
|
||||||
bool SupportsUnionUnderlyingType() const;
|
bool SupportsUnionUnderlyingType() const;
|
||||||
Namespace *UniqueNamespace(Namespace *ns);
|
Namespace* UniqueNamespace(Namespace* ns);
|
||||||
|
|
||||||
FLATBUFFERS_CHECKED_ERROR RecurseError();
|
FLATBUFFERS_CHECKED_ERROR RecurseError();
|
||||||
template<typename F> CheckedError Recurse(F f);
|
template <typename F>
|
||||||
|
CheckedError Recurse(F f);
|
||||||
|
|
||||||
const std::string &GetPooledString(const std::string &s) const;
|
const std::string& GetPooledString(const std::string& s) const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SymbolTable<Type> types_;
|
SymbolTable<Type> types_;
|
||||||
SymbolTable<StructDef> structs_;
|
SymbolTable<StructDef> structs_;
|
||||||
SymbolTable<EnumDef> enums_;
|
SymbolTable<EnumDef> enums_;
|
||||||
SymbolTable<ServiceDef> services_;
|
SymbolTable<ServiceDef> services_;
|
||||||
std::vector<Namespace *> namespaces_;
|
std::vector<Namespace*> namespaces_;
|
||||||
Namespace *current_namespace_;
|
Namespace* current_namespace_;
|
||||||
Namespace *empty_namespace_;
|
Namespace* empty_namespace_;
|
||||||
std::string error_; // User readable error_ if Parse() == false
|
std::string error_; // User readable error_ if Parse() == false
|
||||||
|
|
||||||
FlatBufferBuilder builder_; // any data contained in the file
|
FlatBufferBuilder builder_; // any data contained in the file
|
||||||
flexbuffers::Builder flex_builder_;
|
flexbuffers::Builder flex_builder_;
|
||||||
flexbuffers::Reference flex_root_;
|
flexbuffers::Reference flex_root_;
|
||||||
StructDef *root_struct_def_;
|
StructDef* root_struct_def_;
|
||||||
std::string file_identifier_;
|
std::string file_identifier_;
|
||||||
std::string file_extension_;
|
std::string file_extension_;
|
||||||
|
|
||||||
@@ -1237,9 +1241,9 @@ class Parser : public ParserState {
|
|||||||
std::string file_being_parsed_;
|
std::string file_being_parsed_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *source_;
|
const char* source_;
|
||||||
|
|
||||||
std::vector<std::pair<Value, FieldDef *>> field_stack_;
|
std::vector<std::pair<Value, FieldDef*>> field_stack_;
|
||||||
|
|
||||||
// TODO(cneo): Refactor parser to use string_cache more often to save
|
// TODO(cneo): Refactor parser to use string_cache more often to save
|
||||||
// on memory usage.
|
// on memory usage.
|
||||||
@@ -1260,51 +1264,50 @@ class Parser : public ParserState {
|
|||||||
// These functions return nullptr on success, or an error string,
|
// These functions return nullptr on success, or an error string,
|
||||||
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
|
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
|
||||||
// it contains non-UTF-8 byte arrays in String values).
|
// it contains non-UTF-8 byte arrays in String values).
|
||||||
extern bool GenerateTextFromTable(const Parser &parser,
|
extern bool GenerateTextFromTable(const Parser& parser, const void* table,
|
||||||
const void *table,
|
const std::string& tablename,
|
||||||
const std::string &tablename,
|
std::string* text);
|
||||||
std::string *text);
|
extern const char* GenerateText(const Parser& parser, const void* flatbuffer,
|
||||||
extern const char *GenerateText(const Parser &parser, const void *flatbuffer,
|
std::string* text);
|
||||||
std::string *text);
|
extern const char* GenerateTextFile(const Parser& parser,
|
||||||
extern const char *GenerateTextFile(const Parser &parser,
|
const std::string& path,
|
||||||
const std::string &path,
|
const std::string& file_name);
|
||||||
const std::string &file_name);
|
|
||||||
|
|
||||||
extern const char *GenTextFromTable(const Parser &parser, const void *table,
|
extern const char* GenTextFromTable(const Parser& parser, const void* table,
|
||||||
const std::string &tablename,
|
const std::string& tablename,
|
||||||
std::string *text);
|
std::string* text);
|
||||||
extern const char *GenText(const Parser &parser, const void *flatbuffer,
|
extern const char* GenText(const Parser& parser, const void* flatbuffer,
|
||||||
std::string *text);
|
std::string* text);
|
||||||
extern const char *GenTextFile(const Parser &parser, const std::string &path,
|
extern const char* GenTextFile(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
// Generate GRPC Cpp interfaces.
|
// Generate GRPC Cpp interfaces.
|
||||||
// See idl_gen_grpc.cpp.
|
// See idl_gen_grpc.cpp.
|
||||||
bool GenerateCppGRPC(const Parser &parser, const std::string &path,
|
bool GenerateCppGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
// Generate GRPC Go interfaces.
|
// Generate GRPC Go interfaces.
|
||||||
// See idl_gen_grpc.cpp.
|
// See idl_gen_grpc.cpp.
|
||||||
bool GenerateGoGRPC(const Parser &parser, const std::string &path,
|
bool GenerateGoGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
// Generate GRPC Java classes.
|
// Generate GRPC Java classes.
|
||||||
// See idl_gen_grpc.cpp
|
// See idl_gen_grpc.cpp
|
||||||
bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
|
bool GenerateJavaGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
// Generate GRPC Python interfaces.
|
// Generate GRPC Python interfaces.
|
||||||
// See idl_gen_grpc.cpp.
|
// See idl_gen_grpc.cpp.
|
||||||
bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
|
bool GeneratePythonGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
// Generate GRPC Swift interfaces.
|
// Generate GRPC Swift interfaces.
|
||||||
// See idl_gen_grpc.cpp.
|
// See idl_gen_grpc.cpp.
|
||||||
extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
|
extern bool GenerateSwiftGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
|
|
||||||
extern bool GenerateTSGRPC(const Parser &parser, const std::string &path,
|
extern bool GenerateTSGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name);
|
const std::string& file_name);
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATBUFFERS_IDL_H_
|
#endif // FLATBUFFERS_IDL_H_
|
||||||
|
|||||||
@@ -42,61 +42,70 @@ struct IterationVisitor {
|
|||||||
// If not present, val == nullptr. set_idx is the index of all set fields.
|
// If not present, val == nullptr. set_idx is the index of all set fields.
|
||||||
virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
|
virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
|
||||||
ElementaryType /*type*/, bool /*is_vector*/,
|
ElementaryType /*type*/, bool /*is_vector*/,
|
||||||
const TypeTable * /*type_table*/, const char * /*name*/,
|
const TypeTable* /*type_table*/, const char* /*name*/,
|
||||||
const uint8_t * /*val*/) {}
|
const uint8_t* /*val*/) {}
|
||||||
// Called for a value that is actually present, after a field, or as part
|
// Called for a value that is actually present, after a field, or as part
|
||||||
// of a vector.
|
// of a vector.
|
||||||
virtual void UType(uint8_t, const char *) {}
|
virtual void UType(uint8_t, const char*) {}
|
||||||
virtual void Bool(bool) {}
|
virtual void Bool(bool) {}
|
||||||
virtual void Char(int8_t, const char *) {}
|
virtual void Char(int8_t, const char*) {}
|
||||||
virtual void UChar(uint8_t, const char *) {}
|
virtual void UChar(uint8_t, const char*) {}
|
||||||
virtual void Short(int16_t, const char *) {}
|
virtual void Short(int16_t, const char*) {}
|
||||||
virtual void UShort(uint16_t, const char *) {}
|
virtual void UShort(uint16_t, const char*) {}
|
||||||
virtual void Int(int32_t, const char *) {}
|
virtual void Int(int32_t, const char*) {}
|
||||||
virtual void UInt(uint32_t, const char *) {}
|
virtual void UInt(uint32_t, const char*) {}
|
||||||
virtual void Long(int64_t) {}
|
virtual void Long(int64_t) {}
|
||||||
virtual void ULong(uint64_t) {}
|
virtual void ULong(uint64_t) {}
|
||||||
virtual void Float(float) {}
|
virtual void Float(float) {}
|
||||||
virtual void Double(double) {}
|
virtual void Double(double) {}
|
||||||
virtual void String(const String *) {}
|
virtual void String(const String*) {}
|
||||||
virtual void Unknown(const uint8_t *) {} // From a future version.
|
virtual void Unknown(const uint8_t*) {} // From a future version.
|
||||||
// These mark the scope of a vector.
|
// These mark the scope of a vector.
|
||||||
virtual void StartVector() {}
|
virtual void StartVector() {}
|
||||||
virtual void EndVector() {}
|
virtual void EndVector() {}
|
||||||
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
||||||
const TypeTable * /*type_table*/,
|
const TypeTable* /*type_table*/,
|
||||||
const uint8_t * /*val*/) {}
|
const uint8_t* /*val*/) {}
|
||||||
virtual ~IterationVisitor() {}
|
virtual ~IterationVisitor() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
inline size_t InlineSize(ElementaryType type, const TypeTable* type_table) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ET_UTYPE:
|
case ET_UTYPE:
|
||||||
case ET_BOOL:
|
case ET_BOOL:
|
||||||
case ET_CHAR:
|
case ET_CHAR:
|
||||||
case ET_UCHAR: return 1;
|
case ET_UCHAR:
|
||||||
|
return 1;
|
||||||
case ET_SHORT:
|
case ET_SHORT:
|
||||||
case ET_USHORT: return 2;
|
case ET_USHORT:
|
||||||
|
return 2;
|
||||||
case ET_INT:
|
case ET_INT:
|
||||||
case ET_UINT:
|
case ET_UINT:
|
||||||
case ET_FLOAT:
|
case ET_FLOAT:
|
||||||
case ET_STRING: return 4;
|
case ET_STRING:
|
||||||
|
return 4;
|
||||||
case ET_LONG:
|
case ET_LONG:
|
||||||
case ET_ULONG:
|
case ET_ULONG:
|
||||||
case ET_DOUBLE: return 8;
|
case ET_DOUBLE:
|
||||||
|
return 8;
|
||||||
case ET_SEQUENCE:
|
case ET_SEQUENCE:
|
||||||
switch (type_table->st) {
|
switch (type_table->st) {
|
||||||
case ST_TABLE:
|
case ST_TABLE:
|
||||||
case ST_UNION: return 4;
|
case ST_UNION:
|
||||||
|
return 4;
|
||||||
case ST_STRUCT:
|
case ST_STRUCT:
|
||||||
return static_cast<size_t>(type_table->values[type_table->num_elems]);
|
return static_cast<size_t>(type_table->values[type_table->num_elems]);
|
||||||
default: FLATBUFFERS_ASSERT(false); return 1;
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
default: FLATBUFFERS_ASSERT(false); return 1;
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t LookupEnum(int64_t enum_val, const int64_t *values,
|
inline int64_t LookupEnum(int64_t enum_val, const int64_t* values,
|
||||||
size_t num_values) {
|
size_t num_values) {
|
||||||
if (!values) return enum_val;
|
if (!values) return enum_val;
|
||||||
for (size_t i = 0; i < num_values; i++) {
|
for (size_t i = 0; i < num_values; i++) {
|
||||||
@@ -105,7 +114,8 @@ inline int64_t LookupEnum(int64_t enum_val, const int64_t *values,
|
|||||||
return -1; // Unknown enum value.
|
return -1; // Unknown enum value.
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
template <typename T>
|
||||||
|
const char* EnumName(T tval, const TypeTable* type_table) {
|
||||||
if (!type_table || !type_table->names) return nullptr;
|
if (!type_table || !type_table->names) return nullptr;
|
||||||
auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values,
|
auto i = LookupEnum(static_cast<int64_t>(tval), type_table->values,
|
||||||
type_table->num_elems);
|
type_table->num_elems);
|
||||||
@@ -115,12 +125,12 @@ template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
void IterateObject(const uint8_t* obj, const TypeTable* type_table,
|
||||||
IterationVisitor *visitor);
|
IterationVisitor* visitor);
|
||||||
|
|
||||||
inline void IterateValue(ElementaryType type, const uint8_t *val,
|
inline void IterateValue(ElementaryType type, const uint8_t* val,
|
||||||
const TypeTable *type_table, const uint8_t *prev_val,
|
const TypeTable* type_table, const uint8_t* prev_val,
|
||||||
soffset_t vector_index, IterationVisitor *visitor) {
|
soffset_t vector_index, IterationVisitor* visitor) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ET_UTYPE: {
|
case ET_UTYPE: {
|
||||||
auto tval = ReadScalar<uint8_t>(val);
|
auto tval = ReadScalar<uint8_t>(val);
|
||||||
@@ -179,7 +189,7 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
|||||||
}
|
}
|
||||||
case ET_STRING: {
|
case ET_STRING: {
|
||||||
val += ReadScalar<uoffset_t>(val);
|
val += ReadScalar<uoffset_t>(val);
|
||||||
visitor->String(reinterpret_cast<const String *>(val));
|
visitor->String(reinterpret_cast<const String*>(val));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ET_SEQUENCE: {
|
case ET_SEQUENCE: {
|
||||||
@@ -188,13 +198,15 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
|||||||
val += ReadScalar<uoffset_t>(val);
|
val += ReadScalar<uoffset_t>(val);
|
||||||
IterateObject(val, type_table, visitor);
|
IterateObject(val, type_table, visitor);
|
||||||
break;
|
break;
|
||||||
case ST_STRUCT: IterateObject(val, type_table, visitor); break;
|
case ST_STRUCT:
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
case ST_UNION: {
|
case ST_UNION: {
|
||||||
val += ReadScalar<uoffset_t>(val);
|
val += ReadScalar<uoffset_t>(val);
|
||||||
FLATBUFFERS_ASSERT(prev_val);
|
FLATBUFFERS_ASSERT(prev_val);
|
||||||
auto union_type = *prev_val; // Always a uint8_t.
|
auto union_type = *prev_val; // Always a uint8_t.
|
||||||
if (vector_index >= 0) {
|
if (vector_index >= 0) {
|
||||||
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
|
auto type_vec = reinterpret_cast<const Vector<uint8_t>*>(prev_val);
|
||||||
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||||
}
|
}
|
||||||
auto type_code_idx =
|
auto type_code_idx =
|
||||||
@@ -209,16 +221,19 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ET_STRING:
|
case ET_STRING:
|
||||||
visitor->String(reinterpret_cast<const String *>(val));
|
visitor->String(reinterpret_cast<const String*>(val));
|
||||||
break;
|
break;
|
||||||
default: visitor->Unknown(val);
|
default:
|
||||||
|
visitor->Unknown(val);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
visitor->Unknown(val);
|
visitor->Unknown(val);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ST_ENUM: FLATBUFFERS_ASSERT(false); break;
|
case ST_ENUM:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -229,10 +244,10 @@ inline void IterateValue(ElementaryType type, const uint8_t *val,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
inline void IterateObject(const uint8_t* obj, const TypeTable* type_table,
|
||||||
IterationVisitor *visitor) {
|
IterationVisitor* visitor) {
|
||||||
visitor->StartSequence();
|
visitor->StartSequence();
|
||||||
const uint8_t *prev_val = nullptr;
|
const uint8_t* prev_val = nullptr;
|
||||||
size_t set_idx = 0;
|
size_t set_idx = 0;
|
||||||
size_t array_idx = 0;
|
size_t array_idx = 0;
|
||||||
for (size_t i = 0; i < type_table->num_elems; i++) {
|
for (size_t i = 0; i < type_table->num_elems; i++) {
|
||||||
@@ -240,12 +255,14 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
|||||||
auto type = static_cast<ElementaryType>(type_code.base_type);
|
auto type = static_cast<ElementaryType>(type_code.base_type);
|
||||||
auto is_repeating = type_code.is_repeating != 0;
|
auto is_repeating = type_code.is_repeating != 0;
|
||||||
auto ref_idx = type_code.sequence_ref;
|
auto ref_idx = type_code.sequence_ref;
|
||||||
const TypeTable *ref = nullptr;
|
const TypeTable* ref = nullptr;
|
||||||
if (ref_idx >= 0) { ref = type_table->type_refs[ref_idx](); }
|
if (ref_idx >= 0) {
|
||||||
|
ref = type_table->type_refs[ref_idx]();
|
||||||
|
}
|
||||||
auto name = type_table->names ? type_table->names[i] : nullptr;
|
auto name = type_table->names ? type_table->names[i] : nullptr;
|
||||||
const uint8_t *val = nullptr;
|
const uint8_t* val = nullptr;
|
||||||
if (type_table->st == ST_TABLE) {
|
if (type_table->st == ST_TABLE) {
|
||||||
val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
|
val = reinterpret_cast<const Table*>(obj)->GetAddressOf(
|
||||||
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||||
} else {
|
} else {
|
||||||
val = obj + type_table->values[i];
|
val = obj + type_table->values[i];
|
||||||
@@ -259,7 +276,7 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
|||||||
if (type_table->st == ST_TABLE) {
|
if (type_table->st == ST_TABLE) {
|
||||||
// variable length vector
|
// variable length vector
|
||||||
val += ReadScalar<uoffset_t>(val);
|
val += ReadScalar<uoffset_t>(val);
|
||||||
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
|
auto vec = reinterpret_cast<const Vector<uint8_t>*>(val);
|
||||||
elem_ptr = vec->Data();
|
elem_ptr = vec->Data();
|
||||||
size = vec->size();
|
size = vec->size();
|
||||||
} else {
|
} else {
|
||||||
@@ -284,9 +301,9 @@ inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
|||||||
visitor->EndSequence();
|
visitor->EndSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void IterateFlatBuffer(const uint8_t *buffer,
|
inline void IterateFlatBuffer(const uint8_t* buffer,
|
||||||
const TypeTable *type_table,
|
const TypeTable* type_table,
|
||||||
IterationVisitor *callback) {
|
IterationVisitor* callback) {
|
||||||
IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
|
IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +332,9 @@ struct ToStringVisitor : public IterationVisitor {
|
|||||||
vector_delimited(true) {}
|
vector_delimited(true) {}
|
||||||
|
|
||||||
void append_indent() {
|
void append_indent() {
|
||||||
for (size_t i = 0; i < indent_level; i++) { s += in; }
|
for (size_t i = 0; i < indent_level; i++) {
|
||||||
|
s += in;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartSequence() {
|
void StartSequence() {
|
||||||
@@ -330,8 +349,8 @@ struct ToStringVisitor : public IterationVisitor {
|
|||||||
s += "}";
|
s += "}";
|
||||||
}
|
}
|
||||||
void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
|
void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
|
||||||
bool /*is_vector*/, const TypeTable * /*type_table*/,
|
bool /*is_vector*/, const TypeTable* /*type_table*/,
|
||||||
const char *name, const uint8_t *val) {
|
const char* name, const uint8_t* val) {
|
||||||
if (!val) return;
|
if (!val) return;
|
||||||
if (set_idx) {
|
if (set_idx) {
|
||||||
s += ",";
|
s += ",";
|
||||||
@@ -345,7 +364,8 @@ struct ToStringVisitor : public IterationVisitor {
|
|||||||
s += ": ";
|
s += ": ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template<typename T> void Named(T x, const char *name) {
|
template <typename T>
|
||||||
|
void Named(T x, const char* name) {
|
||||||
if (name) {
|
if (name) {
|
||||||
if (q) s += "\"";
|
if (q) s += "\"";
|
||||||
s += name;
|
s += name;
|
||||||
@@ -354,22 +374,22 @@ struct ToStringVisitor : public IterationVisitor {
|
|||||||
s += NumToString(x);
|
s += NumToString(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void UType(uint8_t x, const char *name) { Named(x, name); }
|
void UType(uint8_t x, const char* name) { Named(x, name); }
|
||||||
void Bool(bool x) { s += x ? "true" : "false"; }
|
void Bool(bool x) { s += x ? "true" : "false"; }
|
||||||
void Char(int8_t x, const char *name) { Named(x, name); }
|
void Char(int8_t x, const char* name) { Named(x, name); }
|
||||||
void UChar(uint8_t x, const char *name) { Named(x, name); }
|
void UChar(uint8_t x, const char* name) { Named(x, name); }
|
||||||
void Short(int16_t x, const char *name) { Named(x, name); }
|
void Short(int16_t x, const char* name) { Named(x, name); }
|
||||||
void UShort(uint16_t x, const char *name) { Named(x, name); }
|
void UShort(uint16_t x, const char* name) { Named(x, name); }
|
||||||
void Int(int32_t x, const char *name) { Named(x, name); }
|
void Int(int32_t x, const char* name) { Named(x, name); }
|
||||||
void UInt(uint32_t x, const char *name) { Named(x, name); }
|
void UInt(uint32_t x, const char* name) { Named(x, name); }
|
||||||
void Long(int64_t x) { s += NumToString(x); }
|
void Long(int64_t x) { s += NumToString(x); }
|
||||||
void ULong(uint64_t x) { s += NumToString(x); }
|
void ULong(uint64_t x) { s += NumToString(x); }
|
||||||
void Float(float x) { s += NumToString(x); }
|
void Float(float x) { s += NumToString(x); }
|
||||||
void Double(double x) { s += NumToString(x); }
|
void Double(double x) { s += NumToString(x); }
|
||||||
void String(const struct String *str) {
|
void String(const struct String* str) {
|
||||||
EscapeString(str->c_str(), str->size(), &s, true, false);
|
EscapeString(str->c_str(), str->size(), &s, true, false);
|
||||||
}
|
}
|
||||||
void Unknown(const uint8_t *) { s += "(?)"; }
|
void Unknown(const uint8_t*) { s += "(?)"; }
|
||||||
void StartVector() {
|
void StartVector() {
|
||||||
s += "[";
|
s += "[";
|
||||||
if (vector_delimited) {
|
if (vector_delimited) {
|
||||||
@@ -391,7 +411,7 @@ struct ToStringVisitor : public IterationVisitor {
|
|||||||
s += "]";
|
s += "]";
|
||||||
}
|
}
|
||||||
void Element(size_t i, ElementaryType /*type*/,
|
void Element(size_t i, ElementaryType /*type*/,
|
||||||
const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
|
const TypeTable* /*type_table*/, const uint8_t* /*val*/) {
|
||||||
if (i) {
|
if (i) {
|
||||||
s += ",";
|
s += ",";
|
||||||
if (vector_delimited) {
|
if (vector_delimited) {
|
||||||
@@ -404,11 +424,11 @@ struct ToStringVisitor : public IterationVisitor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::string FlatBufferToString(const uint8_t *buffer,
|
inline std::string FlatBufferToString(const uint8_t* buffer,
|
||||||
const TypeTable *type_table,
|
const TypeTable* type_table,
|
||||||
bool multi_line = false,
|
bool multi_line = false,
|
||||||
bool vector_delimited = true,
|
bool vector_delimited = true,
|
||||||
const std::string &indent = "",
|
const std::string& indent = "",
|
||||||
bool quotes = false) {
|
bool quotes = false) {
|
||||||
ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", quotes, indent,
|
ToStringVisitor tostring_visitor(multi_line ? "\n" : " ", quotes, indent,
|
||||||
vector_delimited);
|
vector_delimited);
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ inline size_t GetTypeSize(reflection::BaseType base_type) {
|
|||||||
// Same as above, but now correctly returns the size of a struct if
|
// Same as above, but now correctly returns the size of a struct if
|
||||||
// the field (or vector element) is a struct.
|
// the field (or vector element) is a struct.
|
||||||
inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
|
inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
|
||||||
const reflection::Schema &schema) {
|
const reflection::Schema& schema) {
|
||||||
if (base_type == reflection::Obj &&
|
if (base_type == reflection::Obj &&
|
||||||
schema.objects()->Get(type_index)->is_struct()) {
|
schema.objects()->Get(type_index)->is_struct()) {
|
||||||
return schema.objects()->Get(type_index)->bytesize();
|
return schema.objects()->Get(type_index)->bytesize();
|
||||||
@@ -89,119 +89,121 @@ inline size_t GetTypeSizeInline(reflection::BaseType base_type, int type_index,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the root, regardless of what type it is.
|
// Get the root, regardless of what type it is.
|
||||||
inline Table *GetAnyRoot(uint8_t *const flatbuf) {
|
inline Table* GetAnyRoot(uint8_t* const flatbuf) {
|
||||||
return GetMutableRoot<Table>(flatbuf);
|
return GetMutableRoot<Table>(flatbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Table *GetAnyRoot(const uint8_t *const flatbuf) {
|
inline const Table* GetAnyRoot(const uint8_t* const flatbuf) {
|
||||||
return GetRoot<Table>(flatbuf);
|
return GetRoot<Table>(flatbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Table *GetAnySizePrefixedRoot(uint8_t *const flatbuf) {
|
inline Table* GetAnySizePrefixedRoot(uint8_t* const flatbuf) {
|
||||||
return GetMutableSizePrefixedRoot<Table>(flatbuf);
|
return GetMutableSizePrefixedRoot<Table>(flatbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Table *GetAnySizePrefixedRoot(const uint8_t *const flatbuf) {
|
inline const Table* GetAnySizePrefixedRoot(const uint8_t* const flatbuf) {
|
||||||
return GetSizePrefixedRoot<Table>(flatbuf);
|
return GetSizePrefixedRoot<Table>(flatbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field's default, if you know it's an integer, and its exact type.
|
// Get a field's default, if you know it's an integer, and its exact type.
|
||||||
template<typename T> T GetFieldDefaultI(const reflection::Field &field) {
|
template <typename T>
|
||||||
|
T GetFieldDefaultI(const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||||
return static_cast<T>(field.default_integer());
|
return static_cast<T>(field.default_integer());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field's default, if you know it's floating point and its exact type.
|
// Get a field's default, if you know it's floating point and its exact type.
|
||||||
template<typename T> T GetFieldDefaultF(const reflection::Field &field) {
|
template <typename T>
|
||||||
|
T GetFieldDefaultF(const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||||
return static_cast<T>(field.default_real());
|
return static_cast<T>(field.default_real());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's an integer, and its exact type.
|
// Get a field, if you know it's an integer, and its exact type.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T GetFieldI(const Table &table, const reflection::Field &field) {
|
T GetFieldI(const Table& table, const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||||
return table.GetField<T>(field.offset(),
|
return table.GetField<T>(field.offset(),
|
||||||
static_cast<T>(field.default_integer()));
|
static_cast<T>(field.default_integer()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's floating point and its exact type.
|
// Get a field, if you know it's floating point and its exact type.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T GetFieldF(const Table &table, const reflection::Field &field) {
|
T GetFieldF(const Table& table, const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(field.type()->base_type()));
|
||||||
return table.GetField<T>(field.offset(),
|
return table.GetField<T>(field.offset(),
|
||||||
static_cast<T>(field.default_real()));
|
static_cast<T>(field.default_real()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's a string.
|
// Get a field, if you know it's a string.
|
||||||
inline const String *GetFieldS(const Table &table,
|
inline const String* GetFieldS(const Table& table,
|
||||||
const reflection::Field &field) {
|
const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String);
|
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::String);
|
||||||
return table.GetPointer<const String *>(field.offset());
|
return table.GetPointer<const String*>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's a vector.
|
// Get a field, if you know it's a vector.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
Vector<T> *GetFieldV(const Table &table, const reflection::Field &field) {
|
Vector<T>* GetFieldV(const Table& table, const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector &&
|
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Vector &&
|
||||||
sizeof(T) == GetTypeSize(field.type()->element()));
|
sizeof(T) == GetTypeSize(field.type()->element()));
|
||||||
return table.GetPointer<Vector<T> *>(field.offset());
|
return table.GetPointer<Vector<T>*>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's a vector, generically.
|
// Get a field, if you know it's a vector, generically.
|
||||||
// To actually access elements, use the return value together with
|
// To actually access elements, use the return value together with
|
||||||
// field.type()->element() in any of GetAnyVectorElemI below etc.
|
// field.type()->element() in any of GetAnyVectorElemI below etc.
|
||||||
inline VectorOfAny *GetFieldAnyV(const Table &table,
|
inline VectorOfAny* GetFieldAnyV(const Table& table,
|
||||||
const reflection::Field &field) {
|
const reflection::Field& field) {
|
||||||
return table.GetPointer<VectorOfAny *>(field.offset());
|
return table.GetPointer<VectorOfAny*>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's a table.
|
// Get a field, if you know it's a table.
|
||||||
inline Table *GetFieldT(const Table &table, const reflection::Field &field) {
|
inline Table* GetFieldT(const Table& table, const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj ||
|
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj ||
|
||||||
field.type()->base_type() == reflection::Union);
|
field.type()->base_type() == reflection::Union);
|
||||||
return table.GetPointer<Table *>(field.offset());
|
return table.GetPointer<Table*>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a field, if you know it's a struct.
|
// Get a field, if you know it's a struct.
|
||||||
inline const Struct *GetFieldStruct(const Table &table,
|
inline const Struct* GetFieldStruct(const Table& table,
|
||||||
const reflection::Field &field) {
|
const reflection::Field& field) {
|
||||||
// TODO: This does NOT check if the field is a table or struct, but we'd need
|
// TODO: This does NOT check if the field is a table or struct, but we'd need
|
||||||
// access to the schema to check the is_struct flag.
|
// access to the schema to check the is_struct flag.
|
||||||
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
|
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
|
||||||
return table.GetStruct<const Struct *>(field.offset());
|
return table.GetStruct<const Struct*>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a structure's field, if you know it's a struct.
|
// Get a structure's field, if you know it's a struct.
|
||||||
inline const Struct *GetFieldStruct(const Struct &structure,
|
inline const Struct* GetFieldStruct(const Struct& structure,
|
||||||
const reflection::Field &field) {
|
const reflection::Field& field) {
|
||||||
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
|
FLATBUFFERS_ASSERT(field.type()->base_type() == reflection::Obj);
|
||||||
return structure.GetStruct<const Struct *>(field.offset());
|
return structure.GetStruct<const Struct*>(field.offset());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Raw helper functions used below: get any value in memory as a 64bit int, a
|
// Raw helper functions used below: get any value in memory as a 64bit int, a
|
||||||
// double or a string.
|
// double or a string.
|
||||||
// All scalars get static_cast to an int64_t, strings use strtoull, every other
|
// All scalars get static_cast to an int64_t, strings use strtoull, every other
|
||||||
// data type returns 0.
|
// data type returns 0.
|
||||||
int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data);
|
int64_t GetAnyValueI(reflection::BaseType type, const uint8_t* data);
|
||||||
// All scalars static cast to double, strings use strtod, every other data
|
// All scalars static cast to double, strings use strtod, every other data
|
||||||
// type is 0.0.
|
// type is 0.0.
|
||||||
double GetAnyValueF(reflection::BaseType type, const uint8_t *data);
|
double GetAnyValueF(reflection::BaseType type, const uint8_t* data);
|
||||||
// All scalars converted using stringstream, strings as-is, and all other
|
// All scalars converted using stringstream, strings as-is, and all other
|
||||||
// data types provide some level of debug-pretty-printing.
|
// data types provide some level of debug-pretty-printing.
|
||||||
std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
|
std::string GetAnyValueS(reflection::BaseType type, const uint8_t* data,
|
||||||
const reflection::Schema *schema, int type_index);
|
const reflection::Schema* schema, int type_index);
|
||||||
|
|
||||||
// Get any table field as a 64bit int, regardless of what type it is.
|
// Get any table field as a 64bit int, regardless of what type it is.
|
||||||
inline int64_t GetAnyFieldI(const Table &table,
|
inline int64_t GetAnyFieldI(const Table& table,
|
||||||
const reflection::Field &field) {
|
const reflection::Field& field) {
|
||||||
auto field_ptr = table.GetAddressOf(field.offset());
|
auto field_ptr = table.GetAddressOf(field.offset());
|
||||||
return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr)
|
return field_ptr ? GetAnyValueI(field.type()->base_type(), field_ptr)
|
||||||
: field.default_integer();
|
: field.default_integer();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get any table field as a double, regardless of what type it is.
|
// Get any table field as a double, regardless of what type it is.
|
||||||
inline double GetAnyFieldF(const Table &table, const reflection::Field &field) {
|
inline double GetAnyFieldF(const Table& table, const reflection::Field& field) {
|
||||||
auto field_ptr = table.GetAddressOf(field.offset());
|
auto field_ptr = table.GetAddressOf(field.offset());
|
||||||
return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
|
return field_ptr ? GetAnyValueF(field.type()->base_type(), field_ptr)
|
||||||
: field.default_real();
|
: field.default_real();
|
||||||
@@ -210,9 +212,9 @@ inline double GetAnyFieldF(const Table &table, const reflection::Field &field) {
|
|||||||
// Get any table field as a string, regardless of what type it is.
|
// Get any table field as a string, regardless of what type it is.
|
||||||
// You may pass nullptr for the schema if you don't care to have fields that
|
// You may pass nullptr for the schema if you don't care to have fields that
|
||||||
// are of table type pretty-printed.
|
// are of table type pretty-printed.
|
||||||
inline std::string GetAnyFieldS(const Table &table,
|
inline std::string GetAnyFieldS(const Table& table,
|
||||||
const reflection::Field &field,
|
const reflection::Field& field,
|
||||||
const reflection::Schema *schema) {
|
const reflection::Schema* schema) {
|
||||||
auto field_ptr = table.GetAddressOf(field.offset());
|
auto field_ptr = table.GetAddressOf(field.offset());
|
||||||
return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema,
|
return field_ptr ? GetAnyValueS(field.type()->base_type(), field_ptr, schema,
|
||||||
field.type()->index())
|
field.type()->index())
|
||||||
@@ -220,38 +222,38 @@ inline std::string GetAnyFieldS(const Table &table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get any struct field as a 64bit int, regardless of what type it is.
|
// Get any struct field as a 64bit int, regardless of what type it is.
|
||||||
inline int64_t GetAnyFieldI(const Struct &st, const reflection::Field &field) {
|
inline int64_t GetAnyFieldI(const Struct& st, const reflection::Field& field) {
|
||||||
return GetAnyValueI(field.type()->base_type(),
|
return GetAnyValueI(field.type()->base_type(),
|
||||||
st.GetAddressOf(field.offset()));
|
st.GetAddressOf(field.offset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get any struct field as a double, regardless of what type it is.
|
// Get any struct field as a double, regardless of what type it is.
|
||||||
inline double GetAnyFieldF(const Struct &st, const reflection::Field &field) {
|
inline double GetAnyFieldF(const Struct& st, const reflection::Field& field) {
|
||||||
return GetAnyValueF(field.type()->base_type(),
|
return GetAnyValueF(field.type()->base_type(),
|
||||||
st.GetAddressOf(field.offset()));
|
st.GetAddressOf(field.offset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get any struct field as a string, regardless of what type it is.
|
// Get any struct field as a string, regardless of what type it is.
|
||||||
inline std::string GetAnyFieldS(const Struct &st,
|
inline std::string GetAnyFieldS(const Struct& st,
|
||||||
const reflection::Field &field) {
|
const reflection::Field& field) {
|
||||||
return GetAnyValueS(field.type()->base_type(),
|
return GetAnyValueS(field.type()->base_type(),
|
||||||
st.GetAddressOf(field.offset()), nullptr, -1);
|
st.GetAddressOf(field.offset()), nullptr, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get any vector element as a 64bit int, regardless of what type it is.
|
// Get any vector element as a 64bit int, regardless of what type it is.
|
||||||
inline int64_t GetAnyVectorElemI(const VectorOfAny *vec,
|
inline int64_t GetAnyVectorElemI(const VectorOfAny* vec,
|
||||||
reflection::BaseType elem_type, size_t i) {
|
reflection::BaseType elem_type, size_t i) {
|
||||||
return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
|
return GetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get any vector element as a double, regardless of what type it is.
|
// Get any vector element as a double, regardless of what type it is.
|
||||||
inline double GetAnyVectorElemF(const VectorOfAny *vec,
|
inline double GetAnyVectorElemF(const VectorOfAny* vec,
|
||||||
reflection::BaseType elem_type, size_t i) {
|
reflection::BaseType elem_type, size_t i) {
|
||||||
return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
|
return GetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get any vector element as a string, regardless of what type it is.
|
// Get any vector element as a string, regardless of what type it is.
|
||||||
inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
|
inline std::string GetAnyVectorElemS(const VectorOfAny* vec,
|
||||||
reflection::BaseType elem_type, size_t i) {
|
reflection::BaseType elem_type, size_t i) {
|
||||||
return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i,
|
return GetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i,
|
||||||
nullptr, -1);
|
nullptr, -1);
|
||||||
@@ -260,10 +262,10 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
|
|||||||
// Get a vector element that's a table/string/vector from a generic vector.
|
// Get a vector element that's a table/string/vector from a generic vector.
|
||||||
// Pass Table/String/VectorOfAny as template parameter.
|
// Pass Table/String/VectorOfAny as template parameter.
|
||||||
// Warning: does no typechecking.
|
// Warning: does no typechecking.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
|
T* GetAnyVectorElemPointer(const VectorOfAny* vec, size_t i) {
|
||||||
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
|
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
|
||||||
return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
|
return reinterpret_cast<T*>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the inline-address of a vector element. Useful for Structs (pass Struct
|
// Get the inline-address of a vector element. Useful for Structs (pass Struct
|
||||||
@@ -271,37 +273,39 @@ T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
|
|||||||
// Get elem_size from GetTypeSizeInline().
|
// Get elem_size from GetTypeSizeInline().
|
||||||
// Note: little-endian data on all platforms, use EndianScalar() instead of
|
// Note: little-endian data on all platforms, use EndianScalar() instead of
|
||||||
// raw pointer access with scalars).
|
// raw pointer access with scalars).
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T *GetAnyVectorElemAddressOf(const VectorOfAny *vec, size_t i,
|
T* GetAnyVectorElemAddressOf(const VectorOfAny* vec, size_t i,
|
||||||
size_t elem_size) {
|
size_t elem_size) {
|
||||||
return reinterpret_cast<T *>(vec->Data() + elem_size * i);
|
return reinterpret_cast<T*>(vec->Data() + elem_size * i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similarly, for elements of tables.
|
// Similarly, for elements of tables.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T *GetAnyFieldAddressOf(const Table &table, const reflection::Field &field) {
|
T* GetAnyFieldAddressOf(const Table& table, const reflection::Field& field) {
|
||||||
return reinterpret_cast<T *>(table.GetAddressOf(field.offset()));
|
return reinterpret_cast<T*>(table.GetAddressOf(field.offset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Similarly, for elements of structs.
|
// Similarly, for elements of structs.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T *GetAnyFieldAddressOf(const Struct &st, const reflection::Field &field) {
|
T* GetAnyFieldAddressOf(const Struct& st, const reflection::Field& field) {
|
||||||
return reinterpret_cast<T *>(st.GetAddressOf(field.offset()));
|
return reinterpret_cast<T*>(st.GetAddressOf(field.offset()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop over all the fields of the provided `object` and call `func` on each one
|
// Loop over all the fields of the provided `object` and call `func` on each one
|
||||||
// in increasing order by their field->id(). If `reverse` is true, `func` is
|
// in increasing order by their field->id(). If `reverse` is true, `func` is
|
||||||
// called in descending order
|
// called in descending order
|
||||||
void ForAllFields(const reflection::Object *object, bool reverse,
|
void ForAllFields(const reflection::Object* object, bool reverse,
|
||||||
std::function<void(const reflection::Field *)> func);
|
std::function<void(const reflection::Field*)> func);
|
||||||
|
|
||||||
// ------------------------- SETTERS -------------------------
|
// ------------------------- SETTERS -------------------------
|
||||||
|
|
||||||
// Set any scalar field, if you know its exact type.
|
// Set any scalar field, if you know its exact type.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool SetField(Table *table, const reflection::Field &field, T val) {
|
bool SetField(Table* table, const reflection::Field& field, T val) {
|
||||||
reflection::BaseType type = field.type()->base_type();
|
reflection::BaseType type = field.type()->base_type();
|
||||||
if (!IsScalar(type)) { return false; }
|
if (!IsScalar(type)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
|
FLATBUFFERS_ASSERT(sizeof(T) == GetTypeSize(type));
|
||||||
T def;
|
T def;
|
||||||
if (IsInteger(type)) {
|
if (IsInteger(type)) {
|
||||||
@@ -317,12 +321,12 @@ bool SetField(Table *table, const reflection::Field &field, T val) {
|
|||||||
// double or a string.
|
// double or a string.
|
||||||
// These work for all scalar values, but do nothing for other data types.
|
// These work for all scalar values, but do nothing for other data types.
|
||||||
// To set a string, see SetString below.
|
// To set a string, see SetString below.
|
||||||
void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val);
|
void SetAnyValueI(reflection::BaseType type, uint8_t* data, int64_t val);
|
||||||
void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val);
|
void SetAnyValueF(reflection::BaseType type, uint8_t* data, double val);
|
||||||
void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val);
|
void SetAnyValueS(reflection::BaseType type, uint8_t* data, const char* val);
|
||||||
|
|
||||||
// Set any table field as a 64bit int, regardless of type what it is.
|
// Set any table field as a 64bit int, regardless of type what it is.
|
||||||
inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
|
inline bool SetAnyFieldI(Table* table, const reflection::Field& field,
|
||||||
int64_t val) {
|
int64_t val) {
|
||||||
auto field_ptr = table->GetAddressOf(field.offset());
|
auto field_ptr = table->GetAddressOf(field.offset());
|
||||||
if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field);
|
if (!field_ptr) return val == GetFieldDefaultI<int64_t>(field);
|
||||||
@@ -331,7 +335,7 @@ inline bool SetAnyFieldI(Table *table, const reflection::Field &field,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set any table field as a double, regardless of what type it is.
|
// Set any table field as a double, regardless of what type it is.
|
||||||
inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
|
inline bool SetAnyFieldF(Table* table, const reflection::Field& field,
|
||||||
double val) {
|
double val) {
|
||||||
auto field_ptr = table->GetAddressOf(field.offset());
|
auto field_ptr = table->GetAddressOf(field.offset());
|
||||||
if (!field_ptr) return val == GetFieldDefaultF<double>(field);
|
if (!field_ptr) return val == GetFieldDefaultF<double>(field);
|
||||||
@@ -340,8 +344,8 @@ inline bool SetAnyFieldF(Table *table, const reflection::Field &field,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set any table field as a string, regardless of what type it is.
|
// Set any table field as a string, regardless of what type it is.
|
||||||
inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
|
inline bool SetAnyFieldS(Table* table, const reflection::Field& field,
|
||||||
const char *val) {
|
const char* val) {
|
||||||
auto field_ptr = table->GetAddressOf(field.offset());
|
auto field_ptr = table->GetAddressOf(field.offset());
|
||||||
if (!field_ptr) return false;
|
if (!field_ptr) return false;
|
||||||
SetAnyValueS(field.type()->base_type(), field_ptr, val);
|
SetAnyValueS(field.type()->base_type(), field_ptr, val);
|
||||||
@@ -349,41 +353,41 @@ inline bool SetAnyFieldS(Table *table, const reflection::Field &field,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set any struct field as a 64bit int, regardless of type what it is.
|
// Set any struct field as a 64bit int, regardless of type what it is.
|
||||||
inline void SetAnyFieldI(Struct *st, const reflection::Field &field,
|
inline void SetAnyFieldI(Struct* st, const reflection::Field& field,
|
||||||
int64_t val) {
|
int64_t val) {
|
||||||
SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()),
|
SetAnyValueI(field.type()->base_type(), st->GetAddressOf(field.offset()),
|
||||||
val);
|
val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set any struct field as a double, regardless of type what it is.
|
// Set any struct field as a double, regardless of type what it is.
|
||||||
inline void SetAnyFieldF(Struct *st, const reflection::Field &field,
|
inline void SetAnyFieldF(Struct* st, const reflection::Field& field,
|
||||||
double val) {
|
double val) {
|
||||||
SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()),
|
SetAnyValueF(field.type()->base_type(), st->GetAddressOf(field.offset()),
|
||||||
val);
|
val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set any struct field as a string, regardless of type what it is.
|
// Set any struct field as a string, regardless of type what it is.
|
||||||
inline void SetAnyFieldS(Struct *st, const reflection::Field &field,
|
inline void SetAnyFieldS(Struct* st, const reflection::Field& field,
|
||||||
const char *val) {
|
const char* val) {
|
||||||
SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()),
|
SetAnyValueS(field.type()->base_type(), st->GetAddressOf(field.offset()),
|
||||||
val);
|
val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set any vector element as a 64bit int, regardless of type what it is.
|
// Set any vector element as a 64bit int, regardless of type what it is.
|
||||||
inline void SetAnyVectorElemI(VectorOfAny *vec, reflection::BaseType elem_type,
|
inline void SetAnyVectorElemI(VectorOfAny* vec, reflection::BaseType elem_type,
|
||||||
size_t i, int64_t val) {
|
size_t i, int64_t val) {
|
||||||
SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
SetAnyValueI(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set any vector element as a double, regardless of type what it is.
|
// Set any vector element as a double, regardless of type what it is.
|
||||||
inline void SetAnyVectorElemF(VectorOfAny *vec, reflection::BaseType elem_type,
|
inline void SetAnyVectorElemF(VectorOfAny* vec, reflection::BaseType elem_type,
|
||||||
size_t i, double val) {
|
size_t i, double val) {
|
||||||
SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
SetAnyValueF(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set any vector element as a string, regardless of type what it is.
|
// Set any vector element as a string, regardless of type what it is.
|
||||||
inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
|
inline void SetAnyVectorElemS(VectorOfAny* vec, reflection::BaseType elem_type,
|
||||||
size_t i, const char *val) {
|
size_t i, const char* val) {
|
||||||
SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
SetAnyValueS(elem_type, vec->Data() + GetTypeSize(elem_type) * i, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -391,36 +395,37 @@ inline void SetAnyVectorElemS(VectorOfAny *vec, reflection::BaseType elem_type,
|
|||||||
|
|
||||||
// "smart" pointer for use with resizing vectors: turns a pointer inside
|
// "smart" pointer for use with resizing vectors: turns a pointer inside
|
||||||
// a vector into a relative offset, such that it is not affected by resizes.
|
// a vector into a relative offset, such that it is not affected by resizes.
|
||||||
template<typename T, typename U> class pointer_inside_vector {
|
template <typename T, typename U>
|
||||||
|
class pointer_inside_vector {
|
||||||
public:
|
public:
|
||||||
pointer_inside_vector(T *ptr, std::vector<U> &vec)
|
pointer_inside_vector(T* ptr, std::vector<U>& vec)
|
||||||
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
: offset_(reinterpret_cast<uint8_t*>(ptr) -
|
||||||
reinterpret_cast<uint8_t *>(vec.data())),
|
reinterpret_cast<uint8_t*>(vec.data())),
|
||||||
vec_(vec) {}
|
vec_(vec) {}
|
||||||
|
|
||||||
T *operator*() const {
|
T* operator*() const {
|
||||||
return reinterpret_cast<T *>(reinterpret_cast<uint8_t *>(vec_.data()) +
|
return reinterpret_cast<T*>(reinterpret_cast<uint8_t*>(vec_.data()) +
|
||||||
offset_);
|
offset_);
|
||||||
}
|
}
|
||||||
T *operator->() const { return operator*(); }
|
T* operator->() const { return operator*(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
size_t offset_;
|
size_t offset_;
|
||||||
std::vector<U> &vec_;
|
std::vector<U>& vec_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Helper to create the above easily without specifying template args.
|
// Helper to create the above easily without specifying template args.
|
||||||
template<typename T, typename U>
|
template <typename T, typename U>
|
||||||
pointer_inside_vector<T, U> piv(T *ptr, std::vector<U> &vec) {
|
pointer_inside_vector<T, U> piv(T* ptr, std::vector<U>& vec) {
|
||||||
return pointer_inside_vector<T, U>(ptr, vec);
|
return pointer_inside_vector<T, U>(ptr, vec);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *UnionTypeFieldSuffix() { return "_type"; }
|
inline const char* UnionTypeFieldSuffix() { return "_type"; }
|
||||||
|
|
||||||
// Helper to figure out the actual table type a union refers to.
|
// Helper to figure out the actual table type a union refers to.
|
||||||
inline const reflection::Object &GetUnionType(
|
inline const reflection::Object& GetUnionType(
|
||||||
const reflection::Schema &schema, const reflection::Object &parent,
|
const reflection::Schema& schema, const reflection::Object& parent,
|
||||||
const reflection::Field &unionfield, const Table &table) {
|
const reflection::Field& unionfield, const Table& table) {
|
||||||
auto enumdef = schema.enums()->Get(unionfield.type()->index());
|
auto enumdef = schema.enums()->Get(unionfield.type()->index());
|
||||||
// TODO: this is clumsy and slow, but no other way to find it?
|
// TODO: this is clumsy and slow, but no other way to find it?
|
||||||
auto type_field = parent.fields()->LookupByKey(
|
auto type_field = parent.fields()->LookupByKey(
|
||||||
@@ -436,27 +441,27 @@ inline const reflection::Object &GetUnionType(
|
|||||||
// "str" must live inside "flatbuf" and may be invalidated after this call.
|
// "str" must live inside "flatbuf" and may be invalidated after this call.
|
||||||
// If your FlatBuffer's root table is not the schema's root table, you should
|
// If your FlatBuffer's root table is not the schema's root table, you should
|
||||||
// pass in your root_table type as well.
|
// pass in your root_table type as well.
|
||||||
void SetString(const reflection::Schema &schema, const std::string &val,
|
void SetString(const reflection::Schema& schema, const std::string& val,
|
||||||
const String *str, std::vector<uint8_t> *flatbuf,
|
const String* str, std::vector<uint8_t>* flatbuf,
|
||||||
const reflection::Object *root_table = nullptr);
|
const reflection::Object* root_table = nullptr);
|
||||||
|
|
||||||
// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must
|
// Resizes a flatbuffers::Vector inside a FlatBuffer. FlatBuffer must
|
||||||
// live inside a std::vector so we can resize the buffer if needed.
|
// live inside a std::vector so we can resize the buffer if needed.
|
||||||
// "vec" must live inside "flatbuf" and may be invalidated after this call.
|
// "vec" must live inside "flatbuf" and may be invalidated after this call.
|
||||||
// If your FlatBuffer's root table is not the schema's root table, you should
|
// If your FlatBuffer's root table is not the schema's root table, you should
|
||||||
// pass in your root_table type as well.
|
// pass in your root_table type as well.
|
||||||
uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
uint8_t* ResizeAnyVector(const reflection::Schema& schema, uoffset_t newsize,
|
||||||
const VectorOfAny *vec, uoffset_t num_elems,
|
const VectorOfAny* vec, uoffset_t num_elems,
|
||||||
uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
|
uoffset_t elem_size, std::vector<uint8_t>* flatbuf,
|
||||||
const reflection::Object *root_table = nullptr);
|
const reflection::Object* root_table = nullptr);
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
void ResizeVector(const reflection::Schema& schema, uoffset_t newsize, T val,
|
||||||
const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
|
const Vector<T>* vec, std::vector<uint8_t>* flatbuf,
|
||||||
const reflection::Object *root_table = nullptr) {
|
const reflection::Object* root_table = nullptr) {
|
||||||
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
|
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(vec->size());
|
||||||
auto newelems = ResizeAnyVector(
|
auto newelems = ResizeAnyVector(
|
||||||
schema, newsize, reinterpret_cast<const VectorOfAny *>(vec), vec->size(),
|
schema, newsize, reinterpret_cast<const VectorOfAny*>(vec), vec->size(),
|
||||||
static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table);
|
static_cast<uoffset_t>(sizeof(T)), flatbuf, root_table);
|
||||||
// Set new elements to "val".
|
// Set new elements to "val".
|
||||||
for (int i = 0; i < delta_elem; i++) {
|
for (int i = 0; i < delta_elem; i++) {
|
||||||
@@ -465,7 +470,7 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
|||||||
if (is_scalar) {
|
if (is_scalar) {
|
||||||
WriteScalar(loc, val);
|
WriteScalar(loc, val);
|
||||||
} else { // struct
|
} else { // struct
|
||||||
*reinterpret_cast<T *>(loc) = val;
|
*reinterpret_cast<T*>(loc) = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -478,11 +483,11 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
|||||||
// existing one.
|
// existing one.
|
||||||
// The return value can now be set using Vector::MutateOffset or SetFieldT
|
// The return value can now be set using Vector::MutateOffset or SetFieldT
|
||||||
// below.
|
// below.
|
||||||
const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
|
const uint8_t* AddFlatBuffer(std::vector<uint8_t>& flatbuf,
|
||||||
const uint8_t *newbuf, size_t newlen);
|
const uint8_t* newbuf, size_t newlen);
|
||||||
|
|
||||||
inline bool SetFieldT(Table *table, const reflection::Field &field,
|
inline bool SetFieldT(Table* table, const reflection::Field& field,
|
||||||
const uint8_t *val) {
|
const uint8_t* val) {
|
||||||
FLATBUFFERS_ASSERT(sizeof(uoffset_t) ==
|
FLATBUFFERS_ASSERT(sizeof(uoffset_t) ==
|
||||||
GetTypeSize(field.type()->base_type()));
|
GetTypeSize(field.type()->base_type()));
|
||||||
return table->SetPointer(field.offset(), val);
|
return table->SetPointer(field.offset(), val);
|
||||||
@@ -499,22 +504,22 @@ inline bool SetFieldT(Table *table, const reflection::Field &field,
|
|||||||
// DAG, the copy will be a tree instead (with duplicates). Strings can be
|
// DAG, the copy will be a tree instead (with duplicates). Strings can be
|
||||||
// shared however, by passing true for use_string_pooling.
|
// shared however, by passing true for use_string_pooling.
|
||||||
|
|
||||||
Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
Offset<const Table*> CopyTable(FlatBufferBuilder& fbb,
|
||||||
const reflection::Schema &schema,
|
const reflection::Schema& schema,
|
||||||
const reflection::Object &objectdef,
|
const reflection::Object& objectdef,
|
||||||
const Table &table,
|
const Table& table,
|
||||||
bool use_string_pooling = false);
|
bool use_string_pooling = false);
|
||||||
|
|
||||||
// Verifies the provided flatbuffer using reflection.
|
// Verifies the provided flatbuffer using reflection.
|
||||||
// root should point to the root type for this flatbuffer.
|
// root should point to the root type for this flatbuffer.
|
||||||
// buf should point to the start of flatbuffer data.
|
// buf should point to the start of flatbuffer data.
|
||||||
// length specifies the size of the flatbuffer data.
|
// length specifies the size of the flatbuffer data.
|
||||||
bool Verify(const reflection::Schema &schema, const reflection::Object &root,
|
bool Verify(const reflection::Schema& schema, const reflection::Object& root,
|
||||||
const uint8_t *buf, size_t length, uoffset_t max_depth = 64,
|
const uint8_t* buf, size_t length, uoffset_t max_depth = 64,
|
||||||
uoffset_t max_tables = 1000000);
|
uoffset_t max_tables = 1000000);
|
||||||
|
|
||||||
bool VerifySizePrefixed(const reflection::Schema &schema,
|
bool VerifySizePrefixed(const reflection::Schema& schema,
|
||||||
const reflection::Object &root, const uint8_t *buf,
|
const reflection::Object& root, const uint8_t* buf,
|
||||||
size_t length, uoffset_t max_depth = 64,
|
size_t length, uoffset_t max_depth = 64,
|
||||||
uoffset_t max_tables = 1000000);
|
uoffset_t max_tables = 1000000);
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class Registry {
|
|||||||
public:
|
public:
|
||||||
// Call this for all schemas that may be in use. The identifier has
|
// Call this for all schemas that may be in use. The identifier has
|
||||||
// a function in the generated code, e.g. MonsterIdentifier().
|
// a function in the generated code, e.g. MonsterIdentifier().
|
||||||
void Register(const char *file_identifier, const char *schema_path) {
|
void Register(const char* file_identifier, const char* schema_path) {
|
||||||
Schema schema;
|
Schema schema;
|
||||||
schema.path_ = schema_path;
|
schema.path_ = schema_path;
|
||||||
schemas_[file_identifier] = schema;
|
schemas_[file_identifier] = schema;
|
||||||
@@ -38,7 +38,7 @@ class Registry {
|
|||||||
|
|
||||||
// Generate text from an arbitrary FlatBuffer by looking up its
|
// Generate text from an arbitrary FlatBuffer by looking up its
|
||||||
// file_identifier in the registry.
|
// file_identifier in the registry.
|
||||||
bool FlatBufferToText(const uint8_t *flatbuf, size_t len, std::string *dest) {
|
bool FlatBufferToText(const uint8_t* flatbuf, size_t len, std::string* dest) {
|
||||||
// Get the identifier out of the buffer.
|
// Get the identifier out of the buffer.
|
||||||
// If the buffer is truncated, exit.
|
// If the buffer is truncated, exit.
|
||||||
if (len < sizeof(uoffset_t) + kFileIdentifierLength) {
|
if (len < sizeof(uoffset_t) + kFileIdentifierLength) {
|
||||||
@@ -46,7 +46,7 @@ class Registry {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::string ident(
|
std::string ident(
|
||||||
reinterpret_cast<const char *>(flatbuf) + sizeof(uoffset_t),
|
reinterpret_cast<const char*>(flatbuf) + sizeof(uoffset_t),
|
||||||
kFileIdentifierLength);
|
kFileIdentifierLength);
|
||||||
// Load and parse the schema.
|
// Load and parse the schema.
|
||||||
Parser parser;
|
Parser parser;
|
||||||
@@ -64,8 +64,8 @@ class Registry {
|
|||||||
// Converts a binary buffer to text using one of the schemas in the registry,
|
// Converts a binary buffer to text using one of the schemas in the registry,
|
||||||
// use the file_identifier to indicate which.
|
// use the file_identifier to indicate which.
|
||||||
// If DetachedBuffer::data() is null then parsing failed.
|
// If DetachedBuffer::data() is null then parsing failed.
|
||||||
DetachedBuffer TextToFlatBuffer(const char *text,
|
DetachedBuffer TextToFlatBuffer(const char* text,
|
||||||
const char *file_identifier) {
|
const char* file_identifier) {
|
||||||
// Load and parse the schema.
|
// Load and parse the schema.
|
||||||
Parser parser;
|
Parser parser;
|
||||||
if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer();
|
if (!LoadSchema(file_identifier, &parser)) return DetachedBuffer();
|
||||||
@@ -79,17 +79,17 @@ class Registry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Modify any parsing / output options used by the other functions.
|
// Modify any parsing / output options used by the other functions.
|
||||||
void SetOptions(const IDLOptions &opts) { opts_ = opts; }
|
void SetOptions(const IDLOptions& opts) { opts_ = opts; }
|
||||||
|
|
||||||
// If schemas used contain include statements, call this function for every
|
// If schemas used contain include statements, call this function for every
|
||||||
// directory the parser should search them for.
|
// directory the parser should search them for.
|
||||||
void AddIncludeDirectory(const char *path) { include_paths_.push_back(path); }
|
void AddIncludeDirectory(const char* path) { include_paths_.push_back(path); }
|
||||||
|
|
||||||
// Returns a human readable error if any of the above functions fail.
|
// Returns a human readable error if any of the above functions fail.
|
||||||
const std::string &GetLastError() { return lasterror_; }
|
const std::string& GetLastError() { return lasterror_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool LoadSchema(const std::string &ident, Parser *parser) {
|
bool LoadSchema(const std::string& ident, Parser* parser) {
|
||||||
// Find the schema, if not, exit.
|
// Find the schema, if not, exit.
|
||||||
auto it = schemas_.find(ident);
|
auto it = schemas_.find(ident);
|
||||||
if (it == schemas_.end()) {
|
if (it == schemas_.end()) {
|
||||||
@@ -97,7 +97,7 @@ class Registry {
|
|||||||
lasterror_ = "identifier for this buffer not in the registry";
|
lasterror_ = "identifier for this buffer not in the registry";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto &schema = it->second;
|
auto& schema = it->second;
|
||||||
// Load the schema from disk. If not, exit.
|
// Load the schema from disk. If not, exit.
|
||||||
std::string schematext;
|
std::string schematext;
|
||||||
if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
|
if (!LoadFile(schema.path_.c_str(), false, &schematext)) {
|
||||||
@@ -121,7 +121,7 @@ class Registry {
|
|||||||
|
|
||||||
std::string lasterror_;
|
std::string lasterror_;
|
||||||
IDLOptions opts_;
|
IDLOptions opts_;
|
||||||
std::vector<const char *> include_paths_;
|
std::vector<const char*> include_paths_;
|
||||||
std::map<std::string, Schema> schemas_;
|
std::map<std::string, Schema> schemas_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
struct String : public Vector<char> {
|
struct String : public Vector<char> {
|
||||||
const char *c_str() const { return reinterpret_cast<const char *>(Data()); }
|
const char* c_str() const { return reinterpret_cast<const char*>(Data()); }
|
||||||
std::string str() const { return std::string(c_str(), size()); }
|
std::string str() const { return std::string(c_str(), size()); }
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@@ -39,27 +39,27 @@ struct String : public Vector<char> {
|
|||||||
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
bool operator<(const String &o) const {
|
bool operator<(const String& o) const {
|
||||||
return StringLessThan(this->data(), this->size(), o.data(), o.size());
|
return StringLessThan(this->data(), this->size(), o.data(), o.size());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Convenience function to get std::string from a String returning an empty
|
// Convenience function to get std::string from a String returning an empty
|
||||||
// string on null pointer.
|
// string on null pointer.
|
||||||
static inline std::string GetString(const String *str) {
|
static inline std::string GetString(const String* str) {
|
||||||
return str ? str->str() : "";
|
return str ? str->str() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function to get char* from a String returning an empty string on
|
// Convenience function to get char* from a String returning an empty string on
|
||||||
// null pointer.
|
// null pointer.
|
||||||
static inline const char *GetCstring(const String *str) {
|
static inline const char* GetCstring(const String* str) {
|
||||||
return str ? str->c_str() : "";
|
return str ? str->c_str() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FLATBUFFERS_HAS_STRING_VIEW
|
#ifdef FLATBUFFERS_HAS_STRING_VIEW
|
||||||
// Convenience function to get string_view from a String returning an empty
|
// Convenience function to get string_view from a String returning an empty
|
||||||
// string_view on null pointer.
|
// string_view on null pointer.
|
||||||
static inline flatbuffers::string_view GetStringView(const String *str) {
|
static inline flatbuffers::string_view GetStringView(const String* str) {
|
||||||
return str ? str->string_view() : flatbuffers::string_view();
|
return str ? str->string_view() : flatbuffers::string_view();
|
||||||
}
|
}
|
||||||
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
||||||
|
|||||||
@@ -27,23 +27,25 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
class Struct FLATBUFFERS_FINAL_CLASS {
|
class Struct FLATBUFFERS_FINAL_CLASS {
|
||||||
public:
|
public:
|
||||||
template<typename T> T GetField(uoffset_t o) const {
|
template <typename T>
|
||||||
|
T GetField(uoffset_t o) const {
|
||||||
return ReadScalar<T>(&data_[o]);
|
return ReadScalar<T>(&data_[o]);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> T GetStruct(uoffset_t o) const {
|
template <typename T>
|
||||||
|
T GetStruct(uoffset_t o) const {
|
||||||
return reinterpret_cast<T>(&data_[o]);
|
return reinterpret_cast<T>(&data_[o]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *GetAddressOf(uoffset_t o) const { return &data_[o]; }
|
const uint8_t* GetAddressOf(uoffset_t o) const { return &data_[o]; }
|
||||||
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
|
uint8_t* GetAddressOf(uoffset_t o) { return &data_[o]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// private constructor & copy constructor: you obtain instances of this
|
// private constructor & copy constructor: you obtain instances of this
|
||||||
// class by pointing to existing data only
|
// class by pointing to existing data only
|
||||||
Struct();
|
Struct();
|
||||||
Struct(const Struct &);
|
Struct(const Struct&);
|
||||||
Struct &operator=(const Struct &);
|
Struct& operator=(const Struct&);
|
||||||
|
|
||||||
uint8_t data_[1];
|
uint8_t data_[1];
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ namespace flatbuffers {
|
|||||||
// omitted and added at will, but uses an extra indirection to read.
|
// omitted and added at will, but uses an extra indirection to read.
|
||||||
class Table {
|
class Table {
|
||||||
public:
|
public:
|
||||||
const uint8_t *GetVTable() const {
|
const uint8_t* GetVTable() const {
|
||||||
return data_ - ReadScalar<soffset_t>(data_);
|
return data_ - ReadScalar<soffset_t>(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,38 +42,42 @@ class Table {
|
|||||||
return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
|
return field < vtsize ? ReadScalar<voffset_t>(vtable + field) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> T GetField(voffset_t field, T defaultval) const {
|
template <typename T>
|
||||||
|
T GetField(voffset_t field, T defaultval) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
|
return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P, typename OffsetSize = uoffset_t>
|
template <typename P, typename OffsetSize = uoffset_t>
|
||||||
P GetPointer(voffset_t field) {
|
P GetPointer(voffset_t field) {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
auto p = data_ + field_offset;
|
auto p = data_ + field_offset;
|
||||||
return field_offset ? reinterpret_cast<P>(p + ReadScalar<OffsetSize>(p))
|
return field_offset ? reinterpret_cast<P>(p + ReadScalar<OffsetSize>(p))
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
template<typename P, typename OffsetSize = uoffset_t>
|
template <typename P, typename OffsetSize = uoffset_t>
|
||||||
P GetPointer(voffset_t field) const {
|
P GetPointer(voffset_t field) const {
|
||||||
return const_cast<Table *>(this)->GetPointer<P, OffsetSize>(field);
|
return const_cast<Table*>(this)->GetPointer<P, OffsetSize>(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P> P GetPointer64(voffset_t field) {
|
template <typename P>
|
||||||
|
P GetPointer64(voffset_t field) {
|
||||||
return GetPointer<P, uoffset64_t>(field);
|
return GetPointer<P, uoffset64_t>(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P> P GetPointer64(voffset_t field) const {
|
template <typename P>
|
||||||
|
P GetPointer64(voffset_t field) const {
|
||||||
return GetPointer<P, uoffset64_t>(field);
|
return GetPointer<P, uoffset64_t>(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename P> P GetStruct(voffset_t field) const {
|
template <typename P>
|
||||||
|
P GetStruct(voffset_t field) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
auto p = const_cast<uint8_t *>(data_ + field_offset);
|
auto p = const_cast<uint8_t*>(data_ + field_offset);
|
||||||
return field_offset ? reinterpret_cast<P>(p) : nullptr;
|
return field_offset ? reinterpret_cast<P>(p) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Raw, typename Face>
|
template <typename Raw, typename Face>
|
||||||
flatbuffers::Optional<Face> GetOptional(voffset_t field) const {
|
flatbuffers::Optional<Face> GetOptional(voffset_t field) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
auto p = data_ + field_offset;
|
auto p = data_ + field_offset;
|
||||||
@@ -81,20 +85,22 @@ class Table {
|
|||||||
: Optional<Face>();
|
: Optional<Face>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> bool SetField(voffset_t field, T val, T def) {
|
template <typename T>
|
||||||
|
bool SetField(voffset_t field, T val, T def) {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
if (!field_offset) return IsTheSameAs(val, def);
|
if (!field_offset) return IsTheSameAs(val, def);
|
||||||
WriteScalar(data_ + field_offset, val);
|
WriteScalar(data_ + field_offset, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
template<typename T> bool SetField(voffset_t field, T val) {
|
template <typename T>
|
||||||
|
bool SetField(voffset_t field, T val) {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
if (!field_offset) return false;
|
if (!field_offset) return false;
|
||||||
WriteScalar(data_ + field_offset, val);
|
WriteScalar(data_ + field_offset, val);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetPointer(voffset_t field, const uint8_t *val) {
|
bool SetPointer(voffset_t field, const uint8_t* val) {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
if (!field_offset) return false;
|
if (!field_offset) return false;
|
||||||
WriteScalar(data_ + field_offset,
|
WriteScalar(data_ + field_offset,
|
||||||
@@ -102,12 +108,12 @@ class Table {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *GetAddressOf(voffset_t field) {
|
uint8_t* GetAddressOf(voffset_t field) {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
return field_offset ? data_ + field_offset : nullptr;
|
return field_offset ? data_ + field_offset : nullptr;
|
||||||
}
|
}
|
||||||
const uint8_t *GetAddressOf(voffset_t field) const {
|
const uint8_t* GetAddressOf(voffset_t field) const {
|
||||||
return const_cast<Table *>(this)->GetAddressOf(field);
|
return const_cast<Table*>(this)->GetAddressOf(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CheckField(voffset_t field) const {
|
bool CheckField(voffset_t field) const {
|
||||||
@@ -116,13 +122,13 @@ class Table {
|
|||||||
|
|
||||||
// Verify the vtable of this table.
|
// Verify the vtable of this table.
|
||||||
// Call this once per table, followed by VerifyField once per field.
|
// Call this once per table, followed by VerifyField once per field.
|
||||||
bool VerifyTableStart(Verifier &verifier) const {
|
bool VerifyTableStart(Verifier& verifier) const {
|
||||||
return verifier.VerifyTableStart(data_);
|
return verifier.VerifyTableStart(data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a particular field.
|
// Verify a particular field.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool VerifyField(const Verifier &verifier, voffset_t field,
|
bool VerifyField(const Verifier& verifier, voffset_t field,
|
||||||
size_t align) const {
|
size_t align) const {
|
||||||
// Calling GetOptionalFieldOffset should be safe now thanks to
|
// Calling GetOptionalFieldOffset should be safe now thanks to
|
||||||
// VerifyTable().
|
// VerifyTable().
|
||||||
@@ -132,8 +138,8 @@ class Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// VerifyField for required fields.
|
// VerifyField for required fields.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool VerifyFieldRequired(const Verifier &verifier, voffset_t field,
|
bool VerifyFieldRequired(const Verifier& verifier, voffset_t field,
|
||||||
size_t align) const {
|
size_t align) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
return verifier.Check(field_offset != 0) &&
|
return verifier.Check(field_offset != 0) &&
|
||||||
@@ -141,24 +147,24 @@ class Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Versions for offsets.
|
// Versions for offsets.
|
||||||
template<typename OffsetT = uoffset_t>
|
template <typename OffsetT = uoffset_t>
|
||||||
bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
|
bool VerifyOffset(const Verifier& verifier, voffset_t field) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
return !field_offset || verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
return !field_offset || verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OffsetT = uoffset_t>
|
template <typename OffsetT = uoffset_t>
|
||||||
bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
|
bool VerifyOffsetRequired(const Verifier& verifier, voffset_t field) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
return verifier.Check(field_offset != 0) &&
|
return verifier.Check(field_offset != 0) &&
|
||||||
verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifyOffset64(const Verifier &verifier, voffset_t field) const {
|
bool VerifyOffset64(const Verifier& verifier, voffset_t field) const {
|
||||||
return VerifyOffset<uoffset64_t>(verifier, field);
|
return VerifyOffset<uoffset64_t>(verifier, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifyOffset64Required(const Verifier &verifier, voffset_t field) const {
|
bool VerifyOffset64Required(const Verifier& verifier, voffset_t field) const {
|
||||||
return VerifyOffsetRequired<uoffset64_t>(verifier, field);
|
return VerifyOffsetRequired<uoffset64_t>(verifier, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,15 +172,15 @@ class Table {
|
|||||||
// private constructor & copy constructor: you obtain instances of this
|
// private constructor & copy constructor: you obtain instances of this
|
||||||
// class by pointing to existing data only
|
// class by pointing to existing data only
|
||||||
Table();
|
Table();
|
||||||
Table(const Table &other);
|
Table(const Table& other);
|
||||||
Table &operator=(const Table &);
|
Table& operator=(const Table&);
|
||||||
|
|
||||||
uint8_t data_[1];
|
uint8_t data_[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
// This specialization allows avoiding warnings like:
|
// This specialization allows avoiding warnings like:
|
||||||
// MSVC C4800: type: forcing value to bool 'true' or 'false'.
|
// MSVC C4800: type: forcing value to bool 'true' or 'false'.
|
||||||
template<>
|
template <>
|
||||||
inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>(
|
inline flatbuffers::Optional<bool> Table::GetOptional<uint8_t, bool>(
|
||||||
voffset_t field) const {
|
voffset_t field) const {
|
||||||
auto field_offset = GetOptionalFieldOffset(field);
|
auto field_offset = GetOptionalFieldOffset(field);
|
||||||
|
|||||||
@@ -24,11 +24,11 @@
|
|||||||
#include "flatbuffers/stl_emulation.h"
|
#include "flatbuffers/stl_emulation.h"
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_PREFER_PRINTF
|
#ifndef FLATBUFFERS_PREFER_PRINTF
|
||||||
# include <iomanip>
|
#include <iomanip>
|
||||||
# include <sstream>
|
#include <sstream>
|
||||||
#else // FLATBUFFERS_PREFER_PRINTF
|
#else // FLATBUFFERS_PREFER_PRINTF
|
||||||
# include <float.h>
|
#include <float.h>
|
||||||
# include <stdio.h>
|
#include <stdio.h>
|
||||||
#endif // FLATBUFFERS_PREFER_PRINTF
|
#endif // FLATBUFFERS_PREFER_PRINTF
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
@@ -90,7 +90,8 @@ inline char CharToLower(char c) {
|
|||||||
// @end-locale-independent functions for ASCII character set
|
// @end-locale-independent functions for ASCII character set
|
||||||
|
|
||||||
#ifdef FLATBUFFERS_PREFER_PRINTF
|
#ifdef FLATBUFFERS_PREFER_PRINTF
|
||||||
template<typename T> size_t IntToDigitCount(T t) {
|
template <typename T>
|
||||||
|
size_t IntToDigitCount(T t) {
|
||||||
size_t digit_count = 0;
|
size_t digit_count = 0;
|
||||||
// Count the sign for negative numbers
|
// Count the sign for negative numbers
|
||||||
if (t < 0) digit_count++;
|
if (t < 0) digit_count++;
|
||||||
@@ -105,19 +106,20 @@ template<typename T> size_t IntToDigitCount(T t) {
|
|||||||
return digit_count;
|
return digit_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> size_t NumToStringWidth(T t, int precision = 0) {
|
template <typename T>
|
||||||
|
size_t NumToStringWidth(T t, int precision = 0) {
|
||||||
size_t string_width = IntToDigitCount(t);
|
size_t string_width = IntToDigitCount(t);
|
||||||
// Count the dot for floating point numbers
|
// Count the dot for floating point numbers
|
||||||
if (precision) string_width += (precision + 1);
|
if (precision) string_width += (precision + 1);
|
||||||
return string_width;
|
return string_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
|
std::string NumToStringImplWrapper(T t, const char* fmt, int precision = 0) {
|
||||||
size_t string_width = NumToStringWidth(t, precision);
|
size_t string_width = NumToStringWidth(t, precision);
|
||||||
std::string s(string_width, 0x00);
|
std::string s(string_width, 0x00);
|
||||||
// Allow snprintf to use std::string trailing null to detect buffer overflow
|
// Allow snprintf to use std::string trailing null to detect buffer overflow
|
||||||
snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t);
|
snprintf(const_cast<char*>(s.data()), (s.size() + 1), fmt, string_width, t);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif // FLATBUFFERS_PREFER_PRINTF
|
#endif // FLATBUFFERS_PREFER_PRINTF
|
||||||
@@ -125,7 +127,8 @@ std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
|
|||||||
// Convert an integer or floating point value to a string.
|
// Convert an integer or floating point value to a string.
|
||||||
// In contrast to std::stringstream, "char" values are
|
// In contrast to std::stringstream, "char" values are
|
||||||
// converted to a string of digits, and we don't use scientific notation.
|
// converted to a string of digits, and we don't use scientific notation.
|
||||||
template<typename T> std::string NumToString(T t) {
|
template <typename T>
|
||||||
|
std::string NumToString(T t) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_PREFER_PRINTF
|
#ifndef FLATBUFFERS_PREFER_PRINTF
|
||||||
@@ -139,18 +142,22 @@ template<typename T> std::string NumToString(T t) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
// Avoid char types used as character data.
|
// Avoid char types used as character data.
|
||||||
template<> inline std::string NumToString<signed char>(signed char t) {
|
template <>
|
||||||
|
inline std::string NumToString<signed char>(signed char t) {
|
||||||
return NumToString(static_cast<int>(t));
|
return NumToString(static_cast<int>(t));
|
||||||
}
|
}
|
||||||
template<> inline std::string NumToString<unsigned char>(unsigned char t) {
|
template <>
|
||||||
|
inline std::string NumToString<unsigned char>(unsigned char t) {
|
||||||
return NumToString(static_cast<int>(t));
|
return NumToString(static_cast<int>(t));
|
||||||
}
|
}
|
||||||
template<> inline std::string NumToString<char>(char t) {
|
template <>
|
||||||
|
inline std::string NumToString<char>(char t) {
|
||||||
return NumToString(static_cast<int>(t));
|
return NumToString(static_cast<int>(t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special versions for floats/doubles.
|
// Special versions for floats/doubles.
|
||||||
template<typename T> std::string FloatToString(T t, int precision) {
|
template <typename T>
|
||||||
|
std::string FloatToString(T t, int precision) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_PREFER_PRINTF
|
#ifndef FLATBUFFERS_PREFER_PRINTF
|
||||||
@@ -177,10 +184,12 @@ template<typename T> std::string FloatToString(T t, int precision) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline std::string NumToString<double>(double t) {
|
template <>
|
||||||
|
inline std::string NumToString<double>(double t) {
|
||||||
return FloatToString(t, 12);
|
return FloatToString(t, 12);
|
||||||
}
|
}
|
||||||
template<> inline std::string NumToString<float>(float t) {
|
template <>
|
||||||
|
inline std::string NumToString<float>(float t) {
|
||||||
return FloatToString(t, 6);
|
return FloatToString(t, 6);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,8 +288,8 @@ inline void strtoval_impl(float *val, const char *str, char **endptr) {
|
|||||||
// - If full string conversion can't be performed, 0 is returned.
|
// - If full string conversion can't be performed, 0 is returned.
|
||||||
// - If the converted value falls out of range of corresponding return type, a
|
// - If the converted value falls out of range of corresponding return type, a
|
||||||
// range error occurs. In this case value MAX(T)/MIN(T) is returned.
|
// range error occurs. In this case value MAX(T)/MIN(T) is returned.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline bool StringToIntegerImpl(T *val, const char *const str,
|
inline bool StringToIntegerImpl(T* val, const char* const str,
|
||||||
const int base = 0,
|
const int base = 0,
|
||||||
const bool check_errno = true) {
|
const bool check_errno = true) {
|
||||||
// T is int64_t or uint64_T
|
// T is int64_t or uint64_T
|
||||||
@@ -295,7 +304,7 @@ inline bool StringToIntegerImpl(T *val, const char *const str,
|
|||||||
} else {
|
} else {
|
||||||
if (check_errno) errno = 0; // clear thread-local errno
|
if (check_errno) errno = 0; // clear thread-local errno
|
||||||
auto endptr = str;
|
auto endptr = str;
|
||||||
strtoval_impl(val, str, const_cast<char **>(&endptr), base);
|
strtoval_impl(val, str, const_cast<char**>(&endptr), base);
|
||||||
if ((*endptr != '\0') || (endptr == str)) {
|
if ((*endptr != '\0') || (endptr == str)) {
|
||||||
*val = 0; // erase partial result
|
*val = 0; // erase partial result
|
||||||
return false; // invalid string
|
return false; // invalid string
|
||||||
@@ -306,15 +315,17 @@ inline bool StringToIntegerImpl(T *val, const char *const str,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
inline bool StringToFloatImpl(T *val, const char *const str) {
|
inline bool StringToFloatImpl(T* val, const char* const str) {
|
||||||
// Type T must be either float or double.
|
// Type T must be either float or double.
|
||||||
FLATBUFFERS_ASSERT(str && val);
|
FLATBUFFERS_ASSERT(str && val);
|
||||||
auto end = str;
|
auto end = str;
|
||||||
strtoval_impl(val, str, const_cast<char **>(&end));
|
strtoval_impl(val, str, const_cast<char**>(&end));
|
||||||
auto done = (end != str) && (*end == '\0');
|
auto done = (end != str) && (*end == '\0');
|
||||||
if (!done) *val = 0; // erase partial result
|
if (!done) *val = 0; // erase partial result
|
||||||
if (done && std::isnan(*val)) { *val = std::numeric_limits<T>::quiet_NaN(); }
|
if (done && std::isnan(*val)) {
|
||||||
|
*val = std::numeric_limits<T>::quiet_NaN();
|
||||||
|
}
|
||||||
return done;
|
return done;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -324,7 +335,8 @@ inline bool StringToFloatImpl(T *val, const char *const str) {
|
|||||||
// - If full string conversion can't be performed, 0 is returned.
|
// - If full string conversion can't be performed, 0 is returned.
|
||||||
// - If the converted value falls out of range of corresponding return type, a
|
// - If the converted value falls out of range of corresponding return type, a
|
||||||
// range error occurs. In this case value MAX(T)/MIN(T) is returned.
|
// range error occurs. In this case value MAX(T)/MIN(T) is returned.
|
||||||
template<typename T> inline bool StringToNumber(const char *s, T *val) {
|
template <typename T>
|
||||||
|
inline bool StringToNumber(const char* s, T* val) {
|
||||||
// Assert on `unsigned long` and `signed long` on LP64.
|
// Assert on `unsigned long` and `signed long` on LP64.
|
||||||
// If it is necessary, it could be solved with flatbuffers::enable_if<B,T>.
|
// If it is necessary, it could be solved with flatbuffers::enable_if<B,T>.
|
||||||
static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T");
|
static_assert(sizeof(T) < sizeof(int64_t), "unexpected type T");
|
||||||
@@ -351,12 +363,13 @@ template<typename T> inline bool StringToNumber(const char *s, T *val) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline bool StringToNumber<int64_t>(const char *str, int64_t *val) {
|
template <>
|
||||||
|
inline bool StringToNumber<int64_t>(const char* str, int64_t* val) {
|
||||||
return StringToIntegerImpl(val, str);
|
return StringToIntegerImpl(val, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
|
inline bool StringToNumber<uint64_t>(const char* str, uint64_t* val) {
|
||||||
if (!StringToIntegerImpl(val, str)) return false;
|
if (!StringToIntegerImpl(val, str)) return false;
|
||||||
// The strtoull accepts negative numbers:
|
// The strtoull accepts negative numbers:
|
||||||
// If the minus sign was part of the input sequence, the numeric value
|
// If the minus sign was part of the input sequence, the numeric value
|
||||||
@@ -377,39 +390,41 @@ inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline bool StringToNumber(const char *s, float *val) {
|
template <>
|
||||||
|
inline bool StringToNumber(const char* s, float* val) {
|
||||||
return StringToFloatImpl(val, s);
|
return StringToFloatImpl(val, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<> inline bool StringToNumber(const char *s, double *val) {
|
template <>
|
||||||
|
inline bool StringToNumber(const char* s, double* val) {
|
||||||
return StringToFloatImpl(val, s);
|
return StringToFloatImpl(val, s);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int64_t StringToInt(const char *s, int base = 10) {
|
inline int64_t StringToInt(const char* s, int base = 10) {
|
||||||
int64_t val;
|
int64_t val;
|
||||||
return StringToIntegerImpl(&val, s, base) ? val : 0;
|
return StringToIntegerImpl(&val, s, base) ? val : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint64_t StringToUInt(const char *s, int base = 10) {
|
inline uint64_t StringToUInt(const char* s, int base = 10) {
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
return StringToIntegerImpl(&val, s, base) ? val : 0;
|
return StringToIntegerImpl(&val, s, base) ? val : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool StringIsFlatbufferNan(const std::string &s) {
|
inline bool StringIsFlatbufferNan(const std::string& s) {
|
||||||
return s == "nan" || s == "+nan" || s == "-nan";
|
return s == "nan" || s == "+nan" || s == "-nan";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool StringIsFlatbufferPositiveInfinity(const std::string &s) {
|
inline bool StringIsFlatbufferPositiveInfinity(const std::string& s) {
|
||||||
return s == "inf" || s == "+inf" || s == "infinity" || s == "+infinity";
|
return s == "inf" || s == "+inf" || s == "infinity" || s == "+infinity";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool StringIsFlatbufferNegativeInfinity(const std::string &s) {
|
inline bool StringIsFlatbufferNegativeInfinity(const std::string& s) {
|
||||||
return s == "-inf" || s == "-infinity";
|
return s == "-inf" || s == "-infinity";
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef bool (*LoadFileFunction)(const char *filename, bool binary,
|
typedef bool (*LoadFileFunction)(const char* filename, bool binary,
|
||||||
std::string *dest);
|
std::string* dest);
|
||||||
typedef bool (*FileExistsFunction)(const char *filename);
|
typedef bool (*FileExistsFunction)(const char* filename);
|
||||||
|
|
||||||
LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function);
|
LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function);
|
||||||
|
|
||||||
@@ -417,29 +432,29 @@ FileExistsFunction SetFileExistsFunction(
|
|||||||
FileExistsFunction file_exists_function);
|
FileExistsFunction file_exists_function);
|
||||||
|
|
||||||
// Check if file "name" exists.
|
// Check if file "name" exists.
|
||||||
bool FileExists(const char *name);
|
bool FileExists(const char* name);
|
||||||
|
|
||||||
// Check if "name" exists and it is also a directory.
|
// Check if "name" exists and it is also a directory.
|
||||||
bool DirExists(const char *name);
|
bool DirExists(const char* name);
|
||||||
|
|
||||||
// Load file "name" into "buf" returning true if successful
|
// Load file "name" into "buf" returning true if successful
|
||||||
// false otherwise. If "binary" is false data is read
|
// false otherwise. If "binary" is false data is read
|
||||||
// using ifstream's text mode, otherwise data is read with
|
// using ifstream's text mode, otherwise data is read with
|
||||||
// no transcoding.
|
// no transcoding.
|
||||||
bool LoadFile(const char *name, bool binary, std::string *buf);
|
bool LoadFile(const char* name, bool binary, std::string* buf);
|
||||||
|
|
||||||
// Save data "buf" of length "len" bytes into a file
|
// Save data "buf" of length "len" bytes into a file
|
||||||
// "name" returning true if successful, false otherwise.
|
// "name" returning true if successful, false otherwise.
|
||||||
// If "binary" is false data is written using ifstream's
|
// If "binary" is false data is written using ifstream's
|
||||||
// text mode, otherwise data is written with no
|
// text mode, otherwise data is written with no
|
||||||
// transcoding.
|
// transcoding.
|
||||||
bool SaveFile(const char *name, const char *buf, size_t len, bool binary);
|
bool SaveFile(const char* name, const char* buf, size_t len, bool binary);
|
||||||
|
|
||||||
// Save data "buf" into file "name" returning true if
|
// Save data "buf" into file "name" returning true if
|
||||||
// successful, false otherwise. If "binary" is false
|
// successful, false otherwise. If "binary" is false
|
||||||
// data is written using ifstream's text mode, otherwise
|
// data is written using ifstream's text mode, otherwise
|
||||||
// data is written with no transcoding.
|
// data is written with no transcoding.
|
||||||
inline bool SaveFile(const char *name, const std::string &buf, bool binary) {
|
inline bool SaveFile(const char* name, const std::string& buf, bool binary) {
|
||||||
return SaveFile(name, buf.c_str(), buf.size(), binary);
|
return SaveFile(name, buf.c_str(), buf.size(), binary);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -452,51 +467,50 @@ inline bool SaveFile(const char *name, const std::string &buf, bool binary) {
|
|||||||
FLATBUFFERS_CONSTEXPR char kPathSeparator = '/';
|
FLATBUFFERS_CONSTEXPR char kPathSeparator = '/';
|
||||||
|
|
||||||
// Returns the path with the extension, if any, removed.
|
// Returns the path with the extension, if any, removed.
|
||||||
std::string StripExtension(const std::string &filepath);
|
std::string StripExtension(const std::string& filepath);
|
||||||
|
|
||||||
// Returns the extension, if any.
|
// Returns the extension, if any.
|
||||||
std::string GetExtension(const std::string &filepath);
|
std::string GetExtension(const std::string& filepath);
|
||||||
|
|
||||||
// Return the last component of the path, after the last separator.
|
// Return the last component of the path, after the last separator.
|
||||||
std::string StripPath(const std::string &filepath);
|
std::string StripPath(const std::string& filepath);
|
||||||
|
|
||||||
// Strip the last component of the path + separator.
|
// Strip the last component of the path + separator.
|
||||||
std::string StripFileName(const std::string &filepath);
|
std::string StripFileName(const std::string& filepath);
|
||||||
|
|
||||||
std::string StripPrefix(const std::string &filepath,
|
std::string StripPrefix(const std::string& filepath,
|
||||||
const std::string &prefix_to_remove);
|
const std::string& prefix_to_remove);
|
||||||
|
|
||||||
// Concatenates a path with a filename, regardless of whether the path
|
// Concatenates a path with a filename, regardless of whether the path
|
||||||
// ends in a separator or not.
|
// ends in a separator or not.
|
||||||
std::string ConCatPathFileName(const std::string &path,
|
std::string ConCatPathFileName(const std::string& path,
|
||||||
const std::string &filename);
|
const std::string& filename);
|
||||||
|
|
||||||
// Replaces any '\\' separators with '/'
|
// Replaces any '\\' separators with '/'
|
||||||
std::string PosixPath(const char *path);
|
std::string PosixPath(const char* path);
|
||||||
std::string PosixPath(const std::string &path);
|
std::string PosixPath(const std::string& path);
|
||||||
|
|
||||||
// This function ensure a directory exists, by recursively
|
// This function ensure a directory exists, by recursively
|
||||||
// creating dirs for any parts of the path that don't exist yet.
|
// creating dirs for any parts of the path that don't exist yet.
|
||||||
void EnsureDirExists(const std::string &filepath);
|
void EnsureDirExists(const std::string& filepath);
|
||||||
|
|
||||||
// Obtains the relative or absolute path.
|
// Obtains the relative or absolute path.
|
||||||
std::string FilePath(const std::string &project,
|
std::string FilePath(const std::string& project, const std::string& filePath,
|
||||||
const std::string &filePath,
|
|
||||||
bool absolute);
|
bool absolute);
|
||||||
|
|
||||||
// Obtains the absolute path from any other path.
|
// Obtains the absolute path from any other path.
|
||||||
// Returns the input path if the absolute path couldn't be resolved.
|
// Returns the input path if the absolute path couldn't be resolved.
|
||||||
std::string AbsolutePath(const std::string &filepath);
|
std::string AbsolutePath(const std::string& filepath);
|
||||||
|
|
||||||
// Returns files relative to the --project_root path, prefixed with `//`.
|
// Returns files relative to the --project_root path, prefixed with `//`.
|
||||||
std::string RelativeToRootPath(const std::string &project,
|
std::string RelativeToRootPath(const std::string& project,
|
||||||
const std::string &filepath);
|
const std::string& filepath);
|
||||||
|
|
||||||
// To and from UTF-8 unicode conversion functions
|
// To and from UTF-8 unicode conversion functions
|
||||||
|
|
||||||
// Convert a unicode code point into a UTF-8 representation by appending it
|
// Convert a unicode code point into a UTF-8 representation by appending it
|
||||||
// to a string. Returns the number of bytes generated.
|
// to a string. Returns the number of bytes generated.
|
||||||
inline int ToUTF8(uint32_t ucc, std::string *out) {
|
inline int ToUTF8(uint32_t ucc, std::string* out) {
|
||||||
FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set.
|
FLATBUFFERS_ASSERT(!(ucc & 0x80000000)); // Top bit can't be set.
|
||||||
// 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8
|
// 6 possible encodings: http://en.wikipedia.org/wiki/UTF-8
|
||||||
for (int i = 0; i < 6; i++) {
|
for (int i = 0; i < 6; i++) {
|
||||||
@@ -524,7 +538,7 @@ inline int ToUTF8(uint32_t ucc, std::string *out) {
|
|||||||
// advanced past all bytes parsed.
|
// advanced past all bytes parsed.
|
||||||
// returns -1 upon corrupt UTF-8 encoding (ignore the incoming pointer in
|
// returns -1 upon corrupt UTF-8 encoding (ignore the incoming pointer in
|
||||||
// this case).
|
// this case).
|
||||||
inline int FromUTF8(const char **in) {
|
inline int FromUTF8(const char** in) {
|
||||||
int len = 0;
|
int len = 0;
|
||||||
// Count leading 1 bits.
|
// Count leading 1 bits.
|
||||||
for (int mask = 0x80; mask >= 0x04; mask >>= 1) {
|
for (int mask = 0x80; mask >= 0x04; mask >>= 1) {
|
||||||
@@ -538,7 +552,9 @@ inline int FromUTF8(const char **in) {
|
|||||||
return -1; // Bit after leading 1's must be 0.
|
return -1; // Bit after leading 1's must be 0.
|
||||||
if (!len) return *(*in)++;
|
if (!len) return *(*in)++;
|
||||||
// UTF-8 encoded values with a length are between 2 and 4 bytes.
|
// UTF-8 encoded values with a length are between 2 and 4 bytes.
|
||||||
if (len < 2 || len > 4) { return -1; }
|
if (len < 2 || len > 4) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// Grab initial bits of the code.
|
// Grab initial bits of the code.
|
||||||
int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
|
int ucc = *(*in)++ & ((1 << (7 - len)) - 1);
|
||||||
for (int i = 0; i < len - 1; i++) {
|
for (int i = 0; i < len - 1; i++) {
|
||||||
@@ -548,20 +564,28 @@ inline int FromUTF8(const char **in) {
|
|||||||
}
|
}
|
||||||
// UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
|
// UTF-8 cannot encode values between 0xD800 and 0xDFFF (reserved for
|
||||||
// UTF-16 surrogate pairs).
|
// UTF-16 surrogate pairs).
|
||||||
if (ucc >= 0xD800 && ucc <= 0xDFFF) { return -1; }
|
if (ucc >= 0xD800 && ucc <= 0xDFFF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
// UTF-8 must represent code points in their shortest possible encoding.
|
// UTF-8 must represent code points in their shortest possible encoding.
|
||||||
switch (len) {
|
switch (len) {
|
||||||
case 2:
|
case 2:
|
||||||
// Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
|
// Two bytes of UTF-8 can represent code points from U+0080 to U+07FF.
|
||||||
if (ucc < 0x0080 || ucc > 0x07FF) { return -1; }
|
if (ucc < 0x0080 || ucc > 0x07FF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
// Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
|
// Three bytes of UTF-8 can represent code points from U+0800 to U+FFFF.
|
||||||
if (ucc < 0x0800 || ucc > 0xFFFF) { return -1; }
|
if (ucc < 0x0800 || ucc > 0xFFFF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
// Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
|
// Four bytes of UTF-8 can represent code points from U+10000 to U+10FFFF.
|
||||||
if (ucc < 0x10000 || ucc > 0x10FFFF) { return -1; }
|
if (ucc < 0x10000 || ucc > 0x10FFFF) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return ucc;
|
return ucc;
|
||||||
@@ -596,26 +620,40 @@ inline std::string WordWrap(const std::string in, size_t max_length,
|
|||||||
}
|
}
|
||||||
#endif // !FLATBUFFERS_PREFER_PRINTF
|
#endif // !FLATBUFFERS_PREFER_PRINTF
|
||||||
|
|
||||||
inline bool EscapeString(const char *s, size_t length, std::string *_text,
|
inline bool EscapeString(const char* s, size_t length, std::string* _text,
|
||||||
bool allow_non_utf8, bool natural_utf8) {
|
bool allow_non_utf8, bool natural_utf8) {
|
||||||
std::string &text = *_text;
|
std::string& text = *_text;
|
||||||
text += "\"";
|
text += "\"";
|
||||||
for (uoffset_t i = 0; i < length; i++) {
|
for (uoffset_t i = 0; i < length; i++) {
|
||||||
char c = s[i];
|
char c = s[i];
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '\n': text += "\\n"; break;
|
case '\n':
|
||||||
case '\t': text += "\\t"; break;
|
text += "\\n";
|
||||||
case '\r': text += "\\r"; break;
|
break;
|
||||||
case '\b': text += "\\b"; break;
|
case '\t':
|
||||||
case '\f': text += "\\f"; break;
|
text += "\\t";
|
||||||
case '\"': text += "\\\""; break;
|
break;
|
||||||
case '\\': text += "\\\\"; break;
|
case '\r':
|
||||||
|
text += "\\r";
|
||||||
|
break;
|
||||||
|
case '\b':
|
||||||
|
text += "\\b";
|
||||||
|
break;
|
||||||
|
case '\f':
|
||||||
|
text += "\\f";
|
||||||
|
break;
|
||||||
|
case '\"':
|
||||||
|
text += "\\\"";
|
||||||
|
break;
|
||||||
|
case '\\':
|
||||||
|
text += "\\\\";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
if (c >= ' ' && c <= '~') {
|
if (c >= ' ' && c <= '~') {
|
||||||
text += c;
|
text += c;
|
||||||
} else {
|
} else {
|
||||||
// Not printable ASCII data. Let's see if it's valid UTF-8 first:
|
// Not printable ASCII data. Let's see if it's valid UTF-8 first:
|
||||||
const char *utf8 = s + i;
|
const char* utf8 = s + i;
|
||||||
int ucc = FromUTF8(&utf8);
|
int ucc = FromUTF8(&utf8);
|
||||||
if (ucc < 0) {
|
if (ucc < 0) {
|
||||||
if (allow_non_utf8) {
|
if (allow_non_utf8) {
|
||||||
@@ -666,19 +704,21 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
|
inline std::string BufferToHexText(const void* buffer, size_t buffer_size,
|
||||||
size_t max_length,
|
size_t max_length,
|
||||||
const std::string &wrapped_line_prefix,
|
const std::string& wrapped_line_prefix,
|
||||||
const std::string &wrapped_line_suffix) {
|
const std::string& wrapped_line_suffix) {
|
||||||
std::string text = wrapped_line_prefix;
|
std::string text = wrapped_line_prefix;
|
||||||
size_t start_offset = 0;
|
size_t start_offset = 0;
|
||||||
const char *s = reinterpret_cast<const char *>(buffer);
|
const char* s = reinterpret_cast<const char*>(buffer);
|
||||||
for (size_t i = 0; s && i < buffer_size; i++) {
|
for (size_t i = 0; s && i < buffer_size; i++) {
|
||||||
// Last iteration or do we have more?
|
// Last iteration or do we have more?
|
||||||
bool have_more = i + 1 < buffer_size;
|
bool have_more = i + 1 < buffer_size;
|
||||||
text += "0x";
|
text += "0x";
|
||||||
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
|
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
|
||||||
if (have_more) { text += ','; }
|
if (have_more) {
|
||||||
|
text += ',';
|
||||||
|
}
|
||||||
// If we have more to process and we reached max_length
|
// If we have more to process and we reached max_length
|
||||||
if (have_more &&
|
if (have_more &&
|
||||||
text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
|
text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
|
||||||
@@ -693,17 +733,17 @@ inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove paired quotes in a string: "text"|'text' -> text.
|
// Remove paired quotes in a string: "text"|'text' -> text.
|
||||||
std::string RemoveStringQuotes(const std::string &s);
|
std::string RemoveStringQuotes(const std::string& s);
|
||||||
|
|
||||||
// Change th global C-locale to locale with name <locale_name>.
|
// Change th global C-locale to locale with name <locale_name>.
|
||||||
// Returns an actual locale name in <_value>, useful if locale_name is "" or
|
// Returns an actual locale name in <_value>, useful if locale_name is "" or
|
||||||
// null.
|
// null.
|
||||||
bool SetGlobalTestLocale(const char *locale_name,
|
bool SetGlobalTestLocale(const char* locale_name,
|
||||||
std::string *_value = nullptr);
|
std::string* _value = nullptr);
|
||||||
|
|
||||||
// Read (or test) a value of environment variable.
|
// Read (or test) a value of environment variable.
|
||||||
bool ReadEnvironmentVariable(const char *var_name,
|
bool ReadEnvironmentVariable(const char* var_name,
|
||||||
std::string *_value = nullptr);
|
std::string* _value = nullptr);
|
||||||
|
|
||||||
enum class Case {
|
enum class Case {
|
||||||
kUnknown = 0,
|
kUnknown = 0,
|
||||||
@@ -729,7 +769,7 @@ enum class Case {
|
|||||||
|
|
||||||
// Convert the `input` string of case `input_case` to the specified
|
// Convert the `input` string of case `input_case` to the specified
|
||||||
// `output_case`.
|
// `output_case`.
|
||||||
std::string ConvertCase(const std::string &input, Case output_case,
|
std::string ConvertCase(const std::string& input, Case output_case,
|
||||||
Case input_case = Case::kSnake);
|
Case input_case = Case::kSnake);
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -27,56 +27,56 @@ struct String;
|
|||||||
|
|
||||||
// An STL compatible iterator implementation for Vector below, effectively
|
// An STL compatible iterator implementation for Vector below, effectively
|
||||||
// calling Get() for every element.
|
// calling Get() for every element.
|
||||||
template<typename T, typename IT, typename Data = uint8_t *,
|
template <typename T, typename IT, typename Data = uint8_t*,
|
||||||
typename SizeT = uoffset_t>
|
typename SizeT = uoffset_t>
|
||||||
struct VectorIterator {
|
struct VectorIterator {
|
||||||
typedef std::random_access_iterator_tag iterator_category;
|
typedef std::random_access_iterator_tag iterator_category;
|
||||||
typedef IT value_type;
|
typedef IT value_type;
|
||||||
typedef ptrdiff_t difference_type;
|
typedef ptrdiff_t difference_type;
|
||||||
typedef IT *pointer;
|
typedef IT* pointer;
|
||||||
typedef IT &reference;
|
typedef IT& reference;
|
||||||
|
|
||||||
static const SizeT element_stride = IndirectHelper<T>::element_stride;
|
static const SizeT element_stride = IndirectHelper<T>::element_stride;
|
||||||
|
|
||||||
VectorIterator(Data data, SizeT i) : data_(data + element_stride * i) {}
|
VectorIterator(Data data, SizeT i) : data_(data + element_stride * i) {}
|
||||||
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
VectorIterator(const VectorIterator& other) : data_(other.data_) {}
|
||||||
VectorIterator() : data_(nullptr) {}
|
VectorIterator() : data_(nullptr) {}
|
||||||
|
|
||||||
VectorIterator &operator=(const VectorIterator &other) {
|
VectorIterator& operator=(const VectorIterator& other) {
|
||||||
data_ = other.data_;
|
data_ = other.data_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator &operator=(VectorIterator &&other) {
|
VectorIterator& operator=(VectorIterator&& other) {
|
||||||
data_ = other.data_;
|
data_ = other.data_;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator==(const VectorIterator &other) const {
|
bool operator==(const VectorIterator& other) const {
|
||||||
return data_ == other.data_;
|
return data_ == other.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const VectorIterator &other) const {
|
bool operator!=(const VectorIterator& other) const {
|
||||||
return data_ != other.data_;
|
return data_ != other.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<(const VectorIterator &other) const {
|
bool operator<(const VectorIterator& other) const {
|
||||||
return data_ < other.data_;
|
return data_ < other.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>(const VectorIterator &other) const {
|
bool operator>(const VectorIterator& other) const {
|
||||||
return data_ > other.data_;
|
return data_ > other.data_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator<=(const VectorIterator &other) const {
|
bool operator<=(const VectorIterator& other) const {
|
||||||
return !(data_ > other.data_);
|
return !(data_ > other.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator>=(const VectorIterator &other) const {
|
bool operator>=(const VectorIterator& other) const {
|
||||||
return !(data_ < other.data_);
|
return !(data_ < other.data_);
|
||||||
}
|
}
|
||||||
|
|
||||||
difference_type operator-(const VectorIterator &other) const {
|
difference_type operator-(const VectorIterator& other) const {
|
||||||
return (data_ - other.data_) / element_stride;
|
return (data_ - other.data_) / element_stride;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ struct VectorIterator {
|
|||||||
// `pointer operator->()`.
|
// `pointer operator->()`.
|
||||||
IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
|
IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
|
||||||
|
|
||||||
VectorIterator &operator++() {
|
VectorIterator& operator++() {
|
||||||
data_ += element_stride;
|
data_ += element_stride;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -99,16 +99,16 @@ struct VectorIterator {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator operator+(const SizeT &offset) const {
|
VectorIterator operator+(const SizeT& offset) const {
|
||||||
return VectorIterator(data_ + offset * element_stride, 0);
|
return VectorIterator(data_ + offset * element_stride, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator &operator+=(const SizeT &offset) {
|
VectorIterator& operator+=(const SizeT& offset) {
|
||||||
data_ += offset * element_stride;
|
data_ += offset * element_stride;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator &operator--() {
|
VectorIterator& operator--() {
|
||||||
data_ -= element_stride;
|
data_ -= element_stride;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -119,11 +119,11 @@ struct VectorIterator {
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator operator-(const SizeT &offset) const {
|
VectorIterator operator-(const SizeT& offset) const {
|
||||||
return VectorIterator(data_ - offset * element_stride, 0);
|
return VectorIterator(data_ - offset * element_stride, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
VectorIterator &operator-=(const SizeT &offset) {
|
VectorIterator& operator-=(const SizeT& offset) {
|
||||||
data_ -= offset * element_stride;
|
data_ -= offset * element_stride;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -132,10 +132,10 @@ struct VectorIterator {
|
|||||||
Data data_;
|
Data data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename IT, typename SizeT = uoffset_t>
|
template <typename T, typename IT, typename SizeT = uoffset_t>
|
||||||
using VectorConstIterator = VectorIterator<T, IT, const uint8_t *, SizeT>;
|
using VectorConstIterator = VectorIterator<T, IT, const uint8_t*, SizeT>;
|
||||||
|
|
||||||
template<typename Iterator>
|
template <typename Iterator>
|
||||||
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
||||||
explicit VectorReverseIterator(Iterator iter)
|
explicit VectorReverseIterator(Iterator iter)
|
||||||
: std::reverse_iterator<Iterator>(iter) {}
|
: std::reverse_iterator<Iterator>(iter) {}
|
||||||
@@ -157,10 +157,11 @@ struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
|||||||
|
|
||||||
// This is used as a helper type for accessing vectors.
|
// This is used as a helper type for accessing vectors.
|
||||||
// Vector::data() assumes the vector elements start after the length field.
|
// Vector::data() assumes the vector elements start after the length field.
|
||||||
template<typename T, typename SizeT = uoffset_t> class Vector {
|
template <typename T, typename SizeT = uoffset_t>
|
||||||
|
class Vector {
|
||||||
public:
|
public:
|
||||||
typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type,
|
typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type,
|
||||||
uint8_t *, SizeT>
|
uint8_t*, SizeT>
|
||||||
iterator;
|
iterator;
|
||||||
typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type, SizeT>
|
typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type, SizeT>
|
||||||
const_iterator;
|
const_iterator;
|
||||||
@@ -199,24 +200,26 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
|
|||||||
// If this is a Vector of enums, T will be its storage type, not the enum
|
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||||
// type. This function makes it convenient to retrieve value with enum
|
// type. This function makes it convenient to retrieve value with enum
|
||||||
// type E.
|
// type E.
|
||||||
template<typename E> E GetEnum(SizeT i) const {
|
template <typename E>
|
||||||
|
E GetEnum(SizeT i) const {
|
||||||
return static_cast<E>(Get(i));
|
return static_cast<E>(Get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this a vector of unions, this does the cast for you. There's no check
|
// If this a vector of unions, this does the cast for you. There's no check
|
||||||
// to make sure this is the right type!
|
// to make sure this is the right type!
|
||||||
template<typename U> const U *GetAs(SizeT i) const {
|
template <typename U>
|
||||||
return reinterpret_cast<const U *>(Get(i));
|
const U* GetAs(SizeT i) const {
|
||||||
|
return reinterpret_cast<const U*>(Get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this a vector of unions, this does the cast for you. There's no check
|
// If this a vector of unions, this does the cast for you. There's no check
|
||||||
// to make sure this is actually a string!
|
// to make sure this is actually a string!
|
||||||
const String *GetAsString(SizeT i) const {
|
const String* GetAsString(SizeT i) const {
|
||||||
return reinterpret_cast<const String *>(Get(i));
|
return reinterpret_cast<const String*>(Get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
const void *GetStructFromOffset(size_t o) const {
|
const void* GetStructFromOffset(size_t o) const {
|
||||||
return reinterpret_cast<const void *>(Data() + o);
|
return reinterpret_cast<const void*>(Data() + o);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin() { return iterator(Data(), 0); }
|
iterator begin() { return iterator(Data(), 0); }
|
||||||
@@ -245,7 +248,7 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
|
|||||||
|
|
||||||
// Change elements if you have a non-const pointer to this object.
|
// Change elements if you have a non-const pointer to this object.
|
||||||
// Scalars only. See reflection.h, and the documentation.
|
// Scalars only. See reflection.h, and the documentation.
|
||||||
void Mutate(SizeT i, const T &val) {
|
void Mutate(SizeT i, const T& val) {
|
||||||
FLATBUFFERS_ASSERT(i < size());
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
WriteScalar(data() + i, val);
|
WriteScalar(data() + i, val);
|
||||||
}
|
}
|
||||||
@@ -253,7 +256,7 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
|
|||||||
// Change an element of a vector of tables (or strings).
|
// Change an element of a vector of tables (or strings).
|
||||||
// "val" points to the new table/string, as you can obtain from
|
// "val" points to the new table/string, as you can obtain from
|
||||||
// e.g. reflection::AddFlatBuffer().
|
// e.g. reflection::AddFlatBuffer().
|
||||||
void MutateOffset(SizeT i, const uint8_t *val) {
|
void MutateOffset(SizeT i, const uint8_t* val) {
|
||||||
FLATBUFFERS_ASSERT(i < size());
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
static_assert(sizeof(T) == sizeof(SizeT), "Unrelated types");
|
static_assert(sizeof(T) == sizeof(SizeT), "Unrelated types");
|
||||||
WriteScalar(data() + i,
|
WriteScalar(data() + i,
|
||||||
@@ -267,30 +270,32 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The raw data in little endian format. Use with care.
|
// The raw data in little endian format. Use with care.
|
||||||
const uint8_t *Data() const {
|
const uint8_t* Data() const {
|
||||||
return reinterpret_cast<const uint8_t *>(&length_ + 1);
|
return reinterpret_cast<const uint8_t*>(&length_ + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
|
uint8_t* Data() { return reinterpret_cast<uint8_t*>(&length_ + 1); }
|
||||||
|
|
||||||
// Similarly, but typed, much like std::vector::data
|
// Similarly, but typed, much like std::vector::data
|
||||||
const T *data() const { return reinterpret_cast<const T *>(Data()); }
|
const T* data() const { return reinterpret_cast<const T*>(Data()); }
|
||||||
T *data() { return reinterpret_cast<T *>(Data()); }
|
T* data() { return reinterpret_cast<T*>(Data()); }
|
||||||
|
|
||||||
template<typename K> return_type LookupByKey(K key) const {
|
template <typename K>
|
||||||
void *search_result = std::bsearch(
|
return_type LookupByKey(K key) const {
|
||||||
|
void* search_result = std::bsearch(
|
||||||
&key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
|
&key, Data(), size(), IndirectHelper<T>::element_stride, KeyCompare<K>);
|
||||||
|
|
||||||
if (!search_result) {
|
if (!search_result) {
|
||||||
return nullptr; // Key not found.
|
return nullptr; // Key not found.
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *element = reinterpret_cast<const uint8_t *>(search_result);
|
const uint8_t* element = reinterpret_cast<const uint8_t*>(search_result);
|
||||||
|
|
||||||
return IndirectHelper<T>::Read(element, 0);
|
return IndirectHelper<T>::Read(element, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename K> mutable_return_type MutableLookupByKey(K key) {
|
template <typename K>
|
||||||
|
mutable_return_type MutableLookupByKey(K key) {
|
||||||
return const_cast<mutable_return_type>(LookupByKey(key));
|
return const_cast<mutable_return_type>(LookupByKey(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,12 +309,13 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
|
|||||||
private:
|
private:
|
||||||
// This class is a pointer. Copying will therefore create an invalid object.
|
// This class is a pointer. Copying will therefore create an invalid object.
|
||||||
// Private and unimplemented copy constructor.
|
// Private and unimplemented copy constructor.
|
||||||
Vector(const Vector &);
|
Vector(const Vector&);
|
||||||
Vector &operator=(const Vector &);
|
Vector& operator=(const Vector&);
|
||||||
|
|
||||||
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
|
template <typename K>
|
||||||
const K *key = reinterpret_cast<const K *>(ap);
|
static int KeyCompare(const void* ap, const void* bp) {
|
||||||
const uint8_t *data = reinterpret_cast<const uint8_t *>(bp);
|
const K* key = reinterpret_cast<const K*>(ap);
|
||||||
|
const uint8_t* data = reinterpret_cast<const uint8_t*>(bp);
|
||||||
auto table = IndirectHelper<T>::Read(data, 0);
|
auto table = IndirectHelper<T>::Read(data, 0);
|
||||||
|
|
||||||
// std::bsearch compares with the operands transposed, so we negate the
|
// std::bsearch compares with the operands transposed, so we negate the
|
||||||
@@ -318,35 +324,36 @@ template<typename T, typename SizeT = uoffset_t> class Vector {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> using Vector64 = Vector<T, uoffset64_t>;
|
template <typename T>
|
||||||
|
using Vector64 = Vector<T, uoffset64_t>;
|
||||||
|
|
||||||
template<class U>
|
template <class U>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U>& vec)
|
||||||
FLATBUFFERS_NOEXCEPT {
|
FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Vector<U>::is_span_observable,
|
static_assert(Vector<U>::is_span_observable,
|
||||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||||
return span<U>(vec.data(), vec.size());
|
return span<U>(vec.data(), vec.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template <class U>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
||||||
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
const Vector<U>& vec) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Vector<U>::is_span_observable,
|
static_assert(Vector<U>::is_span_observable,
|
||||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||||
return span<const U>(vec.data(), vec.size());
|
return span<const U>(vec.data(), vec.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template <class U>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<uint8_t> make_bytes_span(
|
||||||
Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
Vector<U>& vec) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Vector<U>::scalar_tag::value,
|
static_assert(Vector<U>::scalar_tag::value,
|
||||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||||
return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
return span<uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template <class U>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
|
||||||
const Vector<U> &vec) FLATBUFFERS_NOEXCEPT {
|
const Vector<U>& vec) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Vector<U>::scalar_tag::value,
|
static_assert(Vector<U>::scalar_tag::value,
|
||||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||||
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
return span<const uint8_t>(vec.Data(), vec.size() * sizeof(U));
|
||||||
@@ -354,17 +361,17 @@ FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const uint8_t> make_bytes_span(
|
|||||||
|
|
||||||
// Convenient helper functions to get a span of any vector, regardless
|
// Convenient helper functions to get a span of any vector, regardless
|
||||||
// of whether it is null or not (the field is not set).
|
// of whether it is null or not (the field is not set).
|
||||||
template<class U>
|
template <class U>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> *ptr)
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U>* ptr)
|
||||||
FLATBUFFERS_NOEXCEPT {
|
FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Vector<U>::is_span_observable,
|
static_assert(Vector<U>::is_span_observable,
|
||||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||||
return ptr ? make_span(*ptr) : span<U>();
|
return ptr ? make_span(*ptr) : span<U>();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class U>
|
template <class U>
|
||||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<const U> make_span(
|
||||||
const Vector<U> *ptr) FLATBUFFERS_NOEXCEPT {
|
const Vector<U>* ptr) FLATBUFFERS_NOEXCEPT {
|
||||||
static_assert(Vector<U>::is_span_observable,
|
static_assert(Vector<U>::is_span_observable,
|
||||||
"wrong type U, only LE-scalar, or byte types are allowed");
|
"wrong type U, only LE-scalar, or byte types are allowed");
|
||||||
return ptr ? make_span(*ptr) : span<const U>();
|
return ptr ? make_span(*ptr) : span<const U>();
|
||||||
@@ -376,10 +383,10 @@ class VectorOfAny {
|
|||||||
public:
|
public:
|
||||||
uoffset_t size() const { return EndianScalar(length_); }
|
uoffset_t size() const { return EndianScalar(length_); }
|
||||||
|
|
||||||
const uint8_t *Data() const {
|
const uint8_t* Data() const {
|
||||||
return reinterpret_cast<const uint8_t *>(&length_ + 1);
|
return reinterpret_cast<const uint8_t*>(&length_ + 1);
|
||||||
}
|
}
|
||||||
uint8_t *Data() { return reinterpret_cast<uint8_t *>(&length_ + 1); }
|
uint8_t* Data() { return reinterpret_cast<uint8_t*>(&length_ + 1); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VectorOfAny();
|
VectorOfAny();
|
||||||
@@ -387,25 +394,26 @@ class VectorOfAny {
|
|||||||
uoffset_t length_;
|
uoffset_t length_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VectorOfAny(const VectorOfAny &);
|
VectorOfAny(const VectorOfAny&);
|
||||||
VectorOfAny &operator=(const VectorOfAny &);
|
VectorOfAny& operator=(const VectorOfAny&);
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, typename U>
|
template <typename T, typename U>
|
||||||
Vector<Offset<T>> *VectorCast(Vector<Offset<U>> *ptr) {
|
Vector<Offset<T>>* VectorCast(Vector<Offset<U>>* ptr) {
|
||||||
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
||||||
return reinterpret_cast<Vector<Offset<T>> *>(ptr);
|
return reinterpret_cast<Vector<Offset<T>>*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename U>
|
template <typename T, typename U>
|
||||||
const Vector<Offset<T>> *VectorCast(const Vector<Offset<U>> *ptr) {
|
const Vector<Offset<T>>* VectorCast(const Vector<Offset<U>>* ptr) {
|
||||||
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
static_assert(std::is_base_of<T, U>::value, "Unrelated types");
|
||||||
return reinterpret_cast<const Vector<Offset<T>> *>(ptr);
|
return reinterpret_cast<const Vector<Offset<T>>*>(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenient helper function to get the length of any vector, regardless
|
// Convenient helper function to get the length of any vector, regardless
|
||||||
// of whether it is null or not (the field is not set).
|
// of whether it is null or not (the field is not set).
|
||||||
template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
|
template <typename T>
|
||||||
|
static inline size_t VectorLength(const Vector<T>* v) {
|
||||||
return v ? v->size() : 0;
|
return v ? v->size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,9 +32,10 @@ namespace flatbuffers {
|
|||||||
// Since this vector leaves the lower part unused, we support a "scratch-pad"
|
// Since this vector leaves the lower part unused, we support a "scratch-pad"
|
||||||
// that can be stored there for temporary data, to share the allocated space.
|
// that can be stored there for temporary data, to share the allocated space.
|
||||||
// Essentially, this supports 2 std::vectors in a single buffer.
|
// Essentially, this supports 2 std::vectors in a single buffer.
|
||||||
template<typename SizeT = uoffset_t> class vector_downward {
|
template <typename SizeT = uoffset_t>
|
||||||
|
class vector_downward {
|
||||||
public:
|
public:
|
||||||
explicit vector_downward(size_t initial_size, Allocator *allocator,
|
explicit vector_downward(size_t initial_size, Allocator* allocator,
|
||||||
bool own_allocator, size_t buffer_minalign,
|
bool own_allocator, size_t buffer_minalign,
|
||||||
const SizeT max_size = FLATBUFFERS_MAX_BUFFER_SIZE)
|
const SizeT max_size = FLATBUFFERS_MAX_BUFFER_SIZE)
|
||||||
: allocator_(allocator),
|
: allocator_(allocator),
|
||||||
@@ -48,7 +49,7 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
cur_(nullptr),
|
cur_(nullptr),
|
||||||
scratch_(nullptr) {}
|
scratch_(nullptr) {}
|
||||||
|
|
||||||
vector_downward(vector_downward &&other) noexcept
|
vector_downward(vector_downward&& other) noexcept
|
||||||
// clang-format on
|
// clang-format on
|
||||||
: allocator_(other.allocator_),
|
: allocator_(other.allocator_),
|
||||||
own_allocator_(other.own_allocator_),
|
own_allocator_(other.own_allocator_),
|
||||||
@@ -70,7 +71,7 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
other.scratch_ = nullptr;
|
other.scratch_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector_downward &operator=(vector_downward &&other) noexcept {
|
vector_downward& operator=(vector_downward&& other) noexcept {
|
||||||
// Move construct a temporary and swap idiom
|
// Move construct a temporary and swap idiom
|
||||||
vector_downward temp(std::move(other));
|
vector_downward temp(std::move(other));
|
||||||
swap(temp);
|
swap(temp);
|
||||||
@@ -101,7 +102,9 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
void clear_scratch() { scratch_ = buf_; }
|
void clear_scratch() { scratch_ = buf_; }
|
||||||
|
|
||||||
void clear_allocator() {
|
void clear_allocator() {
|
||||||
if (own_allocator_ && allocator_) { delete allocator_; }
|
if (own_allocator_ && allocator_) {
|
||||||
|
delete allocator_;
|
||||||
|
}
|
||||||
allocator_ = nullptr;
|
allocator_ = nullptr;
|
||||||
own_allocator_ = false;
|
own_allocator_ = false;
|
||||||
}
|
}
|
||||||
@@ -112,8 +115,8 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relinquish the pointer to the caller.
|
// Relinquish the pointer to the caller.
|
||||||
uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) {
|
uint8_t* release_raw(size_t& allocated_bytes, size_t& offset) {
|
||||||
auto *buf = buf_;
|
auto* buf = buf_;
|
||||||
allocated_bytes = reserved_;
|
allocated_bytes = reserved_;
|
||||||
offset = vector_downward::offset();
|
offset = vector_downward::offset();
|
||||||
|
|
||||||
@@ -142,12 +145,14 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
|
FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
|
||||||
// If the length is larger than the unused part of the buffer, we need to
|
// If the length is larger than the unused part of the buffer, we need to
|
||||||
// grow.
|
// grow.
|
||||||
if (len > unused_buffer_size()) { reallocate(len); }
|
if (len > unused_buffer_size()) {
|
||||||
|
reallocate(len);
|
||||||
|
}
|
||||||
FLATBUFFERS_ASSERT(size() < max_size_);
|
FLATBUFFERS_ASSERT(size() < max_size_);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t *make_space(size_t len) {
|
inline uint8_t* make_space(size_t len) {
|
||||||
if (len) {
|
if (len) {
|
||||||
ensure_space(len);
|
ensure_space(len);
|
||||||
cur_ -= len;
|
cur_ -= len;
|
||||||
@@ -157,7 +162,7 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns nullptr if using the DefaultAllocator.
|
// Returns nullptr if using the DefaultAllocator.
|
||||||
Allocator *get_custom_allocator() { return allocator_; }
|
Allocator* get_custom_allocator() { return allocator_; }
|
||||||
|
|
||||||
// The current offset into the buffer.
|
// The current offset into the buffer.
|
||||||
size_t offset() const { return cur_ - buf_; }
|
size_t offset() const { return cur_ - buf_; }
|
||||||
@@ -175,36 +180,40 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
|
|
||||||
size_t capacity() const { return reserved_; }
|
size_t capacity() const { return reserved_; }
|
||||||
|
|
||||||
uint8_t *data() const {
|
uint8_t* data() const {
|
||||||
FLATBUFFERS_ASSERT(cur_);
|
FLATBUFFERS_ASSERT(cur_);
|
||||||
return cur_;
|
return cur_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *scratch_data() const {
|
uint8_t* scratch_data() const {
|
||||||
FLATBUFFERS_ASSERT(buf_);
|
FLATBUFFERS_ASSERT(buf_);
|
||||||
return buf_;
|
return buf_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *scratch_end() const {
|
uint8_t* scratch_end() const {
|
||||||
FLATBUFFERS_ASSERT(scratch_);
|
FLATBUFFERS_ASSERT(scratch_);
|
||||||
return scratch_;
|
return scratch_;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
|
uint8_t* data_at(size_t offset) const { return buf_ + reserved_ - offset; }
|
||||||
|
|
||||||
void push(const uint8_t *bytes, size_t num) {
|
void push(const uint8_t* bytes, size_t num) {
|
||||||
if (num > 0) { memcpy(make_space(num), bytes, num); }
|
if (num > 0) {
|
||||||
|
memcpy(make_space(num), bytes, num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized version of push() that avoids memcpy call for small data.
|
// Specialized version of push() that avoids memcpy call for small data.
|
||||||
template<typename T> void push_small(const T &little_endian_t) {
|
template <typename T>
|
||||||
|
void push_small(const T& little_endian_t) {
|
||||||
make_space(sizeof(T));
|
make_space(sizeof(T));
|
||||||
*reinterpret_cast<T *>(cur_) = little_endian_t;
|
*reinterpret_cast<T*>(cur_) = little_endian_t;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> void scratch_push_small(const T &t) {
|
template <typename T>
|
||||||
|
void scratch_push_small(const T& t) {
|
||||||
ensure_space(sizeof(T));
|
ensure_space(sizeof(T));
|
||||||
*reinterpret_cast<T *>(scratch_) = t;
|
*reinterpret_cast<T*>(scratch_) = t;
|
||||||
scratch_ += sizeof(T);
|
scratch_ += sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +237,7 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
|
|
||||||
void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
|
void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
|
||||||
|
|
||||||
void swap(vector_downward &other) {
|
void swap(vector_downward& other) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(allocator_, other.allocator_);
|
swap(allocator_, other.allocator_);
|
||||||
swap(own_allocator_, other.own_allocator_);
|
swap(own_allocator_, other.own_allocator_);
|
||||||
@@ -242,7 +251,7 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
swap(scratch_, other.scratch_);
|
swap(scratch_, other.scratch_);
|
||||||
}
|
}
|
||||||
|
|
||||||
void swap_allocator(vector_downward &other) {
|
void swap_allocator(vector_downward& other) {
|
||||||
using std::swap;
|
using std::swap;
|
||||||
swap(allocator_, other.allocator_);
|
swap(allocator_, other.allocator_);
|
||||||
swap(own_allocator_, other.own_allocator_);
|
swap(own_allocator_, other.own_allocator_);
|
||||||
@@ -250,10 +259,10 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
// You shouldn't really be copying instances of this class.
|
// You shouldn't really be copying instances of this class.
|
||||||
FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward &));
|
FLATBUFFERS_DELETE_FUNC(vector_downward(const vector_downward&));
|
||||||
FLATBUFFERS_DELETE_FUNC(vector_downward &operator=(const vector_downward &));
|
FLATBUFFERS_DELETE_FUNC(vector_downward& operator=(const vector_downward&));
|
||||||
|
|
||||||
Allocator *allocator_;
|
Allocator* allocator_;
|
||||||
bool own_allocator_;
|
bool own_allocator_;
|
||||||
size_t initial_size_;
|
size_t initial_size_;
|
||||||
|
|
||||||
@@ -262,9 +271,9 @@ template<typename SizeT = uoffset_t> class vector_downward {
|
|||||||
size_t buffer_minalign_;
|
size_t buffer_minalign_;
|
||||||
size_t reserved_;
|
size_t reserved_;
|
||||||
SizeT size_;
|
SizeT size_;
|
||||||
uint8_t *buf_;
|
uint8_t* buf_;
|
||||||
uint8_t *cur_; // Points at location between empty (below) and used (above).
|
uint8_t* cur_; // Points at location between empty (below) and used (above).
|
||||||
uint8_t *scratch_; // Points to the end of the scratchpad in use.
|
uint8_t* scratch_; // Points to the end of the scratchpad in use.
|
||||||
|
|
||||||
void reallocate(size_t len) {
|
void reallocate(size_t len) {
|
||||||
auto old_reserved = reserved_;
|
auto old_reserved = reserved_;
|
||||||
|
|||||||
@@ -41,14 +41,14 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
bool assert = false;
|
bool assert = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit VerifierTemplate(const uint8_t *const buf, const size_t buf_len,
|
explicit VerifierTemplate(const uint8_t* const buf, const size_t buf_len,
|
||||||
const Options &opts)
|
const Options& opts)
|
||||||
: buf_(buf), size_(buf_len), opts_(opts) {
|
: buf_(buf), size_(buf_len), opts_(opts) {
|
||||||
FLATBUFFERS_ASSERT(size_ < opts.max_size);
|
FLATBUFFERS_ASSERT(size_ < opts.max_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated API, please construct with VerifierTemplate::Options.
|
// Deprecated API, please construct with VerifierTemplate::Options.
|
||||||
VerifierTemplate(const uint8_t *const buf, const size_t buf_len,
|
VerifierTemplate(const uint8_t* const buf, const size_t buf_len,
|
||||||
const uoffset_t max_depth = 64,
|
const uoffset_t max_depth = 64,
|
||||||
const uoffset_t max_tables = 1000000,
|
const uoffset_t max_tables = 1000000,
|
||||||
const bool check_alignment = true)
|
const bool check_alignment = true)
|
||||||
@@ -91,59 +91,61 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify a range indicated by sizeof(T).
|
// Verify a range indicated by sizeof(T).
|
||||||
template<typename T> bool Verify(const size_t elem) const {
|
template <typename T>
|
||||||
|
bool Verify(const size_t elem) const {
|
||||||
return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
|
return VerifyAlignment(elem, sizeof(T)) && Verify(elem, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifyFromPointer(const uint8_t *const p, const size_t len) {
|
bool VerifyFromPointer(const uint8_t* const p, const size_t len) {
|
||||||
return Verify(static_cast<size_t>(p - buf_), len);
|
return Verify(static_cast<size_t>(p - buf_), len);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify relative to a known-good base pointer.
|
// Verify relative to a known-good base pointer.
|
||||||
bool VerifyFieldStruct(const uint8_t *const base, const voffset_t elem_off,
|
bool VerifyFieldStruct(const uint8_t* const base, const voffset_t elem_off,
|
||||||
const size_t elem_len, const size_t align) const {
|
const size_t elem_len, const size_t align) const {
|
||||||
const auto f = static_cast<size_t>(base - buf_) + elem_off;
|
const auto f = static_cast<size_t>(base - buf_) + elem_off;
|
||||||
return VerifyAlignment(f, align) && Verify(f, elem_len);
|
return VerifyAlignment(f, align) && Verify(f, elem_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool VerifyField(const uint8_t *const base, const voffset_t elem_off,
|
bool VerifyField(const uint8_t* const base, const voffset_t elem_off,
|
||||||
const size_t align) const {
|
const size_t align) const {
|
||||||
const auto f = static_cast<size_t>(base - buf_) + elem_off;
|
const auto f = static_cast<size_t>(base - buf_) + elem_off;
|
||||||
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
|
return VerifyAlignment(f, align) && Verify(f, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a pointer (may be NULL) of a table type.
|
// Verify a pointer (may be NULL) of a table type.
|
||||||
template<typename T> bool VerifyTable(const T *const table) {
|
template <typename T>
|
||||||
|
bool VerifyTable(const T* const table) {
|
||||||
return !table || table->Verify(*this);
|
return !table || table->Verify(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a pointer (may be NULL) of any vector type.
|
// Verify a pointer (may be NULL) of any vector type.
|
||||||
template<int &..., typename T, typename LenT>
|
template <int&..., typename T, typename LenT>
|
||||||
bool VerifyVector(const Vector<T, LenT> *const vec) const {
|
bool VerifyVector(const Vector<T, LenT>* const vec) const {
|
||||||
return !vec || VerifyVectorOrString<LenT>(
|
return !vec || VerifyVectorOrString<LenT>(
|
||||||
reinterpret_cast<const uint8_t *>(vec), sizeof(T));
|
reinterpret_cast<const uint8_t*>(vec), sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a pointer (may be NULL) of a vector to struct.
|
// Verify a pointer (may be NULL) of a vector to struct.
|
||||||
template<int &..., typename T, typename LenT>
|
template <int&..., typename T, typename LenT>
|
||||||
bool VerifyVector(const Vector<const T *, LenT> *const vec) const {
|
bool VerifyVector(const Vector<const T*, LenT>* const vec) const {
|
||||||
return VerifyVector(reinterpret_cast<const Vector<T, LenT> *>(vec));
|
return VerifyVector(reinterpret_cast<const Vector<T, LenT>*>(vec));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a pointer (may be NULL) to string.
|
// Verify a pointer (may be NULL) to string.
|
||||||
bool VerifyString(const String *const str) const {
|
bool VerifyString(const String* const str) const {
|
||||||
size_t end;
|
size_t end;
|
||||||
return !str || (VerifyVectorOrString<uoffset_t>(
|
return !str || (VerifyVectorOrString<uoffset_t>(
|
||||||
reinterpret_cast<const uint8_t *>(str), 1, &end) &&
|
reinterpret_cast<const uint8_t*>(str), 1, &end) &&
|
||||||
Verify(end, 1) && // Must have terminator
|
Verify(end, 1) && // Must have terminator
|
||||||
Check(buf_[end] == '\0')); // Terminating byte must be 0.
|
Check(buf_[end] == '\0')); // Terminating byte must be 0.
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common code between vectors and strings.
|
// Common code between vectors and strings.
|
||||||
template<typename LenT = uoffset_t>
|
template <typename LenT = uoffset_t>
|
||||||
bool VerifyVectorOrString(const uint8_t *const vec, const size_t elem_size,
|
bool VerifyVectorOrString(const uint8_t* const vec, const size_t elem_size,
|
||||||
size_t *const end = nullptr) const {
|
size_t* const end = nullptr) const {
|
||||||
const auto vec_offset = static_cast<size_t>(vec - buf_);
|
const auto vec_offset = static_cast<size_t>(vec - buf_);
|
||||||
// Check we can read the size field.
|
// Check we can read the size field.
|
||||||
if (!Verify<LenT>(vec_offset)) return false;
|
if (!Verify<LenT>(vec_offset)) return false;
|
||||||
@@ -159,7 +161,7 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Special case for string contents, after the above has been called.
|
// Special case for string contents, after the above has been called.
|
||||||
bool VerifyVectorOfStrings(const Vector<Offset<String>> *const vec) const {
|
bool VerifyVectorOfStrings(const Vector<Offset<String>>* const vec) const {
|
||||||
if (vec) {
|
if (vec) {
|
||||||
for (uoffset_t i = 0; i < vec->size(); i++) {
|
for (uoffset_t i = 0; i < vec->size(); i++) {
|
||||||
if (!VerifyString(vec->Get(i))) return false;
|
if (!VerifyString(vec->Get(i))) return false;
|
||||||
@@ -169,8 +171,8 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Special case for table contents, after the above has been called.
|
// Special case for table contents, after the above has been called.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool VerifyVectorOfTables(const Vector<Offset<T>> *const vec) {
|
bool VerifyVectorOfTables(const Vector<Offset<T>>* const vec) {
|
||||||
if (vec) {
|
if (vec) {
|
||||||
for (uoffset_t i = 0; i < vec->size(); i++) {
|
for (uoffset_t i = 0; i < vec->size(); i++) {
|
||||||
if (!vec->Get(i)->Verify(*this)) return false;
|
if (!vec->Get(i)->Verify(*this)) return false;
|
||||||
@@ -180,7 +182,7 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow")
|
FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow")
|
||||||
bool VerifyTableStart(const uint8_t *const table) {
|
bool VerifyTableStart(const uint8_t* const table) {
|
||||||
// Check the vtable offset.
|
// Check the vtable offset.
|
||||||
const auto tableo = static_cast<size_t>(table - buf_);
|
const auto tableo = static_cast<size_t>(table - buf_);
|
||||||
if (!Verify<soffset_t>(tableo)) return false;
|
if (!Verify<soffset_t>(tableo)) return false;
|
||||||
@@ -197,8 +199,8 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
return Check((vsize & 1) == 0) && Verify(vtableo, vsize);
|
return Check((vsize & 1) == 0) && Verify(vtableo, vsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
bool VerifyBufferFromStart(const char *const identifier, const size_t start) {
|
bool VerifyBufferFromStart(const char* const identifier, const size_t start) {
|
||||||
// Buffers have to be of some size to be valid. The reason it is a runtime
|
// Buffers have to be of some size to be valid. The reason it is a runtime
|
||||||
// check instead of static_assert, is that nested flatbuffers go through
|
// check instead of static_assert, is that nested flatbuffers go through
|
||||||
// this call and their size is determined at runtime.
|
// this call and their size is determined at runtime.
|
||||||
@@ -213,7 +215,7 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
// Call T::Verify, which must be in the generated code for this type.
|
// Call T::Verify, which must be in the generated code for this type.
|
||||||
const auto o = VerifyOffset<uoffset_t>(start);
|
const auto o = VerifyOffset<uoffset_t>(start);
|
||||||
if (!Check(o != 0)) return false;
|
if (!Check(o != 0)) return false;
|
||||||
if (!(reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this))) {
|
if (!(reinterpret_cast<const T*>(buf_ + start + o)->Verify(*this))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (TrackVerifierBufferSize) {
|
if (TrackVerifierBufferSize) {
|
||||||
@@ -222,9 +224,9 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, int &..., typename SizeT>
|
template <typename T, int&..., typename SizeT>
|
||||||
bool VerifyNestedFlatBuffer(const Vector<uint8_t, SizeT> *const buf,
|
bool VerifyNestedFlatBuffer(const Vector<uint8_t, SizeT>* const buf,
|
||||||
const char *const identifier) {
|
const char* const identifier) {
|
||||||
// Caller opted out of this.
|
// Caller opted out of this.
|
||||||
if (!opts_.check_nested_flatbuffers) return true;
|
if (!opts_.check_nested_flatbuffers) return true;
|
||||||
|
|
||||||
@@ -240,14 +242,18 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Verify this whole buffer, starting with root type T.
|
// Verify this whole buffer, starting with root type T.
|
||||||
template<typename T> bool VerifyBuffer() { return VerifyBuffer<T>(nullptr); }
|
template <typename T>
|
||||||
|
bool VerifyBuffer() {
|
||||||
|
return VerifyBuffer<T>(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> bool VerifyBuffer(const char *const identifier) {
|
template <typename T>
|
||||||
|
bool VerifyBuffer(const char* const identifier) {
|
||||||
return VerifyBufferFromStart<T>(identifier, 0);
|
return VerifyBufferFromStart<T>(identifier, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename SizeT = uoffset_t>
|
template <typename T, typename SizeT = uoffset_t>
|
||||||
bool VerifySizePrefixedBuffer(const char *const identifier) {
|
bool VerifySizePrefixedBuffer(const char* const identifier) {
|
||||||
return Verify<SizeT>(0U) &&
|
return Verify<SizeT>(0U) &&
|
||||||
// Ensure the prefixed size is within the bounds of the provided
|
// Ensure the prefixed size is within the bounds of the provided
|
||||||
// length.
|
// length.
|
||||||
@@ -255,7 +261,7 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
|
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OffsetT = uoffset_t, typename SOffsetT = soffset_t>
|
template <typename OffsetT = uoffset_t, typename SOffsetT = soffset_t>
|
||||||
size_t VerifyOffset(const size_t start) const {
|
size_t VerifyOffset(const size_t start) const {
|
||||||
if (!Verify<OffsetT>(start)) return 0;
|
if (!Verify<OffsetT>(start)) return 0;
|
||||||
const auto o = ReadScalar<OffsetT>(buf_ + start);
|
const auto o = ReadScalar<OffsetT>(buf_ + start);
|
||||||
@@ -269,8 +275,8 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename OffsetT = uoffset_t>
|
template <typename OffsetT = uoffset_t>
|
||||||
size_t VerifyOffset(const uint8_t *const base, const voffset_t start) const {
|
size_t VerifyOffset(const uint8_t* const base, const voffset_t start) const {
|
||||||
return VerifyOffset<OffsetT>(static_cast<size_t>(base - buf_) + start);
|
return VerifyOffset<OffsetT>(static_cast<size_t>(base - buf_) + start);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,14 +318,14 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<uint8_t> *GetFlexReuseTracker() { return flex_reuse_tracker_; }
|
std::vector<uint8_t>* GetFlexReuseTracker() { return flex_reuse_tracker_; }
|
||||||
|
|
||||||
void SetFlexReuseTracker(std::vector<uint8_t> *const rt) {
|
void SetFlexReuseTracker(std::vector<uint8_t>* const rt) {
|
||||||
flex_reuse_tracker_ = rt;
|
flex_reuse_tracker_ = rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const uint8_t *buf_;
|
const uint8_t* buf_;
|
||||||
const size_t size_;
|
const size_t size_;
|
||||||
const Options opts_;
|
const Options opts_;
|
||||||
|
|
||||||
@@ -327,18 +333,18 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
uoffset_t depth_ = 0;
|
uoffset_t depth_ = 0;
|
||||||
uoffset_t num_tables_ = 0;
|
uoffset_t num_tables_ = 0;
|
||||||
std::vector<uint8_t> *flex_reuse_tracker_ = nullptr;
|
std::vector<uint8_t>* flex_reuse_tracker_ = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Specialization for 64-bit offsets.
|
// Specialization for 64-bit offsets.
|
||||||
template<>
|
template <>
|
||||||
template<>
|
template <>
|
||||||
inline size_t VerifierTemplate<false>::VerifyOffset<uoffset64_t>(
|
inline size_t VerifierTemplate<false>::VerifyOffset<uoffset64_t>(
|
||||||
const size_t start) const {
|
const size_t start) const {
|
||||||
return VerifyOffset<uoffset64_t, soffset64_t>(start);
|
return VerifyOffset<uoffset64_t, soffset64_t>(start);
|
||||||
}
|
}
|
||||||
template<>
|
template <>
|
||||||
template<>
|
template <>
|
||||||
inline size_t VerifierTemplate<true>::VerifyOffset<uoffset64_t>(
|
inline size_t VerifierTemplate<true>::VerifyOffset<uoffset64_t>(
|
||||||
const size_t start) const {
|
const size_t start) const {
|
||||||
return VerifyOffset<uoffset64_t, soffset64_t>(start);
|
return VerifyOffset<uoffset64_t, soffset64_t>(start);
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ using namespace MyGame::Sample;
|
|||||||
|
|
||||||
// This is an example of parsing text straight into a buffer and then
|
// This is an example of parsing text straight into a buffer and then
|
||||||
// generating flatbuffer (JSON) text from the buffer.
|
// generating flatbuffer (JSON) text from the buffer.
|
||||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
int main(int /*argc*/, const char* /*argv*/[]) {
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
std::string schema_file;
|
std::string schema_file;
|
||||||
std::string json_file;
|
std::string json_file;
|
||||||
@@ -37,8 +37,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *include_directories[] = { "samples", "tests",
|
const char* include_directories[] = {"samples", "tests", "tests/include_test",
|
||||||
"tests/include_test", nullptr };
|
nullptr};
|
||||||
// parse fbs schema
|
// parse fbs schema
|
||||||
flatbuffers::Parser parser1;
|
flatbuffers::Parser parser1;
|
||||||
ok = parser1.Parse(schema_file.c_str(), include_directories);
|
ok = parser1.Parse(schema_file.c_str(), include_directories);
|
||||||
@@ -46,7 +46,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
// inizialize parser by deserializing bfbs schema
|
// inizialize parser by deserializing bfbs schema
|
||||||
flatbuffers::Parser parser2;
|
flatbuffers::Parser parser2;
|
||||||
ok = parser2.Deserialize(reinterpret_cast<const uint8_t *>(bfbs_file.c_str()),
|
ok = parser2.Deserialize(reinterpret_cast<const uint8_t*>(bfbs_file.c_str()),
|
||||||
bfbs_file.length());
|
bfbs_file.length());
|
||||||
assert(ok);
|
assert(ok);
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ using namespace MyGame::Sample;
|
|||||||
|
|
||||||
// Example how to use FlatBuffers to create and read binary buffers.
|
// Example how to use FlatBuffers to create and read binary buffers.
|
||||||
|
|
||||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
int main(int /*argc*/, const char* /*argv*/[]) {
|
||||||
// Build up a serialized buffer algorithmically:
|
// Build up a serialized buffer algorithmically:
|
||||||
flatbuffers::FlatBufferBuilder builder;
|
flatbuffers::FlatBufferBuilder builder;
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
auto name = builder.CreateString("MyMonster");
|
auto name = builder.CreateString("MyMonster");
|
||||||
|
|
||||||
unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
unsigned char inv_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
auto inventory = builder.CreateVector(inv_data, 10);
|
auto inventory = builder.CreateVector(inv_data, 10);
|
||||||
|
|
||||||
// Shortcut for creating monster with all fields set:
|
// Shortcut for creating monster with all fields set:
|
||||||
@@ -83,8 +83,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
(void)inv;
|
(void)inv;
|
||||||
|
|
||||||
// Get and test the `weapons` FlatBuffers's `vector`.
|
// Get and test the `weapons` FlatBuffers's `vector`.
|
||||||
std::string expected_weapon_names[] = { "Sword", "Axe" };
|
std::string expected_weapon_names[] = {"Sword", "Axe"};
|
||||||
short expected_weapon_damages[] = { 3, 5 };
|
short expected_weapon_damages[] = {3, 5};
|
||||||
auto weps = monster->weapons();
|
auto weps = monster->weapons();
|
||||||
for (unsigned int i = 0; i < weps->size(); i++) {
|
for (unsigned int i = 0; i < weps->size(); i++) {
|
||||||
assert(weps->Get(i)->name()->str() == expected_weapon_names[i]);
|
assert(weps->Get(i)->name()->str() == expected_weapon_names[i]);
|
||||||
@@ -95,7 +95,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
// Get and test the `Equipment` union (`equipped` field).
|
// Get and test the `Equipment` union (`equipped` field).
|
||||||
assert(monster->equipped_type() == Equipment_Weapon);
|
assert(monster->equipped_type() == Equipment_Weapon);
|
||||||
auto equipped = static_cast<const Weapon *>(monster->equipped());
|
auto equipped = static_cast<const Weapon*>(monster->equipped());
|
||||||
assert(equipped->name()->str() == "Axe");
|
assert(equipped->name()->str() == "Axe");
|
||||||
assert(equipped->damage() == 5);
|
assert(equipped->damage() == 5);
|
||||||
(void)equipped;
|
(void)equipped;
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ using namespace MyGame::Sample;
|
|||||||
|
|
||||||
// This is an example of parsing text straight into a buffer and then
|
// This is an example of parsing text straight into a buffer and then
|
||||||
// generating flatbuffer (JSON) text from the buffer.
|
// generating flatbuffer (JSON) text from the buffer.
|
||||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
int main(int /*argc*/, const char* /*argv*/[]) {
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
std::string jsonfile;
|
std::string jsonfile;
|
||||||
@@ -35,7 +35,7 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
// parse schema first, so we can use it to parse the data after
|
// parse schema first, so we can use it to parse the data after
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
const char *include_directories[] = { "samples", nullptr };
|
const char* include_directories[] = {"samples", nullptr};
|
||||||
ok = parser.Parse(schemafile.c_str(), include_directories) &&
|
ok = parser.Parse(schemafile.c_str(), include_directories) &&
|
||||||
parser.Parse(jsonfile.c_str(), include_directories);
|
parser.Parse(jsonfile.c_str(), include_directories);
|
||||||
assert(ok);
|
assert(ok);
|
||||||
|
|||||||
@@ -30,18 +30,30 @@ struct OutputConfig {
|
|||||||
|
|
||||||
static std::string ToString(const BinarySectionType type) {
|
static std::string ToString(const BinarySectionType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BinarySectionType::Header: return "header";
|
case BinarySectionType::Header:
|
||||||
case BinarySectionType::Table: return "table";
|
return "header";
|
||||||
case BinarySectionType::RootTable: return "root_table";
|
case BinarySectionType::Table:
|
||||||
case BinarySectionType::VTable: return "vtable";
|
return "table";
|
||||||
case BinarySectionType::Struct: return "struct";
|
case BinarySectionType::RootTable:
|
||||||
case BinarySectionType::String: return "string";
|
return "root_table";
|
||||||
case BinarySectionType::Vector: return "vector";
|
case BinarySectionType::VTable:
|
||||||
case BinarySectionType::Vector64: return "vector64";
|
return "vtable";
|
||||||
case BinarySectionType::Unknown: return "unknown";
|
case BinarySectionType::Struct:
|
||||||
case BinarySectionType::Union: return "union";
|
return "struct";
|
||||||
case BinarySectionType::Padding: return "padding";
|
case BinarySectionType::String:
|
||||||
default: return "todo";
|
return "string";
|
||||||
|
case BinarySectionType::Vector:
|
||||||
|
return "vector";
|
||||||
|
case BinarySectionType::Vector64:
|
||||||
|
return "vector64";
|
||||||
|
case BinarySectionType::Unknown:
|
||||||
|
return "unknown";
|
||||||
|
case BinarySectionType::Union:
|
||||||
|
return "union";
|
||||||
|
case BinarySectionType::Padding:
|
||||||
|
return "padding";
|
||||||
|
default:
|
||||||
|
return "todo";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,7 +63,8 @@ static bool IsOffset(const BinaryRegionType type) {
|
|||||||
type == BinaryRegionType::UOffset64;
|
type == BinaryRegionType::UOffset64;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> std::string ToString(T value) {
|
template <typename T>
|
||||||
|
std::string ToString(T value) {
|
||||||
if (std::is_floating_point<T>::value) {
|
if (std::is_floating_point<T>::value) {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << value;
|
ss << value;
|
||||||
@@ -61,8 +74,8 @@ template<typename T> std::string ToString(T value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
std::string ToValueString(const BinaryRegion ®ion, const uint8_t *binary) {
|
std::string ToValueString(const BinaryRegion& region, const uint8_t* binary) {
|
||||||
std::string s;
|
std::string s;
|
||||||
s += "0x";
|
s += "0x";
|
||||||
const T val = ReadScalar<T>(binary + region.offset);
|
const T val = ReadScalar<T>(binary + region.offset);
|
||||||
@@ -76,16 +89,16 @@ std::string ToValueString(const BinaryRegion ®ion, const uint8_t *binary) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<>
|
template <>
|
||||||
std::string ToValueString<std::string>(const BinaryRegion ®ion,
|
std::string ToValueString<std::string>(const BinaryRegion& region,
|
||||||
const uint8_t *binary) {
|
const uint8_t* binary) {
|
||||||
return std::string(reinterpret_cast<const char *>(binary + region.offset),
|
return std::string(reinterpret_cast<const char*>(binary + region.offset),
|
||||||
static_cast<size_t>(region.array_length));
|
static_cast<size_t>(region.array_length));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ToValueString(const BinaryRegion ®ion,
|
static std::string ToValueString(const BinaryRegion& region,
|
||||||
const uint8_t *binary,
|
const uint8_t* binary,
|
||||||
const OutputConfig &output_config) {
|
const OutputConfig& output_config) {
|
||||||
std::string s;
|
std::string s;
|
||||||
|
|
||||||
if (region.array_length) {
|
if (region.array_length) {
|
||||||
@@ -106,21 +119,31 @@ static std::string ToValueString(const BinaryRegion ®ion,
|
|||||||
switch (region.type) {
|
switch (region.type) {
|
||||||
case BinaryRegionType::Uint32:
|
case BinaryRegionType::Uint32:
|
||||||
return ToValueString<uint32_t>(region, binary);
|
return ToValueString<uint32_t>(region, binary);
|
||||||
case BinaryRegionType::Int32: return ToValueString<int32_t>(region, binary);
|
case BinaryRegionType::Int32:
|
||||||
|
return ToValueString<int32_t>(region, binary);
|
||||||
case BinaryRegionType::Uint16:
|
case BinaryRegionType::Uint16:
|
||||||
return ToValueString<uint16_t>(region, binary);
|
return ToValueString<uint16_t>(region, binary);
|
||||||
case BinaryRegionType::Int16: return ToValueString<int16_t>(region, binary);
|
case BinaryRegionType::Int16:
|
||||||
case BinaryRegionType::Bool: return ToValueString<bool>(region, binary);
|
return ToValueString<int16_t>(region, binary);
|
||||||
case BinaryRegionType::Uint8: return ToValueString<uint8_t>(region, binary);
|
case BinaryRegionType::Bool:
|
||||||
case BinaryRegionType::Char: return ToValueString<char>(region, binary);
|
return ToValueString<bool>(region, binary);
|
||||||
|
case BinaryRegionType::Uint8:
|
||||||
|
return ToValueString<uint8_t>(region, binary);
|
||||||
|
case BinaryRegionType::Char:
|
||||||
|
return ToValueString<char>(region, binary);
|
||||||
case BinaryRegionType::Byte:
|
case BinaryRegionType::Byte:
|
||||||
case BinaryRegionType::Int8: return ToValueString<int8_t>(region, binary);
|
case BinaryRegionType::Int8:
|
||||||
case BinaryRegionType::Int64: return ToValueString<int64_t>(region, binary);
|
return ToValueString<int8_t>(region, binary);
|
||||||
|
case BinaryRegionType::Int64:
|
||||||
|
return ToValueString<int64_t>(region, binary);
|
||||||
case BinaryRegionType::Uint64:
|
case BinaryRegionType::Uint64:
|
||||||
return ToValueString<uint64_t>(region, binary);
|
return ToValueString<uint64_t>(region, binary);
|
||||||
case BinaryRegionType::Double: return ToValueString<double>(region, binary);
|
case BinaryRegionType::Double:
|
||||||
case BinaryRegionType::Float: return ToValueString<float>(region, binary);
|
return ToValueString<double>(region, binary);
|
||||||
case BinaryRegionType::UType: return ToValueString<uint8_t>(region, binary);
|
case BinaryRegionType::Float:
|
||||||
|
return ToValueString<float>(region, binary);
|
||||||
|
case BinaryRegionType::UType:
|
||||||
|
return ToValueString<uint8_t>(region, binary);
|
||||||
|
|
||||||
// Handle Offsets separately, incase they add additional details.
|
// Handle Offsets separately, incase they add additional details.
|
||||||
case BinaryRegionType::UOffset64:
|
case BinaryRegionType::UOffset64:
|
||||||
@@ -136,7 +159,8 @@ static std::string ToValueString(const BinaryRegion ®ion,
|
|||||||
s += ToValueString<uint16_t>(region, binary);
|
s += ToValueString<uint16_t>(region, binary);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
// If this is an offset type, include the calculated offset location in the
|
// If this is an offset type, include the calculated offset location in the
|
||||||
// value.
|
// value.
|
||||||
@@ -156,26 +180,36 @@ struct DocContinuation {
|
|||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::string GenerateTypeString(const BinaryRegion ®ion) {
|
static std::string GenerateTypeString(const BinaryRegion& region) {
|
||||||
return ToString(region.type) +
|
return ToString(region.type) +
|
||||||
((region.array_length)
|
((region.array_length)
|
||||||
? "[" + std::to_string(region.array_length) + "]"
|
? "[" + std::to_string(region.array_length) + "]"
|
||||||
: "");
|
: "");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenerateComment(const BinaryRegionComment &comment,
|
static std::string GenerateComment(const BinaryRegionComment& comment,
|
||||||
const BinarySection &) {
|
const BinarySection&) {
|
||||||
std::string s;
|
std::string s;
|
||||||
switch (comment.type) {
|
switch (comment.type) {
|
||||||
case BinaryRegionCommentType::Unknown: s = "unknown"; break;
|
case BinaryRegionCommentType::Unknown:
|
||||||
case BinaryRegionCommentType::SizePrefix: s = "size prefix"; break;
|
s = "unknown";
|
||||||
|
break;
|
||||||
|
case BinaryRegionCommentType::SizePrefix:
|
||||||
|
s = "size prefix";
|
||||||
|
break;
|
||||||
case BinaryRegionCommentType::RootTableOffset:
|
case BinaryRegionCommentType::RootTableOffset:
|
||||||
s = "offset to root table `" + comment.name + "`";
|
s = "offset to root table `" + comment.name + "`";
|
||||||
break;
|
break;
|
||||||
// TODO(dbaileychess): make this lowercase to follow the convention.
|
// TODO(dbaileychess): make this lowercase to follow the convention.
|
||||||
case BinaryRegionCommentType::FileIdentifier: s = "File Identifier"; break;
|
case BinaryRegionCommentType::FileIdentifier:
|
||||||
case BinaryRegionCommentType::Padding: s = "padding"; break;
|
s = "File Identifier";
|
||||||
case BinaryRegionCommentType::VTableSize: s = "size of this vtable"; break;
|
break;
|
||||||
|
case BinaryRegionCommentType::Padding:
|
||||||
|
s = "padding";
|
||||||
|
break;
|
||||||
|
case BinaryRegionCommentType::VTableSize:
|
||||||
|
s = "size of this vtable";
|
||||||
|
break;
|
||||||
case BinaryRegionCommentType::VTableRefferingTableLength:
|
case BinaryRegionCommentType::VTableRefferingTableLength:
|
||||||
s = "size of referring table";
|
s = "size of referring table";
|
||||||
break;
|
break;
|
||||||
@@ -192,7 +226,9 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
|
|||||||
case BinaryRegionCommentType::TableField:
|
case BinaryRegionCommentType::TableField:
|
||||||
s = "table field `" + comment.name;
|
s = "table field `" + comment.name;
|
||||||
break;
|
break;
|
||||||
case BinaryRegionCommentType::TableUnknownField: s = "unknown field"; break;
|
case BinaryRegionCommentType::TableUnknownField:
|
||||||
|
s = "unknown field";
|
||||||
|
break;
|
||||||
case BinaryRegionCommentType::TableOffsetField:
|
case BinaryRegionCommentType::TableOffsetField:
|
||||||
s = "offset to field `" + comment.name + "`";
|
s = "offset to field `" + comment.name + "`";
|
||||||
break;
|
break;
|
||||||
@@ -203,8 +239,12 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
|
|||||||
s = "array field `" + comment.name + "`[" +
|
s = "array field `" + comment.name + "`[" +
|
||||||
std::to_string(comment.index) + "]";
|
std::to_string(comment.index) + "]";
|
||||||
break;
|
break;
|
||||||
case BinaryRegionCommentType::StringLength: s = "length of string"; break;
|
case BinaryRegionCommentType::StringLength:
|
||||||
case BinaryRegionCommentType::StringValue: s = "string literal"; break;
|
s = "length of string";
|
||||||
|
break;
|
||||||
|
case BinaryRegionCommentType::StringValue:
|
||||||
|
s = "string literal";
|
||||||
|
break;
|
||||||
case BinaryRegionCommentType::StringTerminator:
|
case BinaryRegionCommentType::StringTerminator:
|
||||||
s = "string terminator";
|
s = "string terminator";
|
||||||
break;
|
break;
|
||||||
@@ -224,13 +264,19 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
|
|||||||
s = "offset to union[" + std::to_string(comment.index) + "]";
|
s = "offset to union[" + std::to_string(comment.index) + "]";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!comment.default_value.empty()) {
|
||||||
|
s += " " + comment.default_value;
|
||||||
}
|
}
|
||||||
if (!comment.default_value.empty()) { s += " " + comment.default_value; }
|
|
||||||
|
|
||||||
switch (comment.status) {
|
switch (comment.status) {
|
||||||
case BinaryRegionStatus::OK: break; // no-op
|
case BinaryRegionStatus::OK:
|
||||||
case BinaryRegionStatus::WARN: s = "WARN: " + s; break;
|
break; // no-op
|
||||||
|
case BinaryRegionStatus::WARN:
|
||||||
|
s = "WARN: " + s;
|
||||||
|
break;
|
||||||
case BinaryRegionStatus::WARN_NO_REFERENCES:
|
case BinaryRegionStatus::WARN_NO_REFERENCES:
|
||||||
s = "WARN: nothing refers to this section.";
|
s = "WARN: nothing refers to this section.";
|
||||||
break;
|
break;
|
||||||
@@ -240,7 +286,9 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
|
|||||||
case BinaryRegionStatus::WARN_PADDING_LENGTH:
|
case BinaryRegionStatus::WARN_PADDING_LENGTH:
|
||||||
s = "WARN: padding is longer than expected.";
|
s = "WARN: padding is longer than expected.";
|
||||||
break;
|
break;
|
||||||
case BinaryRegionStatus::ERROR: s = "ERROR: " + s; break;
|
case BinaryRegionStatus::ERROR:
|
||||||
|
s = "ERROR: " + s;
|
||||||
|
break;
|
||||||
case BinaryRegionStatus::ERROR_OFFSET_OUT_OF_BINARY:
|
case BinaryRegionStatus::ERROR_OFFSET_OUT_OF_BINARY:
|
||||||
s = "ERROR: " + s + ". Invalid offset, points outside the binary.";
|
s = "ERROR: " + s + ". Invalid offset, points outside the binary.";
|
||||||
break;
|
break;
|
||||||
@@ -268,11 +316,11 @@ static std::string GenerateComment(const BinaryRegionComment &comment,
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateDocumentation(std::ostream &os, const BinaryRegion ®ion,
|
static void GenerateDocumentation(std::ostream& os, const BinaryRegion& region,
|
||||||
const BinarySection §ion,
|
const BinarySection& section,
|
||||||
const uint8_t *binary,
|
const uint8_t* binary,
|
||||||
DocContinuation &continuation,
|
DocContinuation& continuation,
|
||||||
const OutputConfig &output_config) {
|
const OutputConfig& output_config) {
|
||||||
// Check if there is a doc continuation that should be prioritized.
|
// Check if there is a doc continuation that should be prioritized.
|
||||||
if (continuation.value_start_column) {
|
if (continuation.value_start_column) {
|
||||||
os << std::string(continuation.value_start_column - 2, ' ');
|
os << std::string(continuation.value_start_column - 2, ' ');
|
||||||
@@ -321,9 +369,9 @@ static void GenerateDocumentation(std::ostream &os, const BinaryRegion ®ion,
|
|||||||
os << GenerateComment(region.comment, section);
|
os << GenerateComment(region.comment, section);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateRegion(std::ostream &os, const BinaryRegion ®ion,
|
static void GenerateRegion(std::ostream& os, const BinaryRegion& region,
|
||||||
const BinarySection §ion, const uint8_t *binary,
|
const BinarySection& section, const uint8_t* binary,
|
||||||
const OutputConfig &output_config) {
|
const OutputConfig& output_config) {
|
||||||
bool doc_generated = false;
|
bool doc_generated = false;
|
||||||
DocContinuation doc_continuation;
|
DocContinuation doc_continuation;
|
||||||
for (uint64_t i = 0; i < region.length; ++i) {
|
for (uint64_t i = 0; i < region.length; ++i) {
|
||||||
@@ -364,12 +412,14 @@ static void GenerateRegion(std::ostream &os, const BinaryRegion ®ion,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateSection(std::ostream &os, const BinarySection §ion,
|
static void GenerateSection(std::ostream& os, const BinarySection& section,
|
||||||
const uint8_t *binary,
|
const uint8_t* binary,
|
||||||
const OutputConfig &output_config) {
|
const OutputConfig& output_config) {
|
||||||
os << std::endl;
|
os << std::endl;
|
||||||
os << ToString(section.type);
|
os << ToString(section.type);
|
||||||
if (!section.name.empty()) { os << " (" + section.name + ")"; }
|
if (!section.name.empty()) {
|
||||||
|
os << " (" + section.name + ")";
|
||||||
|
}
|
||||||
os << ":";
|
os << ":";
|
||||||
|
|
||||||
// As a space saving measure, skip generating every vector element, just put
|
// As a space saving measure, skip generating every vector element, just put
|
||||||
@@ -394,7 +444,7 @@ static void GenerateSection(std::ostream &os, const BinarySection §ion,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const BinaryRegion ®ion : section.regions) {
|
for (const BinaryRegion& region : section.regions) {
|
||||||
GenerateRegion(os, region, section, binary, output_config);
|
GenerateRegion(os, region, section, binary, output_config);
|
||||||
}
|
}
|
||||||
os << std::endl;
|
os << std::endl;
|
||||||
@@ -402,8 +452,8 @@ static void GenerateSection(std::ostream &os, const BinarySection §ion,
|
|||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool AnnotatedBinaryTextGenerator::Generate(
|
bool AnnotatedBinaryTextGenerator::Generate(
|
||||||
const std::string &filename, const std::string &schema_filename,
|
const std::string& filename, const std::string& schema_filename,
|
||||||
const std::string &output_filename) {
|
const std::string& output_filename) {
|
||||||
OutputConfig output_config;
|
OutputConfig output_config;
|
||||||
output_config.max_bytes_per_line = options_.max_bytes_per_line;
|
output_config.max_bytes_per_line = options_.max_bytes_per_line;
|
||||||
output_config.include_vector_contents = options_.include_vector_contents;
|
output_config.include_vector_contents = options_.include_vector_contents;
|
||||||
@@ -419,8 +469,8 @@ bool AnnotatedBinaryTextGenerator::Generate(
|
|||||||
// Find the largest type string of all the regions in this file, so we can
|
// Find the largest type string of all the regions in this file, so we can
|
||||||
// align the output nicely.
|
// align the output nicely.
|
||||||
output_config.largest_type_string = 0;
|
output_config.largest_type_string = 0;
|
||||||
for (const auto §ion : annotations_) {
|
for (const auto& section : annotations_) {
|
||||||
for (const auto ®ion : section.second.regions) {
|
for (const auto& region : section.second.regions) {
|
||||||
std::string s = GenerateTypeString(region);
|
std::string s = GenerateTypeString(region);
|
||||||
if (s.size() > output_config.largest_type_string) {
|
if (s.size() > output_config.largest_type_string) {
|
||||||
output_config.largest_type_string = s.size();
|
output_config.largest_type_string = s.size();
|
||||||
@@ -456,7 +506,7 @@ bool AnnotatedBinaryTextGenerator::Generate(
|
|||||||
ofs << "// Binary file: " << filename << std::endl;
|
ofs << "// Binary file: " << filename << std::endl;
|
||||||
|
|
||||||
// Generate each of the binary sections
|
// Generate each of the binary sections
|
||||||
for (const auto §ion : annotations_) {
|
for (const auto& section : annotations_) {
|
||||||
GenerateSection(ofs, section.second, binary_, output_config);
|
GenerateSection(ofs, section.second, binary_, output_config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -39,14 +39,14 @@ namespace {
|
|||||||
namespace r = ::reflection;
|
namespace r = ::reflection;
|
||||||
|
|
||||||
std::set<std::string> LuaKeywords() {
|
std::set<std::string> LuaKeywords() {
|
||||||
return { "and", "break", "do", "else", "elseif", "end",
|
return {"and", "break", "do", "else", "elseif", "end",
|
||||||
"false", "for", "function", "goto", "if", "in",
|
"false", "for", "function", "goto", "if", "in",
|
||||||
"local", "nil", "not", "or", "repeat", "return",
|
"local", "nil", "not", "or", "repeat", "return",
|
||||||
"then", "true", "until", "while" };
|
"then", "true", "until", "while"};
|
||||||
}
|
}
|
||||||
|
|
||||||
Namer::Config LuaDefaultConfig() {
|
Namer::Config LuaDefaultConfig() {
|
||||||
return { /*types=*/Case::kUpperCamel,
|
return {/*types=*/Case::kUpperCamel,
|
||||||
/*constants=*/Case::kUnknown,
|
/*constants=*/Case::kUnknown,
|
||||||
/*methods=*/Case::kUpperCamel,
|
/*methods=*/Case::kUpperCamel,
|
||||||
/*functions=*/Case::kUpperCamel,
|
/*functions=*/Case::kUpperCamel,
|
||||||
@@ -65,12 +65,12 @@ Namer::Config LuaDefaultConfig() {
|
|||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
/*filename_suffix=*/"",
|
/*filename_suffix=*/"",
|
||||||
/*filename_extension=*/".lua" };
|
/*filename_extension=*/".lua"};
|
||||||
}
|
}
|
||||||
|
|
||||||
class LuaBfbsGenerator : public BaseBfbsGenerator {
|
class LuaBfbsGenerator : public BaseBfbsGenerator {
|
||||||
public:
|
public:
|
||||||
explicit LuaBfbsGenerator(const std::string &flatc_version)
|
explicit LuaBfbsGenerator(const std::string& flatc_version)
|
||||||
: BaseBfbsGenerator(),
|
: BaseBfbsGenerator(),
|
||||||
keywords_(),
|
keywords_(),
|
||||||
requires_(),
|
requires_(),
|
||||||
@@ -79,11 +79,13 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
flatc_version_(flatc_version),
|
flatc_version_(flatc_version),
|
||||||
namer_(LuaDefaultConfig(), LuaKeywords()) {}
|
namer_(LuaDefaultConfig(), LuaKeywords()) {}
|
||||||
|
|
||||||
Status GenerateFromSchema(const r::Schema *schema,
|
Status GenerateFromSchema(const r::Schema* schema,
|
||||||
const CodeGenOptions &options)
|
const CodeGenOptions& options)
|
||||||
FLATBUFFERS_OVERRIDE {
|
FLATBUFFERS_OVERRIDE {
|
||||||
options_ = options;
|
options_ = options;
|
||||||
if (!GenerateEnums(schema->enums())) { return ERROR; }
|
if (!GenerateEnums(schema->enums())) {
|
||||||
|
return ERROR;
|
||||||
|
}
|
||||||
if (!GenerateObjects(schema->objects(), schema->root_table())) {
|
if (!GenerateObjects(schema->objects(), schema->root_table())) {
|
||||||
return ERROR;
|
return ERROR;
|
||||||
}
|
}
|
||||||
@@ -92,14 +94,14 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
using BaseBfbsGenerator::GenerateCode;
|
using BaseBfbsGenerator::GenerateCode;
|
||||||
|
|
||||||
Status GenerateCode(const Parser &, const std::string &,
|
Status GenerateCode(const Parser&, const std::string&,
|
||||||
const std::string &) override {
|
const std::string&) override {
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -107,16 +109,16 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
@@ -138,8 +140,8 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool GenerateEnums(
|
bool GenerateEnums(
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<r::Enum>> *enums) {
|
const flatbuffers::Vector<flatbuffers::Offset<r::Enum>>* enums) {
|
||||||
ForAllEnums(enums, [&](const r::Enum *enum_def) {
|
ForAllEnums(enums, [&](const r::Enum* enum_def) {
|
||||||
std::string code;
|
std::string code;
|
||||||
|
|
||||||
StartCodeBlock(enum_def);
|
StartCodeBlock(enum_def);
|
||||||
@@ -151,7 +153,7 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
GenerateDocumentation(enum_def->documentation(), "", code);
|
GenerateDocumentation(enum_def->documentation(), "", code);
|
||||||
code += "local " + enum_name + " = {\n";
|
code += "local " + enum_name + " = {\n";
|
||||||
|
|
||||||
ForAllEnumValues(enum_def, [&](const reflection::EnumVal *enum_val) {
|
ForAllEnumValues(enum_def, [&](const reflection::EnumVal* enum_val) {
|
||||||
GenerateDocumentation(enum_val->documentation(), " ", code);
|
GenerateDocumentation(enum_val->documentation(), " ", code);
|
||||||
code += " " + namer_.Variant(enum_val->name()->str()) + " = " +
|
code += " " + namer_.Variant(enum_val->name()->str()) + " = " +
|
||||||
NumToString(enum_val->value()) + ",\n";
|
NumToString(enum_val->value()) + ",\n";
|
||||||
@@ -165,9 +167,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateObjects(
|
bool GenerateObjects(
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<r::Object>> *objects,
|
const flatbuffers::Vector<flatbuffers::Offset<r::Object>>* objects,
|
||||||
const r::Object *root_object) {
|
const r::Object* root_object) {
|
||||||
ForAllObjects(objects, [&](const r::Object *object) {
|
ForAllObjects(objects, [&](const r::Object* object) {
|
||||||
std::string code;
|
std::string code;
|
||||||
|
|
||||||
StartCodeBlock(object);
|
StartCodeBlock(object);
|
||||||
@@ -215,9 +217,11 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += "\n";
|
code += "\n";
|
||||||
|
|
||||||
// Create all the field accessors.
|
// Create all the field accessors.
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
|
||||||
// Skip writing deprecated fields altogether.
|
// Skip writing deprecated fields altogether.
|
||||||
if (field->deprecated()) { return; }
|
if (field->deprecated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(*field);
|
const std::string field_name = namer_.Field(*field);
|
||||||
const r::BaseType base_type = field->type()->base_type();
|
const r::BaseType base_type = field->type()->base_type();
|
||||||
@@ -247,7 +251,9 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
std::string getter =
|
std::string getter =
|
||||||
GenerateGetter(field->type()) + "self.view.pos + o)";
|
GenerateGetter(field->type()) + "self.view.pos + o)";
|
||||||
if (IsBool(base_type)) { getter = "(" + getter + " ~=0)"; }
|
if (IsBool(base_type)) {
|
||||||
|
getter = "(" + getter + " ~=0)";
|
||||||
|
}
|
||||||
code += " return " + getter + "\n";
|
code += " return " + getter + "\n";
|
||||||
code += " end\n";
|
code += " end\n";
|
||||||
code += " return " + DefaultValue(field) + "\n";
|
code += " return " + DefaultValue(field) + "\n";
|
||||||
@@ -280,7 +286,7 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += " " + offset_prefix;
|
code += " " + offset_prefix;
|
||||||
code += " " + offset_prefix_2;
|
code += " " + offset_prefix_2;
|
||||||
|
|
||||||
const r::Object *field_object = GetObject(field->type());
|
const r::Object* field_object = GetObject(field->type());
|
||||||
if (!field_object) {
|
if (!field_object) {
|
||||||
// TODO(derekbailey): this is an error condition. we
|
// TODO(derekbailey): this is an error condition. we
|
||||||
// should report it better.
|
// should report it better.
|
||||||
@@ -333,7 +339,7 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
} else {
|
} else {
|
||||||
// Vector of structs are inline, so we need to query the
|
// Vector of structs are inline, so we need to query the
|
||||||
// size of the struct.
|
// size of the struct.
|
||||||
const reflection::Object *obj =
|
const reflection::Object* obj =
|
||||||
GetObjectByIndex(field->type()->index());
|
GetObjectByIndex(field->type()->index());
|
||||||
element_size = obj->bytesize();
|
element_size = obj->bytesize();
|
||||||
}
|
}
|
||||||
@@ -408,8 +414,10 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += "end\n";
|
code += "end\n";
|
||||||
code += "\n";
|
code += "\n";
|
||||||
|
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
|
||||||
if (field->deprecated()) { return; }
|
if (field->deprecated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(*field);
|
const std::string field_name = namer_.Field(*field);
|
||||||
const std::string variable_name = namer_.Variable(*field);
|
const std::string variable_name = namer_.Variable(*field);
|
||||||
@@ -455,21 +463,21 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void GenerateDocumentation(
|
void GenerateDocumentation(
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>*
|
||||||
*documentation,
|
documentation,
|
||||||
std::string indent, std::string &code) const {
|
std::string indent, std::string& code) const {
|
||||||
flatbuffers::ForAllDocumentation(
|
flatbuffers::ForAllDocumentation(
|
||||||
documentation, [&](const flatbuffers::String *str) {
|
documentation, [&](const flatbuffers::String* str) {
|
||||||
code += indent + "--" + str->str() + "\n";
|
code += indent + "--" + str->str() + "\n";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateStructBuilderArgs(const r::Object *object,
|
std::string GenerateStructBuilderArgs(const r::Object* object,
|
||||||
std::string prefix = "") const {
|
std::string prefix = "") const {
|
||||||
std::string signature;
|
std::string signature;
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
|
||||||
if (IsStructOrTable(field->type()->base_type())) {
|
if (IsStructOrTable(field->type()->base_type())) {
|
||||||
const r::Object *field_object = GetObject(field->type());
|
const r::Object* field_object = GetObject(field->type());
|
||||||
signature += GenerateStructBuilderArgs(
|
signature += GenerateStructBuilderArgs(
|
||||||
field_object, prefix + namer_.Variable(*field) + "_");
|
field_object, prefix + namer_.Variable(*field) + "_");
|
||||||
} else {
|
} else {
|
||||||
@@ -479,7 +487,7 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AppendStructBuilderBody(const r::Object *object,
|
std::string AppendStructBuilderBody(const r::Object* object,
|
||||||
std::string prefix = "") const {
|
std::string prefix = "") const {
|
||||||
std::string code;
|
std::string code;
|
||||||
code += " builder:Prep(" + NumToString(object->minalign()) + ", " +
|
code += " builder:Prep(" + NumToString(object->minalign()) + ", " +
|
||||||
@@ -487,13 +495,13 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
// We need to reverse the order we iterate over, since we build the
|
// We need to reverse the order we iterate over, since we build the
|
||||||
// buffer backwards.
|
// buffer backwards.
|
||||||
ForAllFields(object, /*reverse=*/true, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/true, [&](const r::Field* field) {
|
||||||
const int32_t num_padding_bytes = field->padding();
|
const int32_t num_padding_bytes = field->padding();
|
||||||
if (num_padding_bytes) {
|
if (num_padding_bytes) {
|
||||||
code += " builder:Pad(" + NumToString(num_padding_bytes) + ")\n";
|
code += " builder:Pad(" + NumToString(num_padding_bytes) + ")\n";
|
||||||
}
|
}
|
||||||
if (IsStructOrTable(field->type()->base_type())) {
|
if (IsStructOrTable(field->type()->base_type())) {
|
||||||
const r::Object *field_object = GetObject(field->type());
|
const r::Object* field_object = GetObject(field->type());
|
||||||
code += AppendStructBuilderBody(field_object,
|
code += AppendStructBuilderBody(field_object,
|
||||||
prefix + namer_.Variable(*field) + "_");
|
prefix + namer_.Variable(*field) + "_");
|
||||||
} else {
|
} else {
|
||||||
@@ -505,36 +513,49 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateMethod(const r::Field *field) const {
|
std::string GenerateMethod(const r::Field* field) const {
|
||||||
const r::BaseType base_type = field->type()->base_type();
|
const r::BaseType base_type = field->type()->base_type();
|
||||||
if (IsScalar(base_type)) { return namer_.Type(GenerateType(base_type)); }
|
if (IsScalar(base_type)) {
|
||||||
if (IsStructOrTable(base_type)) { return "Struct"; }
|
return namer_.Type(GenerateType(base_type));
|
||||||
|
}
|
||||||
|
if (IsStructOrTable(base_type)) {
|
||||||
|
return "Struct";
|
||||||
|
}
|
||||||
return "UOffsetTRelative";
|
return "UOffsetTRelative";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateGetter(const r::Type *type,
|
std::string GenerateGetter(const r::Type* type,
|
||||||
bool element_type = false) const {
|
bool element_type = false) const {
|
||||||
switch (element_type ? type->element() : type->base_type()) {
|
switch (element_type ? type->element() : type->base_type()) {
|
||||||
case r::String: return "self.view:String(";
|
case r::String:
|
||||||
case r::Union: return "self.view:Union(";
|
return "self.view:String(";
|
||||||
case r::Vector: return GenerateGetter(type, true);
|
case r::Union:
|
||||||
|
return "self.view:Union(";
|
||||||
|
case r::Vector:
|
||||||
|
return GenerateGetter(type, true);
|
||||||
default:
|
default:
|
||||||
return "self.view:Get(flatbuffers.N." +
|
return "self.view:Get(flatbuffers.N." +
|
||||||
namer_.Type(GenerateType(type, element_type)) + ", ";
|
namer_.Type(GenerateType(type, element_type)) + ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateType(const r::Type *type,
|
std::string GenerateType(const r::Type* type,
|
||||||
bool element_type = false) const {
|
bool element_type = false) const {
|
||||||
const r::BaseType base_type =
|
const r::BaseType base_type =
|
||||||
element_type ? type->element() : type->base_type();
|
element_type ? type->element() : type->base_type();
|
||||||
if (IsScalar(base_type)) { return GenerateType(base_type); }
|
if (IsScalar(base_type)) {
|
||||||
|
return GenerateType(base_type);
|
||||||
|
}
|
||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case r::String: return "string";
|
case r::String:
|
||||||
case r::Vector: return GenerateGetter(type, true);
|
return "string";
|
||||||
case r::Obj: return namer_.Type(namer_.Denamespace(GetObject(type)));
|
case r::Vector:
|
||||||
|
return GenerateGetter(type, true);
|
||||||
|
case r::Obj:
|
||||||
|
return namer_.Type(namer_.Denamespace(GetObject(type)));
|
||||||
|
|
||||||
default: return "*flatbuffers.Table";
|
default:
|
||||||
|
return "*flatbuffers.Table";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -542,23 +563,36 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
// Need to override the default naming to match the Lua runtime libraries.
|
// Need to override the default naming to match the Lua runtime libraries.
|
||||||
// TODO(derekbailey): make overloads in the runtime libraries to avoid this.
|
// TODO(derekbailey): make overloads in the runtime libraries to avoid this.
|
||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case r::None: return "uint8";
|
case r::None:
|
||||||
case r::UType: return "uint8";
|
return "uint8";
|
||||||
case r::Byte: return "int8";
|
case r::UType:
|
||||||
case r::UByte: return "uint8";
|
return "uint8";
|
||||||
case r::Short: return "int16";
|
case r::Byte:
|
||||||
case r::UShort: return "uint16";
|
return "int8";
|
||||||
case r::Int: return "int32";
|
case r::UByte:
|
||||||
case r::UInt: return "uint32";
|
return "uint8";
|
||||||
case r::Long: return "int64";
|
case r::Short:
|
||||||
case r::ULong: return "uint64";
|
return "int16";
|
||||||
case r::Float: return "Float32";
|
case r::UShort:
|
||||||
case r::Double: return "Float64";
|
return "uint16";
|
||||||
default: return r::EnumNameBaseType(base_type);
|
case r::Int:
|
||||||
|
return "int32";
|
||||||
|
case r::UInt:
|
||||||
|
return "uint32";
|
||||||
|
case r::Long:
|
||||||
|
return "int64";
|
||||||
|
case r::ULong:
|
||||||
|
return "uint64";
|
||||||
|
case r::Float:
|
||||||
|
return "Float32";
|
||||||
|
case r::Double:
|
||||||
|
return "Float64";
|
||||||
|
default:
|
||||||
|
return r::EnumNameBaseType(base_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DefaultValue(const r::Field *field) const {
|
std::string DefaultValue(const r::Field* field) const {
|
||||||
const r::BaseType base_type = field->type()->base_type();
|
const r::BaseType base_type = field->type()->base_type();
|
||||||
if (IsFloatingPoint(base_type)) {
|
if (IsFloatingPoint(base_type)) {
|
||||||
return NumToString(field->default_real());
|
return NumToString(field->default_real());
|
||||||
@@ -566,24 +600,26 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
if (IsBool(base_type)) {
|
if (IsBool(base_type)) {
|
||||||
return field->default_integer() ? "true" : "false";
|
return field->default_integer() ? "true" : "false";
|
||||||
}
|
}
|
||||||
if (IsScalar(base_type)) { return NumToString((field->default_integer())); }
|
if (IsScalar(base_type)) {
|
||||||
|
return NumToString((field->default_integer()));
|
||||||
|
}
|
||||||
// represents offsets
|
// represents offsets
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartCodeBlock(const reflection::Enum *enum_def) {
|
void StartCodeBlock(const reflection::Enum* enum_def) {
|
||||||
current_enum_ = enum_def;
|
current_enum_ = enum_def;
|
||||||
current_obj_ = nullptr;
|
current_obj_ = nullptr;
|
||||||
requires_.clear();
|
requires_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartCodeBlock(const reflection::Object *object) {
|
void StartCodeBlock(const reflection::Object* object) {
|
||||||
current_obj_ = object;
|
current_obj_ = object;
|
||||||
current_enum_ = nullptr;
|
current_enum_ = nullptr;
|
||||||
requires_.clear();
|
requires_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RegisterRequires(const r::Field *field,
|
std::string RegisterRequires(const r::Field* field,
|
||||||
bool use_element = false) {
|
bool use_element = false) {
|
||||||
std::string type_name;
|
std::string type_name;
|
||||||
|
|
||||||
@@ -591,12 +627,16 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
use_element ? field->type()->element() : field->type()->base_type();
|
use_element ? field->type()->element() : field->type()->base_type();
|
||||||
|
|
||||||
if (IsStructOrTable(type)) {
|
if (IsStructOrTable(type)) {
|
||||||
const r::Object *object = GetObjectByIndex(field->type()->index());
|
const r::Object* object = GetObjectByIndex(field->type()->index());
|
||||||
if (object == current_obj_) { return namer_.Denamespace(object); }
|
if (object == current_obj_) {
|
||||||
|
return namer_.Denamespace(object);
|
||||||
|
}
|
||||||
type_name = object->name()->str();
|
type_name = object->name()->str();
|
||||||
} else {
|
} else {
|
||||||
const r::Enum *enum_def = GetEnumByIndex(field->type()->index());
|
const r::Enum* enum_def = GetEnumByIndex(field->type()->index());
|
||||||
if (enum_def == current_enum_) { return namer_.Denamespace(enum_def); }
|
if (enum_def == current_enum_) {
|
||||||
|
return namer_.Denamespace(enum_def);
|
||||||
|
}
|
||||||
type_name = enum_def->name()->str();
|
type_name = enum_def->name()->str();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -609,15 +649,15 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return RegisterRequires(name, type_name);
|
return RegisterRequires(name, type_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RegisterRequires(const std::string &local_name,
|
std::string RegisterRequires(const std::string& local_name,
|
||||||
const std::string &requires_name) {
|
const std::string& requires_name) {
|
||||||
requires_[local_name] = requires_name;
|
requires_[local_name] = requires_name;
|
||||||
return local_name;
|
return local_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCodeBlock(const std::string &code_block, const std::string &name,
|
void EmitCodeBlock(const std::string& code_block, const std::string& name,
|
||||||
const std::string &ns,
|
const std::string& ns,
|
||||||
const std::string &declaring_file) const {
|
const std::string& declaring_file) const {
|
||||||
const std::string root_type = schema_->root_table()->name()->str();
|
const std::string root_type = schema_->root_table()->name()->str();
|
||||||
const std::string root_file =
|
const std::string root_file =
|
||||||
schema_->root_table()->declaration_file()->str();
|
schema_->root_table()->declaration_file()->str();
|
||||||
@@ -665,15 +705,15 @@ class LuaBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
std::map<std::string, std::string> requires_;
|
std::map<std::string, std::string> requires_;
|
||||||
CodeGenOptions options_;
|
CodeGenOptions options_;
|
||||||
|
|
||||||
const r::Object *current_obj_;
|
const r::Object* current_obj_;
|
||||||
const r::Enum *current_enum_;
|
const r::Enum* current_enum_;
|
||||||
const std::string flatc_version_;
|
const std::string flatc_version_;
|
||||||
const BfbsNamer namer_;
|
const BfbsNamer namer_;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<CodeGenerator> NewLuaBfbsGenerator(
|
std::unique_ptr<CodeGenerator> NewLuaBfbsGenerator(
|
||||||
const std::string &flatc_version) {
|
const std::string& flatc_version) {
|
||||||
return std::unique_ptr<LuaBfbsGenerator>(new LuaBfbsGenerator(flatc_version));
|
return std::unique_ptr<LuaBfbsGenerator>(new LuaBfbsGenerator(flatc_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ std::set<std::string> NimKeywords() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Namer::Config NimDefaultConfig() {
|
Namer::Config NimDefaultConfig() {
|
||||||
return { /*types=*/Case::kUpperCamel,
|
return {/*types=*/Case::kUpperCamel,
|
||||||
/*constants=*/Case::kUpperCamel,
|
/*constants=*/Case::kUpperCamel,
|
||||||
/*methods=*/Case::kLowerCamel,
|
/*methods=*/Case::kLowerCamel,
|
||||||
/*functions=*/Case::kUpperCamel,
|
/*functions=*/Case::kUpperCamel,
|
||||||
@@ -74,19 +74,18 @@ Namer::Config NimDefaultConfig() {
|
|||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
/*filename_suffix=*/"",
|
/*filename_suffix=*/"",
|
||||||
/*filename_extension=*/".nim" };
|
/*filename_extension=*/".nim"};
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string Export = "*";
|
const std::string Export = "*";
|
||||||
const std::set<std::string> builtin_types = {
|
const std::set<std::string> builtin_types = {
|
||||||
"uint8", "uint8", "bool", "int8", "uint8", "int16",
|
"uint8", "uint8", "bool", "int8", "uint8", "int16",
|
||||||
"uint16", "int32", "uint32", "int64", "uint64", "float32",
|
"uint16", "int32", "uint32", "int64", "uint64", "float32",
|
||||||
"float64", "string", "int", "uint", "uoffset", "Builder"
|
"float64", "string", "int", "uint", "uoffset", "Builder"};
|
||||||
};
|
|
||||||
|
|
||||||
class NimBfbsGenerator : public BaseBfbsGenerator {
|
class NimBfbsGenerator : public BaseBfbsGenerator {
|
||||||
public:
|
public:
|
||||||
explicit NimBfbsGenerator(const std::string &flatc_version)
|
explicit NimBfbsGenerator(const std::string& flatc_version)
|
||||||
: BaseBfbsGenerator(),
|
: BaseBfbsGenerator(),
|
||||||
keywords_(),
|
keywords_(),
|
||||||
imports_(),
|
imports_(),
|
||||||
@@ -95,15 +94,15 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
flatc_version_(flatc_version),
|
flatc_version_(flatc_version),
|
||||||
namer_(NimDefaultConfig(), NimKeywords()) {}
|
namer_(NimDefaultConfig(), NimKeywords()) {}
|
||||||
|
|
||||||
Status GenerateFromSchema(const r::Schema *schema,
|
Status GenerateFromSchema(const r::Schema* schema,
|
||||||
const CodeGenOptions &options)
|
const CodeGenOptions& options)
|
||||||
FLATBUFFERS_OVERRIDE {
|
FLATBUFFERS_OVERRIDE {
|
||||||
options_ = options;
|
options_ = options;
|
||||||
ForAllEnums(schema->enums(), [&](const r::Enum *enum_def) {
|
ForAllEnums(schema->enums(), [&](const r::Enum* enum_def) {
|
||||||
StartCodeBlock(enum_def);
|
StartCodeBlock(enum_def);
|
||||||
GenerateEnum(enum_def);
|
GenerateEnum(enum_def);
|
||||||
});
|
});
|
||||||
ForAllObjects(schema->objects(), [&](const r::Object *object) {
|
ForAllObjects(schema->objects(), [&](const r::Object* object) {
|
||||||
StartCodeBlock(object);
|
StartCodeBlock(object);
|
||||||
GenerateObject(object);
|
GenerateObject(object);
|
||||||
});
|
});
|
||||||
@@ -112,17 +111,17 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
using BaseBfbsGenerator::GenerateCode;
|
using BaseBfbsGenerator::GenerateCode;
|
||||||
|
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return NOT_IMPLEMENTED;
|
return NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -130,16 +129,16 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return NOT_IMPLEMENTED;
|
return NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return NOT_IMPLEMENTED;
|
return NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return NOT_IMPLEMENTED;
|
return NOT_IMPLEMENTED;
|
||||||
@@ -161,7 +160,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void GenerateEnum(const r::Enum *enum_def) {
|
void GenerateEnum(const r::Enum* enum_def) {
|
||||||
std::string code;
|
std::string code;
|
||||||
|
|
||||||
std::string ns;
|
std::string ns;
|
||||||
@@ -172,7 +171,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
GenerateDocumentation(enum_def->documentation(), "", code);
|
GenerateDocumentation(enum_def->documentation(), "", code);
|
||||||
code += "type " + enum_name + Export + "{.pure.} = enum\n";
|
code += "type " + enum_name + Export + "{.pure.} = enum\n";
|
||||||
|
|
||||||
ForAllEnumValues(enum_def, [&](const reflection::EnumVal *enum_val) {
|
ForAllEnumValues(enum_def, [&](const reflection::EnumVal* enum_val) {
|
||||||
GenerateDocumentation(enum_val->documentation(), " ", code);
|
GenerateDocumentation(enum_val->documentation(), " ", code);
|
||||||
code += " " + namer_.Variant(enum_val->name()->str()) + " = " +
|
code += " " + namer_.Variant(enum_val->name()->str()) + " = " +
|
||||||
NumToString(enum_val->value()) + "." + enum_type + ",\n";
|
NumToString(enum_val->value()) + "." + enum_type + ",\n";
|
||||||
@@ -181,7 +180,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
EmitCodeBlock(code, enum_name, ns, enum_def->declaration_file()->str());
|
EmitCodeBlock(code, enum_name, ns, enum_def->declaration_file()->str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateObject(const r::Object *object) {
|
void GenerateObject(const r::Object* object) {
|
||||||
// Register the main flatbuffers module.
|
// Register the main flatbuffers module.
|
||||||
RegisterImports("flatbuffers", "");
|
RegisterImports("flatbuffers", "");
|
||||||
std::string code;
|
std::string code;
|
||||||
@@ -193,9 +192,11 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += "type " + object_name + "* = object of FlatObj\n";
|
code += "type " + object_name + "* = object of FlatObj\n";
|
||||||
|
|
||||||
// Create all the field accessors.
|
// Create all the field accessors.
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
|
||||||
// Skip writing deprecated fields altogether.
|
// Skip writing deprecated fields altogether.
|
||||||
if (field->deprecated()) { return; }
|
if (field->deprecated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(*field);
|
const std::string field_name = namer_.Field(*field);
|
||||||
const r::BaseType base_type = field->type()->base_type();
|
const r::BaseType base_type = field->type()->base_type();
|
||||||
@@ -256,7 +257,9 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
code += getter_signature + getter_code;
|
code += getter_signature + getter_code;
|
||||||
if (IsScalar(base_type)) { code += setter_signature + setter_code; }
|
if (IsScalar(base_type)) {
|
||||||
|
code += setter_signature + setter_code;
|
||||||
|
}
|
||||||
} else if (base_type == r::Array || base_type == r::Vector) {
|
} else if (base_type == r::Array || base_type == r::Vector) {
|
||||||
const r::BaseType vector_base_type = field->type()->element();
|
const r::BaseType vector_base_type = field->type()->element();
|
||||||
uint32_t element_size = field->type()->element_size();
|
uint32_t element_size = field->type()->element_size();
|
||||||
@@ -309,8 +312,10 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
code += " builder.StartObject(" + NumToString(object->fields()->size()) +
|
code += " builder.StartObject(" + NumToString(object->fields()->size()) +
|
||||||
")\n";
|
")\n";
|
||||||
|
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
|
||||||
if (field->deprecated()) { return; }
|
if (field->deprecated()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(*field);
|
const std::string field_name = namer_.Field(*field);
|
||||||
const std::string variable_name = namer_.Variable(*field);
|
const std::string variable_name = namer_.Variable(*field);
|
||||||
@@ -348,21 +353,21 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void GenerateDocumentation(
|
void GenerateDocumentation(
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>*
|
||||||
*documentation,
|
documentation,
|
||||||
std::string indent, std::string &code) const {
|
std::string indent, std::string& code) const {
|
||||||
flatbuffers::ForAllDocumentation(
|
flatbuffers::ForAllDocumentation(
|
||||||
documentation, [&](const flatbuffers::String *str) {
|
documentation, [&](const flatbuffers::String* str) {
|
||||||
code += indent + "# " + str->str() + "\n";
|
code += indent + "# " + str->str() + "\n";
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateStructBuilderArgs(const r::Object *object,
|
std::string GenerateStructBuilderArgs(const r::Object* object,
|
||||||
std::string prefix = "") const {
|
std::string prefix = "") const {
|
||||||
std::string signature;
|
std::string signature;
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const r::Field* field) {
|
||||||
if (IsStructOrTable(field->type()->base_type())) {
|
if (IsStructOrTable(field->type()->base_type())) {
|
||||||
const r::Object *field_object = GetObject(field->type());
|
const r::Object* field_object = GetObject(field->type());
|
||||||
signature += GenerateStructBuilderArgs(
|
signature += GenerateStructBuilderArgs(
|
||||||
field_object, prefix + namer_.Variable(*field) + "_");
|
field_object, prefix + namer_.Variable(*field) + "_");
|
||||||
} else {
|
} else {
|
||||||
@@ -373,7 +378,7 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return signature;
|
return signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AppendStructBuilderBody(const r::Object *object,
|
std::string AppendStructBuilderBody(const r::Object* object,
|
||||||
std::string prefix = "") const {
|
std::string prefix = "") const {
|
||||||
std::string code;
|
std::string code;
|
||||||
code += " self.Prep(" + NumToString(object->minalign()) + ", " +
|
code += " self.Prep(" + NumToString(object->minalign()) + ", " +
|
||||||
@@ -381,13 +386,13 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
// We need to reverse the order we iterate over, since we build the
|
// We need to reverse the order we iterate over, since we build the
|
||||||
// buffer backwards.
|
// buffer backwards.
|
||||||
ForAllFields(object, /*reverse=*/true, [&](const r::Field *field) {
|
ForAllFields(object, /*reverse=*/true, [&](const r::Field* field) {
|
||||||
const int32_t num_padding_bytes = field->padding();
|
const int32_t num_padding_bytes = field->padding();
|
||||||
if (num_padding_bytes) {
|
if (num_padding_bytes) {
|
||||||
code += " self.Pad(" + NumToString(num_padding_bytes) + ")\n";
|
code += " self.Pad(" + NumToString(num_padding_bytes) + ")\n";
|
||||||
}
|
}
|
||||||
if (IsStructOrTable(field->type()->base_type())) {
|
if (IsStructOrTable(field->type()->base_type())) {
|
||||||
const r::Object *field_object = GetObject(field->type());
|
const r::Object* field_object = GetObject(field->type());
|
||||||
code += AppendStructBuilderBody(field_object,
|
code += AppendStructBuilderBody(field_object,
|
||||||
prefix + namer_.Variable(*field) + "_");
|
prefix + namer_.Variable(*field) + "_");
|
||||||
} else {
|
} else {
|
||||||
@@ -398,28 +403,35 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateMethod(const r::Field *field) const {
|
std::string GenerateMethod(const r::Field* field) const {
|
||||||
const r::BaseType base_type = field->type()->base_type();
|
const r::BaseType base_type = field->type()->base_type();
|
||||||
if (IsStructOrTable(base_type)) { return "Struct"; }
|
if (IsStructOrTable(base_type)) {
|
||||||
|
return "Struct";
|
||||||
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateGetter(const r::Type *type, const std::string &offsetval,
|
std::string GenerateGetter(const r::Type* type, const std::string& offsetval,
|
||||||
bool element_type = false) const {
|
bool element_type = false) const {
|
||||||
const r::BaseType base_type =
|
const r::BaseType base_type =
|
||||||
element_type ? type->element() : type->base_type();
|
element_type ? type->element() : type->base_type();
|
||||||
std::string offset = offsetval;
|
std::string offset = offsetval;
|
||||||
if (!element_type) { offset = "self.tab.Pos + " + offset; }
|
if (!element_type) {
|
||||||
|
offset = "self.tab.Pos + " + offset;
|
||||||
|
}
|
||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case r::String: return "self.tab.String(" + offset + ")";
|
case r::String:
|
||||||
case r::Union: return "self.tab.Union(" + offsetval + ")";
|
return "self.tab.String(" + offset + ")";
|
||||||
|
case r::Union:
|
||||||
|
return "self.tab.Union(" + offsetval + ")";
|
||||||
case r::Obj: {
|
case r::Obj: {
|
||||||
return GenerateType(type, element_type) +
|
return GenerateType(type, element_type) +
|
||||||
"(tab: Vtable(Bytes: self.tab.Bytes, Pos: " + offset + "))";
|
"(tab: Vtable(Bytes: self.tab.Bytes, Pos: " + offset + "))";
|
||||||
}
|
}
|
||||||
case r::Vector: return GenerateGetter(type, offsetval, true);
|
case r::Vector:
|
||||||
|
return GenerateGetter(type, offsetval, true);
|
||||||
default:
|
default:
|
||||||
const r::Enum *type_enum = GetEnum(type, element_type);
|
const r::Enum* type_enum = GetEnum(type, element_type);
|
||||||
if (type_enum != nullptr) {
|
if (type_enum != nullptr) {
|
||||||
return GenerateType(type, element_type) + "(" + "Get[" +
|
return GenerateType(type, element_type) + "(" + "Get[" +
|
||||||
GenerateType(base_type) + "](self.tab, " + offset + ")" + ")";
|
GenerateType(base_type) + "](self.tab, " + offset + ")" + ")";
|
||||||
@@ -430,46 +442,52 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Denamespace(const std::string &s, std::string &importns,
|
std::string Denamespace(const std::string& s, std::string& importns,
|
||||||
std::string &ns) const {
|
std::string& ns) const {
|
||||||
if (builtin_types.find(s) != builtin_types.end()) { return s; }
|
if (builtin_types.find(s) != builtin_types.end()) {
|
||||||
|
return s;
|
||||||
|
}
|
||||||
std::string type = namer_.Type(namer_.Denamespace(s, ns));
|
std::string type = namer_.Type(namer_.Denamespace(s, ns));
|
||||||
importns = ns.empty() ? type : ns + "." + type;
|
importns = ns.empty() ? type : ns + "." + type;
|
||||||
std::replace(importns.begin(), importns.end(), '.', '_');
|
std::replace(importns.begin(), importns.end(), '.', '_');
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Denamespace(const std::string &s, std::string &importns) const {
|
std::string Denamespace(const std::string& s, std::string& importns) const {
|
||||||
std::string ns;
|
std::string ns;
|
||||||
return Denamespace(s, importns, ns);
|
return Denamespace(s, importns, ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Denamespace(const std::string &s) const {
|
std::string Denamespace(const std::string& s) const {
|
||||||
std::string importns;
|
std::string importns;
|
||||||
return Denamespace(s, importns);
|
return Denamespace(s, importns);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateType(const r::Type *type, bool element_type = false,
|
std::string GenerateType(const r::Type* type, bool element_type = false,
|
||||||
bool enum_inner = false) const {
|
bool enum_inner = false) const {
|
||||||
const r::BaseType base_type =
|
const r::BaseType base_type =
|
||||||
element_type ? type->element() : type->base_type();
|
element_type ? type->element() : type->base_type();
|
||||||
if (IsScalar(base_type) && !enum_inner) {
|
if (IsScalar(base_type) && !enum_inner) {
|
||||||
const r::Enum *type_enum = GetEnum(type, element_type);
|
const r::Enum* type_enum = GetEnum(type, element_type);
|
||||||
if (type_enum != nullptr) {
|
if (type_enum != nullptr) {
|
||||||
std::string importns;
|
std::string importns;
|
||||||
std::string type_name = Denamespace(type_enum->name()->str(), importns);
|
std::string type_name = Denamespace(type_enum->name()->str(), importns);
|
||||||
return importns + "." + type_name;
|
return importns + "." + type_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsScalar(base_type)) { return Denamespace(GenerateType(base_type)); }
|
if (IsScalar(base_type)) {
|
||||||
|
return Denamespace(GenerateType(base_type));
|
||||||
|
}
|
||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case r::String: return "string";
|
case r::String:
|
||||||
|
return "string";
|
||||||
case r::Vector: {
|
case r::Vector: {
|
||||||
return "seq[" + GenerateType(type, true) + "]";
|
return "seq[" + GenerateType(type, true) + "]";
|
||||||
}
|
}
|
||||||
case r::Union: return "Vtable";
|
case r::Union:
|
||||||
|
return "Vtable";
|
||||||
case r::Obj: {
|
case r::Obj: {
|
||||||
const r::Object *type_obj = GetObject(type, element_type);
|
const r::Object* type_obj = GetObject(type, element_type);
|
||||||
std::string importns;
|
std::string importns;
|
||||||
std::string type_name = Denamespace(type_obj->name()->str(), importns);
|
std::string type_name = Denamespace(type_obj->name()->str(), importns);
|
||||||
if (type_obj == current_obj_) {
|
if (type_obj == current_obj_) {
|
||||||
@@ -478,11 +496,12 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return importns + "." + type_name;
|
return importns + "." + type_name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: return "uoffset";
|
default:
|
||||||
|
return "uoffset";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateTypeBasic(const r::Type *type,
|
std::string GenerateTypeBasic(const r::Type* type,
|
||||||
bool element_type = false) const {
|
bool element_type = false) const {
|
||||||
const r::BaseType base_type =
|
const r::BaseType base_type =
|
||||||
element_type ? type->element() : type->base_type();
|
element_type ? type->element() : type->base_type();
|
||||||
@@ -495,25 +514,40 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
|
|
||||||
std::string GenerateType(const r::BaseType base_type) const {
|
std::string GenerateType(const r::BaseType base_type) const {
|
||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case r::None: return "uint8";
|
case r::None:
|
||||||
case r::UType: return "uint8";
|
return "uint8";
|
||||||
case r::Bool: return "bool";
|
case r::UType:
|
||||||
case r::Byte: return "int8";
|
return "uint8";
|
||||||
case r::UByte: return "uint8";
|
case r::Bool:
|
||||||
case r::Short: return "int16";
|
return "bool";
|
||||||
case r::UShort: return "uint16";
|
case r::Byte:
|
||||||
case r::Int: return "int32";
|
return "int8";
|
||||||
case r::UInt: return "uint32";
|
case r::UByte:
|
||||||
case r::Long: return "int64";
|
return "uint8";
|
||||||
case r::ULong: return "uint64";
|
case r::Short:
|
||||||
case r::Float: return "float32";
|
return "int16";
|
||||||
case r::Double: return "float64";
|
case r::UShort:
|
||||||
case r::String: return "string";
|
return "uint16";
|
||||||
default: return r::EnumNameBaseType(base_type);
|
case r::Int:
|
||||||
|
return "int32";
|
||||||
|
case r::UInt:
|
||||||
|
return "uint32";
|
||||||
|
case r::Long:
|
||||||
|
return "int64";
|
||||||
|
case r::ULong:
|
||||||
|
return "uint64";
|
||||||
|
case r::Float:
|
||||||
|
return "float32";
|
||||||
|
case r::Double:
|
||||||
|
return "float64";
|
||||||
|
case r::String:
|
||||||
|
return "string";
|
||||||
|
default:
|
||||||
|
return r::EnumNameBaseType(base_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DefaultValue(const r::Field *field) const {
|
std::string DefaultValue(const r::Field* field) const {
|
||||||
const r::BaseType base_type = field->type()->base_type();
|
const r::BaseType base_type = field->type()->base_type();
|
||||||
if (IsFloatingPoint(base_type)) {
|
if (IsFloatingPoint(base_type)) {
|
||||||
if (field->default_real() != field->default_real()) {
|
if (field->default_real() != field->default_real()) {
|
||||||
@@ -531,24 +565,26 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return field->default_integer() ? "true" : "false";
|
return field->default_integer() ? "true" : "false";
|
||||||
}
|
}
|
||||||
if (IsScalar(base_type)) {
|
if (IsScalar(base_type)) {
|
||||||
const r::Enum *type_enum = GetEnum(field->type());
|
const r::Enum* type_enum = GetEnum(field->type());
|
||||||
if (type_enum != nullptr) {
|
if (type_enum != nullptr) {
|
||||||
return "type(result)(" + NumToString((field->default_integer())) + ")";
|
return "type(result)(" + NumToString((field->default_integer())) + ")";
|
||||||
}
|
}
|
||||||
return NumToString((field->default_integer()));
|
return NumToString((field->default_integer()));
|
||||||
}
|
}
|
||||||
if (base_type == r::String) { return "\"\""; }
|
if (base_type == r::String) {
|
||||||
|
return "\"\"";
|
||||||
|
}
|
||||||
// represents offsets
|
// represents offsets
|
||||||
return "0";
|
return "0";
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartCodeBlock(const reflection::Enum *enum_def) {
|
void StartCodeBlock(const reflection::Enum* enum_def) {
|
||||||
current_enum_ = enum_def;
|
current_enum_ = enum_def;
|
||||||
current_obj_ = nullptr;
|
current_obj_ = nullptr;
|
||||||
imports_.clear();
|
imports_.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StartCodeBlock(const reflection::Object *object) {
|
void StartCodeBlock(const reflection::Object* object) {
|
||||||
current_enum_ = nullptr;
|
current_enum_ = nullptr;
|
||||||
current_obj_ = object;
|
current_obj_ = object;
|
||||||
imports_.clear();
|
imports_.clear();
|
||||||
@@ -572,8 +608,8 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetRelativePathFromNamespace(const std::string &relative_to,
|
std::string GetRelativePathFromNamespace(const std::string& relative_to,
|
||||||
const std::string &str2) {
|
const std::string& str2) {
|
||||||
std::vector<std::string> relative_to_vec = StringSplit(relative_to, ".");
|
std::vector<std::string> relative_to_vec = StringSplit(relative_to, ".");
|
||||||
std::vector<std::string> str2_vec = StringSplit(str2, ".");
|
std::vector<std::string> str2_vec = StringSplit(str2, ".");
|
||||||
while (relative_to_vec.size() > 0 && str2_vec.size() > 0) {
|
while (relative_to_vec.size() > 0 && str2_vec.size() > 0) {
|
||||||
@@ -592,12 +628,14 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
std::string new_path;
|
std::string new_path;
|
||||||
for (size_t i = 0; i < str2_vec.size(); ++i) {
|
for (size_t i = 0; i < str2_vec.size(); ++i) {
|
||||||
new_path += str2_vec[i];
|
new_path += str2_vec[i];
|
||||||
if (i != str2_vec.size() - 1) { new_path += "/"; }
|
if (i != str2_vec.size() - 1) {
|
||||||
|
new_path += "/";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return new_path;
|
return new_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterImports(const r::Object *object, const r::Field *field,
|
void RegisterImports(const r::Object* object, const r::Field* field,
|
||||||
bool use_element = false) {
|
bool use_element = false) {
|
||||||
std::string importns;
|
std::string importns;
|
||||||
std::string type_name;
|
std::string type_name;
|
||||||
@@ -606,14 +644,18 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
use_element ? field->type()->element() : field->type()->base_type();
|
use_element ? field->type()->element() : field->type()->base_type();
|
||||||
|
|
||||||
if (IsStructOrTable(type)) {
|
if (IsStructOrTable(type)) {
|
||||||
const r::Object *object_def = GetObjectByIndex(field->type()->index());
|
const r::Object* object_def = GetObjectByIndex(field->type()->index());
|
||||||
if (object_def == current_obj_) { return; }
|
if (object_def == current_obj_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::string ns;
|
std::string ns;
|
||||||
type_name = Denamespace(object_def->name()->str(), importns, ns);
|
type_name = Denamespace(object_def->name()->str(), importns, ns);
|
||||||
type_name = ns.empty() ? type_name : ns + "." + type_name;
|
type_name = ns.empty() ? type_name : ns + "." + type_name;
|
||||||
} else {
|
} else {
|
||||||
const r::Enum *enum_def = GetEnumByIndex(field->type()->index());
|
const r::Enum* enum_def = GetEnumByIndex(field->type()->index());
|
||||||
if (enum_def == current_enum_) { return; }
|
if (enum_def == current_enum_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
std::string ns;
|
std::string ns;
|
||||||
type_name = Denamespace(enum_def->name()->str(), importns, ns);
|
type_name = Denamespace(enum_def->name()->str(), importns, ns);
|
||||||
type_name = ns.empty() ? type_name : ns + "." + type_name;
|
type_name = ns.empty() ? type_name : ns + "." + type_name;
|
||||||
@@ -625,13 +667,13 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
RegisterImports(import_path, importns);
|
RegisterImports(import_path, importns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RegisterImports(const std::string &local_name,
|
void RegisterImports(const std::string& local_name,
|
||||||
const std::string &imports_name) {
|
const std::string& imports_name) {
|
||||||
imports_[local_name] = imports_name;
|
imports_[local_name] = imports_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCodeBlock(const std::string &code_block, const std::string &name,
|
void EmitCodeBlock(const std::string& code_block, const std::string& name,
|
||||||
const std::string &ns, const std::string &declaring_file) {
|
const std::string& ns, const std::string& declaring_file) {
|
||||||
const std::string full_qualified_name = ns.empty() ? name : ns + "." + name;
|
const std::string full_qualified_name = ns.empty() ? name : ns + "." + name;
|
||||||
|
|
||||||
std::string code = "#[ " + full_qualified_name + "\n";
|
std::string code = "#[ " + full_qualified_name + "\n";
|
||||||
@@ -683,15 +725,15 @@ class NimBfbsGenerator : public BaseBfbsGenerator {
|
|||||||
std::map<std::string, std::string> imports_;
|
std::map<std::string, std::string> imports_;
|
||||||
CodeGenOptions options_;
|
CodeGenOptions options_;
|
||||||
|
|
||||||
const r::Object *current_obj_;
|
const r::Object* current_obj_;
|
||||||
const r::Enum *current_enum_;
|
const r::Enum* current_enum_;
|
||||||
const std::string flatc_version_;
|
const std::string flatc_version_;
|
||||||
const BfbsNamer namer_;
|
const BfbsNamer namer_;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<CodeGenerator> NewNimBfbsGenerator(
|
std::unique_ptr<CodeGenerator> NewNimBfbsGenerator(
|
||||||
const std::string &flatc_version) {
|
const std::string& flatc_version) {
|
||||||
return std::unique_ptr<NimBfbsGenerator>(new NimBfbsGenerator(flatc_version));
|
return std::unique_ptr<NimBfbsGenerator>(new NimBfbsGenerator(flatc_version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static bool BinaryRegionSort(const BinaryRegion &a, const BinaryRegion &b) {
|
static bool BinaryRegionSort(const BinaryRegion& a, const BinaryRegion& b) {
|
||||||
return a.offset < b.offset;
|
return a.offset < b.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SetError(BinaryRegionComment &comment, BinaryRegionStatus status,
|
static void SetError(BinaryRegionComment& comment, BinaryRegionStatus status,
|
||||||
std::string message = "") {
|
std::string message = "") {
|
||||||
comment.status = status;
|
comment.status = status;
|
||||||
comment.status_message = message;
|
comment.status_message = message;
|
||||||
@@ -40,7 +40,7 @@ static BinaryRegion MakeBinaryRegion(
|
|||||||
return region;
|
return region;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BinarySection MakeBinarySection(const std::string &name,
|
static BinarySection MakeBinarySection(const std::string& name,
|
||||||
const BinarySectionType type,
|
const BinarySectionType type,
|
||||||
std::vector<BinaryRegion> regions) {
|
std::vector<BinaryRegion> regions) {
|
||||||
BinarySection section;
|
BinarySection section;
|
||||||
@@ -50,33 +50,37 @@ static BinarySection MakeBinarySection(const std::string &name,
|
|||||||
return section;
|
return section;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BinarySection MakeSingleRegionBinarySection(const std::string &name,
|
static BinarySection MakeSingleRegionBinarySection(const std::string& name,
|
||||||
const BinarySectionType type,
|
const BinarySectionType type,
|
||||||
const BinaryRegion ®ion) {
|
const BinaryRegion& region) {
|
||||||
std::vector<BinaryRegion> regions;
|
std::vector<BinaryRegion> regions;
|
||||||
regions.push_back(region);
|
regions.push_back(region);
|
||||||
return MakeBinarySection(name, type, std::move(regions));
|
return MakeBinarySection(name, type, std::move(regions));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsNonZeroRegion(const uint64_t offset, const uint64_t length,
|
static bool IsNonZeroRegion(const uint64_t offset, const uint64_t length,
|
||||||
const uint8_t *const binary) {
|
const uint8_t* const binary) {
|
||||||
for (uint64_t i = offset; i < offset + length; ++i) {
|
for (uint64_t i = offset; i < offset + length; ++i) {
|
||||||
if (binary[i] != 0) { return true; }
|
if (binary[i] != 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsPrintableRegion(const uint64_t offset, const uint64_t length,
|
static bool IsPrintableRegion(const uint64_t offset, const uint64_t length,
|
||||||
const uint8_t *const binary) {
|
const uint8_t* const binary) {
|
||||||
for (uint64_t i = offset; i < offset + length; ++i) {
|
for (uint64_t i = offset; i < offset + length; ++i) {
|
||||||
if (!isprint(binary[i])) { return false; }
|
if (!isprint(binary[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BinarySection GenerateMissingSection(const uint64_t offset,
|
static BinarySection GenerateMissingSection(const uint64_t offset,
|
||||||
const uint64_t length,
|
const uint64_t length,
|
||||||
const uint8_t *const binary) {
|
const uint8_t* const binary) {
|
||||||
std::vector<BinaryRegion> regions;
|
std::vector<BinaryRegion> regions;
|
||||||
|
|
||||||
// Check if the region is all zeros or not, as that can tell us if it is
|
// Check if the region is all zeros or not, as that can tell us if it is
|
||||||
@@ -130,7 +134,9 @@ std::map<uint64_t, BinarySection> BinaryAnnotator::Annotate() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The binary is too short to read as a flatbuffers.
|
// The binary is too short to read as a flatbuffers.
|
||||||
if (binary_length_ < FLATBUFFERS_MIN_BUFFER_SIZE) { return {}; }
|
if (binary_length_ < FLATBUFFERS_MIN_BUFFER_SIZE) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure we start with a clean slate.
|
// Make sure we start with a clean slate.
|
||||||
vtables_.clear();
|
vtables_.clear();
|
||||||
@@ -234,20 +240,24 @@ uint64_t BinaryAnnotator::BuildHeader(const uint64_t header_offset) {
|
|||||||
return root_table_loc;
|
return root_table_loc;
|
||||||
}
|
}
|
||||||
|
|
||||||
BinaryAnnotator::VTable *BinaryAnnotator::GetOrBuildVTable(
|
BinaryAnnotator::VTable* BinaryAnnotator::GetOrBuildVTable(
|
||||||
const uint64_t vtable_offset, const reflection::Object *const table,
|
const uint64_t vtable_offset, const reflection::Object* const table,
|
||||||
const uint64_t offset_of_referring_table) {
|
const uint64_t offset_of_referring_table) {
|
||||||
// Get a list of vtables (if any) already defined at this offset.
|
// Get a list of vtables (if any) already defined at this offset.
|
||||||
std::list<VTable> &vtables = vtables_[vtable_offset];
|
std::list<VTable>& vtables = vtables_[vtable_offset];
|
||||||
|
|
||||||
// See if this vtable for the table type has been generated before.
|
// See if this vtable for the table type has been generated before.
|
||||||
for (VTable &vtable : vtables) {
|
for (VTable& vtable : vtables) {
|
||||||
if (vtable.referring_table == table) { return &vtable; }
|
if (vtable.referring_table == table) {
|
||||||
|
return &vtable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we are trying to make a new vtable and it is already encompassed by
|
// If we are trying to make a new vtable and it is already encompassed by
|
||||||
// another binary section, something is corrupted.
|
// another binary section, something is corrupted.
|
||||||
if (vtables.empty() && ContainsSection(vtable_offset)) { return nullptr; }
|
if (vtables.empty() && ContainsSection(vtable_offset)) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
const std::string referring_table_name = table->name()->str();
|
const std::string referring_table_name = table->name()->str();
|
||||||
|
|
||||||
@@ -352,7 +362,7 @@ BinaryAnnotator::VTable *BinaryAnnotator::GetOrBuildVTable(
|
|||||||
uint16_t fields_processed = 0;
|
uint16_t fields_processed = 0;
|
||||||
|
|
||||||
// Loop over all the fields.
|
// Loop over all the fields.
|
||||||
ForAllFields(table, /*reverse=*/false, [&](const reflection::Field *field) {
|
ForAllFields(table, /*reverse=*/false, [&](const reflection::Field* field) {
|
||||||
const uint64_t field_offset = offset_start + field->id() * sizeof(uint16_t);
|
const uint64_t field_offset = offset_start + field->id() * sizeof(uint16_t);
|
||||||
|
|
||||||
if (field_offset >= vtable_offset + vtable_size) {
|
if (field_offset >= vtable_offset + vtable_size) {
|
||||||
@@ -497,8 +507,10 @@ BinaryAnnotator::VTable *BinaryAnnotator::GetOrBuildVTable(
|
|||||||
|
|
||||||
void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
||||||
const BinarySectionType type,
|
const BinarySectionType type,
|
||||||
const reflection::Object *const table) {
|
const reflection::Object* const table) {
|
||||||
if (ContainsSection(table_offset)) { return; }
|
if (ContainsSection(table_offset)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BinaryRegionComment vtable_offset_comment;
|
BinaryRegionComment vtable_offset_comment;
|
||||||
vtable_offset_comment.type = BinaryRegionCommentType::TableVTableOffset;
|
vtable_offset_comment.type = BinaryRegionCommentType::TableVTableOffset;
|
||||||
@@ -548,7 +560,7 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
|||||||
|
|
||||||
// Parse the vtable first so we know what the rest of the fields in the table
|
// Parse the vtable first so we know what the rest of the fields in the table
|
||||||
// are.
|
// are.
|
||||||
const VTable *const vtable =
|
const VTable* const vtable =
|
||||||
GetOrBuildVTable(vtable_offset, table, table_offset);
|
GetOrBuildVTable(vtable_offset, table, table_offset);
|
||||||
|
|
||||||
if (vtable == nullptr) {
|
if (vtable == nullptr) {
|
||||||
@@ -571,18 +583,18 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
|||||||
// not by their IDs. So copy them over to another vector that we can sort on
|
// not by their IDs. So copy them over to another vector that we can sort on
|
||||||
// the offset_from_table property.
|
// the offset_from_table property.
|
||||||
std::vector<VTable::Entry> fields;
|
std::vector<VTable::Entry> fields;
|
||||||
for (const auto &vtable_field : vtable->fields) {
|
for (const auto& vtable_field : vtable->fields) {
|
||||||
fields.push_back(vtable_field.second);
|
fields.push_back(vtable_field.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::stable_sort(fields.begin(), fields.end(),
|
std::stable_sort(fields.begin(), fields.end(),
|
||||||
[](const VTable::Entry &a, const VTable::Entry &b) {
|
[](const VTable::Entry& a, const VTable::Entry& b) {
|
||||||
return a.offset_from_table < b.offset_from_table;
|
return a.offset_from_table < b.offset_from_table;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Iterate over all the fields by order of their offset.
|
// Iterate over all the fields by order of their offset.
|
||||||
for (size_t i = 0; i < fields.size(); ++i) {
|
for (size_t i = 0; i < fields.size(); ++i) {
|
||||||
const reflection::Field *field = fields[i].field;
|
const reflection::Field* field = fields[i].field;
|
||||||
const uint16_t offset_from_table = fields[i].offset_from_table;
|
const uint16_t offset_from_table = fields[i].offset_from_table;
|
||||||
|
|
||||||
if (offset_from_table == 0) {
|
if (offset_from_table == 0) {
|
||||||
@@ -610,7 +622,9 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
|||||||
: table_end_offset) -
|
: table_end_offset) -
|
||||||
field_offset;
|
field_offset;
|
||||||
|
|
||||||
if (unknown_field_length == 0) { continue; }
|
if (unknown_field_length == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
std::string hint;
|
std::string hint;
|
||||||
|
|
||||||
@@ -741,7 +755,7 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
|||||||
|
|
||||||
switch (field->type()->base_type()) {
|
switch (field->type()->base_type()) {
|
||||||
case reflection::BaseType::Obj: {
|
case reflection::BaseType::Obj: {
|
||||||
const reflection::Object *next_object =
|
const reflection::Object* next_object =
|
||||||
schema_->objects()->Get(field->type()->index());
|
schema_->objects()->Get(field->type()->index());
|
||||||
|
|
||||||
if (next_object->is_struct()) {
|
if (next_object->is_struct()) {
|
||||||
@@ -830,7 +844,8 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
|||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,14 +870,16 @@ void BinaryAnnotator::BuildTable(const uint64_t table_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
uint64_t BinaryAnnotator::BuildStruct(const uint64_t struct_offset,
|
uint64_t BinaryAnnotator::BuildStruct(const uint64_t struct_offset,
|
||||||
std::vector<BinaryRegion> ®ions,
|
std::vector<BinaryRegion>& regions,
|
||||||
const std::string referring_field_name,
|
const std::string referring_field_name,
|
||||||
const reflection::Object *const object) {
|
const reflection::Object* const object) {
|
||||||
if (!object->is_struct()) { return struct_offset; }
|
if (!object->is_struct()) {
|
||||||
|
return struct_offset;
|
||||||
|
}
|
||||||
uint64_t offset = struct_offset;
|
uint64_t offset = struct_offset;
|
||||||
|
|
||||||
// Loop over all the fields in increasing order
|
// Loop over all the fields in increasing order
|
||||||
ForAllFields(object, /*reverse=*/false, [&](const reflection::Field *field) {
|
ForAllFields(object, /*reverse=*/false, [&](const reflection::Field* field) {
|
||||||
if (IsScalar(field->type()->base_type())) {
|
if (IsScalar(field->type()->base_type())) {
|
||||||
// Structure Field value
|
// Structure Field value
|
||||||
const uint64_t type_size = GetTypeSize(field->type()->base_type());
|
const uint64_t type_size = GetTypeSize(field->type()->base_type());
|
||||||
@@ -971,11 +988,13 @@ uint64_t BinaryAnnotator::BuildStruct(const uint64_t struct_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BinaryAnnotator::BuildString(const uint64_t string_offset,
|
void BinaryAnnotator::BuildString(const uint64_t string_offset,
|
||||||
const reflection::Object *const table,
|
const reflection::Object* const table,
|
||||||
const reflection::Field *const field) {
|
const reflection::Field* const field) {
|
||||||
// Check if we have already generated this string section, and this is a
|
// Check if we have already generated this string section, and this is a
|
||||||
// shared string instance.
|
// shared string instance.
|
||||||
if (ContainsSection(string_offset)) { return; }
|
if (ContainsSection(string_offset)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<BinaryRegion> regions;
|
std::vector<BinaryRegion> regions;
|
||||||
const auto string_length = ReadScalar<uint32_t>(string_offset);
|
const auto string_length = ReadScalar<uint32_t>(string_offset);
|
||||||
@@ -1034,10 +1053,12 @@ void BinaryAnnotator::BuildString(const uint64_t string_offset,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BinaryAnnotator::BuildVector(
|
void BinaryAnnotator::BuildVector(
|
||||||
const uint64_t vector_offset, const reflection::Object *const table,
|
const uint64_t vector_offset, const reflection::Object* const table,
|
||||||
const reflection::Field *const field, const uint64_t parent_table_offset,
|
const reflection::Field* const field, const uint64_t parent_table_offset,
|
||||||
const std::map<uint16_t, VTable::Entry> vtable_fields) {
|
const std::map<uint16_t, VTable::Entry> vtable_fields) {
|
||||||
if (ContainsSection(vector_offset)) { return; }
|
if (ContainsSection(vector_offset)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
BinaryRegionComment vector_length_comment;
|
BinaryRegionComment vector_length_comment;
|
||||||
vector_length_comment.type = BinaryRegionCommentType::VectorLength;
|
vector_length_comment.type = BinaryRegionCommentType::VectorLength;
|
||||||
@@ -1052,13 +1073,17 @@ void BinaryAnnotator::BuildVector(
|
|||||||
|
|
||||||
if (is_64_bit_vector) {
|
if (is_64_bit_vector) {
|
||||||
auto v = ReadScalar<uint64_t>(vector_offset);
|
auto v = ReadScalar<uint64_t>(vector_offset);
|
||||||
if (v.has_value()) { vector_length = v.value(); }
|
if (v.has_value()) {
|
||||||
|
vector_length = v.value();
|
||||||
|
}
|
||||||
vector_length_size_type = sizeof(uint64_t);
|
vector_length_size_type = sizeof(uint64_t);
|
||||||
region_type = BinaryRegionType::Uint64;
|
region_type = BinaryRegionType::Uint64;
|
||||||
section_type = BinarySectionType::Vector64;
|
section_type = BinarySectionType::Vector64;
|
||||||
} else {
|
} else {
|
||||||
auto v = ReadScalar<uint32_t>(vector_offset);
|
auto v = ReadScalar<uint32_t>(vector_offset);
|
||||||
if (v.has_value()) { vector_length = v.value(); }
|
if (v.has_value()) {
|
||||||
|
vector_length = v.value();
|
||||||
|
}
|
||||||
vector_length_size_type = sizeof(uint32_t);
|
vector_length_size_type = sizeof(uint32_t);
|
||||||
region_type = BinaryRegionType::Uint32;
|
region_type = BinaryRegionType::Uint32;
|
||||||
section_type = BinarySectionType::Vector;
|
section_type = BinarySectionType::Vector;
|
||||||
@@ -1108,7 +1133,7 @@ void BinaryAnnotator::BuildVector(
|
|||||||
|
|
||||||
switch (field->type()->element()) {
|
switch (field->type()->element()) {
|
||||||
case reflection::BaseType::Obj: {
|
case reflection::BaseType::Obj: {
|
||||||
const reflection::Object *object =
|
const reflection::Object* object =
|
||||||
schema_->objects()->Get(field->type()->index());
|
schema_->objects()->Get(field->type()->index());
|
||||||
|
|
||||||
if (object->is_struct()) {
|
if (object->is_struct()) {
|
||||||
@@ -1117,7 +1142,9 @@ void BinaryAnnotator::BuildVector(
|
|||||||
// Structs are inline to the vector.
|
// Structs are inline to the vector.
|
||||||
const uint64_t next_offset =
|
const uint64_t next_offset =
|
||||||
BuildStruct(offset, regions, "[" + NumToString(i) + "]", object);
|
BuildStruct(offset, regions, "[" + NumToString(i) + "]", object);
|
||||||
if (next_offset == offset) { break; }
|
if (next_offset == offset) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
offset = next_offset;
|
offset = next_offset;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1382,18 +1409,20 @@ void BinaryAnnotator::BuildVector(
|
|||||||
|
|
||||||
std::string BinaryAnnotator::BuildUnion(const uint64_t union_offset,
|
std::string BinaryAnnotator::BuildUnion(const uint64_t union_offset,
|
||||||
const uint8_t realized_type,
|
const uint8_t realized_type,
|
||||||
const reflection::Field *const field) {
|
const reflection::Field* const field) {
|
||||||
const reflection::Enum *next_enum =
|
const reflection::Enum* next_enum =
|
||||||
schema_->enums()->Get(field->type()->index());
|
schema_->enums()->Get(field->type()->index());
|
||||||
|
|
||||||
const reflection::EnumVal *enum_val = next_enum->values()->Get(realized_type);
|
const reflection::EnumVal* enum_val = next_enum->values()->Get(realized_type);
|
||||||
|
|
||||||
if (ContainsSection(union_offset)) { return enum_val->name()->c_str(); }
|
if (ContainsSection(union_offset)) {
|
||||||
|
return enum_val->name()->c_str();
|
||||||
|
}
|
||||||
|
|
||||||
const reflection::Type *union_type = enum_val->union_type();
|
const reflection::Type* union_type = enum_val->union_type();
|
||||||
|
|
||||||
if (union_type->base_type() == reflection::BaseType::Obj) {
|
if (union_type->base_type() == reflection::BaseType::Obj) {
|
||||||
const reflection::Object *object =
|
const reflection::Object* object =
|
||||||
schema_->objects()->Get(union_type->index());
|
schema_->objects()->Get(union_type->index());
|
||||||
|
|
||||||
if (object->is_struct()) {
|
if (object->is_struct()) {
|
||||||
@@ -1418,8 +1447,8 @@ std::string BinaryAnnotator::BuildUnion(const uint64_t union_offset,
|
|||||||
|
|
||||||
void BinaryAnnotator::FixMissingRegions() {
|
void BinaryAnnotator::FixMissingRegions() {
|
||||||
std::vector<BinaryRegion> regions_to_insert;
|
std::vector<BinaryRegion> regions_to_insert;
|
||||||
for (auto ¤t_section : sections_) {
|
for (auto& current_section : sections_) {
|
||||||
BinarySection §ion = current_section.second;
|
BinarySection& section = current_section.second;
|
||||||
if (section.regions.empty()) {
|
if (section.regions.empty()) {
|
||||||
// TODO(dbaileychess): is this possible?
|
// TODO(dbaileychess): is this possible?
|
||||||
continue;
|
continue;
|
||||||
@@ -1427,7 +1456,7 @@ void BinaryAnnotator::FixMissingRegions() {
|
|||||||
|
|
||||||
uint64_t offset = section.regions[0].offset + section.regions[0].length;
|
uint64_t offset = section.regions[0].offset + section.regions[0].length;
|
||||||
for (size_t i = 1; i < section.regions.size(); ++i) {
|
for (size_t i = 1; i < section.regions.size(); ++i) {
|
||||||
BinaryRegion ®ion = section.regions[i];
|
BinaryRegion& region = section.regions[i];
|
||||||
|
|
||||||
const uint64_t next_offset = region.offset;
|
const uint64_t next_offset = region.offset;
|
||||||
if (!IsValidOffset(next_offset)) {
|
if (!IsValidOffset(next_offset)) {
|
||||||
@@ -1470,8 +1499,8 @@ void BinaryAnnotator::FixMissingSections() {
|
|||||||
|
|
||||||
std::vector<BinarySection> sections_to_insert;
|
std::vector<BinarySection> sections_to_insert;
|
||||||
|
|
||||||
for (auto ¤t_section : sections_) {
|
for (auto& current_section : sections_) {
|
||||||
BinarySection §ion = current_section.second;
|
BinarySection& section = current_section.second;
|
||||||
const uint64_t section_start_offset = current_section.first;
|
const uint64_t section_start_offset = current_section.first;
|
||||||
const uint64_t section_end_offset =
|
const uint64_t section_end_offset =
|
||||||
section.regions.back().offset + section.regions.back().length;
|
section.regions.back().offset + section.regions.back().length;
|
||||||
@@ -1494,7 +1523,7 @@ void BinaryAnnotator::FixMissingSections() {
|
|||||||
GenerateMissingSection(offset - 1, pad_bytes, binary_));
|
GenerateMissingSection(offset - 1, pad_bytes, binary_));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const BinarySection §ion_to_insert : sections_to_insert) {
|
for (const BinarySection& section_to_insert : sections_to_insert) {
|
||||||
AddSection(section_to_insert.regions[0].offset, section_to_insert);
|
AddSection(section_to_insert.regions[0].offset, section_to_insert);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1502,11 +1531,15 @@ void BinaryAnnotator::FixMissingSections() {
|
|||||||
bool BinaryAnnotator::ContainsSection(const uint64_t offset) {
|
bool BinaryAnnotator::ContainsSection(const uint64_t offset) {
|
||||||
auto it = sections_.lower_bound(offset);
|
auto it = sections_.lower_bound(offset);
|
||||||
// If the section is found, check that it is exactly equal its offset.
|
// If the section is found, check that it is exactly equal its offset.
|
||||||
if (it != sections_.end() && it->first == offset) { return true; }
|
if (it != sections_.end() && it->first == offset) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// If this was the first section, there are no other previous sections to
|
// If this was the first section, there are no other previous sections to
|
||||||
// check.
|
// check.
|
||||||
if (it == sections_.begin()) { return false; }
|
if (it == sections_.begin()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Go back one section.
|
// Go back one section.
|
||||||
--it;
|
--it;
|
||||||
@@ -1516,7 +1549,7 @@ bool BinaryAnnotator::ContainsSection(const uint64_t offset) {
|
|||||||
it->second.regions.back().length;
|
it->second.regions.back().length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const reflection::Object *BinaryAnnotator::RootTable() const {
|
const reflection::Object* BinaryAnnotator::RootTable() const {
|
||||||
if (!root_table_.empty()) {
|
if (!root_table_.empty()) {
|
||||||
return schema_->objects()->LookupByKey(root_table_);
|
return schema_->objects()->LookupByKey(root_table_);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,21 +24,21 @@
|
|||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(push)
|
#pragma warning(push)
|
||||||
# pragma warning(disable : 4127) // C4127: conditional expression is constant
|
#pragma warning(disable : 4127) // C4127: conditional expression is constant
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
std::string JavaCSharpMakeRule(const bool java, const Parser &parser,
|
std::string JavaCSharpMakeRule(const bool java, const Parser& parser,
|
||||||
const std::string &path,
|
const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
const std::string file_extension = java ? ".java" : ".cs";
|
const std::string file_extension = java ? ".java" : ".cs";
|
||||||
std::string make_rule;
|
std::string make_rule;
|
||||||
|
|
||||||
for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
|
for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &enum_def = **it;
|
auto& enum_def = **it;
|
||||||
if (!make_rule.empty()) make_rule += " ";
|
if (!make_rule.empty()) make_rule += " ";
|
||||||
std::string directory =
|
std::string directory =
|
||||||
BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
|
BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
|
||||||
@@ -47,7 +47,7 @@ std::string JavaCSharpMakeRule(const bool java, const Parser &parser,
|
|||||||
|
|
||||||
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
|
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
if (!make_rule.empty()) make_rule += " ";
|
if (!make_rule.empty()) make_rule += " ";
|
||||||
std::string directory = BaseGenerator::NamespaceDir(
|
std::string directory = BaseGenerator::NamespaceDir(
|
||||||
parser, path, *struct_def.defined_namespace);
|
parser, path, *struct_def.defined_namespace);
|
||||||
@@ -67,10 +67,14 @@ void CodeWriter::operator+=(std::string text) {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
auto begin = text.find("{{");
|
auto begin = text.find("{{");
|
||||||
if (begin == std::string::npos) { break; }
|
if (begin == std::string::npos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
auto end = text.find("}}");
|
auto end = text.find("}}");
|
||||||
if (end == std::string::npos || end < begin) { break; }
|
if (end == std::string::npos || end < begin) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Write all the text before the first {{ into the stream.
|
// Write all the text before the first {{ into the stream.
|
||||||
stream_.write(text.c_str(), begin);
|
stream_.write(text.c_str(), begin);
|
||||||
@@ -82,7 +86,7 @@ void CodeWriter::operator+=(std::string text) {
|
|||||||
// value into the stream, otherwise write the key itself into the stream.
|
// value into the stream, otherwise write the key itself into the stream.
|
||||||
auto iter = value_map_.find(key);
|
auto iter = value_map_.find(key);
|
||||||
if (iter != value_map_.end()) {
|
if (iter != value_map_.end()) {
|
||||||
const std::string &value = iter->second;
|
const std::string& value = iter->second;
|
||||||
stream_ << value;
|
stream_ << value;
|
||||||
} else {
|
} else {
|
||||||
FLATBUFFERS_ASSERT(false && "could not find key");
|
FLATBUFFERS_ASSERT(false && "could not find key");
|
||||||
@@ -102,26 +106,26 @@ void CodeWriter::operator+=(std::string text) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CodeWriter::AppendIdent(std::stringstream &stream) {
|
void CodeWriter::AppendIdent(std::stringstream& stream) {
|
||||||
int lvl = cur_ident_lvl_;
|
int lvl = cur_ident_lvl_;
|
||||||
while (lvl--) {
|
while (lvl--) {
|
||||||
stream.write(pad_.c_str(), static_cast<std::streamsize>(pad_.size()));
|
stream.write(pad_.c_str(), static_cast<std::streamsize>(pad_.size()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *BaseGenerator::FlatBuffersGeneratedWarning() {
|
const char* BaseGenerator::FlatBuffersGeneratedWarning() {
|
||||||
return "automatically generated by the FlatBuffers compiler,"
|
return "automatically generated by the FlatBuffers compiler,"
|
||||||
" do not modify";
|
" do not modify";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::NamespaceDir(const Parser &parser,
|
std::string BaseGenerator::NamespaceDir(const Parser& parser,
|
||||||
const std::string &path,
|
const std::string& path,
|
||||||
const Namespace &ns,
|
const Namespace& ns,
|
||||||
const bool dasherize) {
|
const bool dasherize) {
|
||||||
EnsureDirExists(path);
|
EnsureDirExists(path);
|
||||||
if (parser.opts.one_file) return path;
|
if (parser.opts.one_file) return path;
|
||||||
std::string namespace_dir = path; // Either empty or ends in separator.
|
std::string namespace_dir = path; // Either empty or ends in separator.
|
||||||
auto &namespaces = ns.components;
|
auto& namespaces = ns.components;
|
||||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||||
namespace_dir +=
|
namespace_dir +=
|
||||||
!dasherize ? *it : ConvertCase(*it, Case::kDasher, Case::kUpperCamel);
|
!dasherize ? *it : ConvertCase(*it, Case::kDasher, Case::kUpperCamel);
|
||||||
@@ -131,15 +135,15 @@ std::string BaseGenerator::NamespaceDir(const Parser &parser,
|
|||||||
return namespace_dir;
|
return namespace_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::NamespaceDir(const Namespace &ns,
|
std::string BaseGenerator::NamespaceDir(const Namespace& ns,
|
||||||
const bool dasherize) const {
|
const bool dasherize) const {
|
||||||
return BaseGenerator::NamespaceDir(parser_, path_, ns, dasherize);
|
return BaseGenerator::NamespaceDir(parser_, path_, ns, dasherize);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::FullNamespace(const char *separator,
|
std::string BaseGenerator::FullNamespace(const char* separator,
|
||||||
const Namespace &ns) {
|
const Namespace& ns) {
|
||||||
std::string namespace_name;
|
std::string namespace_name;
|
||||||
auto &namespaces = ns.components;
|
auto& namespaces = ns.components;
|
||||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||||
if (namespace_name.length()) namespace_name += separator;
|
if (namespace_name.length()) namespace_name += separator;
|
||||||
namespace_name += *it;
|
namespace_name += *it;
|
||||||
@@ -147,7 +151,7 @@ std::string BaseGenerator::FullNamespace(const char *separator,
|
|||||||
return namespace_name;
|
return namespace_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::LastNamespacePart(const Namespace &ns) {
|
std::string BaseGenerator::LastNamespacePart(const Namespace& ns) {
|
||||||
if (!ns.components.empty())
|
if (!ns.components.empty())
|
||||||
return ns.components.back();
|
return ns.components.back();
|
||||||
else
|
else
|
||||||
@@ -155,21 +159,21 @@ std::string BaseGenerator::LastNamespacePart(const Namespace &ns) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure that a type is prefixed with its namespace.
|
// Ensure that a type is prefixed with its namespace.
|
||||||
std::string BaseGenerator::WrapInNameSpace(const Namespace *ns,
|
std::string BaseGenerator::WrapInNameSpace(const Namespace* ns,
|
||||||
const std::string &name) const {
|
const std::string& name) const {
|
||||||
std::string qualified_name = qualifying_start_;
|
std::string qualified_name = qualifying_start_;
|
||||||
for (auto it = ns->components.begin(); it != ns->components.end(); ++it)
|
for (auto it = ns->components.begin(); it != ns->components.end(); ++it)
|
||||||
qualified_name += *it + qualifying_separator_;
|
qualified_name += *it + qualifying_separator_;
|
||||||
return qualified_name + name;
|
return qualified_name + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::WrapInNameSpace(const Definition &def,
|
std::string BaseGenerator::WrapInNameSpace(const Definition& def,
|
||||||
const std::string &suffix) const {
|
const std::string& suffix) const {
|
||||||
return WrapInNameSpace(def.defined_namespace, def.name + suffix);
|
return WrapInNameSpace(def.defined_namespace, def.name + suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::GetNameSpace(const Definition &def) const {
|
std::string BaseGenerator::GetNameSpace(const Definition& def) const {
|
||||||
const Namespace *ns = def.defined_namespace;
|
const Namespace* ns = def.defined_namespace;
|
||||||
if (CurrentNameSpace() == ns) return "";
|
if (CurrentNameSpace() == ns) return "";
|
||||||
std::string qualified_name = qualifying_start_;
|
std::string qualified_name = qualifying_start_;
|
||||||
for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
|
for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
|
||||||
@@ -182,23 +186,23 @@ std::string BaseGenerator::GetNameSpace(const Definition &def) const {
|
|||||||
return qualified_name;
|
return qualified_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseGenerator::GeneratedFileName(const std::string &path,
|
std::string BaseGenerator::GeneratedFileName(const std::string& path,
|
||||||
const std::string &file_name,
|
const std::string& file_name,
|
||||||
const IDLOptions &options) const {
|
const IDLOptions& options) const {
|
||||||
return path + file_name + options.filename_suffix + "." +
|
return path + file_name + options.filename_suffix + "." +
|
||||||
(options.filename_extension.empty() ? default_extension_
|
(options.filename_extension.empty() ? default_extension_
|
||||||
: options.filename_extension);
|
: options.filename_extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a documentation comment, if available.
|
// Generate a documentation comment, if available.
|
||||||
void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
|
void GenComment(const std::vector<std::string>& dc, std::string* code_ptr,
|
||||||
const CommentConfig *config, const char *prefix) {
|
const CommentConfig* config, const char* prefix) {
|
||||||
if (dc.begin() == dc.end()) {
|
if (dc.begin() == dc.end()) {
|
||||||
// Don't output empty comment blocks with 0 lines of comment content.
|
// Don't output empty comment blocks with 0 lines of comment content.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
if (config != nullptr && config->first_line != nullptr) {
|
if (config != nullptr && config->first_line != nullptr) {
|
||||||
code += std::string(prefix) + std::string(config->first_line) + "\n";
|
code += std::string(prefix) + std::string(config->first_line) + "\n";
|
||||||
}
|
}
|
||||||
@@ -215,10 +219,10 @@ void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
std::string FloatConstantGenerator::GenFloatConstantImpl(
|
std::string FloatConstantGenerator::GenFloatConstantImpl(
|
||||||
const FieldDef &field) const {
|
const FieldDef& field) const {
|
||||||
const auto &constant = field.value.constant;
|
const auto& constant = field.value.constant;
|
||||||
T v;
|
T v;
|
||||||
auto done = StringToNumber(constant.c_str(), &v);
|
auto done = StringToNumber(constant.c_str(), &v);
|
||||||
FLATBUFFERS_ASSERT(done);
|
FLATBUFFERS_ASSERT(done);
|
||||||
@@ -233,10 +237,12 @@ std::string FloatConstantGenerator::GenFloatConstantImpl(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string FloatConstantGenerator::GenFloatConstant(
|
std::string FloatConstantGenerator::GenFloatConstant(
|
||||||
const FieldDef &field) const {
|
const FieldDef& field) const {
|
||||||
switch (field.value.type.base_type) {
|
switch (field.value.type.base_type) {
|
||||||
case BASE_TYPE_FLOAT: return GenFloatConstantImpl<float>(field);
|
case BASE_TYPE_FLOAT:
|
||||||
case BASE_TYPE_DOUBLE: return GenFloatConstantImpl<double>(field);
|
return GenFloatConstantImpl<float>(field);
|
||||||
|
case BASE_TYPE_DOUBLE:
|
||||||
|
return GenFloatConstantImpl<double>(field);
|
||||||
default: {
|
default: {
|
||||||
FLATBUFFERS_ASSERT(false);
|
FLATBUFFERS_ASSERT(false);
|
||||||
return "INVALID_BASE_TYPE";
|
return "INVALID_BASE_TYPE";
|
||||||
@@ -245,9 +251,9 @@ std::string FloatConstantGenerator::GenFloatConstant(
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypedFloatConstantGenerator::TypedFloatConstantGenerator(
|
TypedFloatConstantGenerator::TypedFloatConstantGenerator(
|
||||||
const char *double_prefix, const char *single_prefix,
|
const char* double_prefix, const char* single_prefix,
|
||||||
const char *nan_number, const char *pos_inf_number,
|
const char* nan_number, const char* pos_inf_number,
|
||||||
const char *neg_inf_number)
|
const char* neg_inf_number)
|
||||||
: double_prefix_(double_prefix),
|
: double_prefix_(double_prefix),
|
||||||
single_prefix_(single_prefix),
|
single_prefix_(single_prefix),
|
||||||
nan_number_(nan_number),
|
nan_number_(nan_number),
|
||||||
@@ -255,11 +261,11 @@ TypedFloatConstantGenerator::TypedFloatConstantGenerator(
|
|||||||
neg_inf_number_(neg_inf_number) {}
|
neg_inf_number_(neg_inf_number) {}
|
||||||
|
|
||||||
std::string TypedFloatConstantGenerator::MakeNaN(
|
std::string TypedFloatConstantGenerator::MakeNaN(
|
||||||
const std::string &prefix) const {
|
const std::string& prefix) const {
|
||||||
return prefix + nan_number_;
|
return prefix + nan_number_;
|
||||||
}
|
}
|
||||||
std::string TypedFloatConstantGenerator::MakeInf(
|
std::string TypedFloatConstantGenerator::MakeInf(
|
||||||
bool neg, const std::string &prefix) const {
|
bool neg, const std::string& prefix) const {
|
||||||
if (neg)
|
if (neg)
|
||||||
return !neg_inf_number_.empty() ? (prefix + neg_inf_number_)
|
return !neg_inf_number_.empty() ? (prefix + neg_inf_number_)
|
||||||
: ("-" + prefix + pos_inf_number_);
|
: ("-" + prefix + pos_inf_number_);
|
||||||
@@ -268,7 +274,7 @@ std::string TypedFloatConstantGenerator::MakeInf(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string TypedFloatConstantGenerator::Value(double v,
|
std::string TypedFloatConstantGenerator::Value(double v,
|
||||||
const std::string &src) const {
|
const std::string& src) const {
|
||||||
(void)v;
|
(void)v;
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
@@ -283,7 +289,7 @@ std::string TypedFloatConstantGenerator::NaN(double v) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string TypedFloatConstantGenerator::Value(float v,
|
std::string TypedFloatConstantGenerator::Value(float v,
|
||||||
const std::string &src) const {
|
const std::string& src) const {
|
||||||
(void)v;
|
(void)v;
|
||||||
return src + "f";
|
return src + "f";
|
||||||
}
|
}
|
||||||
@@ -298,14 +304,14 @@ std::string TypedFloatConstantGenerator::NaN(float v) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SimpleFloatConstantGenerator::SimpleFloatConstantGenerator(
|
SimpleFloatConstantGenerator::SimpleFloatConstantGenerator(
|
||||||
const char *nan_number, const char *pos_inf_number,
|
const char* nan_number, const char* pos_inf_number,
|
||||||
const char *neg_inf_number)
|
const char* neg_inf_number)
|
||||||
: nan_number_(nan_number),
|
: nan_number_(nan_number),
|
||||||
pos_inf_number_(pos_inf_number),
|
pos_inf_number_(pos_inf_number),
|
||||||
neg_inf_number_(neg_inf_number) {}
|
neg_inf_number_(neg_inf_number) {}
|
||||||
|
|
||||||
std::string SimpleFloatConstantGenerator::Value(double v,
|
std::string SimpleFloatConstantGenerator::Value(double v,
|
||||||
const std::string &src) const {
|
const std::string& src) const {
|
||||||
(void)v;
|
(void)v;
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
@@ -320,7 +326,7 @@ std::string SimpleFloatConstantGenerator::NaN(double v) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string SimpleFloatConstantGenerator::Value(float v,
|
std::string SimpleFloatConstantGenerator::Value(float v,
|
||||||
const std::string &src) const {
|
const std::string& src) const {
|
||||||
return this->Value(static_cast<double>(v), src);
|
return this->Value(static_cast<double>(v), src);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,5 +341,5 @@ std::string SimpleFloatConstantGenerator::NaN(float v) const {
|
|||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
class FileBinaryWriter : public FileManager {
|
class FileBinaryWriter : public FileManager {
|
||||||
public:
|
public:
|
||||||
bool SaveFile(const std::string &absolute_file_name,
|
bool SaveFile(const std::string& absolute_file_name,
|
||||||
const std::string &content) override {
|
const std::string& content) override {
|
||||||
std::ofstream ofs(absolute_file_name, std::ofstream::binary);
|
std::ofstream ofs(absolute_file_name, std::ofstream::binary);
|
||||||
if (!ofs.is_open()) return false;
|
if (!ofs.is_open()) return false;
|
||||||
ofs.write(content.c_str(), content.size());
|
ofs.write(content.c_str(), content.size());
|
||||||
return !ofs.bad();
|
return !ofs.bad();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Loadfile(const std::string &absolute_file_name, std::string *output) {
|
bool Loadfile(const std::string& absolute_file_name, std::string* output) {
|
||||||
if (DirExists(absolute_file_name.c_str())) return false;
|
if (DirExists(absolute_file_name.c_str())) return false;
|
||||||
std::ifstream ifs(absolute_file_name, std::ifstream::binary);
|
std::ifstream ifs(absolute_file_name, std::ifstream::binary);
|
||||||
if (!ifs.is_open()) return false;
|
if (!ifs.is_open()) return false;
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ class FileNameSavingFileManager : public FileManager {
|
|||||||
FileNameSavingFileManager(std::set<std::string> file_names)
|
FileNameSavingFileManager(std::set<std::string> file_names)
|
||||||
: file_names_(file_names) {}
|
: file_names_(file_names) {}
|
||||||
|
|
||||||
bool SaveFile(const std::string &absolute_file_name,
|
bool SaveFile(const std::string& absolute_file_name,
|
||||||
const std::string &content) override {
|
const std::string& content) override {
|
||||||
(void)content;
|
(void)content;
|
||||||
auto pair = file_names_.insert(absolute_file_name);
|
auto pair = file_names_.insert(absolute_file_name);
|
||||||
// pair.second indicates whether the insertion is
|
// pair.second indicates whether the insertion is
|
||||||
@@ -36,7 +36,7 @@ class FileNameSavingFileManager : public FileManager {
|
|||||||
return pair.second;
|
return pair.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Loadfile(const std::string &absolute_file_name, std::string *content) {
|
bool Loadfile(const std::string& absolute_file_name, std::string* content) {
|
||||||
(void)absolute_file_name;
|
(void)absolute_file_name;
|
||||||
(void)content;
|
(void)content;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -24,15 +24,15 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
class FileWriter : public FileManager {
|
class FileWriter : public FileManager {
|
||||||
public:
|
public:
|
||||||
bool SaveFile(const std::string &absolute_file_name,
|
bool SaveFile(const std::string& absolute_file_name,
|
||||||
const std::string &content) override {
|
const std::string& content) override {
|
||||||
std::ofstream ofs(absolute_file_name, std::ofstream::out);
|
std::ofstream ofs(absolute_file_name, std::ofstream::out);
|
||||||
if (!ofs.is_open()) return false;
|
if (!ofs.is_open()) return false;
|
||||||
ofs.write(content.c_str(), content.size());
|
ofs.write(content.c_str(), content.size());
|
||||||
return !ofs.bad();
|
return !ofs.bad();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Loadfile(const std::string &absolute_file_name, std::string *output) {
|
bool Loadfile(const std::string& absolute_file_name, std::string* output) {
|
||||||
if (DirExists(absolute_file_name.c_str())) return false;
|
if (DirExists(absolute_file_name.c_str())) return false;
|
||||||
std::ifstream ifs(absolute_file_name, std::ifstream::in);
|
std::ifstream ifs(absolute_file_name, std::ifstream::in);
|
||||||
if (!ifs.is_open()) return false;
|
if (!ifs.is_open()) return false;
|
||||||
|
|||||||
435
src/flatc.cpp
435
src/flatc.cpp
@@ -31,15 +31,15 @@
|
|||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
static const char *FLATC_VERSION() { return FLATBUFFERS_VERSION(); }
|
static const char* FLATC_VERSION() { return FLATBUFFERS_VERSION(); }
|
||||||
|
|
||||||
void FlatCompiler::ParseFile(
|
void FlatCompiler::ParseFile(
|
||||||
flatbuffers::Parser &parser, const std::string &filename,
|
flatbuffers::Parser& parser, const std::string& filename,
|
||||||
const std::string &contents,
|
const std::string& contents,
|
||||||
const std::vector<const char *> &include_directories) const {
|
const std::vector<const char*>& include_directories) const {
|
||||||
auto local_include_directory = flatbuffers::StripFileName(filename);
|
auto local_include_directory = flatbuffers::StripFileName(filename);
|
||||||
|
|
||||||
std::vector<const char *> inc_directories;
|
std::vector<const char*> inc_directories;
|
||||||
inc_directories.insert(inc_directories.end(), include_directories.begin(),
|
inc_directories.insert(inc_directories.end(), include_directories.begin(),
|
||||||
include_directories.end());
|
include_directories.end());
|
||||||
inc_directories.push_back(local_include_directory.c_str());
|
inc_directories.push_back(local_include_directory.c_str());
|
||||||
@@ -48,238 +48,246 @@ void FlatCompiler::ParseFile(
|
|||||||
if (!parser.Parse(contents.c_str(), &inc_directories[0], filename.c_str())) {
|
if (!parser.Parse(contents.c_str(), &inc_directories[0], filename.c_str())) {
|
||||||
Error(parser.error_, false, false);
|
Error(parser.error_, false, false);
|
||||||
}
|
}
|
||||||
if (!parser.error_.empty()) { Warn(parser.error_, false); }
|
if (!parser.error_.empty()) {
|
||||||
|
Warn(parser.error_, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatCompiler::LoadBinarySchema(flatbuffers::Parser &parser,
|
void FlatCompiler::LoadBinarySchema(flatbuffers::Parser& parser,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
const std::string &contents) {
|
const std::string& contents) {
|
||||||
if (!parser.Deserialize(reinterpret_cast<const uint8_t *>(contents.c_str()),
|
if (!parser.Deserialize(reinterpret_cast<const uint8_t*>(contents.c_str()),
|
||||||
contents.size())) {
|
contents.size())) {
|
||||||
Error("failed to load binary schema: " + filename, false, false);
|
Error("failed to load binary schema: " + filename, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatCompiler::Warn(const std::string &warn, bool show_exe_name) const {
|
void FlatCompiler::Warn(const std::string& warn, bool show_exe_name) const {
|
||||||
params_.warn_fn(this, warn, show_exe_name);
|
params_.warn_fn(this, warn, show_exe_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatCompiler::Error(const std::string &err, bool usage,
|
void FlatCompiler::Error(const std::string& err, bool usage,
|
||||||
bool show_exe_name) const {
|
bool show_exe_name) const {
|
||||||
params_.error_fn(this, err, usage, show_exe_name);
|
params_.error_fn(this, err, usage, show_exe_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const static FlatCOption flatc_options[] = {
|
const static FlatCOption flatc_options[] = {
|
||||||
{ "o", "", "PATH", "Prefix PATH to all generated files." },
|
{"o", "", "PATH", "Prefix PATH to all generated files."},
|
||||||
{ "I", "", "PATH", "Search for includes in the specified path." },
|
{"I", "", "PATH", "Search for includes in the specified path."},
|
||||||
{ "M", "", "", "Print make rules for generated files." },
|
{"M", "", "", "Print make rules for generated files."},
|
||||||
{ "", "version", "", "Print the version number of flatc and exit." },
|
{"", "version", "", "Print the version number of flatc and exit."},
|
||||||
{ "h", "help", "", "Prints this help text and exit." },
|
{"h", "help", "", "Prints this help text and exit."},
|
||||||
{ "", "strict-json", "",
|
{"", "strict-json", "",
|
||||||
"Strict JSON: field names must be / will be quoted, no trailing commas in "
|
"Strict JSON: field names must be / will be quoted, no trailing commas in "
|
||||||
"tables/vectors." },
|
"tables/vectors."},
|
||||||
{ "", "allow-non-utf8", "",
|
{"", "allow-non-utf8", "",
|
||||||
"Pass non-UTF-8 input through parser and emit nonstandard \\x escapes in "
|
"Pass non-UTF-8 input through parser and emit nonstandard \\x escapes in "
|
||||||
"JSON. (Default is to raise parse error on non-UTF-8 input.)" },
|
"JSON. (Default is to raise parse error on non-UTF-8 input.)"},
|
||||||
{ "", "natural-utf8", "",
|
{"", "natural-utf8", "",
|
||||||
"Output strings with UTF-8 as human-readable strings. By default, UTF-8 "
|
"Output strings with UTF-8 as human-readable strings. By default, UTF-8 "
|
||||||
"characters are printed as \\uXXXX escapes." },
|
"characters are printed as \\uXXXX escapes."},
|
||||||
{ "", "defaults-json", "",
|
{"", "defaults-json", "",
|
||||||
"Output fields whose value is the default when writing JSON" },
|
"Output fields whose value is the default when writing JSON"},
|
||||||
{ "", "unknown-json", "",
|
{"", "unknown-json", "",
|
||||||
"Allow fields in JSON that are not defined in the schema. These fields "
|
"Allow fields in JSON that are not defined in the schema. These fields "
|
||||||
"will be discarded when generating binaries." },
|
"will be discarded when generating binaries."},
|
||||||
{ "", "no-prefix", "",
|
{"", "no-prefix", "",
|
||||||
"Don't prefix enum values with the enum type in C++." },
|
"Don't prefix enum values with the enum type in C++."},
|
||||||
{ "", "scoped-enums", "",
|
{"", "scoped-enums", "",
|
||||||
"Use C++11 style scoped and strongly typed enums. Also implies "
|
"Use C++11 style scoped and strongly typed enums. Also implies "
|
||||||
"--no-prefix." },
|
"--no-prefix."},
|
||||||
{ "", "no-emit-min-max-enum-values", "",
|
{"", "no-emit-min-max-enum-values", "",
|
||||||
"Disable generation of MIN and MAX enumerated values for scoped enums "
|
"Disable generation of MIN and MAX enumerated values for scoped enums "
|
||||||
"and prefixed enums." },
|
"and prefixed enums."},
|
||||||
{ "", "swift-implementation-only", "",
|
{"", "swift-implementation-only", "",
|
||||||
"Adds a @_implementationOnly to swift imports" },
|
"Adds a @_implementationOnly to swift imports"},
|
||||||
{ "", "gen-includes", "",
|
{"", "gen-includes", "",
|
||||||
"(deprecated), this is the default behavior. If the original behavior is "
|
"(deprecated), this is the default behavior. If the original behavior is "
|
||||||
"required (no include statements) use --no-includes." },
|
"required (no include statements) use --no-includes."},
|
||||||
{ "", "no-includes", "",
|
{"", "no-includes", "",
|
||||||
"Don't generate include statements for included schemas the generated "
|
"Don't generate include statements for included schemas the generated "
|
||||||
"file depends on (C++, Python, Proto-to-Fbs)." },
|
"file depends on (C++, Python, Proto-to-Fbs)."},
|
||||||
{ "", "gen-mutable", "",
|
{"", "gen-mutable", "",
|
||||||
"Generate accessors that can mutate buffers in-place." },
|
"Generate accessors that can mutate buffers in-place."},
|
||||||
{ "", "gen-onefile", "",
|
{"", "gen-onefile", "",
|
||||||
"Generate a single output file for C#, Go, Java, Kotlin and Python. "
|
"Generate a single output file for C#, Go, Java, Kotlin and Python. "
|
||||||
"Implies --no-include." },
|
"Implies --no-include."},
|
||||||
{ "", "gen-name-strings", "",
|
{"", "gen-name-strings", "",
|
||||||
"Generate type name functions for C++ and Rust." },
|
"Generate type name functions for C++ and Rust."},
|
||||||
{ "", "gen-object-api", "", "Generate an additional object-based API." },
|
{"", "gen-object-api", "", "Generate an additional object-based API."},
|
||||||
{ "", "gen-compare", "", "Generate operator== for object-based API types." },
|
{"", "gen-compare", "", "Generate operator== for object-based API types."},
|
||||||
{ "", "gen-nullable", "",
|
{"", "gen-nullable", "",
|
||||||
"Add Clang _Nullable for C++ pointer. or @Nullable for Java" },
|
"Add Clang _Nullable for C++ pointer. or @Nullable for Java"},
|
||||||
{ "", "java-package-prefix", "",
|
{"", "java-package-prefix", "",
|
||||||
"Add a prefix to the generated package name for Java." },
|
"Add a prefix to the generated package name for Java."},
|
||||||
{ "", "java-checkerframework", "", "Add @Pure for Java." },
|
{"", "java-checkerframework", "", "Add @Pure for Java."},
|
||||||
{ "", "gen-generated", "", "Add @Generated annotation for Java." },
|
{"", "gen-generated", "", "Add @Generated annotation for Java."},
|
||||||
{ "", "gen-jvmstatic", "",
|
{"", "gen-jvmstatic", "",
|
||||||
"Add @JvmStatic annotation for Kotlin methods in companion object for "
|
"Add @JvmStatic annotation for Kotlin methods in companion object for "
|
||||||
"interop from Java to Kotlin." },
|
"interop from Java to Kotlin."},
|
||||||
{ "", "gen-all", "",
|
{"", "gen-all", "",
|
||||||
"Generate not just code for the current schema files, but for all files it "
|
"Generate not just code for the current schema files, but for all files "
|
||||||
|
"it "
|
||||||
"includes as well. If the language uses a single file for output (by "
|
"includes as well. If the language uses a single file for output (by "
|
||||||
"default the case for C++ and JS), all code will end up in this one "
|
"default the case for C++ and JS), all code will end up in this one "
|
||||||
"file." },
|
"file."},
|
||||||
{ "", "gen-json-emit", "",
|
{"", "gen-json-emit", "",
|
||||||
"Generates encoding code which emits Flatbuffers into JSON" },
|
"Generates encoding code which emits Flatbuffers into JSON"},
|
||||||
{ "", "cpp-include", "", "Adds an #include in generated file." },
|
{"", "cpp-include", "", "Adds an #include in generated file."},
|
||||||
{ "", "cpp-ptr-type", "T",
|
{"", "cpp-ptr-type", "T",
|
||||||
"Set object API pointer type (default std::unique_ptr)." },
|
"Set object API pointer type (default std::unique_ptr)."},
|
||||||
{ "", "cpp-str-type", "T",
|
{"", "cpp-str-type", "T",
|
||||||
"Set object API string type (default std::string). T::c_str(), T::length() "
|
"Set object API string type (default std::string). T::c_str(), "
|
||||||
|
"T::length() "
|
||||||
"and T::empty() must be supported. The custom type also needs to be "
|
"and T::empty() must be supported. The custom type also needs to be "
|
||||||
"constructible from std::string (see the --cpp-str-flex-ctor option to "
|
"constructible from std::string (see the --cpp-str-flex-ctor option to "
|
||||||
"change this behavior)" },
|
"change this behavior)"},
|
||||||
{ "", "cpp-str-flex-ctor", "",
|
{"", "cpp-str-flex-ctor", "",
|
||||||
"Don't construct custom string types by passing std::string from "
|
"Don't construct custom string types by passing std::string from "
|
||||||
"Flatbuffers, but (char* + length)." },
|
"Flatbuffers, but (char* + length)."},
|
||||||
{ "", "cpp-field-case-style", "STYLE",
|
{"", "cpp-field-case-style", "STYLE",
|
||||||
"Generate C++ fields using selected case style. Supported STYLE values: * "
|
"Generate C++ fields using selected case style. Supported STYLE values: * "
|
||||||
"'unchanged' - leave unchanged (default) * 'upper' - schema snake_case "
|
"'unchanged' - leave unchanged (default) * 'upper' - schema snake_case "
|
||||||
"emits UpperCamel; * 'lower' - schema snake_case emits lowerCamel." },
|
"emits UpperCamel; * 'lower' - schema snake_case emits lowerCamel."},
|
||||||
{ "", "cpp-std", "CPP_STD",
|
{"", "cpp-std", "CPP_STD",
|
||||||
"Generate a C++ code using features of selected C++ standard. Supported "
|
"Generate a C++ code using features of selected C++ standard. Supported "
|
||||||
"CPP_STD values: * 'c++0x' - generate code compatible with old compilers; "
|
"CPP_STD values: * 'c++0x' - generate code compatible with old compilers; "
|
||||||
"'c++11' - use C++11 code generator (default); * 'c++17' - use C++17 "
|
"'c++11' - use C++11 code generator (default); * 'c++17' - use C++17 "
|
||||||
"features in generated code (experimental)." },
|
"features in generated code (experimental)."},
|
||||||
{ "", "cpp-static-reflection", "",
|
{"", "cpp-static-reflection", "",
|
||||||
"When using C++17, generate extra code to provide compile-time (static) "
|
"When using C++17, generate extra code to provide compile-time (static) "
|
||||||
"reflection of Flatbuffers types. Requires --cpp-std to be \"c++17\" or "
|
"reflection of Flatbuffers types. Requires --cpp-std to be \"c++17\" or "
|
||||||
"higher." },
|
"higher."},
|
||||||
{ "", "object-prefix", "PREFIX",
|
{"", "object-prefix", "PREFIX",
|
||||||
"Customize class prefix for C++ object-based API." },
|
"Customize class prefix for C++ object-based API."},
|
||||||
{ "", "object-suffix", "SUFFIX",
|
{"", "object-suffix", "SUFFIX",
|
||||||
"Customize class suffix for C++ object-based API. Default Value is "
|
"Customize class suffix for C++ object-based API. Default Value is "
|
||||||
"\"T\"." },
|
"\"T\"."},
|
||||||
{ "", "go-namespace", "", "Generate the overriding namespace in Golang." },
|
{"", "go-namespace", "", "Generate the overriding namespace in Golang."},
|
||||||
{ "", "go-import", "IMPORT",
|
{"", "go-import", "IMPORT",
|
||||||
"Generate the overriding import for flatbuffers in Golang (default is "
|
"Generate the overriding import for flatbuffers in Golang (default is "
|
||||||
"\"github.com/google/flatbuffers/go\")." },
|
"\"github.com/google/flatbuffers/go\")."},
|
||||||
{ "", "go-module-name", "",
|
{"", "go-module-name", "",
|
||||||
"Prefix local import paths of generated go code with the module name" },
|
"Prefix local import paths of generated go code with the module name"},
|
||||||
{ "", "raw-binary", "",
|
{"", "raw-binary", "",
|
||||||
"Allow binaries without file_identifier to be read. This may crash flatc "
|
"Allow binaries without file_identifier to be read. This may crash flatc "
|
||||||
"given a mismatched schema." },
|
"given a mismatched schema."},
|
||||||
{ "", "size-prefixed", "", "Input binaries are size prefixed buffers." },
|
{"", "size-prefixed", "", "Input binaries are size prefixed buffers."},
|
||||||
{ "", "proto-namespace-suffix", "SUFFIX",
|
{"", "proto-namespace-suffix", "SUFFIX",
|
||||||
"Add this namespace to any flatbuffers generated from protobufs." },
|
"Add this namespace to any flatbuffers generated from protobufs."},
|
||||||
{ "", "oneof-union", "", "Translate .proto oneofs to flatbuffer unions." },
|
{"", "oneof-union", "", "Translate .proto oneofs to flatbuffer unions."},
|
||||||
{ "", "keep-proto-id", "", "Keep protobuf field ids in generated fbs file." },
|
{"", "keep-proto-id", "", "Keep protobuf field ids in generated fbs file."},
|
||||||
{ "", "proto-id-gap", "",
|
{"", "proto-id-gap", "",
|
||||||
"Action that should be taken when a gap between protobuf ids found. "
|
"Action that should be taken when a gap between protobuf ids found. "
|
||||||
"Supported values: * "
|
"Supported values: * "
|
||||||
"'nop' - do not care about gap * 'warn' - A warning message will be shown "
|
"'nop' - do not care about gap * 'warn' - A warning message will be shown "
|
||||||
"about the gap in protobuf ids"
|
"about the gap in protobuf ids"
|
||||||
"(default) "
|
"(default) "
|
||||||
"* 'error' - An error message will be shown and the fbs generation will be "
|
"* 'error' - An error message will be shown and the fbs generation will "
|
||||||
"interrupted." },
|
"be "
|
||||||
{ "", "grpc", "", "Generate GRPC interfaces for the specified languages." },
|
"interrupted."},
|
||||||
{ "", "schema", "", "Serialize schemas instead of JSON (use with -b)." },
|
{"", "grpc", "", "Generate GRPC interfaces for the specified languages."},
|
||||||
{ "", "bfbs-filenames", "PATH",
|
{"", "schema", "", "Serialize schemas instead of JSON (use with -b)."},
|
||||||
|
{"", "bfbs-filenames", "PATH",
|
||||||
"Sets the root path where reflection filenames in reflection.fbs are "
|
"Sets the root path where reflection filenames in reflection.fbs are "
|
||||||
"relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c "
|
"relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c "
|
||||||
"then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to the "
|
"then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to "
|
||||||
"directory of the first provided schema file." },
|
"the "
|
||||||
{ "", "bfbs-absolute-paths", "", "Uses absolute paths instead of relative paths in the BFBS output." },
|
"directory of the first provided schema file."},
|
||||||
{ "", "bfbs-comments", "", "Add doc comments to the binary schema files." },
|
{"", "bfbs-absolute-paths", "",
|
||||||
{ "", "bfbs-builtins", "",
|
"Uses absolute paths instead of relative paths in the BFBS output."},
|
||||||
"Add builtin attributes to the binary schema files." },
|
{"", "bfbs-comments", "", "Add doc comments to the binary schema files."},
|
||||||
{ "", "bfbs-gen-embed", "",
|
{"", "bfbs-builtins", "",
|
||||||
"Generate code to embed the bfbs schema to the source." },
|
"Add builtin attributes to the binary schema files."},
|
||||||
{ "", "conform", "FILE",
|
{"", "bfbs-gen-embed", "",
|
||||||
|
"Generate code to embed the bfbs schema to the source."},
|
||||||
|
{"", "conform", "FILE",
|
||||||
"Specify a schema the following schemas should be an evolution of. Gives "
|
"Specify a schema the following schemas should be an evolution of. Gives "
|
||||||
"errors if not." },
|
"errors if not."},
|
||||||
{ "", "conform-includes", "PATH",
|
{"", "conform-includes", "PATH",
|
||||||
"Include path for the schema given with --conform PATH" },
|
"Include path for the schema given with --conform PATH"},
|
||||||
{ "", "filename-suffix", "SUFFIX",
|
{"", "filename-suffix", "SUFFIX",
|
||||||
"The suffix appended to the generated file names (Default is "
|
"The suffix appended to the generated file names (Default is "
|
||||||
"'_generated')." },
|
"'_generated')."},
|
||||||
{ "", "filename-ext", "EXT",
|
{"", "filename-ext", "EXT",
|
||||||
"The extension appended to the generated file names. Default is "
|
"The extension appended to the generated file names. Default is "
|
||||||
"language-specific (e.g., '.h' for C++)" },
|
"language-specific (e.g., '.h' for C++)"},
|
||||||
{ "", "include-prefix", "PATH",
|
{"", "include-prefix", "PATH",
|
||||||
"Prefix this PATH to any generated include statements." },
|
"Prefix this PATH to any generated include statements."},
|
||||||
{ "", "keep-prefix", "",
|
{"", "keep-prefix", "",
|
||||||
"Keep original prefix of schema include statement." },
|
"Keep original prefix of schema include statement."},
|
||||||
{ "", "reflect-types", "",
|
{"", "reflect-types", "",
|
||||||
"Add minimal type reflection to code generation." },
|
"Add minimal type reflection to code generation."},
|
||||||
{ "", "reflect-names", "", "Add minimal type/name reflection." },
|
{"", "reflect-names", "", "Add minimal type/name reflection."},
|
||||||
{ "", "rust-serialize", "",
|
{"", "rust-serialize", "",
|
||||||
"Implement serde::Serialize on generated Rust types." },
|
"Implement serde::Serialize on generated Rust types."},
|
||||||
{ "", "rust-module-root-file", "",
|
{"", "rust-module-root-file", "",
|
||||||
"Generate rust code in individual files with a module root file." },
|
"Generate rust code in individual files with a module root file."},
|
||||||
{ "", "root-type", "T", "Select or override the default root_type." },
|
{"", "root-type", "T", "Select or override the default root_type."},
|
||||||
{ "", "require-explicit-ids", "",
|
{"", "require-explicit-ids", "",
|
||||||
"When parsing schemas, require explicit ids (id: x)." },
|
"When parsing schemas, require explicit ids (id: x)."},
|
||||||
{ "", "force-defaults", "",
|
{"", "force-defaults", "",
|
||||||
"Emit default values in binary output from JSON" },
|
"Emit default values in binary output from JSON"},
|
||||||
{ "", "force-empty", "",
|
{"", "force-empty", "",
|
||||||
"When serializing from object API representation, force strings and "
|
"When serializing from object API representation, force strings and "
|
||||||
"vectors to empty rather than null." },
|
"vectors to empty rather than null."},
|
||||||
{ "", "force-empty-vectors", "",
|
{"", "force-empty-vectors", "",
|
||||||
"When serializing from object API representation, force vectors to empty "
|
"When serializing from object API representation, force vectors to empty "
|
||||||
"rather than null." },
|
"rather than null."},
|
||||||
{ "", "flexbuffers", "",
|
{"", "flexbuffers", "",
|
||||||
"Used with \"binary\" and \"json\" options, it generates data using "
|
"Used with \"binary\" and \"json\" options, it generates data using "
|
||||||
"schema-less FlexBuffers." },
|
"schema-less FlexBuffers."},
|
||||||
{ "", "no-warnings", "", "Inhibit all warnings messages." },
|
{"", "no-warnings", "", "Inhibit all warnings messages."},
|
||||||
{ "", "warnings-as-errors", "", "Treat all warnings as errors." },
|
{"", "warnings-as-errors", "", "Treat all warnings as errors."},
|
||||||
{ "", "cs-global-alias", "",
|
{"", "cs-global-alias", "",
|
||||||
"Prepend \"global::\" to all user generated csharp classes and "
|
"Prepend \"global::\" to all user generated csharp classes and "
|
||||||
"structs." },
|
"structs."},
|
||||||
{ "", "cs-gen-json-serializer", "",
|
{"", "cs-gen-json-serializer", "",
|
||||||
"Allows (de)serialization of JSON text in the Object API. (requires "
|
"Allows (de)serialization of JSON text in the Object API. (requires "
|
||||||
"--gen-object-api)." },
|
"--gen-object-api)."},
|
||||||
{ "", "json-nested-bytes", "",
|
{"", "json-nested-bytes", "",
|
||||||
"Allow a nested_flatbuffer field to be parsed as a vector of bytes "
|
"Allow a nested_flatbuffer field to be parsed as a vector of bytes "
|
||||||
"in JSON, which is unsafe unless checked by a verifier afterwards." },
|
"in JSON, which is unsafe unless checked by a verifier afterwards."},
|
||||||
{ "", "ts-flat-files", "",
|
{"", "ts-flat-files", "",
|
||||||
"Generate a single typescript file per .fbs file. Implies "
|
"Generate a single typescript file per .fbs file. Implies "
|
||||||
"ts_entry_points." },
|
"ts_entry_points."},
|
||||||
{ "", "ts-entry-points", "",
|
{"", "ts-entry-points", "",
|
||||||
"Generate entry point typescript per namespace. Implies gen-all." },
|
"Generate entry point typescript per namespace. Implies gen-all."},
|
||||||
{ "", "annotate-sparse-vectors", "", "Don't annotate every vector element." },
|
{"", "annotate-sparse-vectors", "", "Don't annotate every vector element."},
|
||||||
{ "", "annotate", "SCHEMA",
|
{"", "annotate", "SCHEMA",
|
||||||
"Annotate the provided BINARY_FILE with the specified SCHEMA file." },
|
"Annotate the provided BINARY_FILE with the specified SCHEMA file."},
|
||||||
{ "", "no-leak-private-annotation", "",
|
{"", "no-leak-private-annotation", "",
|
||||||
"Prevents multiple type of annotations within a Fbs SCHEMA file. "
|
"Prevents multiple type of annotations within a Fbs SCHEMA file. "
|
||||||
"Currently this is required to generate private types in Rust" },
|
"Currently this is required to generate private types in Rust"},
|
||||||
{ "", "python-no-type-prefix-suffix", "",
|
{"", "python-no-type-prefix-suffix", "",
|
||||||
"Skip emission of Python functions that are prefixed with typenames" },
|
"Skip emission of Python functions that are prefixed with typenames"},
|
||||||
{ "", "python-typing", "", "Generate Python type annotations" },
|
{"", "python-typing", "", "Generate Python type annotations"},
|
||||||
{ "", "python-version", "", "Generate code for the given Python version." },
|
{"", "python-version", "", "Generate code for the given Python version."},
|
||||||
{ "", "python-decode-obj-api-strings", "", "Decode bytes to strings for the Python Object API"},
|
{"", "python-decode-obj-api-strings", "",
|
||||||
{ "", "python-gen-numpy", "", "Whether to generate numpy helpers." },
|
"Decode bytes to strings for the Python Object API"},
|
||||||
{ "", "ts-omit-entrypoint", "",
|
{"", "python-gen-numpy", "", "Whether to generate numpy helpers."},
|
||||||
"Omit emission of namespace entrypoint file" },
|
{"", "ts-omit-entrypoint", "",
|
||||||
{ "", "file-names-only", "",
|
"Omit emission of namespace entrypoint file"},
|
||||||
"Print out generated file names without writing to the files" },
|
{"", "file-names-only", "",
|
||||||
{ "", "grpc-filename-suffix", "SUFFIX",
|
"Print out generated file names without writing to the files"},
|
||||||
"The suffix for the generated file names (Default is '.fb')." },
|
{"", "grpc-filename-suffix", "SUFFIX",
|
||||||
{ "", "grpc-additional-header", "",
|
"The suffix for the generated file names (Default is '.fb')."},
|
||||||
"Additional headers to prepend to the generated files." },
|
{"", "grpc-additional-header", "",
|
||||||
{ "", "grpc-use-system-headers", "",
|
"Additional headers to prepend to the generated files."},
|
||||||
"Use <> for headers included from the generated code." },
|
{"", "grpc-use-system-headers", "",
|
||||||
{ "", "grpc-search-path", "PATH", "Prefix to any gRPC includes." },
|
"Use <> for headers included from the generated code."},
|
||||||
{ "", "grpc-python-typed-handlers", "",
|
{"", "grpc-search-path", "PATH", "Prefix to any gRPC includes."},
|
||||||
"The handlers will use the generated classes rather than raw bytes." },
|
{"", "grpc-python-typed-handlers", "",
|
||||||
{ "", "grpc-callback-api", "",
|
"The handlers will use the generated classes rather than raw bytes."},
|
||||||
|
{"", "grpc-callback-api", "",
|
||||||
"Generate gRPC code using the callback (reactor) API instead of legacy "
|
"Generate gRPC code using the callback (reactor) API instead of legacy "
|
||||||
"sync/async." },
|
"sync/async."},
|
||||||
};
|
};
|
||||||
|
|
||||||
auto cmp = [](FlatCOption a, FlatCOption b) { return a.long_opt < b.long_opt; };
|
auto cmp = [](FlatCOption a, FlatCOption b) { return a.long_opt < b.long_opt; };
|
||||||
static std::set<FlatCOption, decltype(cmp)> language_options(cmp);
|
static std::set<FlatCOption, decltype(cmp)> language_options(cmp);
|
||||||
|
|
||||||
static void AppendTextWrappedString(std::stringstream &ss, std::string &text,
|
static void AppendTextWrappedString(std::stringstream& ss, std::string& text,
|
||||||
size_t max_col, size_t start_col) {
|
size_t max_col, size_t start_col) {
|
||||||
size_t max_line_length = max_col - start_col;
|
size_t max_line_length = max_col - start_col;
|
||||||
|
|
||||||
@@ -298,7 +306,7 @@ static void AppendTextWrappedString(std::stringstream &ss, std::string &text,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AppendOption(std::stringstream &ss, const FlatCOption &option,
|
static void AppendOption(std::stringstream& ss, const FlatCOption& option,
|
||||||
size_t max_col, size_t min_col_for_description) {
|
size_t max_col, size_t min_col_for_description) {
|
||||||
size_t chars = 2;
|
size_t chars = 2;
|
||||||
ss << " ";
|
ss << " ";
|
||||||
@@ -337,26 +345,30 @@ static void AppendOption(std::stringstream &ss, const FlatCOption &option,
|
|||||||
ss << "\n";
|
ss << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void AppendShortOption(std::stringstream &ss,
|
static void AppendShortOption(std::stringstream& ss,
|
||||||
const FlatCOption &option) {
|
const FlatCOption& option) {
|
||||||
if (!option.short_opt.empty()) {
|
if (!option.short_opt.empty()) {
|
||||||
ss << "-" << option.short_opt;
|
ss << "-" << option.short_opt;
|
||||||
if (!option.long_opt.empty()) { ss << "|"; }
|
if (!option.long_opt.empty()) {
|
||||||
|
ss << "|";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!option.long_opt.empty()) {
|
||||||
|
ss << "--" << option.long_opt;
|
||||||
}
|
}
|
||||||
if (!option.long_opt.empty()) { ss << "--" << option.long_opt; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FlatCompiler::GetShortUsageString(
|
std::string FlatCompiler::GetShortUsageString(
|
||||||
const std::string &program_name) const {
|
const std::string& program_name) const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Usage: " << program_name << " [";
|
ss << "Usage: " << program_name << " [";
|
||||||
|
|
||||||
for (const FlatCOption &option : language_options) {
|
for (const FlatCOption& option : language_options) {
|
||||||
AppendShortOption(ss, option);
|
AppendShortOption(ss, option);
|
||||||
ss << ", ";
|
ss << ", ";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const FlatCOption &option : flatc_options) {
|
for (const FlatCOption& option : flatc_options) {
|
||||||
AppendShortOption(ss, option);
|
AppendShortOption(ss, option);
|
||||||
ss << ", ";
|
ss << ", ";
|
||||||
}
|
}
|
||||||
@@ -370,17 +382,17 @@ std::string FlatCompiler::GetShortUsageString(
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string FlatCompiler::GetUsageString(
|
std::string FlatCompiler::GetUsageString(
|
||||||
const std::string &program_name) const {
|
const std::string& program_name) const {
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << "Usage: " << program_name
|
ss << "Usage: " << program_name
|
||||||
<< " [OPTION]... FILE... [-- BINARY_FILE...]\n";
|
<< " [OPTION]... FILE... [-- BINARY_FILE...]\n";
|
||||||
|
|
||||||
for (const FlatCOption &option : language_options) {
|
for (const FlatCOption& option : language_options) {
|
||||||
AppendOption(ss, option, 80, 25);
|
AppendOption(ss, option, 80, 25);
|
||||||
}
|
}
|
||||||
ss << "\n";
|
ss << "\n";
|
||||||
|
|
||||||
for (const FlatCOption &option : flatc_options) {
|
for (const FlatCOption& option : flatc_options) {
|
||||||
AppendOption(ss, option, 80, 25);
|
AppendOption(ss, option, 80, 25);
|
||||||
}
|
}
|
||||||
ss << "\n";
|
ss << "\n";
|
||||||
@@ -397,20 +409,20 @@ std::string FlatCompiler::GetUsageString(
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatCompiler::AnnotateBinaries(const uint8_t *binary_schema,
|
void FlatCompiler::AnnotateBinaries(const uint8_t* binary_schema,
|
||||||
const uint64_t binary_schema_size,
|
const uint64_t binary_schema_size,
|
||||||
const FlatCOptions &options) {
|
const FlatCOptions& options) {
|
||||||
const std::string &schema_filename = options.annotate_schema;
|
const std::string& schema_filename = options.annotate_schema;
|
||||||
|
|
||||||
for (const std::string &filename : options.filenames) {
|
for (const std::string& filename : options.filenames) {
|
||||||
std::string binary_contents;
|
std::string binary_contents;
|
||||||
if (!flatbuffers::LoadFile(filename.c_str(), true, &binary_contents)) {
|
if (!flatbuffers::LoadFile(filename.c_str(), true, &binary_contents)) {
|
||||||
Warn("unable to load binary file: " + filename);
|
Warn("unable to load binary file: " + filename);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *binary =
|
const uint8_t* binary =
|
||||||
reinterpret_cast<const uint8_t *>(binary_contents.c_str());
|
reinterpret_cast<const uint8_t*>(binary_contents.c_str());
|
||||||
const size_t binary_size = binary_contents.size();
|
const size_t binary_size = binary_contents.size();
|
||||||
const bool is_size_prefixed = options.opts.size_prefixed;
|
const bool is_size_prefixed = options.opts.size_prefixed;
|
||||||
|
|
||||||
@@ -436,14 +448,16 @@ void FlatCompiler::AnnotateBinaries(const uint8_t *binary_schema,
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
||||||
const char **argv) {
|
const char** argv) {
|
||||||
if (argc <= 1) { Error("Need to provide at least one argument."); }
|
if (argc <= 1) {
|
||||||
|
Error("Need to provide at least one argument.");
|
||||||
|
}
|
||||||
|
|
||||||
FlatCOptions options;
|
FlatCOptions options;
|
||||||
|
|
||||||
options.program_name = std::string(argv[0]);
|
options.program_name = std::string(argv[0]);
|
||||||
|
|
||||||
IDLOptions &opts = options.opts;
|
IDLOptions& opts = options.opts;
|
||||||
|
|
||||||
for (int argi = 1; argi < argc; argi++) {
|
for (int argi = 1; argi < argc; argi++) {
|
||||||
std::string arg = argv[argi];
|
std::string arg = argv[argi];
|
||||||
@@ -741,7 +755,9 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
|||||||
arg == "--grpc-callback-api=false") {
|
arg == "--grpc-callback-api=false") {
|
||||||
opts.grpc_callback_api = false;
|
opts.grpc_callback_api = false;
|
||||||
} else {
|
} else {
|
||||||
if (arg == "--proto") { opts.proto_mode = true; }
|
if (arg == "--proto") {
|
||||||
|
opts.proto_mode = true;
|
||||||
|
}
|
||||||
|
|
||||||
auto code_generator_it = code_generators_.find(arg);
|
auto code_generator_it = code_generators_.find(arg);
|
||||||
if (code_generator_it == code_generators_.end()) {
|
if (code_generator_it == code_generators_.end()) {
|
||||||
@@ -772,8 +788,8 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc,
|
|||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FlatCompiler::ValidateOptions(const FlatCOptions &options) {
|
void FlatCompiler::ValidateOptions(const FlatCOptions& options) {
|
||||||
const IDLOptions &opts = options.opts;
|
const IDLOptions& opts = options.opts;
|
||||||
|
|
||||||
if (!options.filenames.size()) Error("missing input files", false, true);
|
if (!options.filenames.size()) Error("missing input files", false, true);
|
||||||
|
|
||||||
@@ -792,7 +808,7 @@ void FlatCompiler::ValidateOptions(const FlatCOptions &options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
flatbuffers::Parser FlatCompiler::GetConformParser(
|
flatbuffers::Parser FlatCompiler::GetConformParser(
|
||||||
const FlatCOptions &options) {
|
const FlatCOptions& options) {
|
||||||
flatbuffers::Parser conform_parser;
|
flatbuffers::Parser conform_parser;
|
||||||
|
|
||||||
// conform parser should check advanced options,
|
// conform parser should check advanced options,
|
||||||
@@ -817,8 +833,8 @@ flatbuffers::Parser FlatCompiler::GetConformParser(
|
|||||||
return conform_parser;
|
return conform_parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions& options,
|
||||||
Parser &conform_parser) {
|
Parser& conform_parser) {
|
||||||
std::unique_ptr<Parser> parser =
|
std::unique_ptr<Parser> parser =
|
||||||
std::unique_ptr<Parser>(new Parser(options.opts));
|
std::unique_ptr<Parser>(new Parser(options.opts));
|
||||||
|
|
||||||
@@ -826,7 +842,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
file_it != options.filenames.end(); ++file_it) {
|
file_it != options.filenames.end(); ++file_it) {
|
||||||
IDLOptions opts = options.opts;
|
IDLOptions opts = options.opts;
|
||||||
|
|
||||||
auto &filename = *file_it;
|
auto& filename = *file_it;
|
||||||
std::string contents;
|
std::string contents;
|
||||||
if (!flatbuffers::LoadFile(filename.c_str(), true, &contents))
|
if (!flatbuffers::LoadFile(filename.c_str(), true, &contents))
|
||||||
Error("unable to load file: " + filename);
|
Error("unable to load file: " + filename);
|
||||||
@@ -842,7 +858,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
if (is_binary) {
|
if (is_binary) {
|
||||||
parser->builder_.Clear();
|
parser->builder_.Clear();
|
||||||
parser->builder_.PushFlatBuffer(
|
parser->builder_.PushFlatBuffer(
|
||||||
reinterpret_cast<const uint8_t *>(contents.c_str()),
|
reinterpret_cast<const uint8_t*>(contents.c_str()),
|
||||||
contents.length());
|
contents.length());
|
||||||
if (!options.raw_binary) {
|
if (!options.raw_binary) {
|
||||||
// Generally reading binaries that do not correspond to the schema
|
// Generally reading binaries that do not correspond to the schema
|
||||||
@@ -882,7 +898,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
LoadBinarySchema(*parser, filename, contents);
|
LoadBinarySchema(*parser, filename, contents);
|
||||||
} else if (opts.use_flexbuffers) {
|
} else if (opts.use_flexbuffers) {
|
||||||
if (opts.lang_to_generate == IDLOptions::kJson) {
|
if (opts.lang_to_generate == IDLOptions::kJson) {
|
||||||
auto data = reinterpret_cast<const uint8_t *>(contents.c_str());
|
auto data = reinterpret_cast<const uint8_t*>(contents.c_str());
|
||||||
auto size = contents.size();
|
auto size = contents.size();
|
||||||
std::vector<uint8_t> reuse_tracker;
|
std::vector<uint8_t> reuse_tracker;
|
||||||
if (!flexbuffers::VerifyBuffer(data, size, &reuse_tracker))
|
if (!flexbuffers::VerifyBuffer(data, size, &reuse_tracker))
|
||||||
@@ -919,7 +935,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
|
|
||||||
// If one of the generators uses bfbs, serialize the parser and get
|
// If one of the generators uses bfbs, serialize the parser and get
|
||||||
// the serialized buffer and length.
|
// the serialized buffer and length.
|
||||||
const uint8_t *bfbs_buffer = nullptr;
|
const uint8_t* bfbs_buffer = nullptr;
|
||||||
int64_t bfbs_length = 0;
|
int64_t bfbs_length = 0;
|
||||||
if (options.requires_bfbs) {
|
if (options.requires_bfbs) {
|
||||||
parser->Serialize();
|
parser->Serialize();
|
||||||
@@ -927,7 +943,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
bfbs_length = parser->builder_.GetSize();
|
bfbs_length = parser->builder_.GetSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const std::shared_ptr<CodeGenerator> &code_generator :
|
for (const std::shared_ptr<CodeGenerator>& code_generator :
|
||||||
options.generators) {
|
options.generators) {
|
||||||
if (options.print_make_rules) {
|
if (options.print_make_rules) {
|
||||||
std::string make_rule;
|
std::string make_rule;
|
||||||
@@ -996,7 +1012,7 @@ std::unique_ptr<Parser> FlatCompiler::GenerateCode(const FlatCOptions &options,
|
|||||||
return parser;
|
return parser;
|
||||||
}
|
}
|
||||||
|
|
||||||
int FlatCompiler::Compile(const FlatCOptions &options) {
|
int FlatCompiler::Compile(const FlatCOptions& options) {
|
||||||
// TODO(derekbailey): change to std::optional<Parser>
|
// TODO(derekbailey): change to std::optional<Parser>
|
||||||
Parser conform_parser = GetConformParser(options);
|
Parser conform_parser = GetConformParser(options);
|
||||||
|
|
||||||
@@ -1016,7 +1032,7 @@ int FlatCompiler::Compile(const FlatCOptions &options) {
|
|||||||
Error("unable to load schema: " + options.annotate_schema);
|
Error("unable to load schema: " + options.annotate_schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *binary_schema = nullptr;
|
const uint8_t* binary_schema = nullptr;
|
||||||
uint64_t binary_schema_size = 0;
|
uint64_t binary_schema_size = 0;
|
||||||
|
|
||||||
IDLOptions binary_opts;
|
IDLOptions binary_opts;
|
||||||
@@ -1024,8 +1040,7 @@ int FlatCompiler::Compile(const FlatCOptions &options) {
|
|||||||
Parser parser(binary_opts);
|
Parser parser(binary_opts);
|
||||||
|
|
||||||
if (is_binary_schema) {
|
if (is_binary_schema) {
|
||||||
binary_schema =
|
binary_schema = reinterpret_cast<const uint8_t*>(schema_contents.c_str());
|
||||||
reinterpret_cast<const uint8_t *>(schema_contents.c_str());
|
|
||||||
binary_schema_size = schema_contents.size();
|
binary_schema_size = schema_contents.size();
|
||||||
} else {
|
} else {
|
||||||
// If we need to generate the .bfbs file from the provided schema file
|
// If we need to generate the .bfbs file from the provided schema file
|
||||||
@@ -1057,7 +1072,7 @@ int FlatCompiler::Compile(const FlatCOptions &options) {
|
|||||||
|
|
||||||
std::unique_ptr<Parser> parser = GenerateCode(options, conform_parser);
|
std::unique_ptr<Parser> parser = GenerateCode(options, conform_parser);
|
||||||
|
|
||||||
for (const auto &code_generator : options.generators) {
|
for (const auto& code_generator : options.generators) {
|
||||||
if (code_generator->SupportsRootFileGeneration()) {
|
if (code_generator->SupportsRootFileGeneration()) {
|
||||||
code_generator->GenerateRootFile(*parser, options.output_path);
|
code_generator->GenerateRootFile(*parser, options.output_path);
|
||||||
}
|
}
|
||||||
@@ -1067,7 +1082,7 @@ int FlatCompiler::Compile(const FlatCOptions &options) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool FlatCompiler::RegisterCodeGenerator(
|
bool FlatCompiler::RegisterCodeGenerator(
|
||||||
const FlatCOption &option, std::shared_ptr<CodeGenerator> code_generator) {
|
const FlatCOption& option, std::shared_ptr<CodeGenerator> code_generator) {
|
||||||
if (!option.short_opt.empty() &&
|
if (!option.short_opt.empty() &&
|
||||||
code_generators_.find("-" + option.short_opt) != code_generators_.end()) {
|
code_generators_.find("-" + option.short_opt) != code_generators_.end()) {
|
||||||
Error("multiple generators registered under: -" + option.short_opt, false,
|
Error("multiple generators registered under: -" + option.short_opt, false,
|
||||||
|
|||||||
@@ -40,18 +40,22 @@
|
|||||||
#include "idl_gen_text.h"
|
#include "idl_gen_text.h"
|
||||||
#include "idl_gen_ts.h"
|
#include "idl_gen_ts.h"
|
||||||
|
|
||||||
static const char *g_program_name = nullptr;
|
static const char* g_program_name = nullptr;
|
||||||
|
|
||||||
static void Warn(const flatbuffers::FlatCompiler *flatc,
|
static void Warn(const flatbuffers::FlatCompiler* flatc,
|
||||||
const std::string &warn, bool show_exe_name) {
|
const std::string& warn, bool show_exe_name) {
|
||||||
(void)flatc;
|
(void)flatc;
|
||||||
if (show_exe_name) { printf("%s: ", g_program_name); }
|
if (show_exe_name) {
|
||||||
|
printf("%s: ", g_program_name);
|
||||||
|
}
|
||||||
fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str());
|
fprintf(stderr, "\nwarning:\n %s\n\n", warn.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Error(const flatbuffers::FlatCompiler *flatc,
|
static void Error(const flatbuffers::FlatCompiler* flatc,
|
||||||
const std::string &err, bool usage, bool show_exe_name) {
|
const std::string& err, bool usage, bool show_exe_name) {
|
||||||
if (show_exe_name) { printf("%s: ", g_program_name); }
|
if (show_exe_name) {
|
||||||
|
printf("%s: ", g_program_name);
|
||||||
|
}
|
||||||
if (usage && flatc) {
|
if (usage && flatc) {
|
||||||
fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
|
fprintf(stderr, "%s\n", flatc->GetShortUsageString(g_program_name).c_str());
|
||||||
}
|
}
|
||||||
@@ -60,16 +64,16 @@ static void Error(const flatbuffers::FlatCompiler *flatc,
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
void LogCompilerWarn(const std::string &warn) {
|
void LogCompilerWarn(const std::string& warn) {
|
||||||
Warn(static_cast<const flatbuffers::FlatCompiler *>(nullptr), warn, true);
|
Warn(static_cast<const flatbuffers::FlatCompiler*>(nullptr), warn, true);
|
||||||
}
|
}
|
||||||
void LogCompilerError(const std::string &err) {
|
void LogCompilerError(const std::string& err) {
|
||||||
Error(static_cast<const flatbuffers::FlatCompiler *>(nullptr), err, false,
|
Error(static_cast<const flatbuffers::FlatCompiler*>(nullptr), err, false,
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
const std::string flatbuffers_version(flatbuffers::FLATBUFFERS_VERSION());
|
const std::string flatbuffers_version(flatbuffers::FLATBUFFERS_VERSION());
|
||||||
|
|
||||||
g_program_name = argv[0];
|
g_program_name = argv[0];
|
||||||
@@ -83,100 +87,101 @@ int main(int argc, const char *argv[]) {
|
|||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{
|
flatbuffers::FlatCOption{
|
||||||
"b", "binary", "",
|
"b", "binary", "",
|
||||||
"Generate wire format binaries for any data definitions" },
|
"Generate wire format binaries for any data definitions"},
|
||||||
flatbuffers::NewBinaryCodeGenerator());
|
flatbuffers::NewBinaryCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "c", "cpp", "",
|
flatbuffers::FlatCOption{"c", "cpp", "",
|
||||||
"Generate C++ headers for tables/structs" },
|
"Generate C++ headers for tables/structs"},
|
||||||
flatbuffers::NewCppCodeGenerator());
|
flatbuffers::NewCppCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "n", "csharp", "",
|
flatbuffers::FlatCOption{"n", "csharp", "",
|
||||||
"Generate C# classes for tables/structs" },
|
"Generate C# classes for tables/structs"},
|
||||||
flatbuffers::NewCSharpCodeGenerator());
|
flatbuffers::NewCSharpCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "d", "dart", "",
|
flatbuffers::FlatCOption{"d", "dart", "",
|
||||||
"Generate Dart classes for tables/structs" },
|
"Generate Dart classes for tables/structs"},
|
||||||
flatbuffers::NewDartCodeGenerator());
|
flatbuffers::NewDartCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "proto", "",
|
flatbuffers::FlatCOption{"", "proto", "",
|
||||||
"Input is a .proto, translate to .fbs" },
|
"Input is a .proto, translate to .fbs"},
|
||||||
flatbuffers::NewFBSCodeGenerator());
|
flatbuffers::NewFBSCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "g", "go", "",
|
flatbuffers::FlatCOption{"g", "go", "",
|
||||||
"Generate Go files for tables/structs" },
|
"Generate Go files for tables/structs"},
|
||||||
flatbuffers::NewGoCodeGenerator());
|
flatbuffers::NewGoCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "j", "java", "",
|
flatbuffers::FlatCOption{"j", "java", "",
|
||||||
"Generate Java classes for tables/structs" },
|
"Generate Java classes for tables/structs"},
|
||||||
flatbuffers::NewJavaCodeGenerator());
|
flatbuffers::NewJavaCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "jsonschema", "", "Generate Json schema" },
|
flatbuffers::FlatCOption{"", "jsonschema", "", "Generate Json schema"},
|
||||||
flatbuffers::NewJsonSchemaCodeGenerator());
|
flatbuffers::NewJsonSchemaCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "kotlin", "",
|
flatbuffers::FlatCOption{"", "kotlin", "",
|
||||||
"Generate Kotlin classes for tables/structs" },
|
"Generate Kotlin classes for tables/structs"},
|
||||||
flatbuffers::NewKotlinCodeGenerator());
|
flatbuffers::NewKotlinCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "kotlin-kmp", "",
|
flatbuffers::FlatCOption{
|
||||||
"Generate Kotlin multiplatform classes for tables/structs" },
|
"", "kotlin-kmp", "",
|
||||||
|
"Generate Kotlin multiplatform classes for tables/structs"},
|
||||||
flatbuffers::NewKotlinKMPCodeGenerator());
|
flatbuffers::NewKotlinKMPCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "lobster", "",
|
flatbuffers::FlatCOption{"", "lobster", "",
|
||||||
"Generate Lobster files for tables/structs" },
|
"Generate Lobster files for tables/structs"},
|
||||||
flatbuffers::NewLobsterCodeGenerator());
|
flatbuffers::NewLobsterCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "l", "lua", "",
|
flatbuffers::FlatCOption{"l", "lua", "",
|
||||||
"Generate Lua files for tables/structs" },
|
"Generate Lua files for tables/structs"},
|
||||||
flatbuffers::NewLuaBfbsGenerator(flatbuffers_version));
|
flatbuffers::NewLuaBfbsGenerator(flatbuffers_version));
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "nim", "",
|
flatbuffers::FlatCOption{"", "nim", "",
|
||||||
"Generate Nim files for tables/structs" },
|
"Generate Nim files for tables/structs"},
|
||||||
flatbuffers::NewNimBfbsGenerator(flatbuffers_version));
|
flatbuffers::NewNimBfbsGenerator(flatbuffers_version));
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "p", "python", "",
|
flatbuffers::FlatCOption{"p", "python", "",
|
||||||
"Generate Python files for tables/structs" },
|
"Generate Python files for tables/structs"},
|
||||||
flatbuffers::NewPythonCodeGenerator());
|
flatbuffers::NewPythonCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "php", "",
|
flatbuffers::FlatCOption{"", "php", "",
|
||||||
"Generate PHP files for tables/structs" },
|
"Generate PHP files for tables/structs"},
|
||||||
flatbuffers::NewPhpCodeGenerator());
|
flatbuffers::NewPhpCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "r", "rust", "",
|
flatbuffers::FlatCOption{"r", "rust", "",
|
||||||
"Generate Rust files for tables/structs" },
|
"Generate Rust files for tables/structs"},
|
||||||
flatbuffers::NewRustCodeGenerator());
|
flatbuffers::NewRustCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{
|
flatbuffers::FlatCOption{"t", "json", "",
|
||||||
"t", "json", "", "Generate text output for any data definitions" },
|
"Generate text output for any data definitions"},
|
||||||
flatbuffers::NewTextCodeGenerator());
|
flatbuffers::NewTextCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "", "swift", "",
|
flatbuffers::FlatCOption{"", "swift", "",
|
||||||
"Generate Swift files for tables/structs" },
|
"Generate Swift files for tables/structs"},
|
||||||
flatbuffers::NewSwiftCodeGenerator());
|
flatbuffers::NewSwiftCodeGenerator());
|
||||||
|
|
||||||
flatc.RegisterCodeGenerator(
|
flatc.RegisterCodeGenerator(
|
||||||
flatbuffers::FlatCOption{ "T", "ts", "",
|
flatbuffers::FlatCOption{"T", "ts", "",
|
||||||
"Generate TypeScript code for tables/structs" },
|
"Generate TypeScript code for tables/structs"},
|
||||||
flatbuffers::NewTsCodeGenerator());
|
flatbuffers::NewTsCodeGenerator());
|
||||||
|
|
||||||
// Create the FlatC options by parsing the command line arguments.
|
// Create the FlatC options by parsing the command line arguments.
|
||||||
const flatbuffers::FlatCOptions &options =
|
const flatbuffers::FlatCOptions& options =
|
||||||
flatc.ParseFromCommandLineArguments(argc, argv);
|
flatc.ParseFromCommandLineArguments(argc, argv);
|
||||||
|
|
||||||
// Compile with the extracted FlatC options.
|
// Compile with the extracted FlatC options.
|
||||||
|
|||||||
@@ -24,8 +24,8 @@
|
|||||||
|
|
||||||
enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };
|
enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char* argv[]) {
|
||||||
const char *name = argv[0];
|
const char* name = argv[0];
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
printf("%s HASH [OPTION]... [--] STRING...\n", name);
|
printf("%s HASH [OPTION]... [--] STRING...\n", name);
|
||||||
printf("Available hashing algorithms:\n");
|
printf("Available hashing algorithms:\n");
|
||||||
@@ -55,7 +55,7 @@ int main(int argc, char *argv[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *hash_algorithm = argv[1];
|
const char* hash_algorithm = argv[1];
|
||||||
|
|
||||||
flatbuffers::NamedHashFunction<uint16_t>::HashFunction hash_function16 =
|
flatbuffers::NamedHashFunction<uint16_t>::HashFunction hash_function16 =
|
||||||
flatbuffers::FindHashFunction16(hash_algorithm);
|
flatbuffers::FindHashFunction16(hash_algorithm);
|
||||||
@@ -73,7 +73,7 @@ int main(int argc, char *argv[]) {
|
|||||||
bool annotate = false;
|
bool annotate = false;
|
||||||
bool escape_dash = false;
|
bool escape_dash = false;
|
||||||
for (int i = 2; i < argc; i++) {
|
for (int i = 2; i < argc; i++) {
|
||||||
const char *arg = argv[i];
|
const char* arg = argv[i];
|
||||||
if (!escape_dash && arg[0] == '-') {
|
if (!escape_dash && arg[0] == '-') {
|
||||||
std::string opt = arg;
|
std::string opt = arg;
|
||||||
if (opt == "-d")
|
if (opt == "-d")
|
||||||
|
|||||||
@@ -33,17 +33,17 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static std::string BinaryFileName(const Parser &parser, const std::string &path,
|
static std::string BinaryFileName(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
|
auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
|
||||||
return path + file_name + "." + ext;
|
return path + file_name + "." + ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GenerateBinary(const Parser &parser, const std::string &path,
|
static bool GenerateBinary(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
if (parser.opts.use_flexbuffers) {
|
if (parser.opts.use_flexbuffers) {
|
||||||
auto data_vec = parser.flex_builder_.GetBuffer();
|
auto data_vec = parser.flex_builder_.GetBuffer();
|
||||||
auto data_ptr = reinterpret_cast<char *>(data(data_vec));
|
auto data_ptr = reinterpret_cast<char*>(data(data_vec));
|
||||||
return !parser.flex_builder_.GetSize() ||
|
return !parser.flex_builder_.GetSize() ||
|
||||||
flatbuffers::SaveFile(
|
flatbuffers::SaveFile(
|
||||||
BinaryFileName(parser, path, file_name).c_str(), data_ptr,
|
BinaryFileName(parser, path, file_name).c_str(), data_ptr,
|
||||||
@@ -52,12 +52,12 @@ static bool GenerateBinary(const Parser &parser, const std::string &path,
|
|||||||
return !parser.builder_.GetSize() ||
|
return !parser.builder_.GetSize() ||
|
||||||
flatbuffers::SaveFile(
|
flatbuffers::SaveFile(
|
||||||
BinaryFileName(parser, path, file_name).c_str(),
|
BinaryFileName(parser, path, file_name).c_str(),
|
||||||
reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
|
reinterpret_cast<char*>(parser.builder_.GetBufferPointer()),
|
||||||
parser.builder_.GetSize(), true);
|
parser.builder_.GetSize(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string BinaryMakeRule(const Parser &parser, const std::string &path,
|
static std::string BinaryMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
if (!parser.builder_.GetSize()) return "";
|
if (!parser.builder_.GetSize()) return "";
|
||||||
std::string filebase =
|
std::string filebase =
|
||||||
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
|
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
|
||||||
@@ -73,36 +73,37 @@ static std::string BinaryMakeRule(const Parser &parser, const std::string &path,
|
|||||||
|
|
||||||
class BinaryCodeGenerator : public CodeGenerator {
|
class BinaryCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateBinary(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateBinary(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
||||||
// serialized reflection.fbs.
|
// serialized reflection.fbs.
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
output = BinaryMakeRule(parser, path, filename);
|
output = BinaryMakeRule(parser, path, filename);
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -33,7 +33,7 @@ namespace dart {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static Namer::Config DartDefaultConfig() {
|
static Namer::Config DartDefaultConfig() {
|
||||||
return { /*types=*/Case::kUpperCamel,
|
return {/*types=*/Case::kUpperCamel,
|
||||||
/*constants=*/Case::kScreamingSnake,
|
/*constants=*/Case::kScreamingSnake,
|
||||||
/*methods=*/Case::kLowerCamel,
|
/*methods=*/Case::kLowerCamel,
|
||||||
/*functions=*/Case::kUnknown, // unused.
|
/*functions=*/Case::kUnknown, // unused.
|
||||||
@@ -52,23 +52,25 @@ static Namer::Config DartDefaultConfig() {
|
|||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
/*filename_suffix=*/"_generated",
|
/*filename_suffix=*/"_generated",
|
||||||
/*filename_extension=*/".dart" };
|
/*filename_extension=*/".dart"};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::set<std::string> DartKeywords() {
|
static std::set<std::string> DartKeywords() {
|
||||||
// see https://www.dartlang.org/guides/language/language-tour#keywords
|
// see https://www.dartlang.org/guides/language/language-tour#keywords
|
||||||
// yield*, async*, and sync* shouldn't be proble
|
// yield*, async*, and sync* shouldn't be proble
|
||||||
return {
|
return {
|
||||||
"abstract", "else", "import", "show", "as", "enum",
|
"abstract", "else", "import", "show", "as",
|
||||||
"in", "static", "assert", "export", "interface", "super",
|
"enum", "in", "static", "assert", "export",
|
||||||
"async", "extends", "is", "switch", "await", "extension",
|
"interface", "super", "async", "extends", "is",
|
||||||
"late", "sync", "break", "external", "library", "this",
|
"switch", "await", "extension", "late", "sync",
|
||||||
"case", "factory", "mixin", "throw", "catch", "false",
|
"break", "external", "library", "this", "case",
|
||||||
"new", "true", "class", "final", "null", "try",
|
"factory", "mixin", "throw", "catch", "false",
|
||||||
"const", "finally", "on", "typedef", "continue", "for",
|
"new", "true", "class", "final", "null",
|
||||||
"operator", "var", "covariant", "Function", "part", "void",
|
"try", "const", "finally", "on", "typedef",
|
||||||
"default", "get", "required", "while", "deferred", "hide",
|
"continue", "for", "operator", "var", "covariant",
|
||||||
"rethrow", "with", "do", "if", "return", "yield",
|
"Function", "part", "void", "default", "get",
|
||||||
|
"required", "while", "deferred", "hide", "rethrow",
|
||||||
|
"with", "do", "if", "return", "yield",
|
||||||
"dynamic", "implements", "set",
|
"dynamic", "implements", "set",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -82,17 +84,17 @@ class DartGenerator : public BaseGenerator {
|
|||||||
public:
|
public:
|
||||||
typedef std::map<std::string, std::string> namespace_code_map;
|
typedef std::map<std::string, std::string> namespace_code_map;
|
||||||
|
|
||||||
DartGenerator(const Parser &parser, const std::string &path,
|
DartGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", ".", "dart"),
|
: BaseGenerator(parser, path, file_name, "", ".", "dart"),
|
||||||
namer_(WithFlagOptions(DartDefaultConfig(), parser.opts, path),
|
namer_(WithFlagOptions(DartDefaultConfig(), parser.opts, path),
|
||||||
DartKeywords()) {}
|
DartKeywords()) {}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void import_generator(const std::vector<T *> &definitions,
|
void import_generator(const std::vector<T*>& definitions,
|
||||||
const std::string &included,
|
const std::string& included,
|
||||||
std::set<std::string> &imports) {
|
std::set<std::string>& imports) {
|
||||||
for (const auto &item : definitions) {
|
for (const auto& item : definitions) {
|
||||||
if (item->file == included) {
|
if (item->file == included) {
|
||||||
std::string component = namer_.Namespace(*item->defined_namespace);
|
std::string component = namer_.Namespace(*item->defined_namespace);
|
||||||
std::string filebase =
|
std::string filebase =
|
||||||
@@ -118,7 +120,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::set<std::string> imports;
|
std::set<std::string> imports;
|
||||||
|
|
||||||
for (const auto &included_file : parser_.GetIncludedFiles()) {
|
for (const auto& included_file : parser_.GetIncludedFiles()) {
|
||||||
if (included_file.filename == parser_.file_being_parsed_) continue;
|
if (included_file.filename == parser_.file_being_parsed_) continue;
|
||||||
|
|
||||||
import_generator(parser_.structs_.vec, included_file.filename, imports);
|
import_generator(parser_.structs_.vec, included_file.filename, imports);
|
||||||
@@ -126,7 +128,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string import_code = "";
|
std::string import_code = "";
|
||||||
for (const auto &file : imports) { import_code += file; }
|
for (const auto& file : imports) {
|
||||||
|
import_code += file;
|
||||||
|
}
|
||||||
|
|
||||||
import_code += import_code.empty() ? "" : "\n";
|
import_code += import_code.empty() ? "" : "\n";
|
||||||
|
|
||||||
@@ -137,7 +141,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
"// ignore_for_file: unused_import, unused_field, unused_element, "
|
"// ignore_for_file: unused_import, unused_field, unused_element, "
|
||||||
"unused_local_variable, constant_identifier_names\n\n";
|
"unused_local_variable, constant_identifier_names\n\n";
|
||||||
|
|
||||||
if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; }
|
if (!kv->first.empty()) {
|
||||||
|
code += "library " + kv->first + ";\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
code += "import 'dart:typed_data' show Uint8List;\n";
|
code += "import 'dart:typed_data' show Uint8List;\n";
|
||||||
code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb +
|
code += "import 'package:flat_buffers/flat_buffers.dart' as " + _kFb +
|
||||||
@@ -156,18 +162,20 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
code += kv->second;
|
code += kv->second;
|
||||||
|
|
||||||
if (!SaveFile(Filename(kv->first).c_str(), code, false)) { return false; }
|
if (!SaveFile(Filename(kv->first).c_str(), code, false)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Filename(const std::string &suffix, bool path = true) const {
|
std::string Filename(const std::string& suffix, bool path = true) const {
|
||||||
return (path ? path_ : "") +
|
return (path ? path_ : "") +
|
||||||
namer_.File(file_name_ + (suffix.empty() ? "" : "_" + suffix));
|
namer_.File(file_name_ + (suffix.empty() ? "" : "_" + suffix));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static std::string ImportAliasName(const std::string &ns) {
|
static std::string ImportAliasName(const std::string& ns) {
|
||||||
std::string ret;
|
std::string ret;
|
||||||
ret.assign(ns);
|
ret.assign(ns);
|
||||||
size_t pos = ret.find('.');
|
size_t pos = ret.find('.');
|
||||||
@@ -179,25 +187,25 @@ class DartGenerator : public BaseGenerator {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateEnums(namespace_code_map &namespace_code) {
|
void GenerateEnums(namespace_code_map& namespace_code) {
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &enum_def = **it;
|
auto& enum_def = **it;
|
||||||
GenEnum(enum_def, namespace_code);
|
GenEnum(enum_def, namespace_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateStructs(namespace_code_map &namespace_code) {
|
void GenerateStructs(namespace_code_map& namespace_code) {
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
GenStruct(struct_def, namespace_code);
|
GenStruct(struct_def, namespace_code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a documentation comment, if available.
|
// Generate a documentation comment, if available.
|
||||||
static void GenDocComment(const std::vector<std::string> &dc,
|
static void GenDocComment(const std::vector<std::string>& dc,
|
||||||
const char *indent, std::string &code) {
|
const char* indent, std::string& code) {
|
||||||
for (auto it = dc.begin(); it != dc.end(); ++it) {
|
for (auto it = dc.begin(); it != dc.end(); ++it) {
|
||||||
if (indent) code += indent;
|
if (indent) code += indent;
|
||||||
code += "/// " + *it + "\n";
|
code += "/// " + *it + "\n";
|
||||||
@@ -205,9 +213,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate an enum declaration and an enum string lookup table.
|
// Generate an enum declaration and an enum string lookup table.
|
||||||
void GenEnum(EnumDef &enum_def, namespace_code_map &namespace_code) {
|
void GenEnum(EnumDef& enum_def, namespace_code_map& namespace_code) {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
std::string &code =
|
std::string& code =
|
||||||
namespace_code[namer_.Namespace(*enum_def.defined_namespace)];
|
namespace_code[namer_.Namespace(*enum_def.defined_namespace)];
|
||||||
GenDocComment(enum_def.doc_comment, "", code);
|
GenDocComment(enum_def.doc_comment, "", code);
|
||||||
|
|
||||||
@@ -222,12 +230,14 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
code += "enum " + enum_type + " {\n";
|
code += "enum " + enum_type + " {\n";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
const auto enum_var = namer_.Variant(ev);
|
const auto enum_var = namer_.Variant(ev);
|
||||||
if (it != enum_def.Vals().begin()) code += ",\n";
|
if (it != enum_def.Vals().begin()) code += ",\n";
|
||||||
code += " " + enum_var + "(" + enum_def.ToString(ev) + ")";
|
code += " " + enum_var + "(" + enum_def.ToString(ev) + ")";
|
||||||
}
|
}
|
||||||
if (auto_default) { code += ",\n _default(0)"; }
|
if (auto_default) {
|
||||||
|
code += ",\n _default(0)";
|
||||||
|
}
|
||||||
code += ";\n\n";
|
code += ";\n\n";
|
||||||
|
|
||||||
code += " final int value;\n";
|
code += " final int value;\n";
|
||||||
@@ -235,7 +245,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
code += " factory " + enum_type + ".fromValue(int value) {\n";
|
code += " factory " + enum_type + ".fromValue(int value) {\n";
|
||||||
code += " switch (value) {\n";
|
code += " switch (value) {\n";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
const auto enum_var = namer_.Variant(ev);
|
const auto enum_var = namer_.Variant(ev);
|
||||||
code += " case " + enum_def.ToString(ev) + ":";
|
code += " case " + enum_def.ToString(ev) + ":";
|
||||||
code += " return " + enum_type + "." + enum_var + ";\n";
|
code += " return " + enum_type + "." + enum_var + ";\n";
|
||||||
@@ -268,8 +278,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
GenEnumReader(enum_def, enum_type, code);
|
GenEnumReader(enum_def, enum_type, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenEnumReader(EnumDef &enum_def, const std::string &enum_type,
|
void GenEnumReader(EnumDef& enum_def, const std::string& enum_type,
|
||||||
std::string &code) {
|
std::string& code) {
|
||||||
code += "class _" + enum_type + "Reader extends " + _kFb + ".Reader<" +
|
code += "class _" + enum_type + "Reader extends " + _kFb + ".Reader<" +
|
||||||
enum_type + "> {\n";
|
enum_type + "> {\n";
|
||||||
code += " const _" + enum_type + "Reader();\n\n";
|
code += " const _" + enum_type + "Reader();\n\n";
|
||||||
@@ -283,48 +293,69 @@ class DartGenerator : public BaseGenerator {
|
|||||||
code += "}\n\n";
|
code += "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenType(const Type &type) {
|
std::string GenType(const Type& type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_BOOL: return "Bool";
|
case BASE_TYPE_BOOL:
|
||||||
case BASE_TYPE_CHAR: return "Int8";
|
return "Bool";
|
||||||
|
case BASE_TYPE_CHAR:
|
||||||
|
return "Int8";
|
||||||
case BASE_TYPE_UTYPE:
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_UCHAR: return "Uint8";
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_SHORT: return "Int16";
|
return "Uint8";
|
||||||
case BASE_TYPE_USHORT: return "Uint16";
|
case BASE_TYPE_SHORT:
|
||||||
case BASE_TYPE_INT: return "Int32";
|
return "Int16";
|
||||||
case BASE_TYPE_UINT: return "Uint32";
|
case BASE_TYPE_USHORT:
|
||||||
case BASE_TYPE_LONG: return "Int64";
|
return "Uint16";
|
||||||
case BASE_TYPE_ULONG: return "Uint64";
|
case BASE_TYPE_INT:
|
||||||
case BASE_TYPE_FLOAT: return "Float32";
|
return "Int32";
|
||||||
case BASE_TYPE_DOUBLE: return "Float64";
|
case BASE_TYPE_UINT:
|
||||||
case BASE_TYPE_STRING: return "String";
|
return "Uint32";
|
||||||
case BASE_TYPE_VECTOR: return GenType(type.VectorType());
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_STRUCT: return namer_.Type(*type.struct_def);
|
return "Int64";
|
||||||
case BASE_TYPE_UNION: return namer_.Type(*type.enum_def) + "TypeId";
|
case BASE_TYPE_ULONG:
|
||||||
default: return "Table";
|
return "Uint64";
|
||||||
|
case BASE_TYPE_FLOAT:
|
||||||
|
return "Float32";
|
||||||
|
case BASE_TYPE_DOUBLE:
|
||||||
|
return "Float64";
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
return "String";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return GenType(type.VectorType());
|
||||||
|
case BASE_TYPE_STRUCT:
|
||||||
|
return namer_.Type(*type.struct_def);
|
||||||
|
case BASE_TYPE_UNION:
|
||||||
|
return namer_.Type(*type.enum_def) + "TypeId";
|
||||||
|
default:
|
||||||
|
return "Table";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string EnumSize(const Type &type) {
|
static std::string EnumSize(const Type& type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_BOOL:
|
case BASE_TYPE_BOOL:
|
||||||
case BASE_TYPE_CHAR:
|
case BASE_TYPE_CHAR:
|
||||||
case BASE_TYPE_UTYPE:
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_UCHAR: return "1";
|
case BASE_TYPE_UCHAR:
|
||||||
|
return "1";
|
||||||
case BASE_TYPE_SHORT:
|
case BASE_TYPE_SHORT:
|
||||||
case BASE_TYPE_USHORT: return "2";
|
case BASE_TYPE_USHORT:
|
||||||
|
return "2";
|
||||||
case BASE_TYPE_INT:
|
case BASE_TYPE_INT:
|
||||||
case BASE_TYPE_UINT:
|
case BASE_TYPE_UINT:
|
||||||
case BASE_TYPE_FLOAT: return "4";
|
case BASE_TYPE_FLOAT:
|
||||||
|
return "4";
|
||||||
case BASE_TYPE_LONG:
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_ULONG:
|
case BASE_TYPE_ULONG:
|
||||||
case BASE_TYPE_DOUBLE: return "8";
|
case BASE_TYPE_DOUBLE:
|
||||||
default: return "1";
|
return "8";
|
||||||
|
default:
|
||||||
|
return "1";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenReaderTypeName(const Type &type, Namespace *current_namespace,
|
std::string GenReaderTypeName(const Type& type, Namespace* current_namespace,
|
||||||
const FieldDef &def,
|
const FieldDef& def,
|
||||||
bool parent_is_vector = false, bool lazy = true,
|
bool parent_is_vector = false, bool lazy = true,
|
||||||
bool constConstruct = true) {
|
bool constConstruct = true) {
|
||||||
std::string prefix = (constConstruct ? "const " : "") + _kFb;
|
std::string prefix = (constConstruct ? "const " : "") + _kFb;
|
||||||
@@ -357,8 +388,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDartTypeName(const Type &type, Namespace *current_namespace,
|
std::string GenDartTypeName(const Type& type, Namespace* current_namespace,
|
||||||
const FieldDef &def,
|
const FieldDef& def,
|
||||||
std::string struct_type_suffix = "") {
|
std::string struct_type_suffix = "") {
|
||||||
if (type.enum_def) {
|
if (type.enum_def) {
|
||||||
if (type.enum_def->is_union && type.base_type != BASE_TYPE_UNION) {
|
if (type.enum_def->is_union && type.base_type != BASE_TYPE_UNION) {
|
||||||
@@ -371,7 +402,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_BOOL: return "bool";
|
case BASE_TYPE_BOOL:
|
||||||
|
return "bool";
|
||||||
case BASE_TYPE_LONG:
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_ULONG:
|
case BASE_TYPE_ULONG:
|
||||||
case BASE_TYPE_INT:
|
case BASE_TYPE_INT:
|
||||||
@@ -379,10 +411,13 @@ class DartGenerator : public BaseGenerator {
|
|||||||
case BASE_TYPE_SHORT:
|
case BASE_TYPE_SHORT:
|
||||||
case BASE_TYPE_USHORT:
|
case BASE_TYPE_USHORT:
|
||||||
case BASE_TYPE_CHAR:
|
case BASE_TYPE_CHAR:
|
||||||
case BASE_TYPE_UCHAR: return "int";
|
case BASE_TYPE_UCHAR:
|
||||||
|
return "int";
|
||||||
case BASE_TYPE_FLOAT:
|
case BASE_TYPE_FLOAT:
|
||||||
case BASE_TYPE_DOUBLE: return "double";
|
case BASE_TYPE_DOUBLE:
|
||||||
case BASE_TYPE_STRING: return "String";
|
return "double";
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
return "String";
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
return MaybeWrapNamespace(
|
return MaybeWrapNamespace(
|
||||||
namer_.Type(*type.struct_def) + struct_type_suffix,
|
namer_.Type(*type.struct_def) + struct_type_suffix,
|
||||||
@@ -392,12 +427,14 @@ class DartGenerator : public BaseGenerator {
|
|||||||
GenDartTypeName(type.VectorType(), current_namespace, def,
|
GenDartTypeName(type.VectorType(), current_namespace, def,
|
||||||
struct_type_suffix) +
|
struct_type_suffix) +
|
||||||
">";
|
">";
|
||||||
default: assert(0); return "dynamic";
|
default:
|
||||||
|
assert(0);
|
||||||
|
return "dynamic";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDartTypeName(const Type &type, Namespace *current_namespace,
|
std::string GenDartTypeName(const Type& type, Namespace* current_namespace,
|
||||||
const FieldDef &def, bool nullable,
|
const FieldDef& def, bool nullable,
|
||||||
std::string struct_type_suffix) {
|
std::string struct_type_suffix) {
|
||||||
std::string typeName =
|
std::string typeName =
|
||||||
GenDartTypeName(type, current_namespace, def, struct_type_suffix);
|
GenDartTypeName(type, current_namespace, def, struct_type_suffix);
|
||||||
@@ -405,9 +442,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
return typeName;
|
return typeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MaybeWrapNamespace(const std::string &type_name,
|
std::string MaybeWrapNamespace(const std::string& type_name,
|
||||||
Namespace *current_ns,
|
Namespace* current_ns,
|
||||||
const FieldDef &field) const {
|
const FieldDef& field) const {
|
||||||
const std::string current_namespace = namer_.Namespace(*current_ns);
|
const std::string current_namespace = namer_.Namespace(*current_ns);
|
||||||
const std::string field_namespace =
|
const std::string field_namespace =
|
||||||
field.value.type.struct_def
|
field.value.type.struct_def
|
||||||
@@ -424,14 +461,14 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate an accessor struct with constructor for a flatbuffers struct.
|
// Generate an accessor struct with constructor for a flatbuffers struct.
|
||||||
void GenStruct(const StructDef &struct_def,
|
void GenStruct(const StructDef& struct_def,
|
||||||
namespace_code_map &namespace_code) {
|
namespace_code_map& namespace_code) {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
|
|
||||||
std::string &code =
|
std::string& code =
|
||||||
namespace_code[namer_.Namespace(*struct_def.defined_namespace)];
|
namespace_code[namer_.Namespace(*struct_def.defined_namespace)];
|
||||||
|
|
||||||
const auto &struct_type = namer_.Type(struct_def);
|
const auto& struct_type = namer_.Type(struct_def);
|
||||||
|
|
||||||
// Emit constructor
|
// Emit constructor
|
||||||
|
|
||||||
@@ -461,10 +498,10 @@ class DartGenerator : public BaseGenerator {
|
|||||||
code += " final " + _kFb + ".BufferContext _bc;\n";
|
code += " final " + _kFb + ".BufferContext _bc;\n";
|
||||||
code += " final int _bcOffset;\n\n";
|
code += " final int _bcOffset;\n\n";
|
||||||
|
|
||||||
std::vector<std::pair<int, FieldDef *>> non_deprecated_fields;
|
std::vector<std::pair<int, FieldDef*>> non_deprecated_fields;
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
FieldDef &field = **it;
|
FieldDef& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
auto offset = static_cast<int>(it - struct_def.fields.vec.begin());
|
auto offset = static_cast<int>(it - struct_def.fields.vec.begin());
|
||||||
non_deprecated_fields.push_back(std::make_pair(offset, &field));
|
non_deprecated_fields.push_back(std::make_pair(offset, &field));
|
||||||
@@ -500,8 +537,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Generate an accessor struct with constructor for a flatbuffers struct.
|
// Generate an accessor struct with constructor for a flatbuffers struct.
|
||||||
std::string GenStructObjectAPI(
|
std::string GenStructObjectAPI(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields) {
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields) {
|
||||||
std::string code;
|
std::string code;
|
||||||
GenDocComment(struct_def.doc_comment, "", code);
|
GenDocComment(struct_def.doc_comment, "", code);
|
||||||
|
|
||||||
@@ -511,7 +548,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
std::string constructor_args;
|
std::string constructor_args;
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(field);
|
const std::string field_name = namer_.Field(field);
|
||||||
const std::string defaultValue = getDefaultValue(field.value);
|
const std::string defaultValue = getDefaultValue(field.value);
|
||||||
@@ -528,7 +565,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
constructor_args += "this." + field_name;
|
constructor_args += "this." + field_name;
|
||||||
if (!struct_def.fixed && !defaultValue.empty()) {
|
if (!struct_def.fixed && !defaultValue.empty()) {
|
||||||
if (IsEnum(field.value.type)) {
|
if (IsEnum(field.value.type)) {
|
||||||
auto &enum_def = *field.value.type.enum_def;
|
auto& enum_def = *field.value.type.enum_def;
|
||||||
if (auto val = enum_def.FindByValue(defaultValue)) {
|
if (auto val = enum_def.FindByValue(defaultValue)) {
|
||||||
constructor_args += " = " + namer_.EnumVariant(enum_def, *val);
|
constructor_args += " = " + namer_.EnumVariant(enum_def, *val);
|
||||||
} else {
|
} else {
|
||||||
@@ -554,18 +591,18 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Generate function `StructNameT unpack()`
|
// Generate function `StructNameT unpack()`
|
||||||
std::string GenStructObjectAPIUnpack(
|
std::string GenStructObjectAPIUnpack(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields) {
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields) {
|
||||||
std::string constructor_args;
|
std::string constructor_args;
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(field);
|
const std::string field_name = namer_.Field(field);
|
||||||
if (!constructor_args.empty()) constructor_args += ",\n";
|
if (!constructor_args.empty()) constructor_args += ",\n";
|
||||||
constructor_args += " " + field_name + ": ";
|
constructor_args += " " + field_name + ": ";
|
||||||
|
|
||||||
const Type &type = field.value.type;
|
const Type& type = field.value.type;
|
||||||
std::string defaultValue = getDefaultValue(field.value);
|
std::string defaultValue = getDefaultValue(field.value);
|
||||||
bool isNullable = defaultValue.empty() && !struct_def.fixed;
|
bool isNullable = defaultValue.empty() && !struct_def.fixed;
|
||||||
std::string nullableValueAccessOperator = isNullable ? "?" : "";
|
std::string nullableValueAccessOperator = isNullable ? "?" : "";
|
||||||
@@ -601,8 +638,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Generate function `StructNameT pack()`
|
// Generate function `StructNameT pack()`
|
||||||
std::string GenStructObjectAPIPack(
|
std::string GenStructObjectAPIPack(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields) {
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields) {
|
||||||
std::string code;
|
std::string code;
|
||||||
|
|
||||||
code += " @override\n";
|
code += " @override\n";
|
||||||
@@ -613,8 +650,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NamespaceAliasFromUnionType(Namespace *root_namespace,
|
std::string NamespaceAliasFromUnionType(Namespace* root_namespace,
|
||||||
const Type &type) {
|
const Type& type) {
|
||||||
const std::vector<std::string> qualified_name_parts =
|
const std::vector<std::string> qualified_name_parts =
|
||||||
type.struct_def->defined_namespace->components;
|
type.struct_def->defined_namespace->components;
|
||||||
if (std::equal(root_namespace->components.begin(),
|
if (std::equal(root_namespace->components.begin(),
|
||||||
@@ -627,7 +664,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = qualified_name_parts.begin();
|
for (auto it = qualified_name_parts.begin();
|
||||||
it != qualified_name_parts.end(); ++it) {
|
it != qualified_name_parts.end(); ++it) {
|
||||||
auto &part = *it;
|
auto& part = *it;
|
||||||
|
|
||||||
for (size_t i = 0; i < part.length(); i++) {
|
for (size_t i = 0; i < part.length(); i++) {
|
||||||
if (i && !isdigit(part[i]) && part[i] == CharToUpper(part[i])) {
|
if (i && !isdigit(part[i]) && part[i] == CharToUpper(part[i])) {
|
||||||
@@ -637,19 +674,21 @@ class DartGenerator : public BaseGenerator {
|
|||||||
ns += CharToLower(part[i]);
|
ns += CharToLower(part[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (it != qualified_name_parts.end() - 1) { ns += "_"; }
|
if (it != qualified_name_parts.end() - 1) {
|
||||||
|
ns += "_";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ns + "." + namer_.Type(*type.struct_def);
|
return ns + "." + namer_.Type(*type.struct_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenImplementationGetters(
|
void GenImplementationGetters(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
std::string &code) {
|
std::string& code) {
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
const std::string field_name = namer_.Field(field);
|
const std::string field_name = namer_.Field(field);
|
||||||
const std::string defaultValue = getDefaultValue(field.value);
|
const std::string defaultValue = getDefaultValue(field.value);
|
||||||
@@ -664,10 +703,10 @@ class DartGenerator : public BaseGenerator {
|
|||||||
if (field.value.type.base_type == BASE_TYPE_UNION) {
|
if (field.value.type.base_type == BASE_TYPE_UNION) {
|
||||||
code += " {\n";
|
code += " {\n";
|
||||||
code += " switch (" + field_name + "Type?.value) {\n";
|
code += " switch (" + field_name + "Type?.value) {\n";
|
||||||
const auto &enum_def = *field.value.type.enum_def;
|
const auto& enum_def = *field.value.type.enum_def;
|
||||||
for (auto en_it = enum_def.Vals().begin() + 1;
|
for (auto en_it = enum_def.Vals().begin() + 1;
|
||||||
en_it != enum_def.Vals().end(); ++en_it) {
|
en_it != enum_def.Vals().end(); ++en_it) {
|
||||||
const auto &ev = **en_it;
|
const auto& ev = **en_it;
|
||||||
const auto enum_name = NamespaceAliasFromUnionType(
|
const auto enum_name = NamespaceAliasFromUnionType(
|
||||||
enum_def.defined_namespace, ev.union_type);
|
enum_def.defined_namespace, ev.union_type);
|
||||||
code += " case " + enum_def.ToString(ev) + ": return " +
|
code += " case " + enum_def.ToString(ev) + ": return " +
|
||||||
@@ -713,8 +752,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GenToString(
|
std::string GenToString(
|
||||||
const std::string &object_name,
|
const std::string& object_name,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields) {
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields) {
|
||||||
std::string code;
|
std::string code;
|
||||||
code += " @override\n";
|
code += " @override\n";
|
||||||
code += " String toString() {\n";
|
code += " String toString() {\n";
|
||||||
@@ -730,16 +769,20 @@ class DartGenerator : public BaseGenerator {
|
|||||||
escaped_field.push_back(field[i]);
|
escaped_field.push_back(field[i]);
|
||||||
}
|
}
|
||||||
code += escaped_field + ": ${" + field + "}";
|
code += escaped_field + ": ${" + field + "}";
|
||||||
if (it != non_deprecated_fields.end() - 1) { code += ", "; }
|
if (it != non_deprecated_fields.end() - 1) {
|
||||||
|
code += ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
code += "}';\n";
|
code += "}';\n";
|
||||||
code += " }\n";
|
code += " }\n";
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getDefaultValue(const Value &value) const {
|
std::string getDefaultValue(const Value& value) const {
|
||||||
if (!value.constant.empty() && value.constant != "0") {
|
if (!value.constant.empty() && value.constant != "0") {
|
||||||
if (IsBool(value.type.base_type)) { return "true"; }
|
if (IsBool(value.type.base_type)) {
|
||||||
|
return "true";
|
||||||
|
}
|
||||||
if (IsScalar(value.type.base_type)) {
|
if (IsScalar(value.type.base_type)) {
|
||||||
if (StringIsFlatbufferNan(value.constant)) {
|
if (StringIsFlatbufferNan(value.constant)) {
|
||||||
return "double.nan";
|
return "double.nan";
|
||||||
@@ -759,8 +802,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenReader(const StructDef &struct_def, const std::string &reader_name,
|
void GenReader(const StructDef& struct_def, const std::string& reader_name,
|
||||||
std::string &code) {
|
std::string& code) {
|
||||||
const auto struct_type = namer_.Type(struct_def);
|
const auto struct_type = namer_.Type(struct_def);
|
||||||
|
|
||||||
code += "class " + reader_name + " extends " + _kFb;
|
code += "class " + reader_name + " extends " + _kFb;
|
||||||
@@ -784,10 +827,12 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenBuilder(
|
void GenBuilder(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
const std::string &builder_name, std::string &code) {
|
const std::string& builder_name, std::string& code) {
|
||||||
if (non_deprecated_fields.size() == 0) { return; }
|
if (non_deprecated_fields.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
code += "class " + builder_name + " {\n";
|
code += "class " + builder_name + " {\n";
|
||||||
code += " " + builder_name + "(this.fbBuilder);\n\n";
|
code += " " + builder_name + "(this.fbBuilder);\n\n";
|
||||||
@@ -803,13 +848,13 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void StructBuilderBody(
|
void StructBuilderBody(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
std::string &code) {
|
std::string& code) {
|
||||||
code += " int finish(";
|
code += " int finish(";
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
const std::string field_name = namer_.Field(field);
|
const std::string field_name = namer_.Field(field);
|
||||||
|
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
@@ -819,13 +864,15 @@ class DartGenerator : public BaseGenerator {
|
|||||||
field);
|
field);
|
||||||
}
|
}
|
||||||
code += " " + field_name;
|
code += " " + field_name;
|
||||||
if (it != non_deprecated_fields.end() - 1) { code += ", "; }
|
if (it != non_deprecated_fields.end() - 1) {
|
||||||
|
code += ", ";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
code += ") {\n";
|
code += ") {\n";
|
||||||
|
|
||||||
for (auto it = non_deprecated_fields.rbegin();
|
for (auto it = non_deprecated_fields.rbegin();
|
||||||
it != non_deprecated_fields.rend(); ++it) {
|
it != non_deprecated_fields.rend(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
const std::string field_name = namer_.Field(field);
|
const std::string field_name = namer_.Field(field);
|
||||||
|
|
||||||
if (field.padding) {
|
if (field.padding) {
|
||||||
@@ -837,7 +884,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
code += " fbBuilder.put" + GenType(field.value.type) + "(";
|
code += " fbBuilder.put" + GenType(field.value.type) + "(";
|
||||||
code += field_name;
|
code += field_name;
|
||||||
if (field.value.type.enum_def) { code += ".value"; }
|
if (field.value.type.enum_def) {
|
||||||
|
code += ".value";
|
||||||
|
}
|
||||||
code += ");\n";
|
code += ");\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -846,9 +895,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TableBuilderBody(
|
void TableBuilderBody(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
std::string &code) {
|
std::string& code) {
|
||||||
code += " void begin() {\n";
|
code += " void begin() {\n";
|
||||||
code += " fbBuilder.startTable(" +
|
code += " fbBuilder.startTable(" +
|
||||||
NumToString(struct_def.fields.vec.size()) + ");\n";
|
NumToString(struct_def.fields.vec.size()) + ");\n";
|
||||||
@@ -856,7 +905,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const auto &field = *it->second;
|
const auto& field = *it->second;
|
||||||
const auto offset = it->first;
|
const auto offset = it->first;
|
||||||
const std::string add_field = namer_.Method("add", field);
|
const std::string add_field = namer_.Method("add", field);
|
||||||
const std::string field_var = namer_.Variable(field);
|
const std::string field_var = namer_.Variable(field);
|
||||||
@@ -869,7 +918,9 @@ class DartGenerator : public BaseGenerator {
|
|||||||
code += " fbBuilder.add" + GenType(field.value.type) + "(" +
|
code += " fbBuilder.add" + GenType(field.value.type) + "(" +
|
||||||
NumToString(offset) + ", ";
|
NumToString(offset) + ", ";
|
||||||
code += field_var;
|
code += field_var;
|
||||||
if (field.value.type.enum_def) { code += "?.value"; }
|
if (field.value.type.enum_def) {
|
||||||
|
code += "?.value";
|
||||||
|
}
|
||||||
code += ");\n";
|
code += ");\n";
|
||||||
} else if (IsStruct(field.value.type)) {
|
} else if (IsStruct(field.value.type)) {
|
||||||
code += " int " + add_field + "(int offset) {\n";
|
code += " int " + add_field + "(int offset) {\n";
|
||||||
@@ -891,13 +942,13 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenObjectBuilder(
|
void GenObjectBuilder(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
const std::string &builder_name, std::string &code) {
|
const std::string& builder_name, std::string& code) {
|
||||||
code += "class " + builder_name + " extends " + _kFb + ".ObjectBuilder {\n";
|
code += "class " + builder_name + " extends " + _kFb + ".ObjectBuilder {\n";
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
code += " final " +
|
code += " final " +
|
||||||
GenDartTypeName(field.value.type, struct_def.defined_namespace,
|
GenDartTypeName(field.value.type, struct_def.defined_namespace,
|
||||||
@@ -911,7 +962,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
code += "{\n";
|
code += "{\n";
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
code += " ";
|
code += " ";
|
||||||
code += (struct_def.fixed ? "required " : "") +
|
code += (struct_def.fixed ? "required " : "") +
|
||||||
@@ -923,7 +974,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
code += " : ";
|
code += " : ";
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
code += "_" + namer_.Variable(field) + " = " + namer_.Variable(field);
|
code += "_" + namer_.Variable(field) + " = " + namer_.Variable(field);
|
||||||
if (it == non_deprecated_fields.end() - 1) {
|
if (it == non_deprecated_fields.end() - 1) {
|
||||||
@@ -954,13 +1005,13 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GenObjectBuilderImplementation(
|
std::string GenObjectBuilderImplementation(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
bool prependUnderscore = true, bool pack = false) {
|
bool prependUnderscore = true, bool pack = false) {
|
||||||
std::string code;
|
std::string code;
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
|
|
||||||
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type))
|
if (IsScalar(field.value.type.base_type) || IsStruct(field.value.type))
|
||||||
continue;
|
continue;
|
||||||
@@ -1029,13 +1080,13 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string StructObjectBuilderBody(
|
std::string StructObjectBuilderBody(
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
bool prependUnderscore = true, bool pack = false) {
|
bool prependUnderscore = true, bool pack = false) {
|
||||||
std::string code;
|
std::string code;
|
||||||
|
|
||||||
for (auto it = non_deprecated_fields.rbegin();
|
for (auto it = non_deprecated_fields.rbegin();
|
||||||
it != non_deprecated_fields.rend(); ++it) {
|
it != non_deprecated_fields.rend(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
const std::string field_name = namer_.Field(field);
|
const std::string field_name = namer_.Field(field);
|
||||||
|
|
||||||
if (field.padding) {
|
if (field.padding) {
|
||||||
@@ -1044,13 +1095,19 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
code += " ";
|
code += " ";
|
||||||
if (prependUnderscore) { code += "_"; }
|
if (prependUnderscore) {
|
||||||
|
code += "_";
|
||||||
|
}
|
||||||
code += field_name + (pack ? ".pack" : ".finish") + "(fbBuilder);\n";
|
code += field_name + (pack ? ".pack" : ".finish") + "(fbBuilder);\n";
|
||||||
} else {
|
} else {
|
||||||
code += " fbBuilder.put" + GenType(field.value.type) + "(";
|
code += " fbBuilder.put" + GenType(field.value.type) + "(";
|
||||||
if (prependUnderscore) { code += "_"; }
|
if (prependUnderscore) {
|
||||||
|
code += "_";
|
||||||
|
}
|
||||||
code += field_name;
|
code += field_name;
|
||||||
if (field.value.type.enum_def) { code += ".value"; }
|
if (field.value.type.enum_def) {
|
||||||
|
code += ".value";
|
||||||
|
}
|
||||||
code += ");\n";
|
code += ");\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1060,8 +1117,8 @@ class DartGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string TableObjectBuilderBody(
|
std::string TableObjectBuilderBody(
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
const std::vector<std::pair<int, FieldDef *>> &non_deprecated_fields,
|
const std::vector<std::pair<int, FieldDef*>>& non_deprecated_fields,
|
||||||
bool prependUnderscore = true, bool pack = false) {
|
bool prependUnderscore = true, bool pack = false) {
|
||||||
std::string code;
|
std::string code;
|
||||||
code += " fbBuilder.startTable(" +
|
code += " fbBuilder.startTable(" +
|
||||||
@@ -1069,7 +1126,7 @@ class DartGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = non_deprecated_fields.begin();
|
for (auto it = non_deprecated_fields.begin();
|
||||||
it != non_deprecated_fields.end(); ++it) {
|
it != non_deprecated_fields.end(); ++it) {
|
||||||
const FieldDef &field = *it->second;
|
const FieldDef& field = *it->second;
|
||||||
auto offset = it->first;
|
auto offset = it->first;
|
||||||
|
|
||||||
std::string field_var =
|
std::string field_var =
|
||||||
@@ -1101,14 +1158,14 @@ class DartGenerator : public BaseGenerator {
|
|||||||
};
|
};
|
||||||
} // namespace dart
|
} // namespace dart
|
||||||
|
|
||||||
static bool GenerateDart(const Parser &parser, const std::string &path,
|
static bool GenerateDart(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
dart::DartGenerator generator(parser, path, file_name);
|
dart::DartGenerator generator(parser, path, file_name);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string DartMakeRule(const Parser &parser, const std::string &path,
|
static std::string DartMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
auto filebase =
|
auto filebase =
|
||||||
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
|
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
|
||||||
dart::DartGenerator generator(parser, path, file_name);
|
dart::DartGenerator generator(parser, path, file_name);
|
||||||
@@ -1125,34 +1182,35 @@ namespace {
|
|||||||
|
|
||||||
class DartCodeGenerator : public CodeGenerator {
|
class DartCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateDart(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateDart(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
output = DartMakeRule(parser, path, filename);
|
output = DartMakeRule(parser, path, filename);
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
@@ -30,12 +30,13 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static std::string GenType(const Type &type, bool underlying = false) {
|
static std::string GenType(const Type& type, bool underlying = false) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
return type.struct_def->defined_namespace->GetFullyQualifiedName(
|
return type.struct_def->defined_namespace->GetFullyQualifiedName(
|
||||||
type.struct_def->name);
|
type.struct_def->name);
|
||||||
case BASE_TYPE_VECTOR: return "[" + GenType(type.VectorType()) + "]";
|
case BASE_TYPE_VECTOR:
|
||||||
|
return "[" + GenType(type.VectorType()) + "]";
|
||||||
default:
|
default:
|
||||||
if (type.enum_def && !underlying) {
|
if (type.enum_def && !underlying) {
|
||||||
return type.enum_def->defined_namespace->GetFullyQualifiedName(
|
return type.enum_def->defined_namespace->GetFullyQualifiedName(
|
||||||
@@ -46,11 +47,11 @@ static std::string GenType(const Type &type, bool underlying = false) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasFieldWithId(const std::vector<FieldDef *> &fields) {
|
static bool HasFieldWithId(const std::vector<FieldDef*>& fields) {
|
||||||
static const std::string ID = "id";
|
static const std::string ID = "id";
|
||||||
|
|
||||||
for (const auto *field : fields) {
|
for (const auto* field : fields) {
|
||||||
const auto *id_attribute = field->attributes.Lookup(ID);
|
const auto* id_attribute = field->attributes.Lookup(ID);
|
||||||
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -58,81 +59,93 @@ static bool HasFieldWithId(const std::vector<FieldDef *> &fields) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasNonPositiveFieldId(const std::vector<FieldDef *> &fields) {
|
static bool HasNonPositiveFieldId(const std::vector<FieldDef*>& fields) {
|
||||||
static const std::string ID = "id";
|
static const std::string ID = "id";
|
||||||
|
|
||||||
for (const auto *field : fields) {
|
for (const auto* field : fields) {
|
||||||
const auto *id_attribute = field->attributes.Lookup(ID);
|
const auto* id_attribute = field->attributes.Lookup(ID);
|
||||||
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
||||||
voffset_t proto_id = 0;
|
voffset_t proto_id = 0;
|
||||||
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
|
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
|
||||||
if (!done) { return true; }
|
if (!done) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasFieldIdFromReservedIds(
|
static bool HasFieldIdFromReservedIds(
|
||||||
const std::vector<FieldDef *> &fields,
|
const std::vector<FieldDef*>& fields,
|
||||||
const std::vector<voffset_t> &reserved_ids) {
|
const std::vector<voffset_t>& reserved_ids) {
|
||||||
static const std::string ID = "id";
|
static const std::string ID = "id";
|
||||||
|
|
||||||
for (const auto *field : fields) {
|
for (const auto* field : fields) {
|
||||||
const auto *id_attribute = field->attributes.Lookup(ID);
|
const auto* id_attribute = field->attributes.Lookup(ID);
|
||||||
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
||||||
voffset_t proto_id = 0;
|
voffset_t proto_id = 0;
|
||||||
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
|
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
|
||||||
if (!done) { return true; }
|
if (!done) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
auto id_it =
|
auto id_it =
|
||||||
std::find(std::begin(reserved_ids), std::end(reserved_ids), proto_id);
|
std::find(std::begin(reserved_ids), std::end(reserved_ids), proto_id);
|
||||||
if (id_it != reserved_ids.end()) { return true; }
|
if (id_it != reserved_ids.end()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::vector<voffset_t> ExtractProtobufIds(
|
static std::vector<voffset_t> ExtractProtobufIds(
|
||||||
const std::vector<FieldDef *> &fields) {
|
const std::vector<FieldDef*>& fields) {
|
||||||
static const std::string ID = "id";
|
static const std::string ID = "id";
|
||||||
std::vector<voffset_t> used_proto_ids;
|
std::vector<voffset_t> used_proto_ids;
|
||||||
for (const auto *field : fields) {
|
for (const auto* field : fields) {
|
||||||
const auto *id_attribute = field->attributes.Lookup(ID);
|
const auto* id_attribute = field->attributes.Lookup(ID);
|
||||||
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
if (id_attribute != nullptr && !id_attribute->constant.empty()) {
|
||||||
voffset_t proto_id = 0;
|
voffset_t proto_id = 0;
|
||||||
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
|
bool done = StringToNumber(id_attribute->constant.c_str(), &proto_id);
|
||||||
if (done) { used_proto_ids.push_back(proto_id); }
|
if (done) {
|
||||||
|
used_proto_ids.push_back(proto_id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return used_proto_ids;
|
return used_proto_ids;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasTwiceUsedId(const std::vector<FieldDef *> &fields) {
|
static bool HasTwiceUsedId(const std::vector<FieldDef*>& fields) {
|
||||||
std::vector<voffset_t> used_proto_ids = ExtractProtobufIds(fields);
|
std::vector<voffset_t> used_proto_ids = ExtractProtobufIds(fields);
|
||||||
std::sort(std::begin(used_proto_ids), std::end(used_proto_ids));
|
std::sort(std::begin(used_proto_ids), std::end(used_proto_ids));
|
||||||
for (auto it = std::next(std::begin(used_proto_ids));
|
for (auto it = std::next(std::begin(used_proto_ids));
|
||||||
it != std::end(used_proto_ids); it++) {
|
it != std::end(used_proto_ids); it++) {
|
||||||
if (*it == *std::prev(it)) { return true; }
|
if (*it == *std::prev(it)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool HasGapInProtoId(const std::vector<FieldDef *> &fields) {
|
static bool HasGapInProtoId(const std::vector<FieldDef*>& fields) {
|
||||||
std::vector<voffset_t> used_proto_ids = ExtractProtobufIds(fields);
|
std::vector<voffset_t> used_proto_ids = ExtractProtobufIds(fields);
|
||||||
std::sort(std::begin(used_proto_ids), std::end(used_proto_ids));
|
std::sort(std::begin(used_proto_ids), std::end(used_proto_ids));
|
||||||
for (auto it = std::next(std::begin(used_proto_ids));
|
for (auto it = std::next(std::begin(used_proto_ids));
|
||||||
it != std::end(used_proto_ids); it++) {
|
it != std::end(used_proto_ids); it++) {
|
||||||
if (*it != *std::prev(it) + 1) { return true; }
|
if (*it != *std::prev(it) + 1) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool ProtobufIdSanityCheck(const StructDef &struct_def,
|
static bool ProtobufIdSanityCheck(const StructDef& struct_def,
|
||||||
IDLOptions::ProtoIdGapAction gap_action,
|
IDLOptions::ProtoIdGapAction gap_action,
|
||||||
bool no_log = false) {
|
bool no_log = false) {
|
||||||
const auto &fields = struct_def.fields.vec;
|
const auto& fields = struct_def.fields.vec;
|
||||||
if (HasNonPositiveFieldId(fields)) {
|
if (HasNonPositiveFieldId(fields)) {
|
||||||
// TODO: Use LogCompilerWarn
|
// TODO: Use LogCompilerWarn
|
||||||
if (!no_log) {
|
if (!no_log) {
|
||||||
@@ -167,7 +180,9 @@ static bool ProtobufIdSanityCheck(const StructDef &struct_def,
|
|||||||
fprintf(stderr, "Fields in struct %s have gap between ids\n",
|
fprintf(stderr, "Fields in struct %s have gap between ids\n",
|
||||||
struct_def.name.c_str());
|
struct_def.name.c_str());
|
||||||
}
|
}
|
||||||
if (gap_action == IDLOptions::ProtoIdGapAction::ERROR) { return false; }
|
if (gap_action == IDLOptions::ProtoIdGapAction::ERROR) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -184,9 +199,9 @@ struct ProtobufToFbsIdMap {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static ProtobufToFbsIdMap MapProtoIdsToFieldsId(
|
static ProtobufToFbsIdMap MapProtoIdsToFieldsId(
|
||||||
const StructDef &struct_def, IDLOptions::ProtoIdGapAction gap_action,
|
const StructDef& struct_def, IDLOptions::ProtoIdGapAction gap_action,
|
||||||
bool no_log) {
|
bool no_log) {
|
||||||
const auto &fields = struct_def.fields.vec;
|
const auto& fields = struct_def.fields.vec;
|
||||||
|
|
||||||
if (!HasFieldWithId(fields)) {
|
if (!HasFieldWithId(fields)) {
|
||||||
ProtobufToFbsIdMap result;
|
ProtobufToFbsIdMap result;
|
||||||
@@ -194,14 +209,16 @@ static ProtobufToFbsIdMap MapProtoIdsToFieldsId(
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ProtobufIdSanityCheck(struct_def, gap_action, no_log)) { return {}; }
|
if (!ProtobufIdSanityCheck(struct_def, gap_action, no_log)) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
static constexpr int UNION_ID = -1;
|
static constexpr int UNION_ID = -1;
|
||||||
using ProtoIdFieldNamePair = std::pair<int, std::string>;
|
using ProtoIdFieldNamePair = std::pair<int, std::string>;
|
||||||
std::vector<ProtoIdFieldNamePair> proto_ids;
|
std::vector<ProtoIdFieldNamePair> proto_ids;
|
||||||
|
|
||||||
for (const auto *field : fields) {
|
for (const auto* field : fields) {
|
||||||
const auto *id_attribute = field->attributes.Lookup("id");
|
const auto* id_attribute = field->attributes.Lookup("id");
|
||||||
if (id_attribute != nullptr) {
|
if (id_attribute != nullptr) {
|
||||||
// When we have union but do not use union flag to keep them
|
// When we have union but do not use union flag to keep them
|
||||||
if (id_attribute->constant.empty() &&
|
if (id_attribute->constant.empty() &&
|
||||||
@@ -224,25 +241,27 @@ static ProtobufToFbsIdMap MapProtoIdsToFieldsId(
|
|||||||
|
|
||||||
std::sort(
|
std::sort(
|
||||||
std::begin(proto_ids), std::end(proto_ids),
|
std::begin(proto_ids), std::end(proto_ids),
|
||||||
[](const ProtoIdFieldNamePair &rhs, const ProtoIdFieldNamePair &lhs) {
|
[](const ProtoIdFieldNamePair& rhs, const ProtoIdFieldNamePair& lhs) {
|
||||||
return rhs.first < lhs.first;
|
return rhs.first < lhs.first;
|
||||||
});
|
});
|
||||||
struct ProtobufToFbsIdMap proto_to_fbs;
|
struct ProtobufToFbsIdMap proto_to_fbs;
|
||||||
|
|
||||||
voffset_t id = 0;
|
voffset_t id = 0;
|
||||||
for (const auto &element : proto_ids) {
|
for (const auto& element : proto_ids) {
|
||||||
if (element.first == UNION_ID) { id++; }
|
if (element.first == UNION_ID) {
|
||||||
|
id++;
|
||||||
|
}
|
||||||
proto_to_fbs.field_to_id.emplace(element.second, id++);
|
proto_to_fbs.field_to_id.emplace(element.second, id++);
|
||||||
}
|
}
|
||||||
proto_to_fbs.successful = true;
|
proto_to_fbs.successful = true;
|
||||||
return proto_to_fbs;
|
return proto_to_fbs;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenNameSpace(const Namespace &name_space, std::string *_schema,
|
static void GenNameSpace(const Namespace& name_space, std::string* _schema,
|
||||||
const Namespace **last_namespace) {
|
const Namespace** last_namespace) {
|
||||||
if (*last_namespace == &name_space) return;
|
if (*last_namespace == &name_space) return;
|
||||||
*last_namespace = &name_space;
|
*last_namespace = &name_space;
|
||||||
auto &schema = *_schema;
|
auto& schema = *_schema;
|
||||||
schema += "namespace ";
|
schema += "namespace ";
|
||||||
for (auto it = name_space.components.begin();
|
for (auto it = name_space.components.begin();
|
||||||
it != name_space.components.end(); ++it) {
|
it != name_space.components.end(); ++it) {
|
||||||
@@ -253,14 +272,14 @@ static void GenNameSpace(const Namespace &name_space, std::string *_schema,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a flatbuffer schema from the Parser's internal representation.
|
// Generate a flatbuffer schema from the Parser's internal representation.
|
||||||
static std::string GenerateFBS(const Parser &parser,
|
static std::string GenerateFBS(const Parser& parser,
|
||||||
const std::string &file_name,
|
const std::string& file_name,
|
||||||
bool no_log = false) {
|
bool no_log = false) {
|
||||||
// Proto namespaces may clash with table names, escape the ones that were
|
// Proto namespaces may clash with table names, escape the ones that were
|
||||||
// generated from a table:
|
// generated from a table:
|
||||||
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
|
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &ns = **it;
|
auto& ns = **it;
|
||||||
for (size_t i = 0; i < ns.from_table; i++) {
|
for (size_t i = 0; i < ns.from_table; i++) {
|
||||||
ns.components[ns.components.size() - 1 - i] += "_";
|
ns.components[ns.components.size() - 1 - i] += "_";
|
||||||
}
|
}
|
||||||
@@ -298,10 +317,10 @@ static std::string GenerateFBS(const Parser &parser,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate code for all the enum declarations.
|
// Generate code for all the enum declarations.
|
||||||
const Namespace *last_namespace = nullptr;
|
const Namespace* last_namespace = nullptr;
|
||||||
for (auto enum_def_it = parser.enums_.vec.begin();
|
for (auto enum_def_it = parser.enums_.vec.begin();
|
||||||
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
|
enum_def_it != parser.enums_.vec.end(); ++enum_def_it) {
|
||||||
EnumDef &enum_def = **enum_def_it;
|
EnumDef& enum_def = **enum_def_it;
|
||||||
if (parser.opts.include_dependence_headers && enum_def.generated) {
|
if (parser.opts.include_dependence_headers && enum_def.generated) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -316,7 +335,7 @@ static std::string GenerateFBS(const Parser &parser,
|
|||||||
schema += GenType(enum_def.underlying_type, true) + " {\n";
|
schema += GenType(enum_def.underlying_type, true) + " {\n";
|
||||||
|
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
GenComment(ev.doc_comment, &schema, nullptr, " ");
|
GenComment(ev.doc_comment, &schema, nullptr, " ");
|
||||||
if (enum_def.is_union) {
|
if (enum_def.is_union) {
|
||||||
schema += " " + GenType(ev.union_type) + ",\n";
|
schema += " " + GenType(ev.union_type) + ",\n";
|
||||||
@@ -329,10 +348,12 @@ static std::string GenerateFBS(const Parser &parser,
|
|||||||
// Generate code for all structs/tables.
|
// Generate code for all structs/tables.
|
||||||
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
|
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
StructDef &struct_def = **it;
|
StructDef& struct_def = **it;
|
||||||
const auto proto_fbs_ids = MapProtoIdsToFieldsId(
|
const auto proto_fbs_ids = MapProtoIdsToFieldsId(
|
||||||
struct_def, parser.opts.proto_id_gap_action, no_log);
|
struct_def, parser.opts.proto_id_gap_action, no_log);
|
||||||
if (!proto_fbs_ids.successful) { return {}; }
|
if (!proto_fbs_ids.successful) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
if (parser.opts.include_dependence_headers && struct_def.generated) {
|
if (parser.opts.include_dependence_headers && struct_def.generated) {
|
||||||
continue;
|
continue;
|
||||||
@@ -343,7 +364,7 @@ static std::string GenerateFBS(const Parser &parser,
|
|||||||
schema += "table " + struct_def.name + " {\n";
|
schema += "table " + struct_def.name + " {\n";
|
||||||
for (auto field_it = struct_def.fields.vec.begin();
|
for (auto field_it = struct_def.fields.vec.begin();
|
||||||
field_it != struct_def.fields.vec.end(); ++field_it) {
|
field_it != struct_def.fields.vec.end(); ++field_it) {
|
||||||
auto &field = **field_it;
|
auto& field = **field_it;
|
||||||
if (field.value.type.base_type != BASE_TYPE_UTYPE) {
|
if (field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||||
GenComment(field.doc_comment, &schema, nullptr, " ");
|
GenComment(field.doc_comment, &schema, nullptr, " ");
|
||||||
schema += " " + field.name + ":" + GenType(field.value.type);
|
schema += " " + field.name + ":" + GenType(field.value.type);
|
||||||
@@ -361,7 +382,7 @@ static std::string GenerateFBS(const Parser &parser,
|
|||||||
|
|
||||||
if (!attributes.empty()) {
|
if (!attributes.empty()) {
|
||||||
schema += " (";
|
schema += " (";
|
||||||
for (const auto &attribute : attributes) {
|
for (const auto& attribute : attributes) {
|
||||||
schema += attribute + ",";
|
schema += attribute + ",";
|
||||||
}
|
}
|
||||||
schema.pop_back();
|
schema.pop_back();
|
||||||
@@ -376,10 +397,12 @@ static std::string GenerateFBS(const Parser &parser,
|
|||||||
return schema;
|
return schema;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GenerateFBS(const Parser &parser, const std::string &path,
|
static bool GenerateFBS(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name, bool no_log = false) {
|
const std::string& file_name, bool no_log = false) {
|
||||||
const std::string fbs = GenerateFBS(parser, file_name, no_log);
|
const std::string fbs = GenerateFBS(parser, file_name, no_log);
|
||||||
if (fbs.empty()) { return false; }
|
if (fbs.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// TODO: Use LogCompilerWarn
|
// TODO: Use LogCompilerWarn
|
||||||
if (!no_log) {
|
if (!no_log) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
@@ -393,28 +416,29 @@ class FBSCodeGenerator : public CodeGenerator {
|
|||||||
public:
|
public:
|
||||||
explicit FBSCodeGenerator(const bool no_log) : no_log_(no_log) {}
|
explicit FBSCodeGenerator(const bool no_log) : no_log_(no_log) {}
|
||||||
|
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateFBS(parser, path, filename, no_log_)) { return Status::ERROR; }
|
if (!GenerateFBS(parser, path, filename, no_log_)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCodeString(const Parser &parser, const std::string &filename,
|
Status GenerateCodeString(const Parser& parser, const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
output = GenerateFBS(parser, filename, no_log_);
|
output = GenerateFBS(parser, filename, no_log_);
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
||||||
// serialized reflection.fbs.
|
// serialized reflection.fbs.
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -422,16 +446,16 @@ class FBSCodeGenerator : public CodeGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -30,8 +30,8 @@
|
|||||||
#include "src/compiler/ts_generator.h"
|
#include "src/compiler/ts_generator.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(push)
|
#pragma warning(push)
|
||||||
# pragma warning(disable : 4512) // C4512: 'class' : assignment operator could
|
#pragma warning(disable : 4512) // C4512: 'class' : assignment operator could
|
||||||
// not be generated
|
// not be generated
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ class FlatBufMethod : public grpc_generator::Method {
|
|||||||
public:
|
public:
|
||||||
enum Streaming { kNone, kClient, kServer, kBiDi };
|
enum Streaming { kNone, kClient, kServer, kBiDi };
|
||||||
|
|
||||||
FlatBufMethod(const RPCCall *method) : method_(method) {
|
FlatBufMethod(const RPCCall* method) : method_(method) {
|
||||||
streaming_ = kNone;
|
streaming_ = kNone;
|
||||||
auto val = method_->attributes.Lookup("streaming");
|
auto val = method_->attributes.Lookup("streaming");
|
||||||
if (val) {
|
if (val) {
|
||||||
@@ -63,7 +63,7 @@ class FlatBufMethod : public grpc_generator::Method {
|
|||||||
|
|
||||||
// TODO: This method need to incorporate namespace for C++ side. Other
|
// TODO: This method need to incorporate namespace for C++ side. Other
|
||||||
// language bindings simply don't use this method.
|
// language bindings simply don't use this method.
|
||||||
std::string GRPCType(const StructDef &sd) const {
|
std::string GRPCType(const StructDef& sd) const {
|
||||||
return "flatbuffers::grpc::Message<" + sd.name + ">";
|
return "flatbuffers::grpc::Message<" + sd.name + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ class FlatBufMethod : public grpc_generator::Method {
|
|||||||
|
|
||||||
std::string get_output_type_name() const { return (*method_->response).name; }
|
std::string get_output_type_name() const { return (*method_->response).name; }
|
||||||
|
|
||||||
bool get_module_and_message_path_input(grpc::string * /*str*/,
|
bool get_module_and_message_path_input(grpc::string* /*str*/,
|
||||||
grpc::string /*generator_file_name*/,
|
grpc::string /*generator_file_name*/,
|
||||||
bool /*generate_in_pb2_grpc*/,
|
bool /*generate_in_pb2_grpc*/,
|
||||||
grpc::string /*import_prefix*/) const {
|
grpc::string /*import_prefix*/) const {
|
||||||
@@ -87,7 +87,7 @@ class FlatBufMethod : public grpc_generator::Method {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool get_module_and_message_path_output(
|
bool get_module_and_message_path_output(
|
||||||
grpc::string * /*str*/, grpc::string /*generator_file_name*/,
|
grpc::string* /*str*/, grpc::string /*generator_file_name*/,
|
||||||
bool /*generate_in_pb2_grpc*/, grpc::string /*import_prefix*/) const {
|
bool /*generate_in_pb2_grpc*/, grpc::string /*import_prefix*/) const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -107,13 +107,13 @@ class FlatBufMethod : public grpc_generator::Method {
|
|||||||
bool BidiStreaming() const { return streaming_ == kBiDi; }
|
bool BidiStreaming() const { return streaming_ == kBiDi; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const RPCCall *method_;
|
const RPCCall* method_;
|
||||||
Streaming streaming_;
|
Streaming streaming_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatBufService : public grpc_generator::Service {
|
class FlatBufService : public grpc_generator::Service {
|
||||||
public:
|
public:
|
||||||
FlatBufService(const ServiceDef *service) : service_(service) {}
|
FlatBufService(const ServiceDef* service) : service_(service) {}
|
||||||
|
|
||||||
grpc::string GetLeadingComments(const grpc::string) const { return ""; }
|
grpc::string GetLeadingComments(const grpc::string) const { return ""; }
|
||||||
|
|
||||||
@@ -142,20 +142,20 @@ class FlatBufService : public grpc_generator::Service {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const ServiceDef *service_;
|
const ServiceDef* service_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FlatBufPrinter : public grpc_generator::Printer {
|
class FlatBufPrinter : public grpc_generator::Printer {
|
||||||
public:
|
public:
|
||||||
FlatBufPrinter(std::string *str, const char indentation_type)
|
FlatBufPrinter(std::string* str, const char indentation_type)
|
||||||
: str_(str),
|
: str_(str),
|
||||||
escape_char_('$'),
|
escape_char_('$'),
|
||||||
indent_(0),
|
indent_(0),
|
||||||
indentation_size_(2),
|
indentation_size_(2),
|
||||||
indentation_type_(indentation_type) {}
|
indentation_type_(indentation_type) {}
|
||||||
|
|
||||||
void Print(const std::map<std::string, std::string> &vars,
|
void Print(const std::map<std::string, std::string>& vars,
|
||||||
const char *string_template) {
|
const char* string_template) {
|
||||||
std::string s = string_template;
|
std::string s = string_template;
|
||||||
// Replace any occurrences of strings in "vars" that are surrounded
|
// Replace any occurrences of strings in "vars" that are surrounded
|
||||||
// by the escape character by what they're mapped to.
|
// by the escape character by what they're mapped to.
|
||||||
@@ -174,14 +174,16 @@ class FlatBufPrinter : public grpc_generator::Printer {
|
|||||||
Print(s.c_str());
|
Print(s.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Print(const char *s) {
|
void Print(const char* s) {
|
||||||
if (s == nullptr || *s == '\0') { return; }
|
if (s == nullptr || *s == '\0') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
// Add this string, but for each part separated by \n, add indentation.
|
// Add this string, but for each part separated by \n, add indentation.
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// Current indentation.
|
// Current indentation.
|
||||||
str_->insert(str_->end(), indent_ * indentation_size_, indentation_type_);
|
str_->insert(str_->end(), indent_ * indentation_size_, indentation_type_);
|
||||||
// See if this contains more than one line.
|
// See if this contains more than one line.
|
||||||
const char *lf = strchr(s, '\n');
|
const char* lf = strchr(s, '\n');
|
||||||
if (lf) {
|
if (lf) {
|
||||||
(*str_) += std::string(s, lf + 1);
|
(*str_) += std::string(s, lf + 1);
|
||||||
s = lf + 1;
|
s = lf + 1;
|
||||||
@@ -206,7 +208,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string *str_;
|
std::string* str_;
|
||||||
char escape_char_;
|
char escape_char_;
|
||||||
size_t indent_;
|
size_t indent_;
|
||||||
size_t indentation_size_;
|
size_t indentation_size_;
|
||||||
@@ -224,11 +226,11 @@ class FlatBufFile : public grpc_generator::File {
|
|||||||
kLanguageTS
|
kLanguageTS
|
||||||
};
|
};
|
||||||
|
|
||||||
FlatBufFile(const Parser &parser, const std::string &file_name,
|
FlatBufFile(const Parser& parser, const std::string& file_name,
|
||||||
Language language)
|
Language language)
|
||||||
: parser_(parser), file_name_(file_name), language_(language) {}
|
: parser_(parser), file_name_(file_name), language_(language) {}
|
||||||
|
|
||||||
FlatBufFile &operator=(const FlatBufFile &);
|
FlatBufFile& operator=(const FlatBufFile&);
|
||||||
|
|
||||||
grpc::string GetLeadingComments(const grpc::string) const { return ""; }
|
grpc::string GetLeadingComments(const grpc::string) const { return ""; }
|
||||||
|
|
||||||
@@ -257,7 +259,7 @@ class FlatBufFile : public grpc_generator::File {
|
|||||||
case kLanguageCpp: {
|
case kLanguageCpp: {
|
||||||
if (!parser_.opts.grpc_additional_headers.empty()) {
|
if (!parser_.opts.grpc_additional_headers.empty()) {
|
||||||
std::string result = "";
|
std::string result = "";
|
||||||
for (const std::string &header :
|
for (const std::string& header :
|
||||||
parser_.opts.grpc_additional_headers) {
|
parser_.opts.grpc_additional_headers) {
|
||||||
if (!result.empty()) result += "\n";
|
if (!result.empty()) result += "\n";
|
||||||
result += "#include \"" + header + "\"";
|
result += "#include \"" + header + "\"";
|
||||||
@@ -295,21 +297,21 @@ class FlatBufFile : public grpc_generator::File {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<grpc_generator::Printer> CreatePrinter(
|
std::unique_ptr<grpc_generator::Printer> CreatePrinter(
|
||||||
std::string *str, const char indentation_type = ' ') const {
|
std::string* str, const char indentation_type = ' ') const {
|
||||||
return std::unique_ptr<grpc_generator::Printer>(
|
return std::unique_ptr<grpc_generator::Printer>(
|
||||||
new FlatBufPrinter(str, indentation_type));
|
new FlatBufPrinter(str, indentation_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Parser &parser_;
|
const Parser& parser_;
|
||||||
const std::string &file_name_;
|
const std::string& file_name_;
|
||||||
const Language language_;
|
const Language language_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class GoGRPCGenerator : public flatbuffers::BaseGenerator {
|
class GoGRPCGenerator : public flatbuffers::BaseGenerator {
|
||||||
public:
|
public:
|
||||||
GoGRPCGenerator(const Parser &parser, const std::string &path,
|
GoGRPCGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"),
|
: BaseGenerator(parser, path, file_name, "", "" /*Unused*/, "go"),
|
||||||
parser_(parser),
|
parser_(parser),
|
||||||
path_(path),
|
path_(path),
|
||||||
@@ -321,7 +323,7 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
p.custom_method_io_type = "flatbuffers.Builder";
|
p.custom_method_io_type = "flatbuffers.Builder";
|
||||||
for (int i = 0; i < file.service_count(); i++) {
|
for (int i = 0; i < file.service_count(); i++) {
|
||||||
auto service = file.service(i);
|
auto service = file.service(i);
|
||||||
const Definition *def = parser_.services_.vec[i];
|
const Definition* def = parser_.services_.vec[i];
|
||||||
p.package_name = LastNamespacePart(*(def->defined_namespace));
|
p.package_name = LastNamespacePart(*(def->defined_namespace));
|
||||||
p.service_prefix =
|
p.service_prefix =
|
||||||
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
|
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
|
||||||
@@ -335,12 +337,12 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const Parser &parser_;
|
const Parser& parser_;
|
||||||
const std::string &path_, &file_name_;
|
const std::string &path_, &file_name_;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GenerateGoGRPC(const Parser &parser, const std::string &path,
|
bool GenerateGoGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
int nservices = 0;
|
int nservices = 0;
|
||||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -350,9 +352,9 @@ bool GenerateGoGRPC(const Parser &parser, const std::string &path,
|
|||||||
return GoGRPCGenerator(parser, path, file_name).generate();
|
return GoGRPCGenerator(parser, path, file_name).generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GenerateCppGRPC(const Parser &parser, const std::string &path,
|
bool GenerateCppGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
const auto &opts = parser.opts;
|
const auto& opts = parser.opts;
|
||||||
int nservices = 0;
|
int nservices = 0;
|
||||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -403,8 +405,8 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path,
|
|||||||
|
|
||||||
class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
|
class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
|
||||||
public:
|
public:
|
||||||
JavaGRPCGenerator(const Parser &parser, const std::string &path,
|
JavaGRPCGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {}
|
: BaseGenerator(parser, path, file_name, "", "." /*separator*/, "java") {}
|
||||||
|
|
||||||
bool generate() {
|
bool generate() {
|
||||||
@@ -412,7 +414,7 @@ class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
grpc_java_generator::Parameters p;
|
grpc_java_generator::Parameters p;
|
||||||
for (int i = 0; i < file.service_count(); i++) {
|
for (int i = 0; i < file.service_count(); i++) {
|
||||||
auto service = file.service(i);
|
auto service = file.service(i);
|
||||||
const Definition *def = parser_.services_.vec[i];
|
const Definition* def = parser_.services_.vec[i];
|
||||||
p.package_name =
|
p.package_name =
|
||||||
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
|
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
|
||||||
std::string output =
|
std::string output =
|
||||||
@@ -425,8 +427,8 @@ class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
|
bool GenerateJavaGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
int nservices = 0;
|
int nservices = 0;
|
||||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -436,8 +438,8 @@ bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
|
|||||||
return JavaGRPCGenerator(parser, path, file_name).generate();
|
return JavaGRPCGenerator(parser, path, file_name).generate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
|
bool GeneratePythonGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string & /*file_name*/) {
|
const std::string& /*file_name*/) {
|
||||||
int nservices = 0;
|
int nservices = 0;
|
||||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -462,8 +464,8 @@ class SwiftGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
CodeWriter code_;
|
CodeWriter code_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SwiftGRPCGenerator(const Parser &parser, const std::string &path,
|
SwiftGRPCGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename)
|
const std::string& filename)
|
||||||
: BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {}
|
: BaseGenerator(parser, path, filename, "", "" /*Unused*/, "swift") {}
|
||||||
|
|
||||||
bool generate() {
|
bool generate() {
|
||||||
@@ -480,14 +482,14 @@ class SwiftGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
return SaveFile(filename.c_str(), final_code, false);
|
return SaveFile(filename.c_str(), final_code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GeneratedFileName(const std::string &path,
|
static std::string GeneratedFileName(const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
return path + file_name + ".grpc.swift";
|
return path + file_name + ".grpc.swift";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
|
bool GenerateSwiftGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
int nservices = 0;
|
int nservices = 0;
|
||||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -502,8 +504,8 @@ class TSGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
CodeWriter code_;
|
CodeWriter code_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TSGRPCGenerator(const Parser &parser, const std::string &path,
|
TSGRPCGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename)
|
const std::string& filename)
|
||||||
: BaseGenerator(parser, path, filename, "", "" /*Unused*/, "ts") {}
|
: BaseGenerator(parser, path, filename, "", "" /*Unused*/, "ts") {}
|
||||||
|
|
||||||
bool generate() {
|
bool generate() {
|
||||||
@@ -526,16 +528,16 @@ class TSGRPCGenerator : public flatbuffers::BaseGenerator {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GeneratedFileName(const std::string &path,
|
static std::string GeneratedFileName(const std::string& path,
|
||||||
const std::string &file_name,
|
const std::string& file_name,
|
||||||
const bool is_interface = false) {
|
const bool is_interface = false) {
|
||||||
if (is_interface) return path + file_name + "_grpc.d.ts";
|
if (is_interface) return path + file_name + "_grpc.d.ts";
|
||||||
return path + file_name + "_grpc.js";
|
return path + file_name + "_grpc.js";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GenerateTSGRPC(const Parser &parser, const std::string &path,
|
bool GenerateTSGRPC(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
int nservices = 0;
|
int nservices = 0;
|
||||||
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -548,5 +550,5 @@ bool GenerateTSGRPC(const Parser &parser, const std::string &path,
|
|||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -89,8 +89,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JavaGenerator(const Parser &parser, const std::string &path,
|
JavaGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name, const std::string &package_prefix)
|
const std::string& file_name, const std::string& package_prefix)
|
||||||
: BaseGenerator(parser, path, file_name, "", ".", "java"),
|
: BaseGenerator(parser, path, file_name, "", ".", "java"),
|
||||||
cur_name_space_(nullptr),
|
cur_name_space_(nullptr),
|
||||||
namer_(WithFlagOptions(JavaDefaultConfig(), parser.opts, path),
|
namer_(WithFlagOptions(JavaDefaultConfig(), parser.opts, path),
|
||||||
@@ -105,7 +105,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
JavaGenerator &operator=(const JavaGenerator &);
|
JavaGenerator& operator=(const JavaGenerator&);
|
||||||
bool generate() {
|
bool generate() {
|
||||||
std::string one_file_code;
|
std::string one_file_code;
|
||||||
cur_name_space_ = parser_.current_namespace_;
|
cur_name_space_ = parser_.current_namespace_;
|
||||||
@@ -113,7 +113,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
std::string enumcode;
|
std::string enumcode;
|
||||||
auto &enum_def = **it;
|
auto& enum_def = **it;
|
||||||
if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
|
if (!parser_.opts.one_file) cur_name_space_ = enum_def.defined_namespace;
|
||||||
GenEnum(enum_def, enumcode);
|
GenEnum(enum_def, enumcode);
|
||||||
if (parser_.opts.one_file) {
|
if (parser_.opts.one_file) {
|
||||||
@@ -141,7 +141,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
std::string declcode;
|
std::string declcode;
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
if (!parser_.opts.one_file)
|
if (!parser_.opts.one_file)
|
||||||
cur_name_space_ = struct_def.defined_namespace;
|
cur_name_space_ = struct_def.defined_namespace;
|
||||||
GenStruct(struct_def, declcode, parser_.opts);
|
GenStruct(struct_def, declcode, parser_.opts);
|
||||||
@@ -176,8 +176,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Save out the generated code for a single class while adding
|
// Save out the generated code for a single class while adding
|
||||||
// declaration boilerplate.
|
// declaration boilerplate.
|
||||||
bool SaveType(const std::string &defname, const Namespace &ns,
|
bool SaveType(const std::string& defname, const Namespace& ns,
|
||||||
const std::string &classcode, bool needs_includes) const {
|
const std::string& classcode, bool needs_includes) const {
|
||||||
if (!classcode.length()) return true;
|
if (!classcode.length()) return true;
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
@@ -228,9 +228,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return SaveFile(filename.c_str(), code, false);
|
return SaveFile(filename.c_str(), code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Namespace *CurrentNameSpace() const { return cur_name_space_; }
|
const Namespace* CurrentNameSpace() const { return cur_name_space_; }
|
||||||
|
|
||||||
std::string GenNullableAnnotation(const Type &t) const {
|
std::string GenNullableAnnotation(const Type& t) const {
|
||||||
return parser_.opts.gen_nullable &&
|
return parser_.opts.gen_nullable &&
|
||||||
!IsScalar(DestinationType(t, true).base_type) &&
|
!IsScalar(DestinationType(t, true).base_type) &&
|
||||||
t.base_type != BASE_TYPE_VECTOR
|
t.base_type != BASE_TYPE_VECTOR
|
||||||
@@ -238,14 +238,14 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenPureAnnotation(const Type &t) const {
|
std::string GenPureAnnotation(const Type& t) const {
|
||||||
return parser_.opts.java_checkerframework &&
|
return parser_.opts.java_checkerframework &&
|
||||||
!IsScalar(DestinationType(t, true).base_type)
|
!IsScalar(DestinationType(t, true).base_type)
|
||||||
? " @Pure "
|
? " @Pure "
|
||||||
: "";
|
: "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeBasic(const Type &type) const {
|
std::string GenTypeBasic(const Type& type) const {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char * const java_typename[] = {
|
static const char * const java_typename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, ...) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, ...) \
|
||||||
@@ -257,18 +257,22 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return java_typename[type.base_type];
|
return java_typename[type.base_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypePointer(const Type &type) const {
|
std::string GenTypePointer(const Type& type) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "String";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
|
return "String";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return GenTypeGet(type.VectorType());
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
return Prefixed(namer_.NamespacedType(*type.struct_def));
|
return Prefixed(namer_.NamespacedType(*type.struct_def));
|
||||||
case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // else fall thru
|
case BASE_TYPE_UNION:
|
||||||
default: return "Table";
|
FLATBUFFERS_FALLTHROUGH(); // else fall thru
|
||||||
|
default:
|
||||||
|
return "Table";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeGet(const Type &type) const {
|
std::string GenTypeGet(const Type& type) const {
|
||||||
return IsScalar(type.base_type)
|
return IsScalar(type.base_type)
|
||||||
? GenTypeBasic(type)
|
? GenTypeBasic(type)
|
||||||
: (IsArray(type) ? GenTypeGet(type.VectorType())
|
: (IsArray(type) ? GenTypeGet(type.VectorType())
|
||||||
@@ -277,49 +281,57 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Find the destination type the user wants to receive the value in (e.g.
|
// Find the destination type the user wants to receive the value in (e.g.
|
||||||
// one size higher signed types for unsigned serialized values in Java).
|
// one size higher signed types for unsigned serialized values in Java).
|
||||||
Type DestinationType(const Type &type, bool vectorelem) const {
|
Type DestinationType(const Type& type, bool vectorelem) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
// We use int for both uchar/ushort, since that generally means less
|
// We use int for both uchar/ushort, since that generally means less
|
||||||
// casting than using short for uchar.
|
// casting than using short for uchar.
|
||||||
case BASE_TYPE_UCHAR: return Type(BASE_TYPE_INT);
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_USHORT: return Type(BASE_TYPE_INT);
|
return Type(BASE_TYPE_INT);
|
||||||
case BASE_TYPE_UINT: return Type(BASE_TYPE_LONG);
|
case BASE_TYPE_USHORT:
|
||||||
|
return Type(BASE_TYPE_INT);
|
||||||
|
case BASE_TYPE_UINT:
|
||||||
|
return Type(BASE_TYPE_LONG);
|
||||||
case BASE_TYPE_ARRAY:
|
case BASE_TYPE_ARRAY:
|
||||||
case BASE_TYPE_VECTOR:
|
case BASE_TYPE_VECTOR:
|
||||||
if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
|
if (vectorelem) return DestinationType(type.VectorType(), vectorelem);
|
||||||
FLATBUFFERS_FALLTHROUGH(); // else fall thru
|
FLATBUFFERS_FALLTHROUGH(); // else fall thru
|
||||||
default: return type;
|
default:
|
||||||
|
return type;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOffsetType() const { return "int"; }
|
std::string GenOffsetType() const { return "int"; }
|
||||||
|
|
||||||
std::string GenOffsetConstruct(const std::string &variable_name) const {
|
std::string GenOffsetConstruct(const std::string& variable_name) const {
|
||||||
return variable_name;
|
return variable_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenVectorOffsetType() const { return "int"; }
|
std::string GenVectorOffsetType() const { return "int"; }
|
||||||
|
|
||||||
// Generate destination type name
|
// Generate destination type name
|
||||||
std::string GenTypeNameDest(const Type &type) const {
|
std::string GenTypeNameDest(const Type& type) const {
|
||||||
return GenTypeGet(DestinationType(type, true));
|
return GenTypeGet(DestinationType(type, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mask to turn serialized value into destination type value.
|
// Mask to turn serialized value into destination type value.
|
||||||
std::string DestinationMask(const Type &type, bool vectorelem) const {
|
std::string DestinationMask(const Type& type, bool vectorelem) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_UCHAR: return " & 0xFF";
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_USHORT: return " & 0xFFFF";
|
return " & 0xFF";
|
||||||
case BASE_TYPE_UINT: return " & 0xFFFFFFFFL";
|
case BASE_TYPE_USHORT:
|
||||||
|
return " & 0xFFFF";
|
||||||
|
case BASE_TYPE_UINT:
|
||||||
|
return " & 0xFFFFFFFFL";
|
||||||
case BASE_TYPE_VECTOR:
|
case BASE_TYPE_VECTOR:
|
||||||
if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
|
if (vectorelem) return DestinationMask(type.VectorType(), vectorelem);
|
||||||
FLATBUFFERS_FALLTHROUGH(); // else fall thru
|
FLATBUFFERS_FALLTHROUGH(); // else fall thru
|
||||||
default: return "";
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Casts necessary to correctly read serialized data
|
// Casts necessary to correctly read serialized data
|
||||||
std::string DestinationCast(const Type &type) const {
|
std::string DestinationCast(const Type& type) const {
|
||||||
if (IsSeries(type)) {
|
if (IsSeries(type)) {
|
||||||
return DestinationCast(type.VectorType());
|
return DestinationCast(type.VectorType());
|
||||||
} else {
|
} else {
|
||||||
@@ -333,7 +345,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
// In Java, parameters representing unsigned numbers need to be cast down to
|
// In Java, parameters representing unsigned numbers need to be cast down to
|
||||||
// their respective type. For example, a long holding an unsigned int value
|
// their respective type. For example, a long holding an unsigned int value
|
||||||
// would be cast down to int before being put onto the buffer.
|
// would be cast down to int before being put onto the buffer.
|
||||||
std::string SourceCast(const Type &type, bool castFromDest) const {
|
std::string SourceCast(const Type& type, bool castFromDest) const {
|
||||||
if (IsSeries(type)) {
|
if (IsSeries(type)) {
|
||||||
return SourceCast(type.VectorType(), castFromDest);
|
return SourceCast(type.VectorType(), castFromDest);
|
||||||
} else {
|
} else {
|
||||||
@@ -349,41 +361,43 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SourceCast(const Type &type) const {
|
std::string SourceCast(const Type& type) const {
|
||||||
return SourceCast(type, true);
|
return SourceCast(type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SourceCastBasic(const Type &type, bool castFromDest) const {
|
std::string SourceCastBasic(const Type& type, bool castFromDest) const {
|
||||||
return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
|
return IsScalar(type.base_type) ? SourceCast(type, castFromDest) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SourceCastBasic(const Type &type) const {
|
std::string SourceCastBasic(const Type& type) const {
|
||||||
return SourceCastBasic(type, true);
|
return SourceCastBasic(type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenEnumDefaultValue(const FieldDef &field) const {
|
std::string GenEnumDefaultValue(const FieldDef& field) const {
|
||||||
auto &value = field.value;
|
auto& value = field.value;
|
||||||
FLATBUFFERS_ASSERT(value.type.enum_def);
|
FLATBUFFERS_ASSERT(value.type.enum_def);
|
||||||
auto &enum_def = *value.type.enum_def;
|
auto& enum_def = *value.type.enum_def;
|
||||||
auto enum_val = enum_def.FindByValue(value.constant);
|
auto enum_val = enum_def.FindByValue(value.constant);
|
||||||
return enum_val
|
return enum_val
|
||||||
? Prefixed(namer_.NamespacedEnumVariant(enum_def, *enum_val))
|
? Prefixed(namer_.NamespacedEnumVariant(enum_def, *enum_val))
|
||||||
: value.constant;
|
: value.constant;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDefaultValue(const FieldDef &field) const {
|
std::string GenDefaultValue(const FieldDef& field) const {
|
||||||
auto &value = field.value;
|
auto& value = field.value;
|
||||||
auto constant = field.IsScalarOptional() ? "0" : value.constant;
|
auto constant = field.IsScalarOptional() ? "0" : value.constant;
|
||||||
auto longSuffix = "L";
|
auto longSuffix = "L";
|
||||||
switch (value.type.base_type) {
|
switch (value.type.base_type) {
|
||||||
case BASE_TYPE_BOOL: return constant == "0" ? "false" : "true";
|
case BASE_TYPE_BOOL:
|
||||||
|
return constant == "0" ? "false" : "true";
|
||||||
case BASE_TYPE_ULONG: {
|
case BASE_TYPE_ULONG: {
|
||||||
// Converts the ulong into its bits signed equivalent
|
// Converts the ulong into its bits signed equivalent
|
||||||
uint64_t defaultValue = StringToUInt(constant.c_str());
|
uint64_t defaultValue = StringToUInt(constant.c_str());
|
||||||
return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
|
return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UINT:
|
case BASE_TYPE_UINT:
|
||||||
case BASE_TYPE_LONG: return constant + longSuffix;
|
case BASE_TYPE_LONG:
|
||||||
|
return constant + longSuffix;
|
||||||
default:
|
default:
|
||||||
if (IsFloat(value.type.base_type)) {
|
if (IsFloat(value.type.base_type)) {
|
||||||
if (field.IsScalarOptional()) {
|
if (field.IsScalarOptional()) {
|
||||||
@@ -396,13 +410,15 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDefaultValueBasic(const FieldDef &field) const {
|
std::string GenDefaultValueBasic(const FieldDef& field) const {
|
||||||
auto &value = field.value;
|
auto& value = field.value;
|
||||||
if (!IsScalar(value.type.base_type)) { return "0"; }
|
if (!IsScalar(value.type.base_type)) {
|
||||||
|
return "0";
|
||||||
|
}
|
||||||
return GenDefaultValue(field);
|
return GenDefaultValue(field);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenEnum(EnumDef &enum_def, std::string &code) const {
|
void GenEnum(EnumDef& enum_def, std::string& code) const {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
|
|
||||||
// Generate enum definitions of the form:
|
// Generate enum definitions of the form:
|
||||||
@@ -422,7 +438,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " {\n";
|
code += " {\n";
|
||||||
code += " private " + namer_.Type(enum_def) + "() { }\n";
|
code += " private " + namer_.Type(enum_def) + "() { }\n";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
GenComment(ev.doc_comment, &code, &comment_config, " ");
|
GenComment(ev.doc_comment, &code, &comment_config, " ");
|
||||||
code += " public static final ";
|
code += " public static final ";
|
||||||
code += GenTypeBasic(DestinationType(enum_def.underlying_type, false));
|
code += GenTypeBasic(DestinationType(enum_def.underlying_type, false));
|
||||||
@@ -449,10 +465,10 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
"long") {
|
"long") {
|
||||||
code += "\n public static final String";
|
code += "\n public static final String";
|
||||||
code += "[] names = { ";
|
code += "[] names = { ";
|
||||||
const EnumVal *prev = enum_def.Vals().front();
|
const EnumVal* prev = enum_def.Vals().front();
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end();
|
||||||
++it) {
|
++it) {
|
||||||
const EnumVal &ev = **it;
|
const EnumVal& ev = **it;
|
||||||
for (auto k = enum_def.Distance(prev, &ev); k > 1; --k)
|
for (auto k = enum_def.Distance(prev, &ev); k > 1; --k)
|
||||||
code += "\"\", ";
|
code += "\"\", ";
|
||||||
prev = &ev;
|
prev = &ev;
|
||||||
@@ -473,13 +489,18 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the function name that is able to read a value of the given type.
|
// Returns the function name that is able to read a value of the given type.
|
||||||
std::string GenGetter(const Type &type) const {
|
std::string GenGetter(const Type& type) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "__string";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_STRUCT: return "__struct";
|
return "__string";
|
||||||
case BASE_TYPE_UNION: return "__union";
|
case BASE_TYPE_STRUCT:
|
||||||
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
|
return "__struct";
|
||||||
case BASE_TYPE_ARRAY: return GenGetter(type.VectorType());
|
case BASE_TYPE_UNION:
|
||||||
|
return "__union";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return GenGetter(type.VectorType());
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
return GenGetter(type.VectorType());
|
||||||
default: {
|
default: {
|
||||||
std::string getter = "bb.get";
|
std::string getter = "bb.get";
|
||||||
if (type.base_type == BASE_TYPE_BOOL) {
|
if (type.base_type == BASE_TYPE_BOOL) {
|
||||||
@@ -493,9 +514,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the function name that is able to read a value of the given type.
|
// Returns the function name that is able to read a value of the given type.
|
||||||
std::string GenGetterForLookupByKey(flatbuffers::FieldDef *key_field,
|
std::string GenGetterForLookupByKey(flatbuffers::FieldDef* key_field,
|
||||||
const std::string &data_buffer,
|
const std::string& data_buffer,
|
||||||
const char *num = nullptr) const {
|
const char* num = nullptr) const {
|
||||||
auto type = key_field->value.type;
|
auto type = key_field->value.type;
|
||||||
auto dest_mask = DestinationMask(type, true);
|
auto dest_mask = DestinationMask(type, true);
|
||||||
auto dest_cast = DestinationCast(type);
|
auto dest_cast = DestinationCast(type);
|
||||||
@@ -510,7 +531,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Direct mutation is only allowed for scalar fields.
|
// Direct mutation is only allowed for scalar fields.
|
||||||
// Hence a setter method will only be generated for such fields.
|
// Hence a setter method will only be generated for such fields.
|
||||||
std::string GenSetter(const Type &type) const {
|
std::string GenSetter(const Type& type) const {
|
||||||
if (IsScalar(type.base_type)) {
|
if (IsScalar(type.base_type)) {
|
||||||
std::string setter = "bb.put";
|
std::string setter = "bb.put";
|
||||||
if (GenTypeBasic(type) != "byte" && type.base_type != BASE_TYPE_BOOL) {
|
if (GenTypeBasic(type) != "byte" && type.base_type != BASE_TYPE_BOOL) {
|
||||||
@@ -523,7 +544,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the method name for use with add/put calls.
|
// Returns the method name for use with add/put calls.
|
||||||
std::string GenMethod(const Type &type) const {
|
std::string GenMethod(const Type& type) const {
|
||||||
return IsScalar(type.base_type)
|
return IsScalar(type.base_type)
|
||||||
? ConvertCase(GenTypeBasic(type), Case::kUpperCamel)
|
? ConvertCase(GenTypeBasic(type), Case::kUpperCamel)
|
||||||
: (IsStruct(type) ? "Struct" : "Offset");
|
: (IsStruct(type) ? "Struct" : "Offset");
|
||||||
@@ -531,14 +552,14 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Recursively generate arguments for a constructor, to deal with nested
|
// Recursively generate arguments for a constructor, to deal with nested
|
||||||
// structs.
|
// structs.
|
||||||
void GenStructArgs(const StructDef &struct_def, std::string &code,
|
void GenStructArgs(const StructDef& struct_def, std::string& code,
|
||||||
const char *nameprefix, size_t array_count = 0) const {
|
const char* nameprefix, size_t array_count = 0) const {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
const auto &field_type = field.value.type;
|
const auto& field_type = field.value.type;
|
||||||
const auto array_field = IsArray(field_type);
|
const auto array_field = IsArray(field_type);
|
||||||
const auto &type = array_field ? field_type.VectorType()
|
const auto& type = array_field ? field_type.VectorType()
|
||||||
: DestinationType(field_type, false);
|
: DestinationType(field_type, false);
|
||||||
const auto array_cnt = array_field ? (array_count + 1) : array_count;
|
const auto array_cnt = array_field ? (array_count + 1) : array_count;
|
||||||
if (IsStruct(type)) {
|
if (IsStruct(type)) {
|
||||||
@@ -561,8 +582,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
// Recusively generate struct construction statements of the form:
|
// Recusively generate struct construction statements of the form:
|
||||||
// builder.putType(name);
|
// builder.putType(name);
|
||||||
// and insert manual padding.
|
// and insert manual padding.
|
||||||
void GenStructBody(const StructDef &struct_def, std::string &code,
|
void GenStructBody(const StructDef& struct_def, std::string& code,
|
||||||
const char *nameprefix, size_t index = 0,
|
const char* nameprefix, size_t index = 0,
|
||||||
bool in_array = false) const {
|
bool in_array = false) const {
|
||||||
std::string indent((index + 1) * 2, ' ');
|
std::string indent((index + 1) * 2, ' ');
|
||||||
code += indent + " builder.prep(";
|
code += indent + " builder.prep(";
|
||||||
@@ -570,8 +591,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += NumToString(struct_def.bytesize) + ");\n";
|
code += NumToString(struct_def.bytesize) + ");\n";
|
||||||
for (auto it = struct_def.fields.vec.rbegin();
|
for (auto it = struct_def.fields.vec.rbegin();
|
||||||
it != struct_def.fields.vec.rend(); ++it) {
|
it != struct_def.fields.vec.rend(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
const auto &field_type = field.value.type;
|
const auto& field_type = field.value.type;
|
||||||
if (field.padding) {
|
if (field.padding) {
|
||||||
code += indent + " builder.pad(";
|
code += indent + " builder.pad(";
|
||||||
code += NumToString(field.padding) + ");\n";
|
code += NumToString(field.padding) + ");\n";
|
||||||
@@ -581,7 +602,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
(nameprefix + (field.name + "_")).c_str(), index,
|
(nameprefix + (field.name + "_")).c_str(), index,
|
||||||
in_array);
|
in_array);
|
||||||
} else {
|
} else {
|
||||||
const auto &type =
|
const auto& type =
|
||||||
IsArray(field_type) ? field_type.VectorType() : field_type;
|
IsArray(field_type) ? field_type.VectorType() : field_type;
|
||||||
const auto index_var = "_idx" + NumToString(index);
|
const auto index_var = "_idx" + NumToString(index);
|
||||||
if (IsArray(field_type)) {
|
if (IsArray(field_type)) {
|
||||||
@@ -607,13 +628,15 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code += ");\n";
|
code += ");\n";
|
||||||
}
|
}
|
||||||
if (IsArray(field_type)) { code += indent + " }\n"; }
|
if (IsArray(field_type)) {
|
||||||
|
code += indent + " }\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
|
std::string GenOffsetGetter(flatbuffers::FieldDef* key_field,
|
||||||
const char *num = nullptr) const {
|
const char* num = nullptr) const {
|
||||||
std::string key_offset = "";
|
std::string key_offset = "";
|
||||||
key_offset += "__offset(" + NumToString(key_field->value.offset) + ", ";
|
key_offset += "__offset(" + NumToString(key_field->value.offset) + ", ";
|
||||||
if (num) {
|
if (num) {
|
||||||
@@ -626,7 +649,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return key_offset;
|
return key_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) const {
|
std::string GenLookupKeyGetter(flatbuffers::FieldDef* key_field) const {
|
||||||
std::string key_getter = " ";
|
std::string key_getter = " ";
|
||||||
key_getter += "int tableOffset = ";
|
key_getter += "int tableOffset = ";
|
||||||
key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
|
key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
|
||||||
@@ -645,7 +668,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return key_getter;
|
return key_getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenKeyGetter(flatbuffers::FieldDef *key_field) const {
|
std::string GenKeyGetter(flatbuffers::FieldDef* key_field) const {
|
||||||
std::string key_getter = "";
|
std::string key_getter = "";
|
||||||
auto data_buffer = "_bb";
|
auto data_buffer = "_bb";
|
||||||
if (IsString(key_field->value.type)) {
|
if (IsString(key_field->value.type)) {
|
||||||
@@ -669,8 +692,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return key_getter;
|
return key_getter;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenStruct(StructDef &struct_def, std::string &code,
|
void GenStruct(StructDef& struct_def, std::string& code,
|
||||||
const IDLOptions &opts) const {
|
const IDLOptions& opts) const {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
|
|
||||||
// Generate a struct accessor class, with methods of the form:
|
// Generate a struct accessor class, with methods of the form:
|
||||||
@@ -749,7 +772,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "{ __init(_i, _bb); return this; }\n\n";
|
code += "{ __init(_i, _bb); return this; }\n\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
GenComment(field.doc_comment, &code, &comment_config, " ");
|
GenComment(field.doc_comment, &code, &comment_config, " ");
|
||||||
const std::string type_name = GenTypeGet(field.value.type);
|
const std::string type_name = GenTypeGet(field.value.type);
|
||||||
@@ -787,7 +810,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "(new " + type_name + "(), j); }\n";
|
code += "(new " + type_name + "(), j); }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.IsScalarOptional()) { code += GenOptionalScalarCheck(field); }
|
if (field.IsScalarOptional()) {
|
||||||
|
code += GenOptionalScalarCheck(field);
|
||||||
|
}
|
||||||
std::string getter = dest_cast + GenGetter(field.value.type);
|
std::string getter = dest_cast + GenGetter(field.value.type);
|
||||||
code += method_start;
|
code += method_start;
|
||||||
std::string member_suffix = "; ";
|
std::string member_suffix = "; ";
|
||||||
@@ -828,7 +853,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += offset_prefix + getter + "(o + ";
|
code += offset_prefix + getter + "(o + ";
|
||||||
code += "bb_pos) : null";
|
code += "bb_pos) : null";
|
||||||
break;
|
break;
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
code += "(";
|
code += "(";
|
||||||
@@ -874,7 +900,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "(" + type_name + " obj)" + offset_prefix + getter;
|
code += "(" + type_name + " obj)" + offset_prefix + getter;
|
||||||
code += "(obj, o + bb_pos) : null";
|
code += "(obj, o + bb_pos) : null";
|
||||||
break;
|
break;
|
||||||
default: FLATBUFFERS_ASSERT(0);
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
code += member_suffix;
|
code += member_suffix;
|
||||||
@@ -890,10 +917,10 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
// See if we should generate a by-key accessor.
|
// See if we should generate a by-key accessor.
|
||||||
if (field.value.type.element == BASE_TYPE_STRUCT &&
|
if (field.value.type.element == BASE_TYPE_STRUCT &&
|
||||||
!field.value.type.struct_def->fixed) {
|
!field.value.type.struct_def->fixed) {
|
||||||
auto &sd = *field.value.type.struct_def;
|
auto& sd = *field.value.type.struct_def;
|
||||||
auto &fields = sd.fields.vec;
|
auto& fields = sd.fields.vec;
|
||||||
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
||||||
auto &key_field = **kit;
|
auto& key_field = **kit;
|
||||||
if (key_field.key) {
|
if (key_field.key) {
|
||||||
auto qualified_name = Prefixed(namer_.NamespacedType(sd));
|
auto qualified_name = Prefixed(namer_.NamespacedType(sd));
|
||||||
code += " public " + qualified_name + " ";
|
code += " public " + qualified_name + " ";
|
||||||
@@ -922,7 +949,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
// Generate the accessors for vector of structs with vector access object
|
// Generate the accessors for vector of structs with vector access object
|
||||||
if (IsVector(field.value.type)) {
|
if (IsVector(field.value.type)) {
|
||||||
std::string vector_type_name;
|
std::string vector_type_name;
|
||||||
const auto &element_base_type = field.value.type.VectorType().base_type;
|
const auto& element_base_type = field.value.type.VectorType().base_type;
|
||||||
if (IsScalar(element_base_type)) {
|
if (IsScalar(element_base_type)) {
|
||||||
vector_type_name =
|
vector_type_name =
|
||||||
ConvertCase(type_name, Case::kUpperCamel) + "Vector";
|
ConvertCase(type_name, Case::kUpperCamel) + "Vector";
|
||||||
@@ -995,7 +1022,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
// Generate mutators for scalar fields or vectors of scalars.
|
// Generate mutators for scalar fields or vectors of scalars.
|
||||||
if (parser_.opts.mutable_buffer) {
|
if (parser_.opts.mutable_buffer) {
|
||||||
auto is_series = (IsSeries(field.value.type));
|
auto is_series = (IsSeries(field.value.type));
|
||||||
const auto &underlying_type =
|
const auto& underlying_type =
|
||||||
is_series ? field.value.type.VectorType() : field.value.type;
|
is_series ? field.value.type.VectorType() : field.value.type;
|
||||||
// Boolean parameters have to be explicitly converted to byte
|
// Boolean parameters have to be explicitly converted to byte
|
||||||
// representation.
|
// representation.
|
||||||
@@ -1045,8 +1072,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code += "\n";
|
code += "\n";
|
||||||
auto struct_has_create = false;
|
auto struct_has_create = false;
|
||||||
std::set<flatbuffers::FieldDef *> field_has_create_set;
|
std::set<flatbuffers::FieldDef*> field_has_create_set;
|
||||||
flatbuffers::FieldDef *key_field = nullptr;
|
flatbuffers::FieldDef* key_field = nullptr;
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
struct_has_create = true;
|
struct_has_create = true;
|
||||||
// create a struct constructor function
|
// create a struct constructor function
|
||||||
@@ -1067,7 +1094,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
int num_fields = 0;
|
int num_fields = 0;
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
has_no_struct_fields = false;
|
has_no_struct_fields = false;
|
||||||
@@ -1086,7 +1113,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "(FlatBufferBuilder builder";
|
code += "(FlatBufferBuilder builder";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
auto field_name = namer_.Field(field);
|
auto field_name = namer_.Field(field);
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
code += ",\n ";
|
code += ",\n ";
|
||||||
@@ -1102,7 +1129,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
size; size /= 2) {
|
size; size /= 2) {
|
||||||
for (auto it = struct_def.fields.vec.rbegin();
|
for (auto it = struct_def.fields.vec.rbegin();
|
||||||
it != struct_def.fields.vec.rend(); ++it) {
|
it != struct_def.fields.vec.rend(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
auto field_name = namer_.Field(field);
|
auto field_name = namer_.Field(field);
|
||||||
if (!field.deprecated &&
|
if (!field.deprecated &&
|
||||||
(!struct_def.sortbysize ||
|
(!struct_def.sortbysize ||
|
||||||
@@ -1130,7 +1157,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += NumToString(struct_def.fields.vec.size()) + "); }\n";
|
code += NumToString(struct_def.fields.vec.size()) + "); }\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
code += " public static void " + namer_.Method("add", field);
|
code += " public static void " + namer_.Method("add", field);
|
||||||
@@ -1216,7 +1243,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "endTable();\n";
|
code += "endTable();\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (!field.deprecated && field.IsRequired()) {
|
if (!field.deprecated && field.IsRequired()) {
|
||||||
code += " builder.required(o, ";
|
code += " builder.required(o, ";
|
||||||
code += NumToString(field.value.offset);
|
code += NumToString(field.value.offset);
|
||||||
@@ -1225,7 +1252,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code += " return " + GenOffsetConstruct("o") + ";\n }\n";
|
code += " return " + GenOffsetConstruct("o") + ";\n }\n";
|
||||||
if (parser_.root_struct_def_ == &struct_def) {
|
if (parser_.root_struct_def_ == &struct_def) {
|
||||||
std::string size_prefix[] = { "", "SizePrefixed" };
|
std::string size_prefix[] = {"", "SizePrefixed"};
|
||||||
for (int i = 0; i < 2; ++i) {
|
for (int i = 0; i < 2; ++i) {
|
||||||
code += " public static void ";
|
code += " public static void ";
|
||||||
code += namer_.LegacyJavaMethod2("finish" + size_prefix[i],
|
code += namer_.LegacyJavaMethod2("finish" + size_prefix[i],
|
||||||
@@ -1287,14 +1314,14 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "}\n\n";
|
code += "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOptionalScalarCheck(FieldDef &field) const {
|
std::string GenOptionalScalarCheck(FieldDef& field) const {
|
||||||
if (!field.IsScalarOptional()) return "";
|
if (!field.IsScalarOptional()) return "";
|
||||||
return " public boolean " + namer_.Method("has", field) +
|
return " public boolean " + namer_.Method("has", field) +
|
||||||
"() { return 0 != __offset(" + NumToString(field.value.offset) +
|
"() { return 0 != __offset(" + NumToString(field.value.offset) +
|
||||||
"); }\n";
|
"); }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenVectorAccessObject(StructDef &struct_def, std::string &code) const {
|
void GenVectorAccessObject(StructDef& struct_def, std::string& code) const {
|
||||||
// Generate a vector of structs accessor class.
|
// Generate a vector of structs accessor class.
|
||||||
code += "\n";
|
code += "\n";
|
||||||
code += " ";
|
code += " ";
|
||||||
@@ -1323,9 +1350,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += ", bb); }\n";
|
code += ", bb); }\n";
|
||||||
// See if we should generate a by-key accessor.
|
// See if we should generate a by-key accessor.
|
||||||
if (!struct_def.fixed) {
|
if (!struct_def.fixed) {
|
||||||
auto &fields = struct_def.fields.vec;
|
auto& fields = struct_def.fields.vec;
|
||||||
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
||||||
auto &key_field = **kit;
|
auto& key_field = **kit;
|
||||||
if (key_field.key) {
|
if (key_field.key) {
|
||||||
auto nullable_annotation =
|
auto nullable_annotation =
|
||||||
parser_.opts.gen_nullable ? "@Nullable " : "";
|
parser_.opts.gen_nullable ? "@Nullable " : "";
|
||||||
@@ -1353,11 +1380,13 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " }\n";
|
code += " }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenEnum_ObjectAPI(EnumDef &enum_def, std::string &code) const {
|
void GenEnum_ObjectAPI(EnumDef& enum_def, std::string& code) const {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
code += "import com.google.flatbuffers.FlatBufferBuilder;\n\n";
|
code += "import com.google.flatbuffers.FlatBufferBuilder;\n\n";
|
||||||
|
|
||||||
if (!enum_def.attributes.Lookup("private")) { code += "public "; }
|
if (!enum_def.attributes.Lookup("private")) {
|
||||||
|
code += "public ";
|
||||||
|
}
|
||||||
auto union_name = namer_.Type(enum_def) + "Union";
|
auto union_name = namer_.Type(enum_def) + "Union";
|
||||||
auto union_type =
|
auto union_type =
|
||||||
GenTypeBasic(DestinationType(enum_def.underlying_type, false));
|
GenTypeBasic(DestinationType(enum_def.underlying_type, false));
|
||||||
@@ -1382,7 +1411,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " }\n\n";
|
code += " }\n\n";
|
||||||
// As
|
// As
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) continue;
|
if (ev.union_type.base_type == BASE_TYPE_NONE) continue;
|
||||||
auto type_name = GenTypeGet_ObjectAPI(ev.union_type, false, true);
|
auto type_name = GenTypeGet_ObjectAPI(ev.union_type, false, true);
|
||||||
if (ev.union_type.base_type == BASE_TYPE_STRUCT &&
|
if (ev.union_type.base_type == BASE_TYPE_STRUCT &&
|
||||||
@@ -1400,7 +1429,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
union_name + " _o) {\n";
|
union_name + " _o) {\n";
|
||||||
code += " switch (_o.type) {\n";
|
code += " switch (_o.type) {\n";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -1419,9 +1448,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "}\n\n";
|
code += "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenUnionUnPack_ObjectAPI(const EnumDef &enum_def, std::string &code,
|
void GenUnionUnPack_ObjectAPI(const EnumDef& enum_def, std::string& code,
|
||||||
const std::string &type_name,
|
const std::string& type_name,
|
||||||
const std::string &field_name,
|
const std::string& field_name,
|
||||||
bool is_vector) const {
|
bool is_vector) const {
|
||||||
const std::string variable_type =
|
const std::string variable_type =
|
||||||
is_vector ? type_name.substr(0, type_name.length() - 2) : type_name;
|
is_vector ? type_name.substr(0, type_name.length() - 2) : type_name;
|
||||||
@@ -1442,7 +1471,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += indent + "switch (" + variable_name + "Type) {\n";
|
code += indent + "switch (" + variable_name + "Type) {\n";
|
||||||
for (auto eit = enum_def.Vals().begin(); eit != enum_def.Vals().end();
|
for (auto eit = enum_def.Vals().begin(); eit != enum_def.Vals().end();
|
||||||
++eit) {
|
++eit) {
|
||||||
auto &ev = **eit;
|
auto& ev = **eit;
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||||
continue;
|
continue;
|
||||||
} else {
|
} else {
|
||||||
@@ -1473,9 +1502,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void GenPackUnPack_ObjectAPI(
|
void GenPackUnPack_ObjectAPI(
|
||||||
StructDef &struct_def, std::string &code, const IDLOptions &opts,
|
StructDef& struct_def, std::string& code, const IDLOptions& opts,
|
||||||
bool struct_has_create,
|
bool struct_has_create,
|
||||||
const std::set<FieldDef *> &field_has_create) const {
|
const std::set<FieldDef*>& field_has_create) const {
|
||||||
auto struct_name = namer_.ObjectType(struct_def);
|
auto struct_name = namer_.ObjectType(struct_def);
|
||||||
// unpack()
|
// unpack()
|
||||||
code += " public " + struct_name + " unpack() {\n";
|
code += " public " + struct_name + " unpack() {\n";
|
||||||
@@ -1487,7 +1516,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " public void unpackTo(" + struct_name + " _o) {\n";
|
code += " public void unpackTo(" + struct_name + " _o) {\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
||||||
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
||||||
@@ -1560,7 +1589,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += ";}\n";
|
code += ";}\n";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BASE_TYPE_UTYPE: break;
|
case BASE_TYPE_UTYPE:
|
||||||
|
break;
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code, type_name,
|
GenUnionUnPack_ObjectAPI(*field.value.type.enum_def, code, type_name,
|
||||||
accessor, false);
|
accessor, false);
|
||||||
@@ -1587,7 +1617,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " if (_o == null) return 0;\n";
|
code += " if (_o == null) return 0;\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto field_name = namer_.Field(field);
|
const auto field_name = namer_.Field(field);
|
||||||
const auto variable = "_" + namer_.Variable("o", field);
|
const auto variable = "_" + namer_.Variable("o", field);
|
||||||
@@ -1746,7 +1776,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
"Union.pack(builder, _o." + get_field + "());\n";
|
"Union.pack(builder, _o." + get_field + "());\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (struct_has_create) {
|
if (struct_has_create) {
|
||||||
@@ -1756,7 +1787,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " builder";
|
code += " builder";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto field_name = namer_.Field(field);
|
const auto field_name = namer_.Field(field);
|
||||||
const auto get_field = namer_.Method("get", field);
|
const auto get_field = namer_.Method("get", field);
|
||||||
@@ -1790,9 +1821,12 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UNION: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_UNION:
|
||||||
case BASE_TYPE_UTYPE: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_UTYPE:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
code += ",\n";
|
code += ",\n";
|
||||||
code += " _" + field_name;
|
code += " _" + field_name;
|
||||||
@@ -1811,7 +1845,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
"(builder);\n";
|
"(builder);\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto arg = "_" + namer_.Variable(field);
|
const auto arg = "_" + namer_.Variable(field);
|
||||||
const auto get_field = namer_.Method("get", field);
|
const auto get_field = namer_.Method("get", field);
|
||||||
@@ -1828,13 +1862,16 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_STRING: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
code += " " + add_field + "(builder, " + arg + ");\n";
|
code += " " + add_field + "(builder, " + arg + ");\n";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: break;
|
case BASE_TYPE_UTYPE:
|
||||||
|
break;
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
code += " " + add_field + "Type(builder, " + arg + "Type);\n";
|
code += " " + add_field + "Type(builder, " + arg + "Type);\n";
|
||||||
code += " " + add_field + "(builder, " + arg + ");\n";
|
code += " " + add_field + "(builder, " + arg + ");\n";
|
||||||
@@ -1859,14 +1896,14 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " }\n";
|
code += " }\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenStructPackDecl_ObjectAPI(const StructDef &struct_def,
|
void GenStructPackDecl_ObjectAPI(const StructDef& struct_def,
|
||||||
std::vector<FieldArrayLength> &array_lengths,
|
std::vector<FieldArrayLength>& array_lengths,
|
||||||
std::string &code) const {
|
std::string& code) const {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const FieldDef &field = **it;
|
const FieldDef& field = **it;
|
||||||
const bool is_array = IsArray(field.value.type);
|
const bool is_array = IsArray(field.value.type);
|
||||||
const Type &field_type =
|
const Type& field_type =
|
||||||
is_array ? field.value.type.VectorType() : field.value.type;
|
is_array ? field.value.type.VectorType() : field.value.type;
|
||||||
FieldArrayLength tmp_array_length = {
|
FieldArrayLength tmp_array_length = {
|
||||||
field.name,
|
field.name,
|
||||||
@@ -1895,7 +1932,9 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " " + name + " = ";
|
code += " " + name + " = ";
|
||||||
code += "new " + GenTypeBasic(field_type) + "[";
|
code += "new " + GenTypeBasic(field_type) + "[";
|
||||||
for (size_t i = 0; i < array_only_lengths.size(); ++i) {
|
for (size_t i = 0; i < array_only_lengths.size(); ++i) {
|
||||||
if (i != 0) { code += "]["; }
|
if (i != 0) {
|
||||||
|
code += "][";
|
||||||
|
}
|
||||||
code += NumToString(array_only_lengths[i].length);
|
code += NumToString(array_only_lengths[i].length);
|
||||||
}
|
}
|
||||||
code += "];\n";
|
code += "];\n";
|
||||||
@@ -1940,13 +1979,13 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenStructPackCall_ObjectAPI(const StructDef &struct_def,
|
void GenStructPackCall_ObjectAPI(const StructDef& struct_def,
|
||||||
std::string &code,
|
std::string& code,
|
||||||
std::string prefix) const {
|
std::string prefix) const {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
const auto &field_type = field.value.type;
|
const auto& field_type = field.value.type;
|
||||||
if (field_type.struct_def != nullptr) {
|
if (field_type.struct_def != nullptr) {
|
||||||
GenStructPackCall_ObjectAPI(*field_type.struct_def, code,
|
GenStructPackCall_ObjectAPI(*field_type.struct_def, code,
|
||||||
prefix + namer_.Field(field) + "_");
|
prefix + namer_.Field(field) + "_");
|
||||||
@@ -1958,7 +1997,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string ConvertPrimitiveTypeToObjectWrapper_ObjectAPI(
|
std::string ConvertPrimitiveTypeToObjectWrapper_ObjectAPI(
|
||||||
const std::string &type_name) const {
|
const std::string& type_name) const {
|
||||||
if (type_name == "boolean")
|
if (type_name == "boolean")
|
||||||
return "Boolean";
|
return "Boolean";
|
||||||
else if (type_name == "byte")
|
else if (type_name == "byte")
|
||||||
@@ -1978,14 +2017,16 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeGet_ObjectAPI(const flatbuffers::Type &type,
|
std::string GenTypeGet_ObjectAPI(const flatbuffers::Type& type,
|
||||||
bool vectorelem,
|
bool vectorelem,
|
||||||
bool wrap_in_namespace) const {
|
bool wrap_in_namespace) const {
|
||||||
auto type_name = GenTypeNameDest(type);
|
auto type_name = GenTypeNameDest(type);
|
||||||
// Replace to ObjectBaseAPI Type Name
|
// Replace to ObjectBaseAPI Type Name
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_STRUCT:
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
if (type.struct_def != nullptr) {
|
if (type.struct_def != nullptr) {
|
||||||
auto type_name_length = type.struct_def->name.length();
|
auto type_name_length = type.struct_def->name.length();
|
||||||
@@ -2011,27 +2052,34 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (vectorelem) {
|
||||||
|
return type_name;
|
||||||
}
|
}
|
||||||
if (vectorelem) { return type_name; }
|
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
type_name = type_name + "[]";
|
type_name = type_name + "[]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenConcreteTypeGet_ObjectAPI(
|
std::string GenConcreteTypeGet_ObjectAPI(
|
||||||
const flatbuffers::Type &type) const {
|
const flatbuffers::Type& type) const {
|
||||||
auto type_name = GenTypeNameDest(type);
|
auto type_name = GenTypeNameDest(type);
|
||||||
// Replace to ObjectBaseAPI Type Name
|
// Replace to ObjectBaseAPI Type Name
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRUCT: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_STRUCT:
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
if (type.struct_def != nullptr) {
|
if (type.struct_def != nullptr) {
|
||||||
auto type_name_length = type.struct_def->name.length();
|
auto type_name_length = type.struct_def->name.length();
|
||||||
@@ -2048,22 +2096,25 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
type_name = Prefixed(namer_.NamespacedType(*type.enum_def)) + "Union";
|
type_name = Prefixed(namer_.NamespacedType(*type.enum_def)) + "Union";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
type_name = type_name + "[]";
|
type_name = type_name + "[]";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return type_name;
|
return type_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenStruct_ObjectAPI(const StructDef &struct_def,
|
void GenStruct_ObjectAPI(const StructDef& struct_def,
|
||||||
std::string &code) const {
|
std::string& code) const {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
if (struct_def.attributes.Lookup("private")) {
|
if (struct_def.attributes.Lookup("private")) {
|
||||||
// For Java, we leave the enum unmarked to indicate package-private
|
// For Java, we leave the enum unmarked to indicate package-private
|
||||||
@@ -2077,7 +2128,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
// Generate Properties
|
// Generate Properties
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
||||||
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
||||||
@@ -2091,7 +2142,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += "\n";
|
code += "\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
||||||
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
||||||
@@ -2118,7 +2169,7 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
code += " public " + class_name + "() {\n";
|
code += " public " + class_name + "() {\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.base_type == BASE_TYPE_UTYPE) continue;
|
||||||
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
if (field.value.type.element == BASE_TYPE_UTYPE) continue;
|
||||||
@@ -2177,11 +2228,11 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// This tracks the current namespace used to determine if a type need to be
|
// This tracks the current namespace used to determine if a type need to be
|
||||||
// prefixed by its namespace
|
// prefixed by its namespace
|
||||||
const Namespace *cur_name_space_;
|
const Namespace* cur_name_space_;
|
||||||
const IdlNamer namer_;
|
const IdlNamer namer_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string Prefixed(const std::string &str) const {
|
std::string Prefixed(const std::string& str) const {
|
||||||
return package_prefix_ + str;
|
return package_prefix_ + str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2190,8 +2241,8 @@ class JavaGenerator : public BaseGenerator {
|
|||||||
};
|
};
|
||||||
} // namespace java
|
} // namespace java
|
||||||
|
|
||||||
static bool GenerateJava(const Parser &parser, const std::string &path,
|
static bool GenerateJava(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
java::JavaGenerator generator(parser, path, file_name,
|
java::JavaGenerator generator(parser, path, file_name,
|
||||||
parser.opts.java_package_prefix);
|
parser.opts.java_package_prefix);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
@@ -2201,32 +2252,35 @@ namespace {
|
|||||||
|
|
||||||
class JavaCodeGenerator : public CodeGenerator {
|
class JavaCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateJava(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateJava(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
output = JavaCSharpMakeRule(true, parser, path, filename);
|
output = JavaCSharpMakeRule(true, parser, path, filename);
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateJavaGRPC(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateJavaGRPC(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
@@ -30,9 +30,10 @@ namespace jsons {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template<class T> static std::string GenFullName(const T *enum_def) {
|
template <class T>
|
||||||
|
static std::string GenFullName(const T* enum_def) {
|
||||||
std::string full_name;
|
std::string full_name;
|
||||||
const auto &name_spaces = enum_def->defined_namespace->components;
|
const auto& name_spaces = enum_def->defined_namespace->components;
|
||||||
for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) {
|
for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) {
|
||||||
full_name.append(*ns + "_");
|
full_name.append(*ns + "_");
|
||||||
}
|
}
|
||||||
@@ -40,17 +41,19 @@ template<class T> static std::string GenFullName(const T *enum_def) {
|
|||||||
return full_name;
|
return full_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T> static std::string GenTypeRef(const T *enum_def) {
|
template <class T>
|
||||||
|
static std::string GenTypeRef(const T* enum_def) {
|
||||||
return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\"";
|
return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenType(const std::string &name) {
|
static std::string GenType(const std::string& name) {
|
||||||
return "\"type\" : \"" + name + "\"";
|
return "\"type\" : \"" + name + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenType(BaseType type) {
|
static std::string GenType(BaseType type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case BASE_TYPE_BOOL: return "\"type\" : \"boolean\"";
|
case BASE_TYPE_BOOL:
|
||||||
|
return "\"type\" : \"boolean\"";
|
||||||
case BASE_TYPE_CHAR:
|
case BASE_TYPE_CHAR:
|
||||||
return "\"type\" : \"integer\", \"minimum\" : " +
|
return "\"type\" : \"integer\", \"minimum\" : " +
|
||||||
NumToString(std::numeric_limits<int8_t>::min()) +
|
NumToString(std::numeric_limits<int8_t>::min()) +
|
||||||
@@ -84,19 +87,26 @@ static std::string GenType(BaseType type) {
|
|||||||
return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " +
|
return "\"type\" : \"integer\", \"minimum\" : 0, \"maximum\" : " +
|
||||||
NumToString(std::numeric_limits<uint64_t>::max());
|
NumToString(std::numeric_limits<uint64_t>::max());
|
||||||
case BASE_TYPE_FLOAT:
|
case BASE_TYPE_FLOAT:
|
||||||
case BASE_TYPE_DOUBLE: return "\"type\" : \"number\"";
|
case BASE_TYPE_DOUBLE:
|
||||||
case BASE_TYPE_STRING: return "\"type\" : \"string\"";
|
return "\"type\" : \"number\"";
|
||||||
default: return "";
|
case BASE_TYPE_STRING:
|
||||||
|
return "\"type\" : \"string\"";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenBaseType(const Type &type) {
|
static std::string GenBaseType(const Type& type) {
|
||||||
if (type.struct_def != nullptr) { return GenTypeRef(type.struct_def); }
|
if (type.struct_def != nullptr) {
|
||||||
if (type.enum_def != nullptr) { return GenTypeRef(type.enum_def); }
|
return GenTypeRef(type.struct_def);
|
||||||
|
}
|
||||||
|
if (type.enum_def != nullptr) {
|
||||||
|
return GenTypeRef(type.enum_def);
|
||||||
|
}
|
||||||
return GenType(type.base_type);
|
return GenType(type.base_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenArrayType(const Type &type) {
|
static std::string GenArrayType(const Type& type) {
|
||||||
std::string element_type;
|
std::string element_type;
|
||||||
if (type.struct_def != nullptr) {
|
if (type.struct_def != nullptr) {
|
||||||
element_type = GenTypeRef(type.struct_def);
|
element_type = GenTypeRef(type.struct_def);
|
||||||
@@ -109,9 +119,10 @@ static std::string GenArrayType(const Type &type) {
|
|||||||
return "\"type\" : \"array\", \"items\" : {" + element_type + "}";
|
return "\"type\" : \"array\", \"items\" : {" + element_type + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenType(const Type &type) {
|
static std::string GenType(const Type& type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
return GenArrayType(type);
|
return GenArrayType(type);
|
||||||
}
|
}
|
||||||
@@ -120,10 +131,12 @@ static std::string GenType(const Type &type) {
|
|||||||
}
|
}
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
std::string union_type_string("\"anyOf\": [");
|
std::string union_type_string("\"anyOf\": [");
|
||||||
const auto &union_types = type.enum_def->Vals();
|
const auto& union_types = type.enum_def->Vals();
|
||||||
for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) {
|
for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) {
|
||||||
const auto &union_type = *ut;
|
const auto& union_type = *ut;
|
||||||
if (union_type->union_type.base_type == BASE_TYPE_NONE) { continue; }
|
if (union_type->union_type.base_type == BASE_TYPE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
|
if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
|
||||||
union_type_string.append(
|
union_type_string.append(
|
||||||
"{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
|
"{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
|
||||||
@@ -135,7 +148,8 @@ static std::string GenType(const Type &type) {
|
|||||||
union_type_string.append("]");
|
union_type_string.append("]");
|
||||||
return union_type_string;
|
return union_type_string;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: return GenTypeRef(type.enum_def);
|
case BASE_TYPE_UTYPE:
|
||||||
|
return GenTypeRef(type.enum_def);
|
||||||
default: {
|
default: {
|
||||||
return GenBaseType(type);
|
return GenBaseType(type);
|
||||||
}
|
}
|
||||||
@@ -149,16 +163,16 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
std::string code_;
|
std::string code_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
JsonSchemaGenerator(const Parser &parser, const std::string &path,
|
JsonSchemaGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", "", "json") {}
|
: BaseGenerator(parser, path, file_name, "", "", "json") {}
|
||||||
|
|
||||||
explicit JsonSchemaGenerator(const BaseGenerator &base_generator)
|
explicit JsonSchemaGenerator(const BaseGenerator& base_generator)
|
||||||
: BaseGenerator(base_generator) {}
|
: BaseGenerator(base_generator) {}
|
||||||
|
|
||||||
std::string GeneratedFileName(const std::string &path,
|
std::string GeneratedFileName(const std::string& path,
|
||||||
const std::string &file_name,
|
const std::string& file_name,
|
||||||
const IDLOptions &options /* unused */) const {
|
const IDLOptions& options /* unused */) const {
|
||||||
(void)options;
|
(void)options;
|
||||||
return path + file_name + ".schema.json";
|
return path + file_name + ".schema.json";
|
||||||
}
|
}
|
||||||
@@ -175,11 +189,11 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string PrepareDescription(
|
std::string PrepareDescription(
|
||||||
const std::vector<std::string> &comment_lines) {
|
const std::vector<std::string>& comment_lines) {
|
||||||
std::string comment;
|
std::string comment;
|
||||||
for (auto line_iterator = comment_lines.cbegin();
|
for (auto line_iterator = comment_lines.cbegin();
|
||||||
line_iterator != comment_lines.cend(); ++line_iterator) {
|
line_iterator != comment_lines.cend(); ++line_iterator) {
|
||||||
const auto &comment_line = *line_iterator;
|
const auto& comment_line = *line_iterator;
|
||||||
|
|
||||||
// remove leading and trailing spaces from comment line
|
// remove leading and trailing spaces from comment line
|
||||||
const auto start = std::find_if(comment_line.begin(), comment_line.end(),
|
const auto start = std::find_if(comment_line.begin(), comment_line.end(),
|
||||||
@@ -226,7 +240,9 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
for (auto enum_value = (*e)->Vals().begin();
|
for (auto enum_value = (*e)->Vals().begin();
|
||||||
enum_value != (*e)->Vals().end(); ++enum_value) {
|
enum_value != (*e)->Vals().end(); ++enum_value) {
|
||||||
enumdef.append("\"" + (*enum_value)->name + "\"");
|
enumdef.append("\"" + (*enum_value)->name + "\"");
|
||||||
if (*enum_value != (*e)->Vals().back()) { enumdef.append(", "); }
|
if (*enum_value != (*e)->Vals().back()) {
|
||||||
|
enumdef.append(", ");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
enumdef.append("]");
|
enumdef.append("]");
|
||||||
code_ += enumdef + NewLine();
|
code_ += enumdef + NewLine();
|
||||||
@@ -234,10 +250,10 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
for (auto s = parser_.structs_.vec.cbegin();
|
for (auto s = parser_.structs_.vec.cbegin();
|
||||||
s != parser_.structs_.vec.cend(); ++s) {
|
s != parser_.structs_.vec.cend(); ++s) {
|
||||||
const auto &structure = *s;
|
const auto& structure = *s;
|
||||||
code_ += Indent(2) + "\"" + GenFullName(structure) + "\" : {" + NewLine();
|
code_ += Indent(2) + "\"" + GenFullName(structure) + "\" : {" + NewLine();
|
||||||
code_ += Indent(3) + GenType("object") + "," + NewLine();
|
code_ += Indent(3) + GenType("object") + "," + NewLine();
|
||||||
const auto &comment_lines = structure->doc_comment;
|
const auto& comment_lines = structure->doc_comment;
|
||||||
auto comment = PrepareDescription(comment_lines);
|
auto comment = PrepareDescription(comment_lines);
|
||||||
if (comment != "") {
|
if (comment != "") {
|
||||||
code_ += Indent(3) + "\"description\" : " + comment + "," + NewLine();
|
code_ += Indent(3) + "\"description\" : " + comment + "," + NewLine();
|
||||||
@@ -245,9 +261,9 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
code_ += Indent(3) + "\"properties\" : {" + NewLine();
|
code_ += Indent(3) + "\"properties\" : {" + NewLine();
|
||||||
|
|
||||||
const auto &properties = structure->fields.vec;
|
const auto& properties = structure->fields.vec;
|
||||||
for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) {
|
for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) {
|
||||||
const auto &property = *prop;
|
const auto& property = *prop;
|
||||||
std::string arrayInfo = "";
|
std::string arrayInfo = "";
|
||||||
if (IsArray(property->value.type)) {
|
if (IsArray(property->value.type)) {
|
||||||
arrayInfo = "," + NewLine() + Indent(8) + "\"minItems\": " +
|
arrayInfo = "," + NewLine() + Indent(8) + "\"minItems\": " +
|
||||||
@@ -272,15 +288,17 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typeLine += NewLine() + Indent(7) + "}";
|
typeLine += NewLine() + Indent(7) + "}";
|
||||||
if (property != properties.back()) { typeLine.append(","); }
|
if (property != properties.back()) {
|
||||||
|
typeLine.append(",");
|
||||||
|
}
|
||||||
code_ += typeLine + NewLine();
|
code_ += typeLine + NewLine();
|
||||||
}
|
}
|
||||||
code_ += Indent(3) + "}," + NewLine(); // close properties
|
code_ += Indent(3) + "}," + NewLine(); // close properties
|
||||||
|
|
||||||
std::vector<FieldDef *> requiredProperties;
|
std::vector<FieldDef*> requiredProperties;
|
||||||
std::copy_if(properties.begin(), properties.end(),
|
std::copy_if(properties.begin(), properties.end(),
|
||||||
back_inserter(requiredProperties),
|
back_inserter(requiredProperties),
|
||||||
[](FieldDef const *prop) { return prop->IsRequired(); });
|
[](FieldDef const* prop) { return prop->IsRequired(); });
|
||||||
if (!requiredProperties.empty()) {
|
if (!requiredProperties.empty()) {
|
||||||
auto required_string(Indent(3) + "\"required\" : [");
|
auto required_string(Indent(3) + "\"required\" : [");
|
||||||
for (auto req_prop = requiredProperties.cbegin();
|
for (auto req_prop = requiredProperties.cbegin();
|
||||||
@@ -295,7 +313,9 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
code_ += Indent(3) + "\"additionalProperties\" : false" + NewLine();
|
code_ += Indent(3) + "\"additionalProperties\" : false" + NewLine();
|
||||||
auto closeType(Indent(2) + "}");
|
auto closeType(Indent(2) + "}");
|
||||||
if (*s != parser_.structs_.vec.back()) { closeType.append(","); }
|
if (*s != parser_.structs_.vec.back()) {
|
||||||
|
closeType.append(",");
|
||||||
|
}
|
||||||
code_ += closeType + NewLine(); // close type
|
code_ += closeType + NewLine(); // close type
|
||||||
}
|
}
|
||||||
code_ += Indent(1) + "}," + NewLine(); // close definitions
|
code_ += Indent(1) + "}," + NewLine(); // close definitions
|
||||||
@@ -317,10 +337,12 @@ class JsonSchemaGenerator : public BaseGenerator {
|
|||||||
};
|
};
|
||||||
} // namespace jsons
|
} // namespace jsons
|
||||||
|
|
||||||
static bool GenerateJsonSchema(const Parser &parser, const std::string &path,
|
static bool GenerateJsonSchema(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
jsons::JsonSchemaGenerator generator(parser, path, file_name);
|
jsons::JsonSchemaGenerator generator(parser, path, file_name);
|
||||||
if (!generator.generate()) { return false; }
|
if (!generator.generate()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return generator.save();
|
return generator.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -328,20 +350,21 @@ namespace {
|
|||||||
|
|
||||||
class JsonSchemaCodeGenerator : public CodeGenerator {
|
class JsonSchemaCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateJsonSchema(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateJsonSchema(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -349,16 +372,16 @@ class JsonSchemaCodeGenerator : public CodeGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
@@ -38,18 +38,18 @@ static TypedFloatConstantGenerator KotlinFloatGen("Double.", "Float.", "NaN",
|
|||||||
"POSITIVE_INFINITY",
|
"POSITIVE_INFINITY",
|
||||||
"NEGATIVE_INFINITY");
|
"NEGATIVE_INFINITY");
|
||||||
|
|
||||||
static const CommentConfig comment_config = { "/**", " *", " */" };
|
static const CommentConfig comment_config = {"/**", " *", " */"};
|
||||||
static const std::string ident_pad = " ";
|
static const std::string ident_pad = " ";
|
||||||
static std::set<std::string> KotlinKeywords() {
|
static std::set<std::string> KotlinKeywords() {
|
||||||
return { "package", "as", "typealias", "class", "this", "super",
|
return {"package", "as", "typealias", "class", "this", "super",
|
||||||
"val", "var", "fun", "for", "null", "true",
|
"val", "var", "fun", "for", "null", "true",
|
||||||
"false", "is", "in", "throw", "return", "break",
|
"false", "is", "in", "throw", "return", "break",
|
||||||
"continue", "object", "if", "try", "else", "while",
|
"continue", "object", "if", "try", "else", "while",
|
||||||
"do", "when", "interface", "typeof", "Any", "Character" };
|
"do", "when", "interface", "typeof", "Any", "Character"};
|
||||||
}
|
}
|
||||||
|
|
||||||
static Namer::Config KotlinDefaultConfig() {
|
static Namer::Config KotlinDefaultConfig() {
|
||||||
return { /*types=*/Case::kKeep,
|
return {/*types=*/Case::kKeep,
|
||||||
/*constants=*/Case::kKeep,
|
/*constants=*/Case::kKeep,
|
||||||
/*methods=*/Case::kLowerCamel,
|
/*methods=*/Case::kLowerCamel,
|
||||||
/*functions=*/Case::kKeep,
|
/*functions=*/Case::kKeep,
|
||||||
@@ -68,26 +68,26 @@ static Namer::Config KotlinDefaultConfig() {
|
|||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
/*filename_suffix=*/"",
|
/*filename_suffix=*/"",
|
||||||
/*filename_extension=*/".kt" };
|
/*filename_extension=*/".kt"};
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
class KotlinGenerator : public BaseGenerator {
|
class KotlinGenerator : public BaseGenerator {
|
||||||
public:
|
public:
|
||||||
KotlinGenerator(const Parser &parser, const std::string &path,
|
KotlinGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", ".", "kt"),
|
: BaseGenerator(parser, path, file_name, "", ".", "kt"),
|
||||||
namer_(WithFlagOptions(KotlinDefaultConfig(), parser.opts, path),
|
namer_(WithFlagOptions(KotlinDefaultConfig(), parser.opts, path),
|
||||||
KotlinKeywords()) {}
|
KotlinKeywords()) {}
|
||||||
|
|
||||||
KotlinGenerator &operator=(const KotlinGenerator &);
|
KotlinGenerator& operator=(const KotlinGenerator&);
|
||||||
bool generate() FLATBUFFERS_OVERRIDE {
|
bool generate() FLATBUFFERS_OVERRIDE {
|
||||||
std::string one_file_code;
|
std::string one_file_code;
|
||||||
|
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
CodeWriter enumWriter(ident_pad);
|
CodeWriter enumWriter(ident_pad);
|
||||||
auto &enum_def = **it;
|
auto& enum_def = **it;
|
||||||
GenEnum(enum_def, enumWriter);
|
GenEnum(enum_def, enumWriter);
|
||||||
if (parser_.opts.one_file) {
|
if (parser_.opts.one_file) {
|
||||||
one_file_code += enumWriter.ToString();
|
one_file_code += enumWriter.ToString();
|
||||||
@@ -101,7 +101,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
CodeWriter structWriter(ident_pad);
|
CodeWriter structWriter(ident_pad);
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
GenStruct(struct_def, structWriter, parser_.opts);
|
GenStruct(struct_def, structWriter, parser_.opts);
|
||||||
if (parser_.opts.one_file) {
|
if (parser_.opts.one_file) {
|
||||||
one_file_code += structWriter.ToString();
|
one_file_code += structWriter.ToString();
|
||||||
@@ -121,8 +121,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Save out the generated code for a single class while adding
|
// Save out the generated code for a single class while adding
|
||||||
// declaration boilerplate.
|
// declaration boilerplate.
|
||||||
bool SaveType(const std::string &defname, const Namespace &ns,
|
bool SaveType(const std::string& defname, const Namespace& ns,
|
||||||
const std::string &classcode, bool needs_includes) const {
|
const std::string& classcode, bool needs_includes) const {
|
||||||
if (!classcode.length()) return true;
|
if (!classcode.length()) return true;
|
||||||
|
|
||||||
std::string code =
|
std::string code =
|
||||||
@@ -159,11 +159,11 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
return SaveFile(filename.c_str(), code, false);
|
return SaveFile(filename.c_str(), code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsEnum(const Type &type) {
|
static bool IsEnum(const Type& type) {
|
||||||
return type.enum_def != nullptr && IsInteger(type.base_type);
|
return type.enum_def != nullptr && IsInteger(type.base_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenTypeBasic(const BaseType &type) {
|
static std::string GenTypeBasic(const BaseType& type) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char * const kotlin_typename[] = {
|
static const char * const kotlin_typename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
@@ -176,18 +176,22 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
return kotlin_typename[type];
|
return kotlin_typename[type];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypePointer(const Type &type) const {
|
std::string GenTypePointer(const Type& type) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "String";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
|
return "String";
|
||||||
case BASE_TYPE_STRUCT: return WrapInNameSpace(*type.struct_def);
|
case BASE_TYPE_VECTOR:
|
||||||
default: return "Table";
|
return GenTypeGet(type.VectorType());
|
||||||
|
case BASE_TYPE_STRUCT:
|
||||||
|
return WrapInNameSpace(*type.struct_def);
|
||||||
|
default:
|
||||||
|
return "Table";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// with the addition of optional scalar types,
|
// with the addition of optional scalar types,
|
||||||
// we are adding the nullable '?' operator to return type of a field.
|
// we are adding the nullable '?' operator to return type of a field.
|
||||||
std::string GetterReturnType(const FieldDef &field) const {
|
std::string GetterReturnType(const FieldDef& field) const {
|
||||||
auto base_type = field.value.type.base_type;
|
auto base_type = field.value.type.base_type;
|
||||||
|
|
||||||
auto r_type = GenTypeGet(field.value.type);
|
auto r_type = GenTypeGet(field.value.type);
|
||||||
@@ -204,15 +208,15 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
return r_type;
|
return r_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeGet(const Type &type) const {
|
std::string GenTypeGet(const Type& type) const {
|
||||||
return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
|
return IsScalar(type.base_type) ? GenTypeBasic(type.base_type)
|
||||||
: GenTypePointer(type);
|
: GenTypePointer(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenEnumDefaultValue(const FieldDef &field) const {
|
std::string GenEnumDefaultValue(const FieldDef& field) const {
|
||||||
auto &value = field.value;
|
auto& value = field.value;
|
||||||
FLATBUFFERS_ASSERT(value.type.enum_def);
|
FLATBUFFERS_ASSERT(value.type.enum_def);
|
||||||
auto &enum_def = *value.type.enum_def;
|
auto& enum_def = *value.type.enum_def;
|
||||||
auto enum_val = enum_def.FindByValue(value.constant);
|
auto enum_val = enum_def.FindByValue(value.constant);
|
||||||
return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
|
return enum_val ? (WrapInNameSpace(enum_def) + "." + enum_val->name)
|
||||||
: value.constant;
|
: value.constant;
|
||||||
@@ -223,7 +227,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
// Main differences are:
|
// Main differences are:
|
||||||
// - Floats are upcasted to doubles
|
// - Floats are upcasted to doubles
|
||||||
// - Unsigned are casted to signed
|
// - Unsigned are casted to signed
|
||||||
std::string GenFBBDefaultValue(const FieldDef &field) const {
|
std::string GenFBBDefaultValue(const FieldDef& field) const {
|
||||||
if (field.IsScalarOptional()) {
|
if (field.IsScalarOptional()) {
|
||||||
// although default value is null, java API forces us to present a real
|
// although default value is null, java API forces us to present a real
|
||||||
// default value for scalars, while adding a field to the buffer. This is
|
// default value for scalars, while adding a field to the buffer. This is
|
||||||
@@ -231,9 +235,12 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
// calling builder.addMyField()
|
// calling builder.addMyField()
|
||||||
switch (field.value.type.base_type) {
|
switch (field.value.type.base_type) {
|
||||||
case BASE_TYPE_DOUBLE:
|
case BASE_TYPE_DOUBLE:
|
||||||
case BASE_TYPE_FLOAT: return "0.0";
|
case BASE_TYPE_FLOAT:
|
||||||
case BASE_TYPE_BOOL: return "false";
|
return "0.0";
|
||||||
default: return "0";
|
case BASE_TYPE_BOOL:
|
||||||
|
return "false";
|
||||||
|
default:
|
||||||
|
return "0";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto out = GenDefaultValue(field, true);
|
auto out = GenDefaultValue(field, true);
|
||||||
@@ -250,19 +257,21 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// FlatBufferBuilder only store signed types, so this function
|
// FlatBufferBuilder only store signed types, so this function
|
||||||
// returns a cast for unsigned values
|
// returns a cast for unsigned values
|
||||||
std::string GenFBBValueCast(const FieldDef &field) const {
|
std::string GenFBBValueCast(const FieldDef& field) const {
|
||||||
if (IsUnsigned(field.value.type.base_type)) {
|
if (IsUnsigned(field.value.type.base_type)) {
|
||||||
return CastToSigned(field.value.type);
|
return CastToSigned(field.value.type);
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDefaultValue(const FieldDef &field,
|
std::string GenDefaultValue(const FieldDef& field,
|
||||||
bool force_signed = false) const {
|
bool force_signed = false) const {
|
||||||
auto &value = field.value;
|
auto& value = field.value;
|
||||||
auto base_type = field.value.type.base_type;
|
auto base_type = field.value.type.base_type;
|
||||||
|
|
||||||
if (field.IsScalarOptional()) { return "null"; }
|
if (field.IsScalarOptional()) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
if (IsFloat(base_type)) {
|
if (IsFloat(base_type)) {
|
||||||
auto val = KotlinFloatGen.GenFloatConstant(field);
|
auto val = KotlinFloatGen.GenFloatConstant(field);
|
||||||
if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
|
if (base_type == BASE_TYPE_DOUBLE && val.back() == 'f') {
|
||||||
@@ -283,7 +292,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
return value.constant + suffix;
|
return value.constant + suffix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenEnum(EnumDef &enum_def, CodeWriter &writer) const {
|
void GenEnum(EnumDef& enum_def, CodeWriter& writer) const {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
|
|
||||||
GenerateComment(enum_def.doc_comment, writer, &comment_config);
|
GenerateComment(enum_def.doc_comment, writer, &comment_config);
|
||||||
@@ -296,7 +305,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
// Write all properties
|
// Write all properties
|
||||||
auto vals = enum_def.Vals();
|
auto vals = enum_def.Vals();
|
||||||
for (auto it = vals.begin(); it != vals.end(); ++it) {
|
for (auto it = vals.begin(); it != vals.end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
|
auto field_type = GenTypeBasic(enum_def.underlying_type.base_type);
|
||||||
auto val = enum_def.ToString(ev);
|
auto val = enum_def.ToString(ev);
|
||||||
auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
|
auto suffix = LiteralSuffix(enum_def.underlying_type.base_type);
|
||||||
@@ -328,7 +337,9 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer += "\"\", \\";
|
writer += "\"\", \\";
|
||||||
val = ev;
|
val = ev;
|
||||||
writer += "\"" + (*it)->name + "\"\\";
|
writer += "\"" + (*it)->name + "\"\\";
|
||||||
if (it + 1 != vals.end()) { writer += ", \\"; }
|
if (it + 1 != vals.end()) {
|
||||||
|
writer += ", \\";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
writer += ")";
|
writer += ")";
|
||||||
});
|
});
|
||||||
@@ -348,49 +359,65 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the function name that is able to read a value of the given type.
|
// Returns the function name that is able to read a value of the given type.
|
||||||
std::string ByteBufferGetter(const Type &type,
|
std::string ByteBufferGetter(const Type& type,
|
||||||
std::string bb_var_name) const {
|
std::string bb_var_name) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "__string";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_STRUCT: return "__struct";
|
return "__string";
|
||||||
case BASE_TYPE_UNION: return "__union";
|
case BASE_TYPE_STRUCT:
|
||||||
|
return "__struct";
|
||||||
|
case BASE_TYPE_UNION:
|
||||||
|
return "__union";
|
||||||
case BASE_TYPE_VECTOR:
|
case BASE_TYPE_VECTOR:
|
||||||
return ByteBufferGetter(type.VectorType(), bb_var_name);
|
return ByteBufferGetter(type.VectorType(), bb_var_name);
|
||||||
case BASE_TYPE_INT:
|
case BASE_TYPE_INT:
|
||||||
case BASE_TYPE_UINT: return bb_var_name + ".getInt";
|
case BASE_TYPE_UINT:
|
||||||
|
return bb_var_name + ".getInt";
|
||||||
case BASE_TYPE_SHORT:
|
case BASE_TYPE_SHORT:
|
||||||
case BASE_TYPE_USHORT: return bb_var_name + ".getShort";
|
case BASE_TYPE_USHORT:
|
||||||
|
return bb_var_name + ".getShort";
|
||||||
case BASE_TYPE_ULONG:
|
case BASE_TYPE_ULONG:
|
||||||
case BASE_TYPE_LONG: return bb_var_name + ".getLong";
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_FLOAT: return bb_var_name + ".getFloat";
|
return bb_var_name + ".getLong";
|
||||||
case BASE_TYPE_DOUBLE: return bb_var_name + ".getDouble";
|
case BASE_TYPE_FLOAT:
|
||||||
|
return bb_var_name + ".getFloat";
|
||||||
|
case BASE_TYPE_DOUBLE:
|
||||||
|
return bb_var_name + ".getDouble";
|
||||||
case BASE_TYPE_CHAR:
|
case BASE_TYPE_CHAR:
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_NONE:
|
case BASE_TYPE_NONE:
|
||||||
case BASE_TYPE_UTYPE: return bb_var_name + ".get";
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_BOOL: return "0.toByte() != " + bb_var_name + ".get";
|
return bb_var_name + ".get";
|
||||||
|
case BASE_TYPE_BOOL:
|
||||||
|
return "0.toByte() != " + bb_var_name + ".get";
|
||||||
default:
|
default:
|
||||||
return bb_var_name + "." +
|
return bb_var_name + "." +
|
||||||
namer_.Method("get", GenTypeBasic(type.base_type));
|
namer_.Method("get", GenTypeBasic(type.base_type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ByteBufferSetter(const Type &type) const {
|
std::string ByteBufferSetter(const Type& type) const {
|
||||||
if (IsScalar(type.base_type)) {
|
if (IsScalar(type.base_type)) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_INT:
|
case BASE_TYPE_INT:
|
||||||
case BASE_TYPE_UINT: return "bb.putInt";
|
case BASE_TYPE_UINT:
|
||||||
|
return "bb.putInt";
|
||||||
case BASE_TYPE_SHORT:
|
case BASE_TYPE_SHORT:
|
||||||
case BASE_TYPE_USHORT: return "bb.putShort";
|
case BASE_TYPE_USHORT:
|
||||||
|
return "bb.putShort";
|
||||||
case BASE_TYPE_ULONG:
|
case BASE_TYPE_ULONG:
|
||||||
case BASE_TYPE_LONG: return "bb.putLong";
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_FLOAT: return "bb.putFloat";
|
return "bb.putLong";
|
||||||
case BASE_TYPE_DOUBLE: return "bb.putDouble";
|
case BASE_TYPE_FLOAT:
|
||||||
|
return "bb.putFloat";
|
||||||
|
case BASE_TYPE_DOUBLE:
|
||||||
|
return "bb.putDouble";
|
||||||
case BASE_TYPE_CHAR:
|
case BASE_TYPE_CHAR:
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_BOOL:
|
case BASE_TYPE_BOOL:
|
||||||
case BASE_TYPE_NONE:
|
case BASE_TYPE_NONE:
|
||||||
case BASE_TYPE_UTYPE: return "bb.put";
|
case BASE_TYPE_UTYPE:
|
||||||
|
return "bb.put";
|
||||||
default:
|
default:
|
||||||
return "bb." + namer_.Method("put", GenTypeBasic(type.base_type));
|
return "bb." + namer_.Method("put", GenTypeBasic(type.base_type));
|
||||||
}
|
}
|
||||||
@@ -399,27 +426,27 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the function name that is able to read a value of the given type.
|
// Returns the function name that is able to read a value of the given type.
|
||||||
std::string GenLookupByKey(flatbuffers::FieldDef *key_field,
|
std::string GenLookupByKey(flatbuffers::FieldDef* key_field,
|
||||||
const std::string &bb_var_name,
|
const std::string& bb_var_name,
|
||||||
const char *num = nullptr) const {
|
const char* num = nullptr) const {
|
||||||
auto type = key_field->value.type;
|
auto type = key_field->value.type;
|
||||||
return ByteBufferGetter(type, bb_var_name) + "(" +
|
return ByteBufferGetter(type, bb_var_name) + "(" +
|
||||||
GenOffsetGetter(key_field, num) + ")";
|
GenOffsetGetter(key_field, num) + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the method name for use with add/put calls.
|
// Returns the method name for use with add/put calls.
|
||||||
static std::string GenMethod(const Type &type) {
|
static std::string GenMethod(const Type& type) {
|
||||||
return IsScalar(type.base_type) ? ToSignedType(type)
|
return IsScalar(type.base_type) ? ToSignedType(type)
|
||||||
: (IsStruct(type) ? "Struct" : "Offset");
|
: (IsStruct(type) ? "Struct" : "Offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Recursively generate arguments for a constructor, to deal with nested
|
// Recursively generate arguments for a constructor, to deal with nested
|
||||||
// structs.
|
// structs.
|
||||||
void GenStructArgs(const StructDef &struct_def, CodeWriter &writer,
|
void GenStructArgs(const StructDef& struct_def, CodeWriter& writer,
|
||||||
const char *nameprefix) const {
|
const char* nameprefix) const {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
// Generate arguments for a struct inside a struct. To ensure
|
// Generate arguments for a struct inside a struct. To ensure
|
||||||
// names don't clash, and to make it obvious these arguments are
|
// names don't clash, and to make it obvious these arguments are
|
||||||
@@ -438,14 +465,14 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
// Recusively generate struct construction statements of the form:
|
// Recusively generate struct construction statements of the form:
|
||||||
// builder.putType(name);
|
// builder.putType(name);
|
||||||
// and insert manual padding.
|
// and insert manual padding.
|
||||||
void GenStructBody(const StructDef &struct_def, CodeWriter &writer,
|
void GenStructBody(const StructDef& struct_def, CodeWriter& writer,
|
||||||
const char *nameprefix) const {
|
const char* nameprefix) const {
|
||||||
writer.SetValue("align", NumToString(struct_def.minalign));
|
writer.SetValue("align", NumToString(struct_def.minalign));
|
||||||
writer.SetValue("size", NumToString(struct_def.bytesize));
|
writer.SetValue("size", NumToString(struct_def.bytesize));
|
||||||
writer += "builder.prep({{align}}, {{size}})";
|
writer += "builder.prep({{align}}, {{size}})";
|
||||||
auto fields_vec = struct_def.fields.vec;
|
auto fields_vec = struct_def.fields.vec;
|
||||||
for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
|
for (auto it = fields_vec.rbegin(); it != fields_vec.rend(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
|
|
||||||
if (field.padding) {
|
if (field.padding) {
|
||||||
writer.SetValue("pad", NumToString(field.padding));
|
writer.SetValue("pad", NumToString(field.padding));
|
||||||
@@ -463,14 +490,14 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenByteBufferLength(const char *bb_name) const {
|
std::string GenByteBufferLength(const char* bb_name) const {
|
||||||
std::string bb_len = bb_name;
|
std::string bb_len = bb_name;
|
||||||
bb_len += ".capacity()";
|
bb_len += ".capacity()";
|
||||||
return bb_len;
|
return bb_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
|
std::string GenOffsetGetter(flatbuffers::FieldDef* key_field,
|
||||||
const char *num = nullptr) const {
|
const char* num = nullptr) const {
|
||||||
std::string key_offset =
|
std::string key_offset =
|
||||||
"__offset(" + NumToString(key_field->value.offset) + ", ";
|
"__offset(" + NumToString(key_field->value.offset) + ", ";
|
||||||
if (num) {
|
if (num) {
|
||||||
@@ -483,7 +510,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
return key_offset;
|
return key_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenStruct(StructDef &struct_def, CodeWriter &writer,
|
void GenStruct(StructDef& struct_def, CodeWriter& writer,
|
||||||
IDLOptions options) const {
|
IDLOptions options) const {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
|
|
||||||
@@ -517,7 +544,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
// Generate Static Fields
|
// Generate Static Fields
|
||||||
GenerateCompanionObject(writer, [&]() {
|
GenerateCompanionObject(writer, [&]() {
|
||||||
if (!struct_def.fixed) {
|
if (!struct_def.fixed) {
|
||||||
FieldDef *key_field = nullptr;
|
FieldDef* key_field = nullptr;
|
||||||
|
|
||||||
// Generate version check method.
|
// Generate version check method.
|
||||||
// Force compile time error if not using the same version
|
// Force compile time error if not using the same version
|
||||||
@@ -537,7 +564,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
auto fields = struct_def.fields.vec;
|
auto fields = struct_def.fields.vec;
|
||||||
int field_pos = -1;
|
int field_pos = -1;
|
||||||
for (auto it = fields.begin(); it != fields.end(); ++it) {
|
for (auto it = fields.begin(); it != fields.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
field_pos++;
|
field_pos++;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.key) key_field = &field;
|
if (field.key) key_field = &field;
|
||||||
@@ -576,8 +603,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move key_field to reference instead of pointer
|
// TODO: move key_field to reference instead of pointer
|
||||||
void GenerateLookupByKey(FieldDef *key_field, StructDef &struct_def,
|
void GenerateLookupByKey(FieldDef* key_field, StructDef& struct_def,
|
||||||
CodeWriter &writer, const IDLOptions options) const {
|
CodeWriter& writer, const IDLOptions options) const {
|
||||||
std::stringstream params;
|
std::stringstream params;
|
||||||
params << "obj: " << namer_.Type(struct_def) << "?"
|
params << "obj: " << namer_.Type(struct_def) << "?"
|
||||||
<< ", ";
|
<< ", ";
|
||||||
@@ -637,9 +664,9 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateFinishSizePrefixed(StructDef &struct_def,
|
void GenerateFinishSizePrefixed(StructDef& struct_def,
|
||||||
const std::string &identifier,
|
const std::string& identifier,
|
||||||
CodeWriter &writer,
|
CodeWriter& writer,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
|
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
|
||||||
auto params = "builder: FlatBufferBuilder, offset: Int";
|
auto params = "builder: FlatBufferBuilder, offset: Int";
|
||||||
@@ -650,9 +677,9 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
[&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; },
|
[&]() { writer += "builder.finishSizePrefixed(offset" + id + ")"; },
|
||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
void GenerateFinishStructBuffer(StructDef &struct_def,
|
void GenerateFinishStructBuffer(StructDef& struct_def,
|
||||||
const std::string &identifier,
|
const std::string& identifier,
|
||||||
CodeWriter &writer,
|
CodeWriter& writer,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
|
auto id = identifier.length() > 0 ? ", \"" + identifier + "\"" : "";
|
||||||
auto params = "builder: FlatBufferBuilder, offset: Int";
|
auto params = "builder: FlatBufferBuilder, offset: Int";
|
||||||
@@ -664,7 +691,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateEndStructMethod(StructDef &struct_def, CodeWriter &writer,
|
void GenerateEndStructMethod(StructDef& struct_def, CodeWriter& writer,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
// Generate end{{TableName}}(builder: FlatBufferBuilder) method
|
// Generate end{{TableName}}(builder: FlatBufferBuilder) method
|
||||||
auto name = namer_.LegacyJavaMethod2("end", struct_def, "");
|
auto name = namer_.LegacyJavaMethod2("end", struct_def, "");
|
||||||
@@ -678,8 +705,10 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer += "val o = builder.endTable()";
|
writer += "val o = builder.endTable()";
|
||||||
writer.IncrementIdentLevel();
|
writer.IncrementIdentLevel();
|
||||||
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
|
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated || !field.IsRequired()) { continue; }
|
if (field.deprecated || !field.IsRequired()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
writer.SetValue("offset", NumToString(field.value.offset));
|
writer.SetValue("offset", NumToString(field.value.offset));
|
||||||
writer += "builder.required(o, {{offset}})";
|
writer += "builder.required(o, {{offset}})";
|
||||||
}
|
}
|
||||||
@@ -690,7 +719,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a method to create a vector from a Kotlin array.
|
// Generate a method to create a vector from a Kotlin array.
|
||||||
void GenerateCreateVectorField(FieldDef &field, CodeWriter &writer,
|
void GenerateCreateVectorField(FieldDef& field, CodeWriter& writer,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
auto vector_type = field.value.type.VectorType();
|
auto vector_type = field.value.type.VectorType();
|
||||||
auto method_name = namer_.Method("create", field, "vector");
|
auto method_name = namer_.Method("create", field, "vector");
|
||||||
@@ -718,7 +747,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateStartVectorField(FieldDef &field, CodeWriter &writer,
|
void GenerateStartVectorField(FieldDef& field, CodeWriter& writer,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
// Generate a method to start a vector, data to be added manually
|
// Generate a method to start a vector, data to be added manually
|
||||||
// after.
|
// after.
|
||||||
@@ -735,8 +764,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateAddField(std::string field_pos, FieldDef &field,
|
void GenerateAddField(std::string field_pos, FieldDef& field,
|
||||||
CodeWriter &writer, const IDLOptions options) const {
|
CodeWriter& writer, const IDLOptions options) const {
|
||||||
auto field_type = GenTypeBasic(field.value.type.base_type);
|
auto field_type = GenTypeBasic(field.value.type.base_type);
|
||||||
auto secondArg = namer_.Variable(field.name) + ": " + field_type;
|
auto secondArg = namer_.Variable(field.name) + ": " + field_type;
|
||||||
|
|
||||||
@@ -770,21 +799,27 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ToSignedType(const Type &type) {
|
static std::string ToSignedType(const Type& type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_UINT: return GenTypeBasic(BASE_TYPE_INT);
|
case BASE_TYPE_UINT:
|
||||||
case BASE_TYPE_ULONG: return GenTypeBasic(BASE_TYPE_LONG);
|
return GenTypeBasic(BASE_TYPE_INT);
|
||||||
|
case BASE_TYPE_ULONG:
|
||||||
|
return GenTypeBasic(BASE_TYPE_LONG);
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_NONE:
|
case BASE_TYPE_NONE:
|
||||||
case BASE_TYPE_UTYPE: return GenTypeBasic(BASE_TYPE_CHAR);
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_USHORT: return GenTypeBasic(BASE_TYPE_SHORT);
|
return GenTypeBasic(BASE_TYPE_CHAR);
|
||||||
case BASE_TYPE_VECTOR: return ToSignedType(type.VectorType());
|
case BASE_TYPE_USHORT:
|
||||||
default: return GenTypeBasic(type.base_type);
|
return GenTypeBasic(BASE_TYPE_SHORT);
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return ToSignedType(type.VectorType());
|
||||||
|
default:
|
||||||
|
return GenTypeBasic(type.base_type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string FlexBufferBuilderCast(const std::string &method,
|
static std::string FlexBufferBuilderCast(const std::string& method,
|
||||||
FieldDef &field, bool isFirst) {
|
FieldDef& field, bool isFirst) {
|
||||||
auto field_type = GenTypeBasic(field.value.type.base_type);
|
auto field_type = GenTypeBasic(field.value.type.base_type);
|
||||||
std::string to_type;
|
std::string to_type;
|
||||||
if (method == "Boolean")
|
if (method == "Boolean")
|
||||||
@@ -808,7 +843,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
|
// fun startMonster(builder: FlatBufferBuilder) = builder.startTable(11)
|
||||||
void GenerateStartStructMethod(StructDef &struct_def, CodeWriter &code,
|
void GenerateStartStructMethod(StructDef& struct_def, CodeWriter& code,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
GenerateFunOneLine(
|
GenerateFunOneLine(
|
||||||
code, namer_.LegacyJavaMethod2("start", struct_def, ""),
|
code, namer_.LegacyJavaMethod2("start", struct_def, ""),
|
||||||
@@ -820,7 +855,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateTableCreator(StructDef &struct_def, CodeWriter &writer,
|
void GenerateTableCreator(StructDef& struct_def, CodeWriter& writer,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
// Generate a method that creates a table in one go. This is only possible
|
// Generate a method that creates a table in one go. This is only possible
|
||||||
// when the table has no struct fields, since those have to be created
|
// when the table has no struct fields, since those have to be created
|
||||||
@@ -830,7 +865,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
auto fields_vec = struct_def.fields.vec;
|
auto fields_vec = struct_def.fields.vec;
|
||||||
|
|
||||||
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
|
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
has_no_struct_fields = false;
|
has_no_struct_fields = false;
|
||||||
@@ -848,7 +883,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
std::stringstream params;
|
std::stringstream params;
|
||||||
params << "builder: FlatBufferBuilder";
|
params << "builder: FlatBufferBuilder";
|
||||||
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
|
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
params << ", " << namer_.Variable(field);
|
params << ", " << namer_.Variable(field);
|
||||||
if (!IsScalar(field.value.type.base_type)) {
|
if (!IsScalar(field.value.type.base_type)) {
|
||||||
@@ -872,7 +907,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
for (size_t size = largest; size; size /= 2) {
|
for (size_t size = largest; size; size /= 2) {
|
||||||
for (auto it = fields_vec.rbegin(); it != fields_vec.rend();
|
for (auto it = fields_vec.rbegin(); it != fields_vec.rend();
|
||||||
++it) {
|
++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
auto base_type_size = SizeOf(field.value.type.base_type);
|
auto base_type_size = SizeOf(field.value.type.base_type);
|
||||||
if (!field.deprecated &&
|
if (!field.deprecated &&
|
||||||
(!sortbysize || size == base_type_size)) {
|
(!sortbysize || size == base_type_size)) {
|
||||||
@@ -898,7 +933,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void GenerateBufferHasIdentifier(StructDef &struct_def, CodeWriter &writer,
|
void GenerateBufferHasIdentifier(StructDef& struct_def, CodeWriter& writer,
|
||||||
IDLOptions options) const {
|
IDLOptions options) const {
|
||||||
auto file_identifier = parser_.file_identifier_;
|
auto file_identifier = parser_.file_identifier_;
|
||||||
// Check if a buffer has the identifier.
|
// Check if a buffer has the identifier.
|
||||||
@@ -913,11 +948,11 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateStructGetters(StructDef &struct_def, CodeWriter &writer) const {
|
void GenerateStructGetters(StructDef& struct_def, CodeWriter& writer) const {
|
||||||
auto fields_vec = struct_def.fields.vec;
|
auto fields_vec = struct_def.fields.vec;
|
||||||
FieldDef *key_field = nullptr;
|
FieldDef* key_field = nullptr;
|
||||||
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
|
for (auto it = fields_vec.begin(); it != fields_vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.key) key_field = &field;
|
if (field.key) key_field = &field;
|
||||||
|
|
||||||
@@ -1090,7 +1125,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
case BASE_TYPE_UNION:
|
case BASE_TYPE_UNION:
|
||||||
found = "{{bbgetter}}(obj, {{index}}){{ucast}}";
|
found = "{{bbgetter}}(obj, {{index}}){{ucast}}";
|
||||||
break;
|
break;
|
||||||
default: found = "{{bbgetter}}({{index}}){{ucast}}";
|
default:
|
||||||
|
found = "{{bbgetter}}({{index}}){{ucast}}";
|
||||||
}
|
}
|
||||||
OffsetWrapper(
|
OffsetWrapper(
|
||||||
writer, offset_val, [&]() { writer += found; },
|
writer, offset_val, [&]() { writer += found; },
|
||||||
@@ -1105,7 +1141,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
offset_val, bbgetter + "(obj, o + bb_pos)", "null");
|
offset_val, bbgetter + "(obj, o + bb_pos)", "null");
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
default: FLATBUFFERS_ASSERT(0);
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1118,10 +1155,10 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
// See if we should generate a by-key accessor.
|
// See if we should generate a by-key accessor.
|
||||||
if (field.value.type.element == BASE_TYPE_STRUCT &&
|
if (field.value.type.element == BASE_TYPE_STRUCT &&
|
||||||
!field.value.type.struct_def->fixed) {
|
!field.value.type.struct_def->fixed) {
|
||||||
auto &sd = *field.value.type.struct_def;
|
auto& sd = *field.value.type.struct_def;
|
||||||
auto &fields = sd.fields.vec;
|
auto& fields = sd.fields.vec;
|
||||||
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
||||||
auto &kfield = **kit;
|
auto& kfield = **kit;
|
||||||
if (kfield.key) {
|
if (kfield.key) {
|
||||||
auto qualified_name = WrapInNameSpace(sd);
|
auto qualified_name = WrapInNameSpace(sd);
|
||||||
auto name = namer_.Method(field, "ByKey");
|
auto name = namer_.Method(field, "ByKey");
|
||||||
@@ -1286,35 +1323,47 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string CastToUsigned(const FieldDef &field) {
|
static std::string CastToUsigned(const FieldDef& field) {
|
||||||
return CastToUsigned(field.value.type);
|
return CastToUsigned(field.value.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string CastToUsigned(const Type type) {
|
static std::string CastToUsigned(const Type type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_UINT: return ".toUInt()";
|
case BASE_TYPE_UINT:
|
||||||
|
return ".toUInt()";
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_UTYPE: return ".toUByte()";
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_USHORT: return ".toUShort()";
|
return ".toUByte()";
|
||||||
case BASE_TYPE_ULONG: return ".toULong()";
|
case BASE_TYPE_USHORT:
|
||||||
case BASE_TYPE_VECTOR: return CastToUsigned(type.VectorType());
|
return ".toUShort()";
|
||||||
default: return "";
|
case BASE_TYPE_ULONG:
|
||||||
|
return ".toULong()";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return CastToUsigned(type.VectorType());
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string CastToSigned(const FieldDef &field) {
|
static std::string CastToSigned(const FieldDef& field) {
|
||||||
return CastToSigned(field.value.type);
|
return CastToSigned(field.value.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string CastToSigned(const Type type) {
|
static std::string CastToSigned(const Type type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_UINT: return ".toInt()";
|
case BASE_TYPE_UINT:
|
||||||
|
return ".toInt()";
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_UTYPE: return ".toByte()";
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_USHORT: return ".toShort()";
|
return ".toByte()";
|
||||||
case BASE_TYPE_ULONG: return ".toLong()";
|
case BASE_TYPE_USHORT:
|
||||||
case BASE_TYPE_VECTOR: return CastToSigned(type.VectorType());
|
return ".toShort()";
|
||||||
default: return "";
|
case BASE_TYPE_ULONG:
|
||||||
|
return ".toLong()";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return CastToSigned(type.VectorType());
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1323,15 +1372,19 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
case BASE_TYPE_UINT:
|
case BASE_TYPE_UINT:
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_UTYPE:
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_USHORT: return "u";
|
case BASE_TYPE_USHORT:
|
||||||
case BASE_TYPE_ULONG: return "UL";
|
return "u";
|
||||||
case BASE_TYPE_LONG: return "L";
|
case BASE_TYPE_ULONG:
|
||||||
default: return "";
|
return "UL";
|
||||||
|
case BASE_TYPE_LONG:
|
||||||
|
return "L";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateCompanionObject(CodeWriter &code,
|
void GenerateCompanionObject(CodeWriter& code,
|
||||||
const std::function<void()> &callback) const {
|
const std::function<void()>& callback) const {
|
||||||
code += "companion object {";
|
code += "companion object {";
|
||||||
code.IncrementIdentLevel();
|
code.IncrementIdentLevel();
|
||||||
callback();
|
callback();
|
||||||
@@ -1340,8 +1393,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a documentation comment, if available.
|
// Generate a documentation comment, if available.
|
||||||
void GenerateComment(const std::vector<std::string> &dc, CodeWriter &writer,
|
void GenerateComment(const std::vector<std::string>& dc, CodeWriter& writer,
|
||||||
const CommentConfig *config) const {
|
const CommentConfig* config) const {
|
||||||
if (dc.begin() == dc.end()) {
|
if (dc.begin() == dc.end()) {
|
||||||
// Don't output empty comment blocks with 0 lines of comment content.
|
// Don't output empty comment blocks with 0 lines of comment content.
|
||||||
return;
|
return;
|
||||||
@@ -1362,8 +1415,8 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateGetRootAsAccessors(const std::string &struct_name,
|
void GenerateGetRootAsAccessors(const std::string& struct_name,
|
||||||
CodeWriter &writer,
|
CodeWriter& writer,
|
||||||
IDLOptions options) const {
|
IDLOptions options) const {
|
||||||
// Generate a special accessor for the table that when used as the root
|
// Generate a special accessor for the table that when used as the root
|
||||||
// ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
|
// ex: fun getRootAsMonster(_bb: ByteBuffer): Monster {...}
|
||||||
@@ -1390,7 +1443,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer += "}";
|
writer += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateStaticConstructor(const StructDef &struct_def, CodeWriter &code,
|
void GenerateStaticConstructor(const StructDef& struct_def, CodeWriter& code,
|
||||||
const IDLOptions options) const {
|
const IDLOptions options) const {
|
||||||
// create a struct constructor function
|
// create a struct constructor function
|
||||||
auto params = StructConstructorParams(struct_def);
|
auto params = StructConstructorParams(struct_def);
|
||||||
@@ -1403,14 +1456,16 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
options.gen_jvmstatic);
|
options.gen_jvmstatic);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StructConstructorParams(const StructDef &struct_def,
|
std::string StructConstructorParams(const StructDef& struct_def,
|
||||||
const std::string &prefix = "") const {
|
const std::string& prefix = "") const {
|
||||||
// builder: FlatBufferBuilder
|
// builder: FlatBufferBuilder
|
||||||
std::stringstream out;
|
std::stringstream out;
|
||||||
auto field_vec = struct_def.fields.vec;
|
auto field_vec = struct_def.fields.vec;
|
||||||
if (prefix.empty()) { out << "builder: FlatBufferBuilder"; }
|
if (prefix.empty()) {
|
||||||
|
out << "builder: FlatBufferBuilder";
|
||||||
|
}
|
||||||
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
|
for (auto it = field_vec.begin(); it != field_vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
// Generate arguments for a struct inside a struct. To ensure
|
// Generate arguments for a struct inside a struct. To ensure
|
||||||
// names don't clash, and to make it obvious these arguments are
|
// names don't clash, and to make it obvious these arguments are
|
||||||
@@ -1426,10 +1481,10 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GeneratePropertyOneLine(CodeWriter &writer,
|
static void GeneratePropertyOneLine(CodeWriter& writer,
|
||||||
const std::string &name,
|
const std::string& name,
|
||||||
const std::string &type,
|
const std::string& type,
|
||||||
const std::function<void()> &body) {
|
const std::function<void()>& body) {
|
||||||
// Generates Kotlin getter for properties
|
// Generates Kotlin getter for properties
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// val prop: Mytype = x
|
// val prop: Mytype = x
|
||||||
@@ -1438,9 +1493,9 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer += "val {{_name}} : {{_type}} = \\";
|
writer += "val {{_name}} : {{_type}} = \\";
|
||||||
body();
|
body();
|
||||||
}
|
}
|
||||||
static void GenerateGetterOneLine(CodeWriter &writer, const std::string &name,
|
static void GenerateGetterOneLine(CodeWriter& writer, const std::string& name,
|
||||||
const std::string &type,
|
const std::string& type,
|
||||||
const std::function<void()> &body) {
|
const std::function<void()>& body) {
|
||||||
// Generates Kotlin getter for properties
|
// Generates Kotlin getter for properties
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// val prop: Mytype get() = x
|
// val prop: Mytype get() = x
|
||||||
@@ -1450,9 +1505,9 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
body();
|
body();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateGetter(CodeWriter &writer, const std::string &name,
|
static void GenerateGetter(CodeWriter& writer, const std::string& name,
|
||||||
const std::string &type,
|
const std::string& type,
|
||||||
const std::function<void()> &body) {
|
const std::function<void()>& body) {
|
||||||
// Generates Kotlin getter for properties
|
// Generates Kotlin getter for properties
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// val prop: Mytype
|
// val prop: Mytype
|
||||||
@@ -1471,10 +1526,10 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer.DecrementIdentLevel();
|
writer.DecrementIdentLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateFun(CodeWriter &writer, const std::string &name,
|
static void GenerateFun(CodeWriter& writer, const std::string& name,
|
||||||
const std::string ¶ms,
|
const std::string& params,
|
||||||
const std::string &returnType,
|
const std::string& returnType,
|
||||||
const std::function<void()> &body,
|
const std::function<void()>& body,
|
||||||
bool gen_jvmstatic = false) {
|
bool gen_jvmstatic = false) {
|
||||||
// Generates Kotlin function
|
// Generates Kotlin function
|
||||||
// e.g.:
|
// e.g.:
|
||||||
@@ -1493,10 +1548,10 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer += "}";
|
writer += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateFunOneLine(CodeWriter &writer, const std::string &name,
|
static void GenerateFunOneLine(CodeWriter& writer, const std::string& name,
|
||||||
const std::string ¶ms,
|
const std::string& params,
|
||||||
const std::string &returnType,
|
const std::string& returnType,
|
||||||
const std::function<void()> &body,
|
const std::function<void()>& body,
|
||||||
bool gen_jvmstatic = false) {
|
bool gen_jvmstatic = false) {
|
||||||
// Generates Kotlin function
|
// Generates Kotlin function
|
||||||
// e.g.:
|
// e.g.:
|
||||||
@@ -1510,10 +1565,10 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
body();
|
body();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateOverrideFun(CodeWriter &writer, const std::string &name,
|
static void GenerateOverrideFun(CodeWriter& writer, const std::string& name,
|
||||||
const std::string ¶ms,
|
const std::string& params,
|
||||||
const std::string &returnType,
|
const std::string& returnType,
|
||||||
const std::function<void()> &body) {
|
const std::function<void()>& body) {
|
||||||
// Generates Kotlin function
|
// Generates Kotlin function
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// override fun path(j: Int): Vec3 = return path(Vec3(), j)
|
// override fun path(j: Int): Vec3 = return path(Vec3(), j)
|
||||||
@@ -1521,11 +1576,11 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
GenerateFun(writer, name, params, returnType, body);
|
GenerateFun(writer, name, params, returnType, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GenerateOverrideFunOneLine(CodeWriter &writer,
|
static void GenerateOverrideFunOneLine(CodeWriter& writer,
|
||||||
const std::string &name,
|
const std::string& name,
|
||||||
const std::string ¶ms,
|
const std::string& params,
|
||||||
const std::string &returnType,
|
const std::string& returnType,
|
||||||
const std::string &statement) {
|
const std::string& statement) {
|
||||||
// Generates Kotlin function
|
// Generates Kotlin function
|
||||||
// e.g.:
|
// e.g.:
|
||||||
// override fun path(j: Int): Vec3 = return path(Vec3(), j)
|
// override fun path(j: Int): Vec3 = return path(Vec3(), j)
|
||||||
@@ -1537,16 +1592,16 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
writer += statement;
|
writer += statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string OffsetWrapperOneLine(const std::string &offset,
|
static std::string OffsetWrapperOneLine(const std::string& offset,
|
||||||
const std::string &found,
|
const std::string& found,
|
||||||
const std::string ¬_found) {
|
const std::string& not_found) {
|
||||||
return "val o = __offset(" + offset + "); return if (o != 0) " + found +
|
return "val o = __offset(" + offset + "); return if (o != 0) " + found +
|
||||||
" else " + not_found;
|
" else " + not_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void OffsetWrapper(CodeWriter &code, const std::string &offset,
|
static void OffsetWrapper(CodeWriter& code, const std::string& offset,
|
||||||
const std::function<void()> &found,
|
const std::function<void()>& found,
|
||||||
const std::function<void()> ¬_found) {
|
const std::function<void()>& not_found) {
|
||||||
code += "val o = __offset(" + offset + ")";
|
code += "val o = __offset(" + offset + ")";
|
||||||
code += "return if (o != 0) {";
|
code += "return if (o != 0) {";
|
||||||
code.IncrementIdentLevel();
|
code.IncrementIdentLevel();
|
||||||
@@ -1559,7 +1614,7 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
code += "}";
|
code += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string Indirect(const std::string &index, bool fixed) {
|
static std::string Indirect(const std::string& index, bool fixed) {
|
||||||
// We apply __indirect() and struct is not fixed.
|
// We apply __indirect() and struct is not fixed.
|
||||||
if (!fixed) return "__indirect(" + index + ")";
|
if (!fixed) return "__indirect(" + index + ")";
|
||||||
return index;
|
return index;
|
||||||
@@ -1567,34 +1622,43 @@ class KotlinGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
static std::string NotFoundReturn(BaseType el) {
|
static std::string NotFoundReturn(BaseType el) {
|
||||||
switch (el) {
|
switch (el) {
|
||||||
case BASE_TYPE_FLOAT: return "0.0f";
|
case BASE_TYPE_FLOAT:
|
||||||
case BASE_TYPE_DOUBLE: return "0.0";
|
return "0.0f";
|
||||||
case BASE_TYPE_BOOL: return "false";
|
case BASE_TYPE_DOUBLE:
|
||||||
|
return "0.0";
|
||||||
|
case BASE_TYPE_BOOL:
|
||||||
|
return "false";
|
||||||
case BASE_TYPE_LONG:
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_INT:
|
case BASE_TYPE_INT:
|
||||||
case BASE_TYPE_CHAR:
|
case BASE_TYPE_CHAR:
|
||||||
case BASE_TYPE_SHORT: return "0";
|
case BASE_TYPE_SHORT:
|
||||||
|
return "0";
|
||||||
case BASE_TYPE_UINT:
|
case BASE_TYPE_UINT:
|
||||||
case BASE_TYPE_UCHAR:
|
case BASE_TYPE_UCHAR:
|
||||||
case BASE_TYPE_USHORT:
|
case BASE_TYPE_USHORT:
|
||||||
case BASE_TYPE_UTYPE: return "0u";
|
case BASE_TYPE_UTYPE:
|
||||||
case BASE_TYPE_ULONG: return "0uL";
|
return "0u";
|
||||||
default: return "null";
|
case BASE_TYPE_ULONG:
|
||||||
|
return "0uL";
|
||||||
|
default:
|
||||||
|
return "null";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepend @JvmStatic to methods in companion object.
|
// Prepend @JvmStatic to methods in companion object.
|
||||||
static void GenerateJvmStaticAnnotation(CodeWriter &code,
|
static void GenerateJvmStaticAnnotation(CodeWriter& code,
|
||||||
bool gen_jvmstatic) {
|
bool gen_jvmstatic) {
|
||||||
if (gen_jvmstatic) { code += "@JvmStatic"; }
|
if (gen_jvmstatic) {
|
||||||
|
code += "@JvmStatic";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const IdlNamer namer_;
|
const IdlNamer namer_;
|
||||||
};
|
};
|
||||||
} // namespace kotlin
|
} // namespace kotlin
|
||||||
|
|
||||||
static bool GenerateKotlin(const Parser &parser, const std::string &path,
|
static bool GenerateKotlin(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
kotlin::KotlinGenerator generator(parser, path, file_name);
|
kotlin::KotlinGenerator generator(parser, path, file_name);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
@@ -1603,20 +1667,21 @@ namespace {
|
|||||||
|
|
||||||
class KotlinCodeGenerator : public CodeGenerator {
|
class KotlinCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateKotlin(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateKotlin(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -1624,16 +1689,16 @@ class KotlinCodeGenerator : public CodeGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -29,11 +29,11 @@ namespace lobster {
|
|||||||
|
|
||||||
class LobsterGenerator : public BaseGenerator {
|
class LobsterGenerator : public BaseGenerator {
|
||||||
public:
|
public:
|
||||||
LobsterGenerator(const Parser &parser, const std::string &path,
|
LobsterGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "" /* not used */, ".",
|
: BaseGenerator(parser, path, file_name, "" /* not used */, ".",
|
||||||
"lobster") {
|
"lobster") {
|
||||||
static const char *const keywords[] = {
|
static const char* const keywords[] = {
|
||||||
"nil", "true", "false", "return", "struct", "class",
|
"nil", "true", "false", "return", "struct", "class",
|
||||||
"import", "int", "float", "string", "any", "def",
|
"import", "int", "float", "string", "any", "def",
|
||||||
"is", "from", "program", "private", "coroutine", "resource",
|
"is", "from", "program", "private", "coroutine", "resource",
|
||||||
@@ -44,23 +44,23 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
keywords_.insert(std::begin(keywords), std::end(keywords));
|
keywords_.insert(std::begin(keywords), std::end(keywords));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string EscapeKeyword(const std::string &name) const {
|
std::string EscapeKeyword(const std::string& name) const {
|
||||||
return keywords_.find(name) == keywords_.end() ? name : name + "_";
|
return keywords_.find(name) == keywords_.end() ? name : name + "_";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NormalizedName(const Definition &definition) const {
|
std::string NormalizedName(const Definition& definition) const {
|
||||||
return EscapeKeyword(definition.name);
|
return EscapeKeyword(definition.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NormalizedName(const EnumVal &ev) const {
|
std::string NormalizedName(const EnumVal& ev) const {
|
||||||
return EscapeKeyword(ev.name);
|
return EscapeKeyword(ev.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NamespacedName(const Definition &def) {
|
std::string NamespacedName(const Definition& def) {
|
||||||
return WrapInNameSpace(def.defined_namespace, NormalizedName(def));
|
return WrapInNameSpace(def.defined_namespace, NormalizedName(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeName(const Type &type) {
|
std::string GenTypeName(const Type& type) {
|
||||||
auto bits = NumToString(SizeOf(type.base_type) * 8);
|
auto bits = NumToString(SizeOf(type.base_type) * 8);
|
||||||
if (IsInteger(type.base_type)) {
|
if (IsInteger(type.base_type)) {
|
||||||
if (IsUnsigned(type.base_type))
|
if (IsUnsigned(type.base_type))
|
||||||
@@ -74,7 +74,7 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
return "none";
|
return "none";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LobsterType(const Type &type) {
|
std::string LobsterType(const Type& type) {
|
||||||
if (IsFloat(type.base_type)) return "float";
|
if (IsFloat(type.base_type)) return "float";
|
||||||
if (IsBool(type.base_type)) return "bool";
|
if (IsBool(type.base_type)) return "bool";
|
||||||
if (IsScalar(type.base_type) && type.enum_def)
|
if (IsScalar(type.base_type) && type.enum_def)
|
||||||
@@ -85,14 +85,14 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the method name for use with add/put calls.
|
// Returns the method name for use with add/put calls.
|
||||||
std::string GenMethod(const Type &type) {
|
std::string GenMethod(const Type& type) {
|
||||||
return IsScalar(type.base_type)
|
return IsScalar(type.base_type)
|
||||||
? ConvertCase(GenTypeBasic(type), Case::kUpperCamel)
|
? ConvertCase(GenTypeBasic(type), Case::kUpperCamel)
|
||||||
: (IsStruct(type) ? "Struct" : "UOffsetTRelative");
|
: (IsStruct(type) ? "Struct" : "UOffsetTRelative");
|
||||||
}
|
}
|
||||||
|
|
||||||
// This uses Python names for now..
|
// This uses Python names for now..
|
||||||
std::string GenTypeBasic(const Type &type) {
|
std::string GenTypeBasic(const Type& type) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char *ctypename[] = {
|
static const char *ctypename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
@@ -106,10 +106,10 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a struct field, conditioned on its child type(s).
|
// Generate a struct field, conditioned on its child type(s).
|
||||||
void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
|
void GenStructAccessor(const StructDef& struct_def, const FieldDef& field,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
GenComment(field.doc_comment, code_ptr, nullptr, " ");
|
GenComment(field.doc_comment, code_ptr, nullptr, " ");
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
auto offsets = NumToString(field.value.offset);
|
auto offsets = NumToString(field.value.offset);
|
||||||
auto def = " def " + NormalizedName(field);
|
auto def = " def " + NormalizedName(field);
|
||||||
if (IsScalar(field.value.type.base_type)) {
|
if (IsScalar(field.value.type.base_type)) {
|
||||||
@@ -195,7 +195,7 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
for (auto it = field.value.type.enum_def->Vals().begin();
|
for (auto it = field.value.type.enum_def->Vals().begin();
|
||||||
it != field.value.type.enum_def->Vals().end(); ++it) {
|
it != field.value.type.enum_def->Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
if (ev.IsNonZero()) {
|
if (ev.IsNonZero()) {
|
||||||
code += def + "_as_" + ev.name + "():\n return " +
|
code += def + "_as_" + ev.name + "():\n return " +
|
||||||
NamespacedName(*ev.union_type.struct_def) +
|
NamespacedName(*ev.union_type.struct_def) +
|
||||||
@@ -205,7 +205,8 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: FLATBUFFERS_ASSERT(0);
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
}
|
}
|
||||||
if (IsVector(field.value.type)) {
|
if (IsVector(field.value.type)) {
|
||||||
code += def +
|
code += def +
|
||||||
@@ -216,8 +217,8 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate table constructors, conditioned on its members' types.
|
// Generate table constructors, conditioned on its members' types.
|
||||||
void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
|
void GenTableBuilders(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "struct " + NormalizedName(struct_def) +
|
code += "struct " + NormalizedName(struct_def) +
|
||||||
"Builder:\n b_:flatbuffers.builder\n";
|
"Builder:\n b_:flatbuffers.builder\n";
|
||||||
code += " def start():\n b_.StartObject(" +
|
code += " def start():\n b_.StartObject(" +
|
||||||
@@ -225,7 +226,7 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
")\n return this\n";
|
")\n return this\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
auto offset = it - struct_def.fields.vec.begin();
|
auto offset = it - struct_def.fields.vec.begin();
|
||||||
code += " def add_" + NormalizedName(field) + "(" +
|
code += " def add_" + NormalizedName(field) + "(" +
|
||||||
@@ -239,7 +240,7 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
code += " def end():\n return b_.EndObject()\n\n";
|
code += " def end():\n return b_.EndObject()\n\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (IsVector(field.value.type)) {
|
if (IsVector(field.value.type)) {
|
||||||
code += "def " + NormalizedName(struct_def) + "Start" +
|
code += "def " + NormalizedName(struct_def) + "Start" +
|
||||||
@@ -266,23 +267,23 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenStructPreDecl(const StructDef &struct_def, std::string *code_ptr) {
|
void GenStructPreDecl(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
CheckNameSpace(struct_def, &code);
|
CheckNameSpace(struct_def, &code);
|
||||||
code += "class " + NormalizedName(struct_def) + "\n\n";
|
code += "class " + NormalizedName(struct_def) + "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate struct or table methods.
|
// Generate struct or table methods.
|
||||||
void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
|
void GenStruct(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
CheckNameSpace(struct_def, &code);
|
CheckNameSpace(struct_def, &code);
|
||||||
GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
|
GenComment(struct_def.doc_comment, code_ptr, nullptr, "");
|
||||||
code += "class " + NormalizedName(struct_def) + " : flatbuffers.handle\n";
|
code += "class " + NormalizedName(struct_def) + " : flatbuffers.handle\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
GenStructAccessor(struct_def, field, code_ptr);
|
GenStructAccessor(struct_def, field, code_ptr);
|
||||||
}
|
}
|
||||||
@@ -304,14 +305,14 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate enum declarations.
|
// Generate enum declarations.
|
||||||
void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
|
void GenEnum(const EnumDef& enum_def, std::string* code_ptr) {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
CheckNameSpace(enum_def, &code);
|
CheckNameSpace(enum_def, &code);
|
||||||
GenComment(enum_def.doc_comment, code_ptr, nullptr, "");
|
GenComment(enum_def.doc_comment, code_ptr, nullptr, "");
|
||||||
code += "enum " + NormalizedName(enum_def) + ":\n";
|
code += "enum " + NormalizedName(enum_def) + ":\n";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
|
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
|
||||||
code += " " + enum_def.name + "_" + NormalizedName(ev) + " = " +
|
code += " " + enum_def.name + "_" + NormalizedName(ev) + " = " +
|
||||||
enum_def.ToString(ev) + "\n";
|
enum_def.ToString(ev) + "\n";
|
||||||
@@ -321,11 +322,11 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Recursively generate arguments for a constructor, to deal with nested
|
// Recursively generate arguments for a constructor, to deal with nested
|
||||||
// structs.
|
// structs.
|
||||||
void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
|
void StructBuilderArgs(const StructDef& struct_def, const char* nameprefix,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
// Generate arguments for a struct inside a struct. To ensure names
|
// Generate arguments for a struct inside a struct. To ensure names
|
||||||
// don't clash, and to make it obvious these arguments are constructing
|
// don't clash, and to make it obvious these arguments are constructing
|
||||||
@@ -334,7 +335,7 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
(nameprefix + (NormalizedName(field) + "_")).c_str(),
|
(nameprefix + (NormalizedName(field) + "_")).c_str(),
|
||||||
code_ptr);
|
code_ptr);
|
||||||
} else {
|
} else {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += ", " + (nameprefix + NormalizedName(field)) + ":" +
|
code += ", " + (nameprefix + NormalizedName(field)) + ":" +
|
||||||
LobsterType(field.value.type);
|
LobsterType(field.value.type);
|
||||||
}
|
}
|
||||||
@@ -343,14 +344,14 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Recursively generate struct construction statements and instert manual
|
// Recursively generate struct construction statements and instert manual
|
||||||
// padding.
|
// padding.
|
||||||
void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
|
void StructBuilderBody(const StructDef& struct_def, const char* nameprefix,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " +
|
code += " b_.Prep(" + NumToString(struct_def.minalign) + ", " +
|
||||||
NumToString(struct_def.bytesize) + ")\n";
|
NumToString(struct_def.bytesize) + ")\n";
|
||||||
for (auto it = struct_def.fields.vec.rbegin();
|
for (auto it = struct_def.fields.vec.rbegin();
|
||||||
it != struct_def.fields.vec.rend(); ++it) {
|
it != struct_def.fields.vec.rend(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.padding)
|
if (field.padding)
|
||||||
code += " b_.Pad(" + NumToString(field.padding) + ")\n";
|
code += " b_.Pad(" + NumToString(field.padding) + ")\n";
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
@@ -365,8 +366,8 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a struct with a builder and the struct's arguments.
|
// Create a struct with a builder and the struct's arguments.
|
||||||
void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
|
void GenStructBuilder(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code +=
|
code +=
|
||||||
"def Create" + NormalizedName(struct_def) + "(b_:flatbuffers.builder";
|
"def Create" + NormalizedName(struct_def) + "(b_:flatbuffers.builder";
|
||||||
StructBuilderArgs(struct_def, "", code_ptr);
|
StructBuilderArgs(struct_def, "", code_ptr);
|
||||||
@@ -375,11 +376,11 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
code += " return b_.Offset()\n\n";
|
code += " return b_.Offset()\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void CheckNameSpace(const Definition &def, std::string *code_ptr) {
|
void CheckNameSpace(const Definition& def, std::string* code_ptr) {
|
||||||
auto ns = GetNameSpace(def);
|
auto ns = GetNameSpace(def);
|
||||||
if (ns == current_namespace_) return;
|
if (ns == current_namespace_) return;
|
||||||
current_namespace_ = ns;
|
current_namespace_ = ns;
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "namespace " + ns + "\n\n";
|
code += "namespace " + ns + "\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -389,17 +390,17 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
"\nimport flatbuffers\n\n";
|
"\nimport flatbuffers\n\n";
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &enum_def = **it;
|
auto& enum_def = **it;
|
||||||
GenEnum(enum_def, &code);
|
GenEnum(enum_def, &code);
|
||||||
}
|
}
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
GenStructPreDecl(struct_def, &code);
|
GenStructPreDecl(struct_def, &code);
|
||||||
}
|
}
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
GenStruct(struct_def, &code);
|
GenStruct(struct_def, &code);
|
||||||
}
|
}
|
||||||
return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
|
return SaveFile(GeneratedFileName(path_, file_name_, parser_.opts).c_str(),
|
||||||
@@ -413,8 +414,8 @@ class LobsterGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
} // namespace lobster
|
} // namespace lobster
|
||||||
|
|
||||||
static bool GenerateLobster(const Parser &parser, const std::string &path,
|
static bool GenerateLobster(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
lobster::LobsterGenerator generator(parser, path, file_name);
|
lobster::LobsterGenerator generator(parser, path, file_name);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
@@ -423,20 +424,21 @@ namespace {
|
|||||||
|
|
||||||
class LobsterCodeGenerator : public CodeGenerator {
|
class LobsterCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateLobster(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateLobster(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -444,16 +446,16 @@ class LobsterCodeGenerator : public CodeGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ namespace php {
|
|||||||
const std::string Indent = " ";
|
const std::string Indent = " ";
|
||||||
class PhpGenerator : public BaseGenerator {
|
class PhpGenerator : public BaseGenerator {
|
||||||
public:
|
public:
|
||||||
PhpGenerator(const Parser &parser, const std::string &path,
|
PhpGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "\\", "\\", "php") {}
|
: BaseGenerator(parser, path, file_name, "\\", "\\", "php") {}
|
||||||
bool generate() {
|
bool generate() {
|
||||||
if (!GenerateEnums()) return false;
|
if (!GenerateEnums()) return false;
|
||||||
@@ -44,7 +44,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
bool GenerateEnums() {
|
bool GenerateEnums() {
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
auto &enum_def = **it;
|
auto& enum_def = **it;
|
||||||
std::string enumcode;
|
std::string enumcode;
|
||||||
GenEnum(enum_def, &enumcode);
|
GenEnum(enum_def, &enumcode);
|
||||||
if (!SaveType(enum_def, enumcode, false)) return false;
|
if (!SaveType(enum_def, enumcode, false)) return false;
|
||||||
@@ -55,7 +55,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
bool GenerateStructs() {
|
bool GenerateStructs() {
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
auto &struct_def = **it;
|
auto& struct_def = **it;
|
||||||
std::string declcode;
|
std::string declcode;
|
||||||
GenStruct(struct_def, &declcode);
|
GenStruct(struct_def, &declcode);
|
||||||
if (!SaveType(struct_def, declcode, true)) return false;
|
if (!SaveType(struct_def, declcode, true)) return false;
|
||||||
@@ -64,9 +64,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Begin by declaring namespace and imports.
|
// Begin by declaring namespace and imports.
|
||||||
void BeginFile(const std::string &name_space_name, const bool needs_imports,
|
void BeginFile(const std::string& name_space_name, const bool needs_imports,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
auto &code = *code_ptr;
|
auto& code = *code_ptr;
|
||||||
code += "<?php\n";
|
code += "<?php\n";
|
||||||
code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
|
code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Save out the generated code for a Php Table type.
|
// Save out the generated code for a Php Table type.
|
||||||
bool SaveType(const Definition &def, const std::string &classcode,
|
bool SaveType(const Definition& def, const std::string& classcode,
|
||||||
bool needs_imports) {
|
bool needs_imports) {
|
||||||
if (!classcode.length()) return true;
|
if (!classcode.length()) return true;
|
||||||
|
|
||||||
@@ -99,8 +99,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Begin a class declaration.
|
// Begin a class declaration.
|
||||||
static void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
|
static void BeginClass(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
code += "class " + struct_def.name + " extends Struct\n";
|
code += "class " + struct_def.name + " extends Struct\n";
|
||||||
} else {
|
} else {
|
||||||
@@ -109,21 +109,21 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
code += "{\n";
|
code += "{\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static void EndClass(std::string *code_ptr) {
|
static void EndClass(std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "}\n";
|
code += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Begin enum code with a class declaration.
|
// Begin enum code with a class declaration.
|
||||||
static void BeginEnum(const std::string &class_name, std::string *code_ptr) {
|
static void BeginEnum(const std::string& class_name, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "class " + class_name + "\n{\n";
|
code += "class " + class_name + "\n{\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// A single enum member.
|
// A single enum member.
|
||||||
static void EnumMember(const EnumDef &enum_def, const EnumVal &ev,
|
static void EnumMember(const EnumDef& enum_def, const EnumVal& ev,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += Indent + "const ";
|
code += Indent + "const ";
|
||||||
code += ev.name;
|
code += ev.name;
|
||||||
code += " = ";
|
code += " = ";
|
||||||
@@ -131,15 +131,15 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// End enum code.
|
// End enum code.
|
||||||
static void EndEnum(std::string *code_ptr) {
|
static void EndEnum(std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "}\n";
|
code += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize a new struct or table from existing data.
|
// Initialize a new struct or table from existing data.
|
||||||
static void NewRootTypeFromBuffer(const StructDef &struct_def,
|
static void NewRootTypeFromBuffer(const StructDef& struct_def,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @param ByteBuffer $bb\n";
|
code += Indent + " * @param ByteBuffer $bb\n";
|
||||||
@@ -158,9 +158,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize an existing object with other data, to avoid an allocation.
|
// Initialize an existing object with other data, to avoid an allocation.
|
||||||
static void InitializeExisting(const StructDef &struct_def,
|
static void InitializeExisting(const StructDef& struct_def,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @param int $_i offset\n";
|
code += Indent + " * @param int $_i offset\n";
|
||||||
@@ -176,8 +176,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the length of a vector.
|
// Get the length of a vector.
|
||||||
static void GetVectorLen(const FieldDef &field, std::string *code_ptr) {
|
static void GetVectorLen(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @return int\n";
|
code += Indent + " * @return int\n";
|
||||||
@@ -193,8 +193,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get a [ubyte] vector as a byte array.
|
// Get a [ubyte] vector as a byte array.
|
||||||
static void GetUByte(const FieldDef &field, std::string *code_ptr) {
|
static void GetUByte(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @return string\n";
|
code += Indent + " * @return string\n";
|
||||||
@@ -208,9 +208,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a struct's scalar.
|
// Get the value of a struct's scalar.
|
||||||
static void GetScalarFieldOfStruct(const FieldDef &field,
|
static void GetScalarFieldOfStruct(const FieldDef& field,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
std::string getter = GenGetter(field.value.type);
|
std::string getter = GenGetter(field.value.type);
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
@@ -232,8 +232,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a table's scalar.
|
// Get the value of a table's scalar.
|
||||||
void GetScalarFieldOfTable(const FieldDef &field, std::string *code_ptr) {
|
void GetScalarFieldOfTable(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
|
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
|
||||||
@@ -254,8 +254,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Get a struct by initializing an existing struct.
|
// Get a struct by initializing an existing struct.
|
||||||
// Specific to Struct.
|
// Specific to Struct.
|
||||||
void GetStructFieldOfStruct(const FieldDef &field, std::string *code_ptr) {
|
void GetStructFieldOfStruct(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
|
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
|
||||||
@@ -273,8 +273,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Get a struct by initializing an existing struct.
|
// Get a struct by initializing an existing struct.
|
||||||
// Specific to Table.
|
// Specific to Table.
|
||||||
void GetStructFieldOfTable(const FieldDef &field, std::string *code_ptr) {
|
void GetStructFieldOfTable(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "public function get";
|
code += Indent + "public function get";
|
||||||
code += ConvertCase(field.name, Case::kUpperCamel);
|
code += ConvertCase(field.name, Case::kUpperCamel);
|
||||||
@@ -297,8 +297,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a string.
|
// Get the value of a string.
|
||||||
void GetStringField(const FieldDef &field, std::string *code_ptr) {
|
void GetStringField(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += Indent + "public function get";
|
code += Indent + "public function get";
|
||||||
code += ConvertCase(field.name, Case::kUpperCamel);
|
code += ConvertCase(field.name, Case::kUpperCamel);
|
||||||
code += "()\n";
|
code += "()\n";
|
||||||
@@ -312,8 +312,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a union from an object.
|
// Get the value of a union from an object.
|
||||||
void GetUnionField(const FieldDef &field, std::string *code_ptr) {
|
void GetUnionField(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n";
|
code += Indent + " * @return" + GenTypeBasic(field.value.type) + "\n";
|
||||||
@@ -329,9 +329,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a vector's struct member.
|
// Get the value of a vector's struct member.
|
||||||
void GetMemberOfVectorOfStruct(const StructDef &struct_def,
|
void GetMemberOfVectorOfStruct(const StructDef& struct_def,
|
||||||
const FieldDef &field, std::string *code_ptr) {
|
const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
@@ -382,7 +382,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
code += Indent + Indent + "return $o != 0 ? $this->";
|
code += Indent + Indent + "return $o != 0 ? $this->";
|
||||||
code += GenGetter(field.value.type) + "($obj, $o); null;\n";
|
code += GenGetter(field.value.type) + "($obj, $o); null;\n";
|
||||||
break;
|
break;
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
code += Indent + "}\n\n";
|
code += Indent + "}\n\n";
|
||||||
@@ -390,9 +391,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Get the value of a vector's non-struct member. Uses a named return
|
// Get the value of a vector's non-struct member. Uses a named return
|
||||||
// argument to conveniently set the zero value for the result.
|
// argument to conveniently set the zero value for the result.
|
||||||
void GetMemberOfVectorOfNonStruct(const FieldDef &field,
|
void GetMemberOfVectorOfNonStruct(const FieldDef& field,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
@@ -423,8 +424,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Get the value of a vector's union member. Uses a named return
|
// Get the value of a vector's union member. Uses a named return
|
||||||
// argument to conveniently set the zero value for the result.
|
// argument to conveniently set the zero value for the result.
|
||||||
void GetMemberOfVectorOfUnion(const FieldDef &field, std::string *code_ptr) {
|
void GetMemberOfVectorOfUnion(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
@@ -445,11 +446,11 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Recursively generate arguments for a constructor, to deal with nested
|
// Recursively generate arguments for a constructor, to deal with nested
|
||||||
// structs.
|
// structs.
|
||||||
static void StructBuilderArgs(const StructDef &struct_def,
|
static void StructBuilderArgs(const StructDef& struct_def,
|
||||||
const char *nameprefix, std::string *code_ptr) {
|
const char* nameprefix, std::string* code_ptr) {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
// Generate arguments for a struct inside a struct. To ensure names
|
// Generate arguments for a struct inside a struct. To ensure names
|
||||||
// don't clash, and to make it obvious
|
// don't clash, and to make it obvious
|
||||||
@@ -458,7 +459,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
StructBuilderArgs(*field.value.type.struct_def,
|
StructBuilderArgs(*field.value.type.struct_def,
|
||||||
(nameprefix + (field.name + "_")).c_str(), code_ptr);
|
(nameprefix + (field.name + "_")).c_str(), code_ptr);
|
||||||
} else {
|
} else {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += std::string(", $") + nameprefix;
|
code += std::string(", $") + nameprefix;
|
||||||
code += ConvertCase(field.name, Case::kLowerCamel);
|
code += ConvertCase(field.name, Case::kLowerCamel);
|
||||||
}
|
}
|
||||||
@@ -467,15 +468,15 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
// Recursively generate struct construction statements and instert manual
|
// Recursively generate struct construction statements and instert manual
|
||||||
// padding.
|
// padding.
|
||||||
static void StructBuilderBody(const StructDef &struct_def,
|
static void StructBuilderBody(const StructDef& struct_def,
|
||||||
const char *nameprefix, std::string *code_ptr) {
|
const char* nameprefix, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += Indent + Indent + "$builder->prep(";
|
code += Indent + Indent + "$builder->prep(";
|
||||||
code += NumToString(struct_def.minalign) + ", ";
|
code += NumToString(struct_def.minalign) + ", ";
|
||||||
code += NumToString(struct_def.bytesize) + ");\n";
|
code += NumToString(struct_def.bytesize) + ");\n";
|
||||||
for (auto it = struct_def.fields.vec.rbegin();
|
for (auto it = struct_def.fields.vec.rbegin();
|
||||||
it != struct_def.fields.vec.rend(); ++it) {
|
it != struct_def.fields.vec.rend(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.padding) {
|
if (field.padding) {
|
||||||
code += Indent + Indent + "$builder->pad(";
|
code += Indent + Indent + "$builder->pad(";
|
||||||
code += NumToString(field.padding) + ");\n";
|
code += NumToString(field.padding) + ");\n";
|
||||||
@@ -492,9 +493,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a table's starting offset.
|
// Get the value of a table's starting offset.
|
||||||
static void GetStartOfTable(const StructDef &struct_def,
|
static void GetStartOfTable(const StructDef& struct_def,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @param FlatBufferBuilder $builder\n";
|
code += Indent + " * @param FlatBufferBuilder $builder\n";
|
||||||
@@ -517,10 +518,12 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
|
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (it != struct_def.fields.vec.begin()) { code += ", "; }
|
if (it != struct_def.fields.vec.begin()) {
|
||||||
|
code += ", ";
|
||||||
|
}
|
||||||
code += "$" + field.name;
|
code += "$" + field.name;
|
||||||
}
|
}
|
||||||
code += ")\n";
|
code += ")\n";
|
||||||
@@ -530,7 +533,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
code += ");\n";
|
code += ");\n";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
code += Indent + Indent + "self::add";
|
code += Indent + Indent + "self::add";
|
||||||
@@ -542,7 +545,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (!field.deprecated && field.IsRequired()) {
|
if (!field.deprecated && field.IsRequired()) {
|
||||||
code += Indent + Indent + "$builder->required($o, ";
|
code += Indent + Indent + "$builder->required($o, ";
|
||||||
code += NumToString(field.value.offset);
|
code += NumToString(field.value.offset);
|
||||||
@@ -554,9 +557,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the value of a table's field.
|
// Set the value of a table's field.
|
||||||
static void BuildFieldOfTable(const FieldDef &field, const size_t offset,
|
static void BuildFieldOfTable(const FieldDef& field, const size_t offset,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @param FlatBufferBuilder $builder\n";
|
code += Indent + " * @param FlatBufferBuilder $builder\n";
|
||||||
@@ -586,8 +589,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set the value of one of the members of a table's vector.
|
// Set the value of one of the members of a table's vector.
|
||||||
static void BuildVectorOfTable(const FieldDef &field, std::string *code_ptr) {
|
static void BuildVectorOfTable(const FieldDef& field, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
auto vector_type = field.value.type.VectorType();
|
auto vector_type = field.value.type.VectorType();
|
||||||
auto alignment = InlineAlignment(vector_type);
|
auto alignment = InlineAlignment(vector_type);
|
||||||
@@ -638,8 +641,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the offset of the end of a table.
|
// Get the offset of the end of a table.
|
||||||
void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
|
void GetEndOffsetOnTable(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
|
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @param FlatBufferBuilder $builder\n";
|
code += Indent + " * @param FlatBufferBuilder $builder\n";
|
||||||
@@ -652,7 +655,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (!field.deprecated && field.IsRequired()) {
|
if (!field.deprecated && field.IsRequired()) {
|
||||||
code += Indent + Indent + "$builder->required($o, ";
|
code += Indent + Indent + "$builder->required($o, ";
|
||||||
code += NumToString(field.value.offset);
|
code += NumToString(field.value.offset);
|
||||||
@@ -678,8 +681,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate a struct field, conditioned on its child type(s).
|
// Generate a struct field, conditioned on its child type(s).
|
||||||
void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
|
void GenStructAccessor(const StructDef& struct_def, const FieldDef& field,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
GenComment(field.doc_comment, code_ptr, nullptr, Indent.c_str());
|
GenComment(field.doc_comment, code_ptr, nullptr, Indent.c_str());
|
||||||
|
|
||||||
if (IsScalar(field.value.type.base_type)) {
|
if (IsScalar(field.value.type.base_type)) {
|
||||||
@@ -697,7 +700,9 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
GetStructFieldOfTable(field, code_ptr);
|
GetStructFieldOfTable(field, code_ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case BASE_TYPE_STRING: GetStringField(field, code_ptr); break;
|
case BASE_TYPE_STRING:
|
||||||
|
GetStringField(field, code_ptr);
|
||||||
|
break;
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
if (vectortype.base_type == BASE_TYPE_UNION) {
|
if (vectortype.base_type == BASE_TYPE_UNION) {
|
||||||
@@ -709,8 +714,11 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UNION: GetUnionField(field, code_ptr); break;
|
case BASE_TYPE_UNION:
|
||||||
default: FLATBUFFERS_ASSERT(0);
|
GetUnionField(field, code_ptr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsVector(field.value.type)) {
|
if (IsVector(field.value.type)) {
|
||||||
@@ -722,17 +730,17 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate table constructors, conditioned on its members' types.
|
// Generate table constructors, conditioned on its members' types.
|
||||||
void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
|
void GenTableBuilders(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
GetStartOfTable(struct_def, code_ptr);
|
GetStartOfTable(struct_def, code_ptr);
|
||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
auto offset = it - struct_def.fields.vec.begin();
|
auto offset = it - struct_def.fields.vec.begin();
|
||||||
if (field.value.type.base_type == BASE_TYPE_UNION) {
|
if (field.value.type.base_type == BASE_TYPE_UNION) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += Indent + "public static function add";
|
code += Indent + "public static function add";
|
||||||
code += ConvertCase(field.name, Case::kUpperCamel);
|
code += ConvertCase(field.name, Case::kUpperCamel);
|
||||||
code += "(FlatBufferBuilder $builder, $offset)\n";
|
code += "(FlatBufferBuilder $builder, $offset)\n";
|
||||||
@@ -743,14 +751,16 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
} else {
|
} else {
|
||||||
BuildFieldOfTable(field, offset, code_ptr);
|
BuildFieldOfTable(field, offset, code_ptr);
|
||||||
}
|
}
|
||||||
if (IsVector(field.value.type)) { BuildVectorOfTable(field, code_ptr); }
|
if (IsVector(field.value.type)) {
|
||||||
|
BuildVectorOfTable(field, code_ptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GetEndOffsetOnTable(struct_def, code_ptr);
|
GetEndOffsetOnTable(struct_def, code_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate struct or table methods.
|
// Generate struct or table methods.
|
||||||
void GenStruct(const StructDef &struct_def, std::string *code_ptr) {
|
void GenStruct(const StructDef& struct_def, std::string* code_ptr) {
|
||||||
if (struct_def.generated) return;
|
if (struct_def.generated) return;
|
||||||
|
|
||||||
GenComment(struct_def.doc_comment, code_ptr, nullptr);
|
GenComment(struct_def.doc_comment, code_ptr, nullptr);
|
||||||
@@ -762,7 +772,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
NewRootTypeFromBuffer(struct_def, code_ptr);
|
NewRootTypeFromBuffer(struct_def, code_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
if (!struct_def.fixed) {
|
if (!struct_def.fixed) {
|
||||||
if (parser_.file_identifier_.length()) {
|
if (parser_.file_identifier_.length()) {
|
||||||
// Return the identifier
|
// Return the identifier
|
||||||
@@ -799,7 +809,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
InitializeExisting(struct_def, code_ptr);
|
InitializeExisting(struct_def, code_ptr);
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
GenStructAccessor(struct_def, field, code_ptr);
|
GenStructAccessor(struct_def, field, code_ptr);
|
||||||
@@ -816,22 +826,22 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate enum declarations.
|
// Generate enum declarations.
|
||||||
static void GenEnum(const EnumDef &enum_def, std::string *code_ptr) {
|
static void GenEnum(const EnumDef& enum_def, std::string* code_ptr) {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
|
|
||||||
GenComment(enum_def.doc_comment, code_ptr, nullptr);
|
GenComment(enum_def.doc_comment, code_ptr, nullptr);
|
||||||
BeginEnum(enum_def.name, code_ptr);
|
BeginEnum(enum_def.name, code_ptr);
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
GenComment(ev.doc_comment, code_ptr, nullptr, Indent.c_str());
|
GenComment(ev.doc_comment, code_ptr, nullptr, Indent.c_str());
|
||||||
EnumMember(enum_def, ev, code_ptr);
|
EnumMember(enum_def, ev, code_ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "\n";
|
code += "\n";
|
||||||
code += Indent + "private static $names = array(\n";
|
code += Indent + "private static $names = array(\n";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
auto &ev = **it;
|
auto& ev = **it;
|
||||||
code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
|
code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
|
||||||
ev.name + "\",\n";
|
ev.name + "\",\n";
|
||||||
}
|
}
|
||||||
@@ -848,24 +858,29 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Returns the function name that is able to read a value of the given type.
|
// Returns the function name that is able to read a value of the given type.
|
||||||
static std::string GenGetter(const Type &type) {
|
static std::string GenGetter(const Type& type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "__string";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_STRUCT: return "__struct";
|
return "__string";
|
||||||
case BASE_TYPE_UNION: return "__union";
|
case BASE_TYPE_STRUCT:
|
||||||
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
|
return "__struct";
|
||||||
default: return "Get";
|
case BASE_TYPE_UNION:
|
||||||
|
return "__union";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return GenGetter(type.VectorType());
|
||||||
|
default:
|
||||||
|
return "Get";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the method name for use with add/put calls.
|
// Returns the method name for use with add/put calls.
|
||||||
static std::string GenMethod(const FieldDef &field) {
|
static std::string GenMethod(const FieldDef& field) {
|
||||||
return IsScalar(field.value.type.base_type)
|
return IsScalar(field.value.type.base_type)
|
||||||
? ConvertCase(GenTypeBasic(field.value.type), Case::kUpperCamel)
|
? ConvertCase(GenTypeBasic(field.value.type), Case::kUpperCamel)
|
||||||
: (IsStruct(field.value.type) ? "Struct" : "Offset");
|
: (IsStruct(field.value.type) ? "Struct" : "Offset");
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenTypeBasic(const Type &type) {
|
static std::string GenTypeBasic(const Type& type) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char *ctypename[] = {
|
static const char *ctypename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
@@ -878,7 +893,7 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
return ctypename[type.base_type];
|
return ctypename[type.base_type];
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenDefaultValue(const Value &value) {
|
std::string GenDefaultValue(const Value& value) {
|
||||||
if (value.type.enum_def) {
|
if (value.type.enum_def) {
|
||||||
if (auto val = value.type.enum_def->FindByValue(value.constant)) {
|
if (auto val = value.type.enum_def->FindByValue(value.constant)) {
|
||||||
return WrapInNameSpace(*value.type.enum_def) + "::" + val->name;
|
return WrapInNameSpace(*value.type.enum_def) + "::" + val->name;
|
||||||
@@ -886,9 +901,11 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch (value.type.base_type) {
|
switch (value.type.base_type) {
|
||||||
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
|
case BASE_TYPE_BOOL:
|
||||||
|
return value.constant == "0" ? "false" : "true";
|
||||||
|
|
||||||
case BASE_TYPE_STRING: return "null";
|
case BASE_TYPE_STRING:
|
||||||
|
return "null";
|
||||||
|
|
||||||
case BASE_TYPE_LONG:
|
case BASE_TYPE_LONG:
|
||||||
case BASE_TYPE_ULONG:
|
case BASE_TYPE_ULONG:
|
||||||
@@ -898,29 +915,34 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
return "0";
|
return "0";
|
||||||
|
|
||||||
default: return value.constant;
|
default:
|
||||||
|
return value.constant;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenTypePointer(const Type &type) {
|
static std::string GenTypePointer(const Type& type) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "string";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_VECTOR: return GenTypeGet(type.VectorType());
|
return "string";
|
||||||
case BASE_TYPE_STRUCT: return type.struct_def->name;
|
case BASE_TYPE_VECTOR:
|
||||||
|
return GenTypeGet(type.VectorType());
|
||||||
|
case BASE_TYPE_STRUCT:
|
||||||
|
return type.struct_def->name;
|
||||||
case BASE_TYPE_UNION:
|
case BASE_TYPE_UNION:
|
||||||
// fall through
|
// fall through
|
||||||
default: return "Table";
|
default:
|
||||||
|
return "Table";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenTypeGet(const Type &type) {
|
static std::string GenTypeGet(const Type& type) {
|
||||||
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
|
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a struct with a builder and the struct's arguments.
|
// Create a struct with a builder and the struct's arguments.
|
||||||
static void GenStructBuilder(const StructDef &struct_def,
|
static void GenStructBuilder(const StructDef& struct_def,
|
||||||
std::string *code_ptr) {
|
std::string* code_ptr) {
|
||||||
std::string &code = *code_ptr;
|
std::string& code = *code_ptr;
|
||||||
code += "\n";
|
code += "\n";
|
||||||
code += Indent + "/**\n";
|
code += Indent + "/**\n";
|
||||||
code += Indent + " * @return int offset\n";
|
code += Indent + " * @return int offset\n";
|
||||||
@@ -939,8 +961,8 @@ class PhpGenerator : public BaseGenerator {
|
|||||||
};
|
};
|
||||||
} // namespace php
|
} // namespace php
|
||||||
|
|
||||||
static bool GeneratePhp(const Parser &parser, const std::string &path,
|
static bool GeneratePhp(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
php::PhpGenerator generator(parser, path, file_name);
|
php::PhpGenerator generator(parser, path, file_name);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
@@ -949,20 +971,21 @@ namespace {
|
|||||||
|
|
||||||
class PhpCodeGenerator : public CodeGenerator {
|
class PhpCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GeneratePhp(parser, path, filename)) { return Status::ERROR; }
|
if (!GeneratePhp(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -970,16 +993,16 @@ class PhpCodeGenerator : public CodeGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -32,7 +32,7 @@ namespace swift {
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static Namer::Config SwiftDefaultConfig() {
|
static Namer::Config SwiftDefaultConfig() {
|
||||||
return { /*types=*/Case::kKeep,
|
return {/*types=*/Case::kKeep,
|
||||||
/*constants=*/Case::kLowerCamel,
|
/*constants=*/Case::kLowerCamel,
|
||||||
/*methods=*/Case::kLowerCamel,
|
/*methods=*/Case::kLowerCamel,
|
||||||
/*functions=*/Case::kLowerCamel,
|
/*functions=*/Case::kLowerCamel,
|
||||||
@@ -51,7 +51,7 @@ static Namer::Config SwiftDefaultConfig() {
|
|||||||
/*directories=*/Case::kKeep,
|
/*directories=*/Case::kKeep,
|
||||||
/*output_path=*/"",
|
/*output_path=*/"",
|
||||||
/*filename_suffix=*/"_generated",
|
/*filename_suffix=*/"_generated",
|
||||||
/*filename_extension=*/".swift" };
|
/*filename_extension=*/".swift"};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::set<std::string> SwiftKeywords() {
|
static std::set<std::string> SwiftKeywords() {
|
||||||
@@ -138,11 +138,11 @@ static std::set<std::string> SwiftKeywords() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenIndirect(const std::string &reading) {
|
static std::string GenIndirect(const std::string& reading) {
|
||||||
return "{{ACCESS}}.indirect(" + reading + ")";
|
return "{{ACCESS}}.indirect(" + reading + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenArrayMainBody(const std::string &optional) {
|
static std::string GenArrayMainBody(const std::string& optional) {
|
||||||
return "{{ACCESS_TYPE}} func {{FIELDMETHOD}}(at index: Int32) -> "
|
return "{{ACCESS_TYPE}} func {{FIELDMETHOD}}(at index: Int32) -> "
|
||||||
"{{VALUETYPE}}" +
|
"{{VALUETYPE}}" +
|
||||||
optional + " { ";
|
optional + " { ";
|
||||||
@@ -157,8 +157,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
int namespace_depth;
|
int namespace_depth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SwiftGenerator(const Parser &parser, const std::string &path,
|
SwiftGenerator(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name)
|
const std::string& file_name)
|
||||||
: BaseGenerator(parser, path, file_name, "", "_", "swift"),
|
: BaseGenerator(parser, path, file_name, "", "_", "swift"),
|
||||||
namer_(WithFlagOptions(SwiftDefaultConfig(), parser.opts, path),
|
namer_(WithFlagOptions(SwiftDefaultConfig(), parser.opts, path),
|
||||||
SwiftKeywords()) {
|
SwiftKeywords()) {
|
||||||
@@ -174,7 +174,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "// swiftlint:disable all";
|
code_ += "// swiftlint:disable all";
|
||||||
code_ += "// swiftformat:disable all\n";
|
code_ += "// swiftformat:disable all\n";
|
||||||
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
|
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
|
||||||
code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only ? "@_implementationOnly " : "");
|
code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only
|
||||||
|
? "@_implementationOnly "
|
||||||
|
: "");
|
||||||
code_ += "#if canImport(Common)";
|
code_ += "#if canImport(Common)";
|
||||||
code_ += "{{IMPLEMENTONLY}}import Common";
|
code_ += "{{IMPLEMENTONLY}}import Common";
|
||||||
code_ += "#endif";
|
code_ += "#endif";
|
||||||
@@ -185,13 +187,15 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
// Generate code for all the enum declarations.
|
// Generate code for all the enum declarations.
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
const auto &enum_def = **it;
|
const auto& enum_def = **it;
|
||||||
if (!enum_def.generated) { GenEnum(enum_def); }
|
if (!enum_def.generated) {
|
||||||
|
GenEnum(enum_def);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
const auto &struct_def = **it;
|
const auto& struct_def = **it;
|
||||||
if (struct_def.fixed && !struct_def.generated) {
|
if (struct_def.fixed && !struct_def.generated) {
|
||||||
GenStructReader(struct_def);
|
GenStructReader(struct_def);
|
||||||
GenMutableStructReader(struct_def);
|
GenMutableStructReader(struct_def);
|
||||||
@@ -200,7 +204,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
const auto &struct_def = **it;
|
const auto& struct_def = **it;
|
||||||
if (!struct_def.fixed && !struct_def.generated) {
|
if (!struct_def.fixed && !struct_def.generated) {
|
||||||
GenTable(struct_def);
|
GenTable(struct_def);
|
||||||
if (parser_.opts.generate_object_based_api) {
|
if (parser_.opts.generate_object_based_api) {
|
||||||
@@ -214,7 +218,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
return SaveFile(filename.c_str(), final_code, false);
|
return SaveFile(filename.c_str(), final_code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mark(const std::string &str) {
|
void mark(const std::string& str) {
|
||||||
code_.SetValue("MARKVALUE", str);
|
code_.SetValue("MARKVALUE", str);
|
||||||
code_ += "\n// MARK: - {{MARKVALUE}}\n";
|
code_ += "\n// MARK: - {{MARKVALUE}}\n";
|
||||||
}
|
}
|
||||||
@@ -222,7 +226,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
// MARK: - Generating structs
|
// MARK: - Generating structs
|
||||||
|
|
||||||
// Generates the reader for swift
|
// Generates the reader for swift
|
||||||
void GenStructReader(const StructDef &struct_def) {
|
void GenStructReader(const StructDef& struct_def) {
|
||||||
const bool is_private_access =
|
const bool is_private_access =
|
||||||
parser_.opts.swift_implementation_only ||
|
parser_.opts.swift_implementation_only ||
|
||||||
struct_def.attributes.Lookup("private") != nullptr;
|
struct_def.attributes.Lookup("private") != nullptr;
|
||||||
@@ -245,7 +249,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
if (!constructor.empty()) constructor += ", ";
|
if (!constructor.empty()) constructor += ", ";
|
||||||
@@ -269,7 +273,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
accessing_value);
|
accessing_value);
|
||||||
base_constructor.push_back("_" + field_var + " = " + base_value);
|
base_constructor.push_back("_" + field_var + " = " + base_value);
|
||||||
|
|
||||||
if (field.padding) { GenPadding(field, &padding_id); }
|
if (field.padding) {
|
||||||
|
GenPadding(field, &padding_id);
|
||||||
|
}
|
||||||
constructor += field_var + ": " + type;
|
constructor += field_var + ": " + type;
|
||||||
}
|
}
|
||||||
code_ += "";
|
code_ += "";
|
||||||
@@ -282,7 +288,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
code_.SetValue("FIELDVAR", namer_.Variable(field));
|
code_.SetValue("FIELDVAR", namer_.Variable(field));
|
||||||
code_.SetValue("VALUETYPE", GenType(field.value.type));
|
code_.SetValue("VALUETYPE", GenType(field.value.type));
|
||||||
@@ -309,13 +315,13 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
if (parser_.opts.gen_json_coders) GenerateJSONEncodingAPIs(struct_def);
|
if (parser_.opts.gen_json_coders) GenerateJSONEncodingAPIs(struct_def);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildStructConstructor(const StructDef &struct_def) {
|
void BuildStructConstructor(const StructDef& struct_def) {
|
||||||
code_ += "{{ACCESS_TYPE}} init(_ bb: ByteBuffer, o: Int32) {";
|
code_ += "{{ACCESS_TYPE}} init(_ bb: ByteBuffer, o: Int32) {";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "let {{ACCESS}} = Struct(bb: bb, position: o)";
|
code_ += "let {{ACCESS}} = Struct(bb: bb, position: o)";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto type = field.value.type;
|
const auto type = field.value.type;
|
||||||
code_.SetValue("FIELDVAR", namer_.Variable(field));
|
code_.SetValue("FIELDVAR", namer_.Variable(field));
|
||||||
@@ -337,12 +343,12 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenMutableStructReader(const StructDef &struct_def) {
|
void GenMutableStructReader(const StructDef& struct_def) {
|
||||||
GenObjectHeader(struct_def);
|
GenObjectHeader(struct_def);
|
||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto offset = NumToString(field.value.offset);
|
const auto offset = NumToString(field.value.offset);
|
||||||
const auto type = GenType(field.value.type);
|
const auto type = GenType(field.value.type);
|
||||||
@@ -379,17 +385,17 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateStructArgs(const StructDef &struct_def, std::string *code_ptr,
|
void GenerateStructArgs(const StructDef& struct_def, std::string* code_ptr,
|
||||||
const std::string &nameprefix,
|
const std::string& nameprefix,
|
||||||
const std::string &object_name,
|
const std::string& object_name,
|
||||||
const std::string &obj_api_named = "",
|
const std::string& obj_api_named = "",
|
||||||
bool is_obj_api = false) {
|
bool is_obj_api = false) {
|
||||||
auto &code = *code_ptr;
|
auto& code = *code_ptr;
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto &field_type = field.value.type;
|
const auto& field_type = field.value.type;
|
||||||
if (IsStruct(field.value.type)) {
|
if (IsStruct(field.value.type)) {
|
||||||
GenerateStructArgs(
|
GenerateStructArgs(
|
||||||
*field_type.struct_def, code_ptr, (nameprefix + field.name),
|
*field_type.struct_def, code_ptr, (nameprefix + field.name),
|
||||||
@@ -417,7 +423,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
// MARK: - Table Generator
|
// MARK: - Table Generator
|
||||||
|
|
||||||
// Generates the reader for swift
|
// Generates the reader for swift
|
||||||
void GenTable(const StructDef &struct_def) {
|
void GenTable(const StructDef& struct_def) {
|
||||||
const bool is_private_access =
|
const bool is_private_access =
|
||||||
parser_.opts.swift_implementation_only ||
|
parser_.opts.swift_implementation_only ||
|
||||||
struct_def.attributes.Lookup("private") != nullptr;
|
struct_def.attributes.Lookup("private") != nullptr;
|
||||||
@@ -436,15 +442,17 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generates the reader for swift
|
// Generates the reader for swift
|
||||||
void GenTableAccessors(const StructDef &struct_def) {
|
void GenTableAccessors(const StructDef& struct_def) {
|
||||||
// Generate field id constants.
|
// Generate field id constants.
|
||||||
if (struct_def.fields.vec.size() > 0) {
|
if (struct_def.fields.vec.size() > 0) {
|
||||||
code_ += "private enum {{TABLEOFFSET}}: VOffset {";
|
code_ += "private enum {{TABLEOFFSET}}: VOffset {";
|
||||||
Indent();
|
Indent();
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) { continue; }
|
if (field.deprecated) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
code_.SetValue("OFFSET_NAME", namer_.Variable(field));
|
code_.SetValue("OFFSET_NAME", namer_.Variable(field));
|
||||||
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
|
code_.SetValue("OFFSET_VALUE", NumToString(field.value.offset));
|
||||||
code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}";
|
code_ += "case {{OFFSET_NAME}} = {{OFFSET_VALUE}}";
|
||||||
@@ -457,7 +465,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenObjectHeader(const StructDef &struct_def) {
|
void GenObjectHeader(const StructDef& struct_def) {
|
||||||
GenComment(struct_def.doc_comment);
|
GenComment(struct_def.doc_comment);
|
||||||
|
|
||||||
code_.SetValue("SHORT_STRUCTNAME", namer_.Type(struct_def));
|
code_.SetValue("SHORT_STRUCTNAME", namer_.Type(struct_def));
|
||||||
@@ -495,8 +503,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "";
|
code_ += "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableWriter(const StructDef &struct_def) {
|
void GenTableWriter(const StructDef& struct_def) {
|
||||||
flatbuffers::FieldDef *key_field = nullptr;
|
flatbuffers::FieldDef* key_field = nullptr;
|
||||||
std::vector<std::string> require_fields;
|
std::vector<std::string> require_fields;
|
||||||
std::vector<std::string> create_func_body;
|
std::vector<std::string> create_func_body;
|
||||||
std::vector<std::string> create_func_header;
|
std::vector<std::string> create_func_header;
|
||||||
@@ -510,7 +518,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
if (field.key) key_field = &field;
|
if (field.key) key_field = &field;
|
||||||
if (field.IsRequired())
|
if (field.IsRequired())
|
||||||
@@ -568,8 +576,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"_ fbb: inout FlatBufferBuilder) -> Offset {";
|
"_ fbb: inout FlatBufferBuilder) -> Offset {";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += spacing + "var off = offsets";
|
code_ += spacing + "var off = offsets";
|
||||||
code_ +=
|
code_ += spacing +
|
||||||
spacing +
|
|
||||||
"off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: "
|
"off.sort { Table.compare(Table.offset(Int32($1.o), vOffset: "
|
||||||
"{{VOFFSET}}, fbb: &fbb), Table.offset(Int32($0.o), vOffset: "
|
"{{VOFFSET}}, fbb: &fbb), Table.offset(Int32($0.o), vOffset: "
|
||||||
"{{VOFFSET}}, fbb: &fbb), fbb: &fbb) < 0 } ";
|
"{{VOFFSET}}, fbb: &fbb), fbb: &fbb) < 0 } ";
|
||||||
@@ -580,12 +587,12 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableWriterFields(const FieldDef &field,
|
void GenTableWriterFields(const FieldDef& field,
|
||||||
std::vector<std::string> *create_body,
|
std::vector<std::string>* create_body,
|
||||||
std::vector<std::string> *create_header) {
|
std::vector<std::string>* create_header) {
|
||||||
std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { ";
|
std::string builder_string = ", _ fbb: inout FlatBufferBuilder) { ";
|
||||||
auto &create_func_body = *create_body;
|
auto& create_func_body = *create_body;
|
||||||
auto &create_func_header = *create_header;
|
auto& create_func_header = *create_header;
|
||||||
const auto field_field = namer_.Field(field);
|
const auto field_field = namer_.Field(field);
|
||||||
const auto field_var = namer_.Variable(field);
|
const auto field_var = namer_.Variable(field);
|
||||||
const auto type = GenType(field.value.type);
|
const auto type = GenType(field.value.type);
|
||||||
@@ -687,16 +694,16 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableReader(const StructDef &struct_def) {
|
void GenTableReader(const StructDef& struct_def) {
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
GenTableReaderFields(field);
|
GenTableReaderFields(field);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableReaderFields(const FieldDef &field) {
|
void GenTableReaderFields(const FieldDef& field) {
|
||||||
const auto offset = NumToString(field.value.offset);
|
const auto offset = NumToString(field.value.offset);
|
||||||
const auto field_field = namer_.Field(field);
|
const auto field_field = namer_.Field(field);
|
||||||
const auto type = GenType(field.value.type);
|
const auto type = GenType(field.value.type);
|
||||||
@@ -780,8 +787,11 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }";
|
"{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
|
case BASE_TYPE_ARRAY:
|
||||||
case BASE_TYPE_VECTOR: GenTableReaderVectorFields(field); break;
|
FLATBUFFERS_FALLTHROUGH(); // fall thru
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
GenTableReaderVectorFields(field);
|
||||||
|
break;
|
||||||
case BASE_TYPE_UNION:
|
case BASE_TYPE_UNION:
|
||||||
code_.SetValue("CONSTANT", "nil");
|
code_.SetValue("CONSTANT", "nil");
|
||||||
code_ +=
|
code_ +=
|
||||||
@@ -791,11 +801,12 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
is_required + " { " + GenOffset() + required_reader +
|
is_required + " { " + GenOffset() + required_reader +
|
||||||
"{{ACCESS}}.union(o) }";
|
"{{ACCESS}}.union(o) }";
|
||||||
break;
|
break;
|
||||||
default: FLATBUFFERS_ASSERT(0);
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenTableReaderVectorFields(const FieldDef &field) {
|
void GenTableReaderVectorFields(const FieldDef& field) {
|
||||||
std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
|
std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
|
||||||
const auto vectortype = field.value.type.VectorType();
|
const auto vectortype = field.value.type.VectorType();
|
||||||
code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
|
code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
|
||||||
@@ -879,10 +890,10 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += GenConstructor(
|
code_ += GenConstructor(
|
||||||
"{{ACCESS}}.indirect({{ACCESS}}.vector(at: o) + index * "
|
"{{ACCESS}}.indirect({{ACCESS}}.vector(at: o) + index * "
|
||||||
"{{SIZE}})");
|
"{{SIZE}})");
|
||||||
const auto &sd = *field.value.type.struct_def;
|
const auto& sd = *field.value.type.struct_def;
|
||||||
const auto &fields = sd.fields.vec;
|
const auto& fields = sd.fields.vec;
|
||||||
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
for (auto kit = fields.begin(); kit != fields.end(); ++kit) {
|
||||||
const auto &key_field = **kit;
|
const auto& key_field = **kit;
|
||||||
if (key_field.key) {
|
if (key_field.key) {
|
||||||
GenByKeyFunctions(key_field);
|
GenByKeyFunctions(key_field);
|
||||||
break;
|
break;
|
||||||
@@ -891,7 +902,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenUnsafeBufferPointer(const FieldDef &field) {
|
void GenUnsafeBufferPointer(const FieldDef& field) {
|
||||||
code_.SetValue("functionName",
|
code_.SetValue("functionName",
|
||||||
namer_.Variable("withUnsafePointerTo", field));
|
namer_.Variable("withUnsafePointerTo", field));
|
||||||
code_ +=
|
code_ +=
|
||||||
@@ -901,12 +912,12 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"body: body) }";
|
"body: body) }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateCodingKeys(const StructDef &struct_def) {
|
void GenerateCodingKeys(const StructDef& struct_def) {
|
||||||
code_ += "enum CodingKeys: String, CodingKey {";
|
code_ += "enum CodingKeys: String, CodingKey {";
|
||||||
Indent();
|
Indent();
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
code_.SetValue("RAWVALUENAME", field.name);
|
code_.SetValue("RAWVALUENAME", field.name);
|
||||||
@@ -917,8 +928,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateEncoderUnionBody(const FieldDef &field) {
|
void GenerateEncoderUnionBody(const FieldDef& field) {
|
||||||
EnumDef &union_def = *field.value.type.enum_def;
|
EnumDef& union_def = *field.value.type.enum_def;
|
||||||
const auto is_vector = field.value.type.base_type == BASE_TYPE_VECTOR ||
|
const auto is_vector = field.value.type.base_type == BASE_TYPE_VECTOR ||
|
||||||
field.value.type.base_type == BASE_TYPE_ARRAY;
|
field.value.type.base_type == BASE_TYPE_ARRAY;
|
||||||
if (field.value.type.base_type == BASE_TYPE_UTYPE ||
|
if (field.value.type.base_type == BASE_TYPE_UTYPE ||
|
||||||
@@ -939,11 +950,13 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "switch type {";
|
code_ += "switch type {";
|
||||||
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
||||||
++it) {
|
++it) {
|
||||||
const auto &ev = **it;
|
const auto& ev = **it;
|
||||||
const auto type = GenType(ev.union_type);
|
const auto type = GenType(ev.union_type);
|
||||||
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
||||||
code_.SetValue("VALUETYPE", type);
|
code_.SetValue("VALUETYPE", type);
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
|
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
code_ += "case .{{KEY}}:";
|
code_ += "case .{{KEY}}:";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "let _v = {{FIELDVAR}}(at: index, type: {{VALUETYPE}}.self)";
|
code_ += "let _v = {{FIELDVAR}}(at: index, type: {{VALUETYPE}}.self)";
|
||||||
@@ -960,11 +973,13 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "switch {{FIELDVAR}}Type {";
|
code_ += "switch {{FIELDVAR}}Type {";
|
||||||
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
||||||
++it) {
|
++it) {
|
||||||
const auto &ev = **it;
|
const auto& ev = **it;
|
||||||
const auto type = GenType(ev.union_type);
|
const auto type = GenType(ev.union_type);
|
||||||
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
||||||
code_.SetValue("VALUETYPE", type);
|
code_.SetValue("VALUETYPE", type);
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
|
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
code_ += "case .{{KEY}}:";
|
code_ += "case .{{KEY}}:";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "let _v = {{FIELDVAR}}(type: {{VALUETYPE}}.self)";
|
code_ += "let _v = {{FIELDVAR}}(type: {{VALUETYPE}}.self)";
|
||||||
@@ -975,11 +990,11 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateEncoderBody(const StructDef &struct_def) {
|
void GenerateEncoderBody(const StructDef& struct_def) {
|
||||||
code_ += "var container = encoder.container(keyedBy: CodingKeys.self)";
|
code_ += "var container = encoder.container(keyedBy: CodingKeys.self)";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto type = field.value.type;
|
const auto type = field.value.type;
|
||||||
|
|
||||||
@@ -1038,7 +1053,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateJSONEncodingAPIs(const StructDef &struct_def) {
|
void GenerateJSONEncodingAPIs(const StructDef& struct_def) {
|
||||||
code_ += "extension {{STRUCTNAME}}: Encodable {";
|
code_ += "extension {{STRUCTNAME}}: Encodable {";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "";
|
code_ += "";
|
||||||
@@ -1054,7 +1069,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "";
|
code_ += "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateVerifier(const StructDef &struct_def) {
|
void GenerateVerifier(const StructDef& struct_def) {
|
||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} static func verify<T>(_ verifier: inout Verifier, at "
|
"{{ACCESS_TYPE}} static func verify<T>(_ verifier: inout Verifier, at "
|
||||||
"position: "
|
"position: "
|
||||||
@@ -1063,7 +1078,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "var _v = try verifier.visitTable(at: position)";
|
code_ += "var _v = try verifier.visitTable(at: position)";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto offset = NumToString(field.value.offset);
|
const auto offset = NumToString(field.value.offset);
|
||||||
|
|
||||||
@@ -1087,14 +1102,14 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateUnionTypeVerifier(const FieldDef &field) {
|
void GenerateUnionTypeVerifier(const FieldDef& field) {
|
||||||
const auto is_vector =
|
const auto is_vector =
|
||||||
IsVector(field.value.type) || IsArray(field.value.type);
|
IsVector(field.value.type) || IsArray(field.value.type);
|
||||||
if (field.value.type.base_type == BASE_TYPE_UTYPE ||
|
if (field.value.type.base_type == BASE_TYPE_UTYPE ||
|
||||||
(is_vector &&
|
(is_vector &&
|
||||||
field.value.type.VectorType().base_type == BASE_TYPE_UTYPE))
|
field.value.type.VectorType().base_type == BASE_TYPE_UTYPE))
|
||||||
return;
|
return;
|
||||||
EnumDef &union_def = *field.value.type.enum_def;
|
EnumDef& union_def = *field.value.type.enum_def;
|
||||||
code_.SetValue("VALUETYPE", namer_.NamespacedType(union_def));
|
code_.SetValue("VALUETYPE", namer_.NamespacedType(union_def));
|
||||||
code_.SetValue("FUNCTION_NAME", is_vector ? "visitUnionVector" : "visit");
|
code_.SetValue("FUNCTION_NAME", is_vector ? "visitUnionVector" : "visit");
|
||||||
code_ +=
|
code_ +=
|
||||||
@@ -1106,7 +1121,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "switch key {";
|
code_ += "switch key {";
|
||||||
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
for (auto it = union_def.Vals().begin(); it != union_def.Vals().end();
|
||||||
++it) {
|
++it) {
|
||||||
const auto &ev = **it;
|
const auto& ev = **it;
|
||||||
const auto type = GenType(ev.union_type);
|
const auto type = GenType(ev.union_type);
|
||||||
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
||||||
code_.SetValue("VALUETYPE", type);
|
code_.SetValue("VALUETYPE", type);
|
||||||
@@ -1133,7 +1148,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "})";
|
code_ += "})";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateVerifierType(const FieldDef &field) {
|
std::string GenerateVerifierType(const FieldDef& field) {
|
||||||
const auto type = field.value.type;
|
const auto type = field.value.type;
|
||||||
const auto is_vector = IsVector(type) || IsArray(type);
|
const auto is_vector = IsVector(type) || IsArray(type);
|
||||||
|
|
||||||
@@ -1147,19 +1162,25 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
return GenerateNestedVerifierTypes(field.value.type);
|
return GenerateNestedVerifierTypes(field.value.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateNestedVerifierTypes(const Type &type) {
|
std::string GenerateNestedVerifierTypes(const Type& type) {
|
||||||
const auto string_type = GenType(type);
|
const auto string_type = GenType(type);
|
||||||
|
|
||||||
if (IsScalar(type.base_type)) { return string_type; }
|
if (IsScalar(type.base_type)) {
|
||||||
|
return string_type;
|
||||||
|
}
|
||||||
|
|
||||||
if (IsString(type)) { return "ForwardOffset<" + string_type + ">"; }
|
if (IsString(type)) {
|
||||||
|
return "ForwardOffset<" + string_type + ">";
|
||||||
|
}
|
||||||
|
|
||||||
if (type.struct_def && type.struct_def->fixed) { return string_type; }
|
if (type.struct_def && type.struct_def->fixed) {
|
||||||
|
return string_type;
|
||||||
|
}
|
||||||
|
|
||||||
return "ForwardOffset<" + string_type + ">";
|
return "ForwardOffset<" + string_type + ">";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenByKeyFunctions(const FieldDef &key_field) {
|
void GenByKeyFunctions(const FieldDef& key_field) {
|
||||||
code_.SetValue("TYPE", GenType(key_field.value.type));
|
code_.SetValue("TYPE", GenType(key_field.value.type));
|
||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} func {{FIELDVAR}}By(key: {{TYPE}}) -> {{VALUETYPE}}? "
|
"{{ACCESS_TYPE}} func {{FIELDVAR}}By(key: {{TYPE}}) -> {{VALUETYPE}}? "
|
||||||
@@ -1169,7 +1190,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
|
"{{ACCESS}}.vector(at: o), key: key, fbb: {{ACCESS}}.bb) }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenEnum(const EnumDef &enum_def) {
|
void GenEnum(const EnumDef& enum_def) {
|
||||||
if (enum_def.generated) return;
|
if (enum_def.generated) return;
|
||||||
const bool is_private_access =
|
const bool is_private_access =
|
||||||
parser_.opts.swift_implementation_only ||
|
parser_.opts.swift_implementation_only ||
|
||||||
@@ -1199,7 +1220,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} var value: {{BASE_TYPE}} { return self.rawValue }";
|
"{{ACCESS_TYPE}} var value: {{BASE_TYPE}} { return self.rawValue }";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
const auto &ev = **it;
|
const auto& ev = **it;
|
||||||
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
||||||
code_.SetValue("VALUE", enum_def.ToString(ev));
|
code_.SetValue("VALUE", enum_def.ToString(ev));
|
||||||
GenComment(ev.doc_comment);
|
GenComment(ev.doc_comment);
|
||||||
@@ -1238,7 +1259,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnumEncoder(const EnumDef &enum_def) {
|
void EnumEncoder(const EnumDef& enum_def) {
|
||||||
code_ += "extension {{ENUM_NAME}}: Encodable {";
|
code_ += "extension {{ENUM_NAME}}: Encodable {";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";
|
code_ += "{{ACCESS_TYPE}} func encode(to encoder: Encoder) throws {";
|
||||||
@@ -1246,7 +1267,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "var container = encoder.singleValueContainer()";
|
code_ += "var container = encoder.singleValueContainer()";
|
||||||
code_ += "switch self {";
|
code_ += "switch self {";
|
||||||
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
|
||||||
const auto &ev = **it;
|
const auto& ev = **it;
|
||||||
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
code_.SetValue("KEY", namer_.LegacySwiftVariant(ev));
|
||||||
code_.SetValue("RAWKEY", ev.name);
|
code_.SetValue("RAWKEY", ev.name);
|
||||||
code_ += "case .{{KEY}}: try container.encode(\"{{RAWKEY}}\")";
|
code_ += "case .{{KEY}}: try container.encode(\"{{RAWKEY}}\")";
|
||||||
@@ -1286,13 +1307,13 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
Indent();
|
Indent();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateObjectAPIStructConstructor(const StructDef &struct_def) {
|
void GenerateObjectAPIStructConstructor(const StructDef& struct_def) {
|
||||||
code_ +=
|
code_ +=
|
||||||
"{{ACCESS_TYPE}} init(_ _t: inout {{STRUCTNAME}}" + Mutable() + ") {";
|
"{{ACCESS_TYPE}} init(_ _t: inout {{STRUCTNAME}}" + Mutable() + ") {";
|
||||||
Indent();
|
Indent();
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
|
|
||||||
const auto type = GenType(field.value.type);
|
const auto type = GenType(field.value.type);
|
||||||
@@ -1309,7 +1330,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}\n";
|
code_ += "}\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenObjectAPI(const StructDef &struct_def) {
|
void GenObjectAPI(const StructDef& struct_def) {
|
||||||
code_ += "{{ACCESS_TYPE}} class " +
|
code_ += "{{ACCESS_TYPE}} class " +
|
||||||
namer_.NamespacedObjectType(struct_def) + ": NativeObject {\n";
|
namer_.NamespacedObjectType(struct_def) + ": NativeObject {\n";
|
||||||
std::vector<std::string> buffer_constructor;
|
std::vector<std::string> buffer_constructor;
|
||||||
@@ -1317,7 +1338,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
Indent();
|
Indent();
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
BuildObjectAPIConstructorBody(field, struct_def.fixed, buffer_constructor,
|
BuildObjectAPIConstructorBody(field, struct_def.fixed, buffer_constructor,
|
||||||
base_constructor);
|
base_constructor);
|
||||||
@@ -1335,13 +1356,13 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateObjectAPITableExtension(const StructDef &struct_def) {
|
void GenerateObjectAPITableExtension(const StructDef& struct_def) {
|
||||||
GenerateObjectAPIExtensionHeader(namer_.NamespacedObjectType(struct_def));
|
GenerateObjectAPIExtensionHeader(namer_.NamespacedObjectType(struct_def));
|
||||||
std::vector<std::string> unpack_body;
|
std::vector<std::string> unpack_body;
|
||||||
std::string builder = ", &builder)";
|
std::string builder = ", &builder)";
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
const auto &field = **it;
|
const auto& field = **it;
|
||||||
if (field.deprecated) continue;
|
if (field.deprecated) continue;
|
||||||
const auto field_var = namer_.Variable(field);
|
const auto field_var = namer_.Variable(field);
|
||||||
const auto field_field = namer_.Field(field);
|
const auto field_field = namer_.Field(field);
|
||||||
@@ -1353,7 +1374,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
: "(";
|
: "(";
|
||||||
std::string body = "add" + check_if_vector + field_method + ": ";
|
std::string body = "add" + check_if_vector + field_method + ": ";
|
||||||
switch (field.value.type.base_type) {
|
switch (field.value.type.base_type) {
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH();
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
GenerateVectorObjectAPITableExtension(field);
|
GenerateVectorObjectAPITableExtension(field);
|
||||||
unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var +
|
unpack_body.push_back("{{STRUCTNAME}}." + body + "__" + field_var +
|
||||||
@@ -1401,7 +1423,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: break;
|
case BASE_TYPE_UTYPE:
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." +
|
unpack_body.push_back("{{STRUCTNAME}}." + body + "obj." +
|
||||||
field_field + builder);
|
field_field + builder);
|
||||||
@@ -1417,8 +1440,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateVectorObjectAPITableExtension(const FieldDef &field_def) {
|
void GenerateVectorObjectAPITableExtension(const FieldDef& field_def) {
|
||||||
const Type &field_type = field_def.value.type;
|
const Type& field_type = field_def.value.type;
|
||||||
const auto type = GenType(field_type);
|
const auto type = GenType(field_type);
|
||||||
const auto var = namer_.Variable(field_def);
|
const auto var = namer_.Variable(field_def);
|
||||||
const auto field = namer_.Field(field_def);
|
const auto field = namer_.Field(field_def);
|
||||||
@@ -1439,7 +1462,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
".compactMap { $0?.type })";
|
".compactMap { $0?.type })";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: break;
|
case BASE_TYPE_UTYPE:
|
||||||
|
break;
|
||||||
case BASE_TYPE_STRUCT: {
|
case BASE_TYPE_STRUCT: {
|
||||||
if (field_type.struct_def && !field_type.struct_def->fixed) {
|
if (field_type.struct_def && !field_type.struct_def->fixed) {
|
||||||
code_ += "var __" + var + "__: [Offset] = []";
|
code_ += "var __" + var + "__: [Offset] = []";
|
||||||
@@ -1480,8 +1504,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildingOptionalObjects(const std::string &var,
|
void BuildingOptionalObjects(const std::string& var,
|
||||||
const std::string &body_front) {
|
const std::string& body_front) {
|
||||||
code_ += "let __" + var + ": Offset";
|
code_ += "let __" + var + ": Offset";
|
||||||
code_ += "if let s = obj." + var + " {";
|
code_ += "if let s = obj." + var + " {";
|
||||||
Indent();
|
Indent();
|
||||||
@@ -1495,8 +1519,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "";
|
code_ += "";
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildObjectConstructor(const std::vector<std::string> &body,
|
void BuildObjectConstructor(const std::vector<std::string>& body,
|
||||||
const std::string &header = "") {
|
const std::string& header = "") {
|
||||||
code_.SetValue("HEADER", header);
|
code_.SetValue("HEADER", header);
|
||||||
code_ += "{{ACCESS_TYPE}} init({{HEADER}}) {";
|
code_ += "{{ACCESS_TYPE}} init({{HEADER}}) {";
|
||||||
Indent();
|
Indent();
|
||||||
@@ -1506,9 +1530,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BuildObjectAPIConstructorBody(
|
void BuildObjectAPIConstructorBody(
|
||||||
const FieldDef &field, bool is_fixed,
|
const FieldDef& field, bool is_fixed,
|
||||||
std::vector<std::string> &buffer_constructor,
|
std::vector<std::string>& buffer_constructor,
|
||||||
std::vector<std::string> &base_constructor) {
|
std::vector<std::string>& base_constructor) {
|
||||||
const auto field_field = namer_.Field(field);
|
const auto field_field = namer_.Field(field);
|
||||||
const auto field_var = namer_.Variable(field);
|
const auto field_var = namer_.Variable(field);
|
||||||
const auto type = GenType(field.value.type);
|
const auto type = GenType(field.value.type);
|
||||||
@@ -1540,7 +1564,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH();
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
BuildObjectAPIConstructorBodyVectors(field, buffer_constructor,
|
BuildObjectAPIConstructorBodyVectors(field, buffer_constructor,
|
||||||
base_constructor, " ");
|
base_constructor, " ");
|
||||||
@@ -1563,7 +1588,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: break;
|
case BASE_TYPE_UTYPE:
|
||||||
|
break;
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
BuildUnionEnumSwitchCase(*field.value.type.enum_def, field_var,
|
BuildUnionEnumSwitchCase(*field.value.type.enum_def, field_var,
|
||||||
buffer_constructor);
|
buffer_constructor);
|
||||||
@@ -1601,9 +1627,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BuildObjectAPIConstructorBodyVectors(
|
void BuildObjectAPIConstructorBodyVectors(
|
||||||
const FieldDef &field, std::vector<std::string> &buffer_constructor,
|
const FieldDef& field, std::vector<std::string>& buffer_constructor,
|
||||||
std::vector<std::string> &base_constructor,
|
std::vector<std::string>& base_constructor,
|
||||||
const std::string &indentation) {
|
const std::string& indentation) {
|
||||||
const auto vectortype = field.value.type.VectorType();
|
const auto vectortype = field.value.type.VectorType();
|
||||||
const auto field_var = namer_.Field(field);
|
const auto field_var = namer_.Field(field);
|
||||||
const auto field_field = namer_.Field(field);
|
const auto field_field = namer_.Field(field);
|
||||||
@@ -1630,7 +1656,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH();
|
case BASE_TYPE_ARRAY:
|
||||||
|
FLATBUFFERS_FALLTHROUGH();
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1639,7 +1666,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
buffer_constructor, indentation, true);
|
buffer_constructor, indentation, true);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: break;
|
case BASE_TYPE_UTYPE:
|
||||||
|
break;
|
||||||
default: {
|
default: {
|
||||||
code_.SetValue(
|
code_.SetValue(
|
||||||
"VALUETYPE",
|
"VALUETYPE",
|
||||||
@@ -1663,14 +1691,16 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
buffer_constructor.push_back("}");
|
buffer_constructor.push_back("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildUnionEnumSwitchCaseWritter(const EnumDef &ed) {
|
void BuildUnionEnumSwitchCaseWritter(const EnumDef& ed) {
|
||||||
code_ += "switch type {";
|
code_ += "switch type {";
|
||||||
for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
|
for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
|
||||||
const auto ev = **it;
|
const auto ev = **it;
|
||||||
const auto variant = namer_.LegacySwiftVariant(ev);
|
const auto variant = namer_.LegacySwiftVariant(ev);
|
||||||
const auto type = GenType(ev.union_type);
|
const auto type = GenType(ev.union_type);
|
||||||
const auto is_struct = IsStruct(ev.union_type) ? type + Mutable() : type;
|
const auto is_struct = IsStruct(ev.union_type) ? type + Mutable() : type;
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
|
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
code_ += "case ." + variant + ":";
|
code_ += "case ." + variant + ":";
|
||||||
Indent();
|
Indent();
|
||||||
code_ += "var __obj = value as? " + GenType(ev.union_type, true);
|
code_ += "var __obj = value as? " + GenType(ev.union_type, true);
|
||||||
@@ -1681,9 +1711,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
void BuildUnionEnumSwitchCase(const EnumDef &ed, const std::string &field,
|
void BuildUnionEnumSwitchCase(const EnumDef& ed, const std::string& field,
|
||||||
std::vector<std::string> &buffer_constructor,
|
std::vector<std::string>& buffer_constructor,
|
||||||
const std::string &indentation = "",
|
const std::string& indentation = "",
|
||||||
const bool is_vector = false) {
|
const bool is_vector = false) {
|
||||||
const auto ns_type = namer_.NamespacedType(ed);
|
const auto ns_type = namer_.NamespacedType(ed);
|
||||||
code_.SetValue("VALUETYPE", ns_type);
|
code_.SetValue("VALUETYPE", ns_type);
|
||||||
@@ -1697,7 +1727,9 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
|
for (auto it = ed.Vals().begin(); it < ed.Vals().end(); ++it) {
|
||||||
const auto ev = **it;
|
const auto ev = **it;
|
||||||
const auto variant = namer_.LegacySwiftVariant(ev);
|
const auto variant = namer_.LegacySwiftVariant(ev);
|
||||||
if (ev.union_type.base_type == BASE_TYPE_NONE) { continue; }
|
if (ev.union_type.base_type == BASE_TYPE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const auto type = IsStruct(ev.union_type)
|
const auto type = IsStruct(ev.union_type)
|
||||||
? GenType(ev.union_type) + Mutable()
|
? GenType(ev.union_type) + Mutable()
|
||||||
: GenType(ev.union_type);
|
: GenType(ev.union_type);
|
||||||
@@ -1715,14 +1747,14 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
buffer_constructor.push_back(indentation + "}");
|
buffer_constructor.push_back(indentation + "}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) {
|
void AddMinOrMaxEnumValue(const std::string& str, const std::string& type) {
|
||||||
const auto current_value = str;
|
const auto current_value = str;
|
||||||
code_.SetValue(type, current_value);
|
code_.SetValue(type, current_value);
|
||||||
code_ += "{{ACCESS_TYPE}} static var " + type +
|
code_ += "{{ACCESS_TYPE}} static var " + type +
|
||||||
": {{ENUM_NAME}} { return .{{" + type + "}} }";
|
": {{ENUM_NAME}} { return .{{" + type + "}} }";
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenLookup(const FieldDef &key_field, const std::string &struct_type) {
|
void GenLookup(const FieldDef& key_field, const std::string& struct_type) {
|
||||||
code_.SetValue("STRUCTTYPE", struct_type);
|
code_.SetValue("STRUCTTYPE", struct_type);
|
||||||
code_.SetValue("OFFSET", NumToString(key_field.value.offset));
|
code_.SetValue("OFFSET", NumToString(key_field.value.offset));
|
||||||
std::string offset_reader =
|
std::string offset_reader =
|
||||||
@@ -1773,7 +1805,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
code_ += "}";
|
code_ += "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void GenPadding(const FieldDef &field, int *id) {
|
inline void GenPadding(const FieldDef& field, int* id) {
|
||||||
if (field.padding) {
|
if (field.padding) {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
if (static_cast<int>(field.padding) & (1 << i)) {
|
if (static_cast<int>(field.padding) & (1 << i)) {
|
||||||
@@ -1786,33 +1818,35 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenComment(const std::vector<std::string> &dc) {
|
void GenComment(const std::vector<std::string>& dc) {
|
||||||
if (dc.begin() == dc.end()) {
|
if (dc.begin() == dc.end()) {
|
||||||
// Don't output empty comment blocks with 0 lines of comment content.
|
// Don't output empty comment blocks with 0 lines of comment content.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
for (auto it = dc.begin(); it != dc.end(); ++it) { code_ += "/// " + *it; }
|
for (auto it = dc.begin(); it != dc.end(); ++it) {
|
||||||
|
code_ += "/// " + *it;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenOffset() {
|
std::string GenOffset() {
|
||||||
return "let o = {{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}.v); ";
|
return "let o = {{ACCESS}}.offset({{TABLEOFFSET}}.{{OFFSET}}.v); ";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenReaderMainBody(const std::string &optional = "") {
|
std::string GenReaderMainBody(const std::string& optional = "") {
|
||||||
return "{{ACCESS_TYPE}} var {{FIELDVAR}}: {{VALUETYPE}}" + optional + " { ";
|
return "{{ACCESS_TYPE}} var {{FIELDVAR}}: {{VALUETYPE}}" + optional + " { ";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenReader(const std::string &type,
|
std::string GenReader(const std::string& type,
|
||||||
const std::string &at = "{{OFFSET}}") {
|
const std::string& at = "{{OFFSET}}") {
|
||||||
return "{{ACCESS}}.readBuffer(of: {{" + type + "}}.self, at: " + at + ")";
|
return "{{ACCESS}}.readBuffer(of: {{" + type + "}}.self, at: " + at + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenConstructor(const std::string &offset) {
|
std::string GenConstructor(const std::string& offset) {
|
||||||
return "{{VALUETYPE}}({{ACCESS}}.bb, o: " + offset + ") }";
|
return "{{VALUETYPE}}({{ACCESS}}.bb, o: " + offset + ") }";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenMutate(const std::string &offset,
|
std::string GenMutate(const std::string& offset,
|
||||||
const std::string &get_offset, bool isRaw = false) {
|
const std::string& get_offset, bool isRaw = false) {
|
||||||
return "@discardableResult {{ACCESS_TYPE}} func mutate({{FIELDVAR}}: "
|
return "@discardableResult {{ACCESS_TYPE}} func mutate({{FIELDVAR}}: "
|
||||||
"{{VALUETYPE}}) -> Bool {" +
|
"{{VALUETYPE}}) -> Bool {" +
|
||||||
get_offset + " return {{ACCESS}}.mutate({{FIELDVAR}}" +
|
get_offset + " return {{ACCESS}}.mutate({{FIELDVAR}}" +
|
||||||
@@ -1827,22 +1861,22 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
"{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
|
"{{ACCESS}}.vector(at: o) + index * {{SIZE}}) }";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenEnumDefaultValue(const FieldDef &field) {
|
std::string GenEnumDefaultValue(const FieldDef& field) {
|
||||||
const auto &value = field.value;
|
const auto& value = field.value;
|
||||||
FLATBUFFERS_ASSERT(value.type.enum_def);
|
FLATBUFFERS_ASSERT(value.type.enum_def);
|
||||||
const auto &enum_def = *value.type.enum_def;
|
const auto& enum_def = *value.type.enum_def;
|
||||||
// Vector of enum defaults are always "[]" which never works.
|
// Vector of enum defaults are always "[]" which never works.
|
||||||
const std::string constant = IsVector(value.type) ? "0" : value.constant;
|
const std::string constant = IsVector(value.type) ? "0" : value.constant;
|
||||||
const auto enum_val = enum_def.FindByValue(constant);
|
const auto enum_val = enum_def.FindByValue(constant);
|
||||||
if (enum_val) {
|
if (enum_val) {
|
||||||
return "." + namer_.LegacySwiftVariant(*enum_val);
|
return "." + namer_.LegacySwiftVariant(*enum_val);
|
||||||
} else {
|
} else {
|
||||||
const auto &ev = **enum_def.Vals().begin();
|
const auto& ev = **enum_def.Vals().begin();
|
||||||
return "." + namer_.LegacySwiftVariant(ev);
|
return "." + namer_.LegacySwiftVariant(ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string SwiftConstant(const FieldDef &field) {
|
std::string SwiftConstant(const FieldDef& field) {
|
||||||
const auto default_value =
|
const auto default_value =
|
||||||
StringIsFlatbufferNan(field.value.constant) ? ".nan"
|
StringIsFlatbufferNan(field.value.constant) ? ".nan"
|
||||||
: StringIsFlatbufferPositiveInfinity(field.value.constant) ? ".infinity"
|
: StringIsFlatbufferPositiveInfinity(field.value.constant) ? ".infinity"
|
||||||
@@ -1854,7 +1888,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
return default_value;
|
return default_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenEnumConstructor(const std::string &at) {
|
std::string GenEnumConstructor(const std::string& at) {
|
||||||
return "{{VALUETYPE}}(rawValue: " + GenReader("BASEVALUE", at) + ") ";
|
return "{{VALUETYPE}}(rawValue: " + GenReader("BASEVALUE", at) + ") ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1862,31 +1896,34 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
return "static func validateVersion() { FlatBuffersVersion_25_2_10() }";
|
return "static func validateVersion() { FlatBuffersVersion_25_2_10() }";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenType(const Type &type,
|
std::string GenType(const Type& type,
|
||||||
const bool should_consider_suffix = false) const {
|
const bool should_consider_suffix = false) const {
|
||||||
return IsScalar(type.base_type) ? GenTypeBasic(type)
|
return IsScalar(type.base_type) ? GenTypeBasic(type)
|
||||||
: IsArray(type) ? GenType(type.VectorType())
|
: IsArray(type) ? GenType(type.VectorType())
|
||||||
: GenTypePointer(type, should_consider_suffix);
|
: GenTypePointer(type, should_consider_suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypePointer(const Type &type,
|
std::string GenTypePointer(const Type& type,
|
||||||
const bool should_consider_suffix) const {
|
const bool should_consider_suffix) const {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRING: return "String";
|
case BASE_TYPE_STRING:
|
||||||
case BASE_TYPE_VECTOR: return GenType(type.VectorType());
|
return "String";
|
||||||
|
case BASE_TYPE_VECTOR:
|
||||||
|
return GenType(type.VectorType());
|
||||||
case BASE_TYPE_STRUCT: {
|
case BASE_TYPE_STRUCT: {
|
||||||
const auto &sd = *type.struct_def;
|
const auto& sd = *type.struct_def;
|
||||||
if (should_consider_suffix && !sd.fixed) {
|
if (should_consider_suffix && !sd.fixed) {
|
||||||
return namer_.NamespacedObjectType(sd);
|
return namer_.NamespacedObjectType(sd);
|
||||||
}
|
}
|
||||||
return namer_.NamespacedType(sd);
|
return namer_.NamespacedType(sd);
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UNION:
|
case BASE_TYPE_UNION:
|
||||||
default: return "FlatbuffersInitializable";
|
default:
|
||||||
|
return "FlatbuffersInitializable";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeBasic(const Type &type) const {
|
std::string GenTypeBasic(const Type& type) const {
|
||||||
return GenTypeBasic(type, true);
|
return GenTypeBasic(type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1894,7 +1931,7 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
void Outdent() { code_.DecrementIdentLevel(); }
|
void Outdent() { code_.DecrementIdentLevel(); }
|
||||||
|
|
||||||
std::string GenTypeBasic(const Type &type, bool can_override) const {
|
std::string GenTypeBasic(const Type& type, bool can_override) const {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const char * const swift_type[] = {
|
static const char * const swift_type[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
@@ -1917,8 +1954,8 @@ class SwiftGenerator : public BaseGenerator {
|
|||||||
};
|
};
|
||||||
} // namespace swift
|
} // namespace swift
|
||||||
|
|
||||||
static bool GenerateSwift(const Parser &parser, const std::string &path,
|
static bool GenerateSwift(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
swift::SwiftGenerator generator(parser, path, file_name);
|
swift::SwiftGenerator generator(parser, path, file_name);
|
||||||
return generator.generate();
|
return generator.generate();
|
||||||
}
|
}
|
||||||
@@ -1927,26 +1964,29 @@ namespace {
|
|||||||
|
|
||||||
class SwiftCodeGenerator : public CodeGenerator {
|
class SwiftCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateSwift(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateSwift(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
if (!GenerateSwiftGRPC(parser, path, filename)) { return Status::ERROR; }
|
if (!GenerateSwiftGRPC(parser, path, filename)) {
|
||||||
|
return Status::ERROR;
|
||||||
|
}
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
@@ -1954,8 +1994,8 @@ class SwiftCodeGenerator : public CodeGenerator {
|
|||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
struct PrintScalarTag {};
|
struct PrintScalarTag {};
|
||||||
struct PrintPointerTag {};
|
struct PrintPointerTag {};
|
||||||
template<typename T> struct PrintTag {
|
template <typename T>
|
||||||
|
struct PrintTag {
|
||||||
typedef PrintScalarTag type;
|
typedef PrintScalarTag type;
|
||||||
};
|
};
|
||||||
template<> struct PrintTag<const void *> {
|
template <>
|
||||||
|
struct PrintTag<const void*> {
|
||||||
typedef PrintPointerTag type;
|
typedef PrintPointerTag type;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,7 +51,7 @@ struct JsonPrinter {
|
|||||||
int Indent() const { return std::max(opts.indent_step, 0); }
|
int Indent() const { return std::max(opts.indent_step, 0); }
|
||||||
|
|
||||||
// Output an identifier with or without quotes depending on strictness.
|
// Output an identifier with or without quotes depending on strictness.
|
||||||
void OutputIdentifier(const std::string &name) {
|
void OutputIdentifier(const std::string& name) {
|
||||||
if (opts.strict_json) text += '\"';
|
if (opts.strict_json) text += '\"';
|
||||||
text += name;
|
text += name;
|
||||||
if (opts.strict_json) text += '\"';
|
if (opts.strict_json) text += '\"';
|
||||||
@@ -58,15 +60,15 @@ struct JsonPrinter {
|
|||||||
// Print (and its template specialization below for pointers) generate text
|
// Print (and its template specialization below for pointers) generate text
|
||||||
// for a single FlatBuffer value into JSON format.
|
// for a single FlatBuffer value into JSON format.
|
||||||
// The general case for scalars:
|
// The general case for scalars:
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void PrintScalar(T val, const Type &type, int /*indent*/) {
|
void PrintScalar(T val, const Type& type, int /*indent*/) {
|
||||||
if (IsBool(type.base_type)) {
|
if (IsBool(type.base_type)) {
|
||||||
text += val != 0 ? "true" : "false";
|
text += val != 0 ? "true" : "false";
|
||||||
return; // done
|
return; // done
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opts.output_enum_identifiers && type.enum_def) {
|
if (opts.output_enum_identifiers && type.enum_def) {
|
||||||
const auto &enum_def = *type.enum_def;
|
const auto& enum_def = *type.enum_def;
|
||||||
if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
|
if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
|
||||||
text += '\"';
|
text += '\"';
|
||||||
text += ev->name;
|
text += ev->name;
|
||||||
@@ -106,9 +108,9 @@ struct JsonPrinter {
|
|||||||
|
|
||||||
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
||||||
// "[]".
|
// "[]".
|
||||||
template<typename Container, typename SizeT = typename Container::size_type>
|
template <typename Container, typename SizeT = typename Container::size_type>
|
||||||
const char *PrintContainer(PrintScalarTag, const Container &c, SizeT size,
|
const char* PrintContainer(PrintScalarTag, const Container& c, SizeT size,
|
||||||
const Type &type, int indent, const uint8_t *) {
|
const Type& type, int indent, const uint8_t*) {
|
||||||
const auto elem_indent = indent + Indent();
|
const auto elem_indent = indent + Indent();
|
||||||
text += '[';
|
text += '[';
|
||||||
AddNewLine();
|
AddNewLine();
|
||||||
@@ -128,10 +130,10 @@ struct JsonPrinter {
|
|||||||
|
|
||||||
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
// Print a vector or an array of JSON values, comma seperated, wrapped in
|
||||||
// "[]".
|
// "[]".
|
||||||
template<typename Container, typename SizeT = typename Container::size_type>
|
template <typename Container, typename SizeT = typename Container::size_type>
|
||||||
const char *PrintContainer(PrintPointerTag, const Container &c, SizeT size,
|
const char* PrintContainer(PrintPointerTag, const Container& c, SizeT size,
|
||||||
const Type &type, int indent,
|
const Type& type, int indent,
|
||||||
const uint8_t *prev_val) {
|
const uint8_t* prev_val) {
|
||||||
const auto is_struct = IsStruct(type);
|
const auto is_struct = IsStruct(type);
|
||||||
const auto elem_indent = indent + Indent();
|
const auto elem_indent = indent + Indent();
|
||||||
text += '[';
|
text += '[';
|
||||||
@@ -142,7 +144,7 @@ struct JsonPrinter {
|
|||||||
AddNewLine();
|
AddNewLine();
|
||||||
}
|
}
|
||||||
AddIndent(elem_indent);
|
AddIndent(elem_indent);
|
||||||
auto ptr = is_struct ? reinterpret_cast<const void *>(
|
auto ptr = is_struct ? reinterpret_cast<const void*>(
|
||||||
c.Data() + type.struct_def->bytesize * i)
|
c.Data() + type.struct_def->bytesize * i)
|
||||||
: c[i];
|
: c[i];
|
||||||
auto err = PrintOffset(ptr, type, elem_indent, prev_val,
|
auto err = PrintOffset(ptr, type, elem_indent, prev_val,
|
||||||
@@ -155,29 +157,29 @@ struct JsonPrinter {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, typename SizeT = uoffset_t>
|
template <typename T, typename SizeT = uoffset_t>
|
||||||
const char *PrintVector(const void *val, const Type &type, int indent,
|
const char* PrintVector(const void* val, const Type& type, int indent,
|
||||||
const uint8_t *prev_val) {
|
const uint8_t* prev_val) {
|
||||||
typedef Vector<T, SizeT> Container;
|
typedef Vector<T, SizeT> Container;
|
||||||
typedef typename PrintTag<typename Container::return_type>::type tag;
|
typedef typename PrintTag<typename Container::return_type>::type tag;
|
||||||
auto &vec = *reinterpret_cast<const Container *>(val);
|
auto& vec = *reinterpret_cast<const Container*>(val);
|
||||||
return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
|
return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
|
||||||
prev_val);
|
prev_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print an array a sequence of JSON values, comma separated, wrapped in "[]".
|
// Print an array a sequence of JSON values, comma separated, wrapped in "[]".
|
||||||
template<typename T>
|
template <typename T>
|
||||||
const char *PrintArray(const void *val, uint16_t size, const Type &type,
|
const char* PrintArray(const void* val, uint16_t size, const Type& type,
|
||||||
|
|
||||||
int indent) {
|
int indent) {
|
||||||
typedef Array<T, 0xFFFF> Container;
|
typedef Array<T, 0xFFFF> Container;
|
||||||
typedef typename PrintTag<typename Container::return_type>::type tag;
|
typedef typename PrintTag<typename Container::return_type>::type tag;
|
||||||
auto &arr = *reinterpret_cast<const Container *>(val);
|
auto& arr = *reinterpret_cast<const Container*>(val);
|
||||||
return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
|
return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *PrintOffset(const void *val, const Type &type, int indent,
|
const char* PrintOffset(const void* val, const Type& type, int indent,
|
||||||
const uint8_t *prev_val, soffset_t vector_index) {
|
const uint8_t* prev_val, soffset_t vector_index) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
// If this assert hits, you have an corrupt buffer, a union type field
|
// If this assert hits, you have an corrupt buffer, a union type field
|
||||||
@@ -185,7 +187,7 @@ struct JsonPrinter {
|
|||||||
FLATBUFFERS_ASSERT(prev_val);
|
FLATBUFFERS_ASSERT(prev_val);
|
||||||
auto union_type_byte = *prev_val; // Always a uint8_t.
|
auto union_type_byte = *prev_val; // Always a uint8_t.
|
||||||
if (vector_index >= 0) {
|
if (vector_index >= 0) {
|
||||||
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(
|
auto type_vec = reinterpret_cast<const Vector<uint8_t>*>(
|
||||||
prev_val + ReadScalar<uoffset_t>(prev_val));
|
prev_val + ReadScalar<uoffset_t>(prev_val));
|
||||||
union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||||
}
|
}
|
||||||
@@ -197,10 +199,10 @@ struct JsonPrinter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
return GenStruct(*type.struct_def, reinterpret_cast<const Table *>(val),
|
return GenStruct(*type.struct_def, reinterpret_cast<const Table*>(val),
|
||||||
indent);
|
indent);
|
||||||
case BASE_TYPE_STRING: {
|
case BASE_TYPE_STRING: {
|
||||||
auto s = reinterpret_cast<const String *>(val);
|
auto s = reinterpret_cast<const String*>(val);
|
||||||
bool ok = EscapeString(s->c_str(), s->size(), &text,
|
bool ok = EscapeString(s->c_str(), s->size(), &text,
|
||||||
opts.allow_non_utf8, opts.natural_utf8);
|
opts.allow_non_utf8, opts.natural_utf8);
|
||||||
return ok ? nullptr : "string contains non-utf8 bytes";
|
return ok ? nullptr : "string contains non-utf8 bytes";
|
||||||
@@ -240,11 +242,14 @@ struct JsonPrinter {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
default: FLATBUFFERS_ASSERT(0); return "unknown type";
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
|
return "unknown type";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> static T GetFieldDefault(const FieldDef &fd) {
|
template <typename T>
|
||||||
|
static T GetFieldDefault(const FieldDef& fd) {
|
||||||
T val{};
|
T val{};
|
||||||
auto check = StringToNumber(fd.value.constant.c_str(), &val);
|
auto check = StringToNumber(fd.value.constant.c_str(), &val);
|
||||||
(void)check;
|
(void)check;
|
||||||
@@ -253,12 +258,12 @@ struct JsonPrinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for a scalar field.
|
// Generate text for a scalar field.
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void GenField(const FieldDef &fd, const Table *table, bool fixed,
|
void GenField(const FieldDef& fd, const Table* table, bool fixed,
|
||||||
int indent) {
|
int indent) {
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
PrintScalar(
|
PrintScalar(
|
||||||
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset),
|
reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
|
||||||
fd.value.type, indent);
|
fd.value.type, indent);
|
||||||
} else if (fd.IsOptional()) {
|
} else if (fd.IsOptional()) {
|
||||||
auto opt = table->GetOptional<T, T>(fd.value.offset);
|
auto opt = table->GetOptional<T, T>(fd.value.offset);
|
||||||
@@ -274,13 +279,13 @@ struct JsonPrinter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for non-scalar field.
|
// Generate text for non-scalar field.
|
||||||
const char *GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
const char* GenFieldOffset(const FieldDef& fd, const Table* table, bool fixed,
|
||||||
int indent, const uint8_t *prev_val) {
|
int indent, const uint8_t* prev_val) {
|
||||||
const void *val = nullptr;
|
const void* val = nullptr;
|
||||||
if (fixed) {
|
if (fixed) {
|
||||||
// The only non-scalar fields in structs are structs or arrays.
|
// The only non-scalar fields in structs are structs or arrays.
|
||||||
FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type));
|
FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type));
|
||||||
val = reinterpret_cast<const Struct *>(table)->GetStruct<const void *>(
|
val = reinterpret_cast<const Struct*>(table)->GetStruct<const void*>(
|
||||||
fd.value.offset);
|
fd.value.offset);
|
||||||
} else if (fd.flexbuffer && opts.json_nested_flexbuffers) {
|
} else if (fd.flexbuffer && opts.json_nested_flexbuffers) {
|
||||||
// We could verify this FlexBuffer before access, but since this sits
|
// We could verify this FlexBuffer before access, but since this sits
|
||||||
@@ -289,38 +294,40 @@ struct JsonPrinter {
|
|||||||
// The caller should really be verifying the whole.
|
// The caller should really be verifying the whole.
|
||||||
// If the whole buffer is corrupt, we likely crash before we even get
|
// If the whole buffer is corrupt, we likely crash before we even get
|
||||||
// here.
|
// here.
|
||||||
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
auto vec = table->GetPointer<const Vector<uint8_t>*>(fd.value.offset);
|
||||||
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
|
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
|
||||||
root.ToString(true, opts.strict_json, text);
|
root.ToString(true, opts.strict_json, text);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if (fd.nested_flatbuffer && opts.json_nested_flatbuffers) {
|
} else if (fd.nested_flatbuffer && opts.json_nested_flatbuffers) {
|
||||||
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
auto vec = table->GetPointer<const Vector<uint8_t>*>(fd.value.offset);
|
||||||
auto root = GetRoot<Table>(vec->data());
|
auto root = GetRoot<Table>(vec->data());
|
||||||
return GenStruct(*fd.nested_flatbuffer, root, indent);
|
return GenStruct(*fd.nested_flatbuffer, root, indent);
|
||||||
} else {
|
} else {
|
||||||
val = IsStruct(fd.value.type)
|
val = IsStruct(fd.value.type)
|
||||||
? table->GetStruct<const void *>(fd.value.offset)
|
? table->GetStruct<const void*>(fd.value.offset)
|
||||||
: table->GetPointer<const void *>(fd.value.offset);
|
: table->GetPointer<const void*>(fd.value.offset);
|
||||||
}
|
}
|
||||||
return PrintOffset(val, fd.value.type, indent, prev_val, -1);
|
return PrintOffset(val, fd.value.type, indent, prev_val, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate text for a struct or table, values separated by commas, indented,
|
// Generate text for a struct or table, values separated by commas, indented,
|
||||||
// and bracketed by "{}"
|
// and bracketed by "{}"
|
||||||
const char *GenStruct(const StructDef &struct_def, const Table *table,
|
const char* GenStruct(const StructDef& struct_def, const Table* table,
|
||||||
int indent) {
|
int indent) {
|
||||||
text += '{';
|
text += '{';
|
||||||
int fieldout = 0;
|
int fieldout = 0;
|
||||||
const uint8_t *prev_val = nullptr;
|
const uint8_t* prev_val = nullptr;
|
||||||
const auto elem_indent = indent + Indent();
|
const auto elem_indent = indent + Indent();
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
FieldDef &fd = **it;
|
FieldDef& fd = **it;
|
||||||
auto is_present = struct_def.fixed || table->CheckField(fd.value.offset);
|
auto is_present = struct_def.fixed || table->CheckField(fd.value.offset);
|
||||||
auto output_anyway = (opts.output_default_scalars_in_json || fd.key) &&
|
auto output_anyway = (opts.output_default_scalars_in_json || fd.key) &&
|
||||||
IsScalar(fd.value.type.base_type) && !fd.deprecated;
|
IsScalar(fd.value.type.base_type) && !fd.deprecated;
|
||||||
if (is_present || output_anyway) {
|
if (is_present || output_anyway) {
|
||||||
if (fieldout++) { AddComma(); }
|
if (fieldout++) {
|
||||||
|
AddComma();
|
||||||
|
}
|
||||||
AddNewLine();
|
AddNewLine();
|
||||||
AddIndent(elem_indent);
|
AddIndent(elem_indent);
|
||||||
OutputIdentifier(fd.name);
|
OutputIdentifier(fd.name);
|
||||||
@@ -352,7 +359,7 @@ struct JsonPrinter {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
// Track prev val for use with union types.
|
// Track prev val for use with union types.
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
prev_val = reinterpret_cast<const uint8_t *>(table) + fd.value.offset;
|
prev_val = reinterpret_cast<const uint8_t*>(table) + fd.value.offset;
|
||||||
} else {
|
} else {
|
||||||
prev_val = table->GetAddressOf(fd.value.offset);
|
prev_val = table->GetAddressOf(fd.value.offset);
|
||||||
}
|
}
|
||||||
@@ -364,18 +371,18 @@ struct JsonPrinter {
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonPrinter(const Parser &parser, std::string &dest)
|
JsonPrinter(const Parser& parser, std::string& dest)
|
||||||
: opts(parser.opts), text(dest) {
|
: opts(parser.opts), text(dest) {
|
||||||
text.reserve(1024); // Reduce amount of inevitable reallocs.
|
text.reserve(1024); // Reduce amount of inevitable reallocs.
|
||||||
}
|
}
|
||||||
|
|
||||||
const IDLOptions &opts;
|
const IDLOptions& opts;
|
||||||
std::string &text;
|
std::string& text;
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *GenerateTextImpl(const Parser &parser, const Table *table,
|
static const char* GenerateTextImpl(const Parser& parser, const Table* table,
|
||||||
const StructDef &struct_def,
|
const StructDef& struct_def,
|
||||||
std::string *_text) {
|
std::string* _text) {
|
||||||
JsonPrinter printer(parser, *_text);
|
JsonPrinter printer(parser, *_text);
|
||||||
auto err = printer.GenStruct(struct_def, table, 0);
|
auto err = printer.GenStruct(struct_def, table, 0);
|
||||||
if (err) return err;
|
if (err) return err;
|
||||||
@@ -385,49 +392,51 @@ static const char *GenerateTextImpl(const Parser &parser, const Table *table,
|
|||||||
|
|
||||||
// Generate a text representation of a flatbuffer in JSON format.
|
// Generate a text representation of a flatbuffer in JSON format.
|
||||||
// Deprecated: please use `GenTextFromTable`
|
// Deprecated: please use `GenTextFromTable`
|
||||||
bool GenerateTextFromTable(const Parser &parser, const void *table,
|
bool GenerateTextFromTable(const Parser& parser, const void* table,
|
||||||
const std::string &table_name,
|
const std::string& table_name, std::string* _text) {
|
||||||
std::string *_text) {
|
|
||||||
return GenTextFromTable(parser, table, table_name, _text) != nullptr;
|
return GenTextFromTable(parser, table, table_name, _text) != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a text representation of a flatbuffer in JSON format.
|
// Generate a text representation of a flatbuffer in JSON format.
|
||||||
const char *GenTextFromTable(const Parser &parser, const void *table,
|
const char* GenTextFromTable(const Parser& parser, const void* table,
|
||||||
const std::string &table_name, std::string *_text) {
|
const std::string& table_name,
|
||||||
|
std::string* _text) {
|
||||||
auto struct_def = parser.LookupStruct(table_name);
|
auto struct_def = parser.LookupStruct(table_name);
|
||||||
if (struct_def == nullptr) { return "unknown struct"; }
|
if (struct_def == nullptr) {
|
||||||
auto root = static_cast<const Table *>(table);
|
return "unknown struct";
|
||||||
|
}
|
||||||
|
auto root = static_cast<const Table*>(table);
|
||||||
return GenerateTextImpl(parser, root, *struct_def, _text);
|
return GenerateTextImpl(parser, root, *struct_def, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: please use `GenText`
|
// Deprecated: please use `GenText`
|
||||||
const char *GenerateText(const Parser &parser, const void *flatbuffer,
|
const char* GenerateText(const Parser& parser, const void* flatbuffer,
|
||||||
std::string *_text) {
|
std::string* _text) {
|
||||||
return GenText(parser, flatbuffer, _text);
|
return GenText(parser, flatbuffer, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a text representation of a flatbuffer in JSON format.
|
// Generate a text representation of a flatbuffer in JSON format.
|
||||||
const char *GenText(const Parser &parser, const void *flatbuffer,
|
const char* GenText(const Parser& parser, const void* flatbuffer,
|
||||||
std::string *_text) {
|
std::string* _text) {
|
||||||
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
|
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
|
||||||
auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
|
auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
|
||||||
: GetRoot<Table>(flatbuffer);
|
: GetRoot<Table>(flatbuffer);
|
||||||
return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text);
|
return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string TextFileName(const std::string &path,
|
static std::string TextFileName(const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
return path + file_name + ".json";
|
return path + file_name + ".json";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated: please use `GenTextFile`
|
// Deprecated: please use `GenTextFile`
|
||||||
const char *GenerateTextFile(const Parser &parser, const std::string &path,
|
const char* GenerateTextFile(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
return GenTextFile(parser, path, file_name);
|
return GenTextFile(parser, path, file_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *GenTextFile(const Parser &parser, const std::string &path,
|
const char* GenTextFile(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
if (parser.opts.use_flexbuffers) {
|
if (parser.opts.use_flexbuffers) {
|
||||||
std::string json;
|
std::string json;
|
||||||
parser.flex_root_.ToString(true, parser.opts.strict_json, json);
|
parser.flex_root_.ToString(true, parser.opts.strict_json, json);
|
||||||
@@ -446,8 +455,8 @@ const char *GenTextFile(const Parser &parser, const std::string &path,
|
|||||||
: "SaveFile failed";
|
: "SaveFile failed";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string TextMakeRule(const Parser &parser, const std::string &path,
|
static std::string TextMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &file_name) {
|
const std::string& file_name) {
|
||||||
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return "";
|
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return "";
|
||||||
std::string filebase =
|
std::string filebase =
|
||||||
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
|
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
|
||||||
@@ -464,8 +473,8 @@ namespace {
|
|||||||
|
|
||||||
class TextCodeGenerator : public CodeGenerator {
|
class TextCodeGenerator : public CodeGenerator {
|
||||||
public:
|
public:
|
||||||
Status GenerateCode(const Parser &parser, const std::string &path,
|
Status GenerateCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
auto err = GenTextFile(parser, path, filename);
|
auto err = GenTextFile(parser, path, filename);
|
||||||
if (err) {
|
if (err) {
|
||||||
status_detail = " (" + std::string(err) + ")";
|
status_detail = " (" + std::string(err) + ")";
|
||||||
@@ -476,28 +485,27 @@ class TextCodeGenerator : public CodeGenerator {
|
|||||||
|
|
||||||
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
||||||
// serialized reflection.fbs.
|
// serialized reflection.fbs.
|
||||||
Status GenerateCode(const uint8_t *, int64_t,
|
Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
|
||||||
const CodeGenOptions &) override {
|
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
Status GenerateMakeRule(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename,
|
const std::string& filename,
|
||||||
std::string &output) override {
|
std::string& output) override {
|
||||||
output = TextMakeRule(parser, path, filename);
|
output = TextMakeRule(parser, path, filename);
|
||||||
return Status::OK;
|
return Status::OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateGrpcCode(const Parser &parser, const std::string &path,
|
Status GenerateGrpcCode(const Parser& parser, const std::string& path,
|
||||||
const std::string &filename) override {
|
const std::string& filename) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
(void)filename;
|
(void)filename;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
Status GenerateRootFile(const Parser &parser,
|
Status GenerateRootFile(const Parser& parser,
|
||||||
const std::string &path) override {
|
const std::string& path) override {
|
||||||
(void)parser;
|
(void)parser;
|
||||||
(void)path;
|
(void)path;
|
||||||
return Status::NOT_IMPLEMENTED;
|
return Status::NOT_IMPLEMENTED;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -24,47 +24,51 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static void CopyInline(FlatBufferBuilder &fbb,
|
static void CopyInline(FlatBufferBuilder& fbb,
|
||||||
const reflection::Field &fielddef, const Table &table,
|
const reflection::Field& fielddef, const Table& table,
|
||||||
size_t align, size_t size) {
|
size_t align, size_t size) {
|
||||||
fbb.Align(align);
|
fbb.Align(align);
|
||||||
fbb.PushBytes(table.GetStruct<const uint8_t *>(fielddef.offset()), size);
|
fbb.PushBytes(table.GetStruct<const uint8_t*>(fielddef.offset()), size);
|
||||||
fbb.TrackField(fielddef.offset(), fbb.GetSize());
|
fbb.TrackField(fielddef.offset(), fbb.GetSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool VerifyStruct(flatbuffers::Verifier &v,
|
static bool VerifyStruct(flatbuffers::Verifier& v,
|
||||||
const flatbuffers::Table &parent_table,
|
const flatbuffers::Table& parent_table,
|
||||||
voffset_t field_offset, const reflection::Object &obj,
|
voffset_t field_offset, const reflection::Object& obj,
|
||||||
bool required) {
|
bool required) {
|
||||||
auto offset = parent_table.GetOptionalFieldOffset(field_offset);
|
auto offset = parent_table.GetOptionalFieldOffset(field_offset);
|
||||||
if (required && !offset) { return false; }
|
if (required && !offset) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return !offset ||
|
return !offset ||
|
||||||
v.VerifyFieldStruct(reinterpret_cast<const uint8_t *>(&parent_table),
|
v.VerifyFieldStruct(reinterpret_cast<const uint8_t*>(&parent_table),
|
||||||
offset, obj.bytesize(), obj.minalign());
|
offset, obj.bytesize(), obj.minalign());
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
|
static bool VerifyVectorOfStructs(flatbuffers::Verifier& v,
|
||||||
const flatbuffers::Table &parent_table,
|
const flatbuffers::Table& parent_table,
|
||||||
voffset_t field_offset,
|
voffset_t field_offset,
|
||||||
const reflection::Object &obj,
|
const reflection::Object& obj,
|
||||||
bool required) {
|
bool required) {
|
||||||
auto p = parent_table.GetPointer<const uint8_t *>(field_offset);
|
auto p = parent_table.GetPointer<const uint8_t*>(field_offset);
|
||||||
if (required && !p) { return false; }
|
if (required && !p) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return !p || v.VerifyVectorOrString(p, obj.bytesize());
|
return !p || v.VerifyVectorOrString(p, obj.bytesize());
|
||||||
}
|
}
|
||||||
|
|
||||||
// forward declare to resolve cyclic deps between VerifyObject and VerifyVector
|
// forward declare to resolve cyclic deps between VerifyObject and VerifyVector
|
||||||
static bool VerifyObject(flatbuffers::Verifier &v,
|
static bool VerifyObject(flatbuffers::Verifier& v,
|
||||||
const reflection::Schema &schema,
|
const reflection::Schema& schema,
|
||||||
const reflection::Object &obj,
|
const reflection::Object& obj,
|
||||||
const flatbuffers::Table *table, bool required);
|
const flatbuffers::Table* table, bool required);
|
||||||
|
|
||||||
static bool VerifyUnion(flatbuffers::Verifier &v,
|
static bool VerifyUnion(flatbuffers::Verifier& v,
|
||||||
const reflection::Schema &schema, uint8_t utype,
|
const reflection::Schema& schema, uint8_t utype,
|
||||||
const uint8_t *elem,
|
const uint8_t* elem,
|
||||||
const reflection::Field &union_field) {
|
const reflection::Field& union_field) {
|
||||||
if (!utype) return true; // Not present.
|
if (!utype) return true; // Not present.
|
||||||
auto fb_enum = schema.enums()->Get(union_field.type()->index());
|
auto fb_enum = schema.enums()->Get(union_field.type()->index());
|
||||||
if (utype >= fb_enum->values()->size()) return false;
|
if (utype >= fb_enum->values()->size()) return false;
|
||||||
@@ -76,21 +80,21 @@ static bool VerifyUnion(flatbuffers::Verifier &v,
|
|||||||
return v.VerifyFromPointer(elem, elem_obj->bytesize());
|
return v.VerifyFromPointer(elem, elem_obj->bytesize());
|
||||||
} else {
|
} else {
|
||||||
return VerifyObject(v, schema, *elem_obj,
|
return VerifyObject(v, schema, *elem_obj,
|
||||||
reinterpret_cast<const flatbuffers::Table *>(elem),
|
reinterpret_cast<const flatbuffers::Table*>(elem),
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case reflection::String:
|
case reflection::String:
|
||||||
return v.VerifyString(
|
return v.VerifyString(reinterpret_cast<const flatbuffers::String*>(elem));
|
||||||
reinterpret_cast<const flatbuffers::String *>(elem));
|
default:
|
||||||
default: return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool VerifyVector(flatbuffers::Verifier &v,
|
static bool VerifyVector(flatbuffers::Verifier& v,
|
||||||
const reflection::Schema &schema,
|
const reflection::Schema& schema,
|
||||||
const flatbuffers::Table &table,
|
const flatbuffers::Table& table,
|
||||||
const reflection::Field &vec_field) {
|
const reflection::Field& vec_field) {
|
||||||
FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector);
|
FLATBUFFERS_ASSERT(vec_field.type()->base_type() == reflection::Vector);
|
||||||
if (!table.VerifyField<uoffset_t>(v, vec_field.offset(), sizeof(uoffset_t)))
|
if (!table.VerifyField<uoffset_t>(v, vec_field.offset(), sizeof(uoffset_t)))
|
||||||
return false;
|
return false;
|
||||||
@@ -149,7 +153,7 @@ static bool VerifyVector(flatbuffers::Verifier &v,
|
|||||||
table, vec_field);
|
table, vec_field);
|
||||||
if (!v.VerifyVector(vec)) return false;
|
if (!v.VerifyVector(vec)) return false;
|
||||||
if (!vec) return true;
|
if (!vec) return true;
|
||||||
auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
|
auto type_vec = table.GetPointer<Vector<uint8_t>*>(vec_field.offset() -
|
||||||
sizeof(voffset_t));
|
sizeof(voffset_t));
|
||||||
if (!v.VerifyVector(type_vec)) return false;
|
if (!v.VerifyVector(type_vec)) return false;
|
||||||
for (uoffset_t j = 0; j < vec->size(); j++) {
|
for (uoffset_t j = 0; j < vec->size(); j++) {
|
||||||
@@ -162,20 +166,24 @@ static bool VerifyVector(flatbuffers::Verifier &v,
|
|||||||
}
|
}
|
||||||
case reflection::Vector:
|
case reflection::Vector:
|
||||||
case reflection::None:
|
case reflection::None:
|
||||||
default: FLATBUFFERS_ASSERT(false); return false;
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool VerifyObject(flatbuffers::Verifier &v,
|
static bool VerifyObject(flatbuffers::Verifier& v,
|
||||||
const reflection::Schema &schema,
|
const reflection::Schema& schema,
|
||||||
const reflection::Object &obj,
|
const reflection::Object& obj,
|
||||||
const flatbuffers::Table *table, bool required) {
|
const flatbuffers::Table* table, bool required) {
|
||||||
if (!table) return !required;
|
if (!table) return !required;
|
||||||
if (!table->VerifyTableStart(v)) return false;
|
if (!table->VerifyTableStart(v)) return false;
|
||||||
for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
|
for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
|
||||||
auto field_def = obj.fields()->Get(i);
|
auto field_def = obj.fields()->Get(i);
|
||||||
switch (field_def->type()->base_type()) {
|
switch (field_def->type()->base_type()) {
|
||||||
case reflection::None: FLATBUFFERS_ASSERT(false); break;
|
case reflection::None:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
break;
|
||||||
case reflection::UType:
|
case reflection::UType:
|
||||||
if (!table->VerifyField<uint8_t>(v, field_def->offset(),
|
if (!table->VerifyField<uint8_t>(v, field_def->offset(),
|
||||||
sizeof(uint8_t)))
|
sizeof(uint8_t)))
|
||||||
@@ -243,12 +251,16 @@ static bool VerifyObject(flatbuffers::Verifier &v,
|
|||||||
// get union type from the prev field
|
// get union type from the prev field
|
||||||
voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
|
voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
|
||||||
auto utype = table->GetField<uint8_t>(utype_offset, 0);
|
auto utype = table->GetField<uint8_t>(utype_offset, 0);
|
||||||
auto uval = reinterpret_cast<const uint8_t *>(
|
auto uval = reinterpret_cast<const uint8_t*>(
|
||||||
flatbuffers::GetFieldT(*table, *field_def));
|
flatbuffers::GetFieldT(*table, *field_def));
|
||||||
if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
|
if (!VerifyUnion(v, schema, utype, uval, *field_def)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: FLATBUFFERS_ASSERT(false); break;
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,7 +271,7 @@ static bool VerifyObject(flatbuffers::Verifier &v,
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) {
|
int64_t GetAnyValueI(reflection::BaseType type, const uint8_t* data) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data))
|
#define FLATBUFFERS_GET(T) static_cast<int64_t>(ReadScalar<T>(data))
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -286,13 +298,15 @@ int64_t GetAnyValueI(reflection::BaseType type, const uint8_t *data) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
double GetAnyValueF(reflection::BaseType type, const uint8_t *data) {
|
double GetAnyValueF(reflection::BaseType type, const uint8_t* data) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case reflection::Float: return static_cast<double>(ReadScalar<float>(data));
|
case reflection::Float:
|
||||||
case reflection::Double: return ReadScalar<double>(data);
|
return static_cast<double>(ReadScalar<float>(data));
|
||||||
|
case reflection::Double:
|
||||||
|
return ReadScalar<double>(data);
|
||||||
case reflection::String: {
|
case reflection::String: {
|
||||||
auto s =
|
auto s =
|
||||||
reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data);
|
reinterpret_cast<const String*>(ReadScalar<uoffset_t>(data) + data);
|
||||||
if (s) {
|
if (s) {
|
||||||
double d;
|
double d;
|
||||||
StringToNumber(s->c_str(), &d);
|
StringToNumber(s->c_str(), &d);
|
||||||
@@ -301,18 +315,20 @@ double GetAnyValueF(reflection::BaseType type, const uint8_t *data) {
|
|||||||
return 0.0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default: return static_cast<double>(GetAnyValueI(type, data));
|
default:
|
||||||
|
return static_cast<double>(GetAnyValueI(type, data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
|
std::string GetAnyValueS(reflection::BaseType type, const uint8_t* data,
|
||||||
const reflection::Schema *schema, int type_index) {
|
const reflection::Schema* schema, int type_index) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case reflection::Float:
|
case reflection::Float:
|
||||||
case reflection::Double: return NumToString(GetAnyValueF(type, data));
|
case reflection::Double:
|
||||||
|
return NumToString(GetAnyValueF(type, data));
|
||||||
case reflection::String: {
|
case reflection::String: {
|
||||||
auto s =
|
auto s =
|
||||||
reinterpret_cast<const String *>(ReadScalar<uoffset_t>(data) + data);
|
reinterpret_cast<const String*>(ReadScalar<uoffset_t>(data) + data);
|
||||||
return s ? s->c_str() : "";
|
return s ? s->c_str() : "";
|
||||||
}
|
}
|
||||||
case reflection::Obj:
|
case reflection::Obj:
|
||||||
@@ -320,17 +336,17 @@ std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
|
|||||||
// Convert the table to a string. This is mostly for debugging purposes,
|
// Convert the table to a string. This is mostly for debugging purposes,
|
||||||
// and does NOT promise to be JSON compliant.
|
// and does NOT promise to be JSON compliant.
|
||||||
// Also prefixes the type.
|
// Also prefixes the type.
|
||||||
auto &objectdef = *schema->objects()->Get(type_index);
|
auto& objectdef = *schema->objects()->Get(type_index);
|
||||||
auto s = objectdef.name()->str();
|
auto s = objectdef.name()->str();
|
||||||
if (objectdef.is_struct()) {
|
if (objectdef.is_struct()) {
|
||||||
s += "(struct)"; // TODO: implement this as well.
|
s += "(struct)"; // TODO: implement this as well.
|
||||||
} else {
|
} else {
|
||||||
auto table_field = reinterpret_cast<const Table *>(
|
auto table_field = reinterpret_cast<const Table*>(
|
||||||
ReadScalar<uoffset_t>(data) + data);
|
ReadScalar<uoffset_t>(data) + data);
|
||||||
s += " { ";
|
s += " { ";
|
||||||
auto fielddefs = objectdef.fields();
|
auto fielddefs = objectdef.fields();
|
||||||
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
||||||
auto &fielddef = **it;
|
auto& fielddef = **it;
|
||||||
if (!table_field->CheckField(fielddef.offset())) continue;
|
if (!table_field->CheckField(fielddef.offset())) continue;
|
||||||
auto val = GetAnyFieldS(*table_field, fielddef, schema);
|
auto val = GetAnyFieldS(*table_field, fielddef, schema);
|
||||||
if (fielddef.type()->base_type() == reflection::String) {
|
if (fielddef.type()->base_type() == reflection::String) {
|
||||||
@@ -352,13 +368,15 @@ std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
|
|||||||
}
|
}
|
||||||
case reflection::Vector:
|
case reflection::Vector:
|
||||||
return "[(elements)]"; // TODO: implement this as well.
|
return "[(elements)]"; // TODO: implement this as well.
|
||||||
case reflection::Union: return "(union)"; // TODO: implement this as well.
|
case reflection::Union:
|
||||||
default: return NumToString(GetAnyValueI(type, data));
|
return "(union)"; // TODO: implement this as well.
|
||||||
|
default:
|
||||||
|
return NumToString(GetAnyValueI(type, data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ForAllFields(const reflection::Object *object, bool reverse,
|
void ForAllFields(const reflection::Object* object, bool reverse,
|
||||||
std::function<void(const reflection::Field *)> func) {
|
std::function<void(const reflection::Field*)> func) {
|
||||||
std::vector<uint32_t> field_to_id_map;
|
std::vector<uint32_t> field_to_id_map;
|
||||||
field_to_id_map.resize(object->fields()->size());
|
field_to_id_map.resize(object->fields()->size());
|
||||||
|
|
||||||
@@ -374,7 +392,7 @@ void ForAllFields(const reflection::Object *object, bool reverse,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) {
|
void SetAnyValueI(reflection::BaseType type, uint8_t* data, int64_t val) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val))
|
#define FLATBUFFERS_SET(T) WriteScalar(data, static_cast<T>(val))
|
||||||
switch (type) {
|
switch (type) {
|
||||||
@@ -397,16 +415,22 @@ void SetAnyValueI(reflection::BaseType type, uint8_t *data, int64_t val) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAnyValueF(reflection::BaseType type, uint8_t *data, double val) {
|
void SetAnyValueF(reflection::BaseType type, uint8_t* data, double val) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case reflection::Float: WriteScalar(data, static_cast<float>(val)); break;
|
case reflection::Float:
|
||||||
case reflection::Double: WriteScalar(data, val); break;
|
WriteScalar(data, static_cast<float>(val));
|
||||||
|
break;
|
||||||
|
case reflection::Double:
|
||||||
|
WriteScalar(data, val);
|
||||||
|
break;
|
||||||
// TODO: support strings.
|
// TODO: support strings.
|
||||||
default: SetAnyValueI(type, data, static_cast<int64_t>(val)); break;
|
default:
|
||||||
|
SetAnyValueI(type, data, static_cast<int64_t>(val));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) {
|
void SetAnyValueS(reflection::BaseType type, uint8_t* data, const char* val) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case reflection::Float:
|
case reflection::Float:
|
||||||
case reflection::Double: {
|
case reflection::Double: {
|
||||||
@@ -416,7 +440,9 @@ void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// TODO: support strings.
|
// TODO: support strings.
|
||||||
default: SetAnyValueI(type, data, StringToInt(val)); break;
|
default:
|
||||||
|
SetAnyValueI(type, data, StringToInt(val));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -430,9 +456,9 @@ void SetAnyValueS(reflection::BaseType type, uint8_t *data, const char *val) {
|
|||||||
// pass in your root_table type as well.
|
// pass in your root_table type as well.
|
||||||
class ResizeContext {
|
class ResizeContext {
|
||||||
public:
|
public:
|
||||||
ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta,
|
ResizeContext(const reflection::Schema& schema, uoffset_t start, int delta,
|
||||||
std::vector<uint8_t> *flatbuf,
|
std::vector<uint8_t>* flatbuf,
|
||||||
const reflection::Object *root_table = nullptr)
|
const reflection::Object* root_table = nullptr)
|
||||||
: schema_(schema),
|
: schema_(schema),
|
||||||
startptr_(flatbuf->data() + start),
|
startptr_(flatbuf->data() + start),
|
||||||
delta_(delta),
|
delta_(delta),
|
||||||
@@ -455,8 +481,8 @@ class ResizeContext {
|
|||||||
// Check if the range between first (lower address) and second straddles
|
// Check if the range between first (lower address) and second straddles
|
||||||
// the insertion point. If it does, change the offset at offsetloc (of
|
// the insertion point. If it does, change the offset at offsetloc (of
|
||||||
// type T, with direction D).
|
// type T, with direction D).
|
||||||
template<typename T, int D>
|
template <typename T, int D>
|
||||||
void Straddle(const void *first, const void *second, void *offsetloc) {
|
void Straddle(const void* first, const void* second, void* offsetloc) {
|
||||||
if (first <= startptr_ && second >= startptr_) {
|
if (first <= startptr_ && second >= startptr_) {
|
||||||
WriteScalar<T>(offsetloc, ReadScalar<T>(offsetloc) + delta_ * D);
|
WriteScalar<T>(offsetloc, ReadScalar<T>(offsetloc) + delta_ * D);
|
||||||
DagCheck(offsetloc) = true;
|
DagCheck(offsetloc) = true;
|
||||||
@@ -469,18 +495,18 @@ class ResizeContext {
|
|||||||
// resize actually happens.
|
// resize actually happens.
|
||||||
// This must be checked for every offset, since we can't know which offsets
|
// This must be checked for every offset, since we can't know which offsets
|
||||||
// will straddle and which won't.
|
// will straddle and which won't.
|
||||||
uint8_t &DagCheck(const void *offsetloc) {
|
uint8_t& DagCheck(const void* offsetloc) {
|
||||||
auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) -
|
auto dag_idx = reinterpret_cast<const uoffset_t*>(offsetloc) -
|
||||||
reinterpret_cast<const uoffset_t *>(buf_.data());
|
reinterpret_cast<const uoffset_t*>(buf_.data());
|
||||||
return dag_check_[dag_idx];
|
return dag_check_[dag_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResizeTable(const reflection::Object &objectdef, Table *table) {
|
void ResizeTable(const reflection::Object& objectdef, Table* table) {
|
||||||
if (DagCheck(table)) return; // Table already visited.
|
if (DagCheck(table)) return; // Table already visited.
|
||||||
auto vtable = table->GetVTable();
|
auto vtable = table->GetVTable();
|
||||||
// Early out: since all fields inside the table must point forwards in
|
// Early out: since all fields inside the table must point forwards in
|
||||||
// memory, if the insertion point is before the table we can stop here.
|
// memory, if the insertion point is before the table we can stop here.
|
||||||
auto tableloc = reinterpret_cast<uint8_t *>(table);
|
auto tableloc = reinterpret_cast<uint8_t*>(table);
|
||||||
if (startptr_ <= tableloc) {
|
if (startptr_ <= tableloc) {
|
||||||
// Check if insertion point is between the table and a vtable that
|
// Check if insertion point is between the table and a vtable that
|
||||||
// precedes it. This can't happen in current construction code, but check
|
// precedes it. This can't happen in current construction code, but check
|
||||||
@@ -490,7 +516,7 @@ class ResizeContext {
|
|||||||
// Check each field.
|
// Check each field.
|
||||||
auto fielddefs = objectdef.fields();
|
auto fielddefs = objectdef.fields();
|
||||||
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
||||||
auto &fielddef = **it;
|
auto& fielddef = **it;
|
||||||
auto base_type = fielddef.type()->base_type();
|
auto base_type = fielddef.type()->base_type();
|
||||||
// Ignore scalars.
|
// Ignore scalars.
|
||||||
if (base_type <= reflection::Double) continue;
|
if (base_type <= reflection::Double) continue;
|
||||||
@@ -512,7 +538,7 @@ class ResizeContext {
|
|||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case reflection::Obj: {
|
case reflection::Obj: {
|
||||||
if (subobjectdef) {
|
if (subobjectdef) {
|
||||||
ResizeTable(*subobjectdef, reinterpret_cast<Table *>(ref));
|
ResizeTable(*subobjectdef, reinterpret_cast<Table*>(ref));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -520,7 +546,7 @@ class ResizeContext {
|
|||||||
auto elem_type = fielddef.type()->element();
|
auto elem_type = fielddef.type()->element();
|
||||||
if (elem_type != reflection::Obj && elem_type != reflection::String)
|
if (elem_type != reflection::Obj && elem_type != reflection::String)
|
||||||
break;
|
break;
|
||||||
auto vec = reinterpret_cast<Vector<uoffset_t> *>(ref);
|
auto vec = reinterpret_cast<Vector<uoffset_t>*>(ref);
|
||||||
auto elemobjectdef =
|
auto elemobjectdef =
|
||||||
elem_type == reflection::Obj
|
elem_type == reflection::Obj
|
||||||
? schema_.objects()->Get(fielddef.type()->index())
|
? schema_.objects()->Get(fielddef.type()->index())
|
||||||
@@ -532,17 +558,19 @@ class ResizeContext {
|
|||||||
auto dest = loc + vec->Get(i);
|
auto dest = loc + vec->Get(i);
|
||||||
Straddle<uoffset_t, 1>(loc, dest, loc);
|
Straddle<uoffset_t, 1>(loc, dest, loc);
|
||||||
if (elemobjectdef)
|
if (elemobjectdef)
|
||||||
ResizeTable(*elemobjectdef, reinterpret_cast<Table *>(dest));
|
ResizeTable(*elemobjectdef, reinterpret_cast<Table*>(dest));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case reflection::Union: {
|
case reflection::Union: {
|
||||||
ResizeTable(GetUnionType(schema_, objectdef, fielddef, *table),
|
ResizeTable(GetUnionType(schema_, objectdef, fielddef, *table),
|
||||||
reinterpret_cast<Table *>(ref));
|
reinterpret_cast<Table*>(ref));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case reflection::String: break;
|
case reflection::String:
|
||||||
default: FLATBUFFERS_ASSERT(false);
|
break;
|
||||||
|
default:
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check if the vtable offset points beyond the insertion point.
|
// Check if the vtable offset points beyond the insertion point.
|
||||||
@@ -553,19 +581,19 @@ class ResizeContext {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const reflection::Schema &schema_;
|
const reflection::Schema& schema_;
|
||||||
uint8_t *startptr_;
|
uint8_t* startptr_;
|
||||||
int delta_;
|
int delta_;
|
||||||
std::vector<uint8_t> &buf_;
|
std::vector<uint8_t>& buf_;
|
||||||
std::vector<uint8_t> dag_check_;
|
std::vector<uint8_t> dag_check_;
|
||||||
};
|
};
|
||||||
|
|
||||||
void SetString(const reflection::Schema &schema, const std::string &val,
|
void SetString(const reflection::Schema& schema, const std::string& val,
|
||||||
const String *str, std::vector<uint8_t> *flatbuf,
|
const String* str, std::vector<uint8_t>* flatbuf,
|
||||||
const reflection::Object *root_table) {
|
const reflection::Object* root_table) {
|
||||||
auto delta = static_cast<int>(val.size()) - static_cast<int>(str->size());
|
auto delta = static_cast<int>(val.size()) - static_cast<int>(str->size());
|
||||||
auto str_start = static_cast<uoffset_t>(
|
auto str_start = static_cast<uoffset_t>(
|
||||||
reinterpret_cast<const uint8_t *>(str) - flatbuf->data());
|
reinterpret_cast<const uint8_t*>(str) - flatbuf->data());
|
||||||
auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t));
|
auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t));
|
||||||
if (delta) {
|
if (delta) {
|
||||||
// Clear the old string, since we don't want parts of it remaining.
|
// Clear the old string, since we don't want parts of it remaining.
|
||||||
@@ -580,13 +608,13 @@ void SetString(const reflection::Schema &schema, const std::string &val,
|
|||||||
memcpy(flatbuf->data() + start, val.c_str(), val.size() + 1);
|
memcpy(flatbuf->data() + start, val.c_str(), val.size() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
uint8_t* ResizeAnyVector(const reflection::Schema& schema, uoffset_t newsize,
|
||||||
const VectorOfAny *vec, uoffset_t num_elems,
|
const VectorOfAny* vec, uoffset_t num_elems,
|
||||||
uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
|
uoffset_t elem_size, std::vector<uint8_t>* flatbuf,
|
||||||
const reflection::Object *root_table) {
|
const reflection::Object* root_table) {
|
||||||
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems);
|
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems);
|
||||||
auto delta_bytes = delta_elem * static_cast<int>(elem_size);
|
auto delta_bytes = delta_elem * static_cast<int>(elem_size);
|
||||||
auto vec_start = reinterpret_cast<const uint8_t *>(vec) - flatbuf->data();
|
auto vec_start = reinterpret_cast<const uint8_t*>(vec) - flatbuf->data();
|
||||||
auto start = static_cast<uoffset_t>(vec_start) +
|
auto start = static_cast<uoffset_t>(vec_start) +
|
||||||
static_cast<uoffset_t>(sizeof(uoffset_t)) +
|
static_cast<uoffset_t>(sizeof(uoffset_t)) +
|
||||||
elem_size * num_elems;
|
elem_size * num_elems;
|
||||||
@@ -608,8 +636,8 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
|||||||
return flatbuf->data() + start;
|
return flatbuf->data() + start;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
|
const uint8_t* AddFlatBuffer(std::vector<uint8_t>& flatbuf,
|
||||||
const uint8_t *newbuf, size_t newlen) {
|
const uint8_t* newbuf, size_t newlen) {
|
||||||
// Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're
|
// Align to sizeof(uoffset_t) past sizeof(largest_scalar_t) since we're
|
||||||
// going to chop off the root offset.
|
// going to chop off the root offset.
|
||||||
while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) ||
|
while ((flatbuf.size() & (sizeof(uoffset_t) - 1)) ||
|
||||||
@@ -623,16 +651,16 @@ const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
|
|||||||
return flatbuf.data() + insertion_point + root_offset;
|
return flatbuf.data() + insertion_point + root_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
Offset<const Table*> CopyTable(FlatBufferBuilder& fbb,
|
||||||
const reflection::Schema &schema,
|
const reflection::Schema& schema,
|
||||||
const reflection::Object &objectdef,
|
const reflection::Object& objectdef,
|
||||||
const Table &table, bool use_string_pooling) {
|
const Table& table, bool use_string_pooling) {
|
||||||
// Before we can construct the table, we have to first generate any
|
// Before we can construct the table, we have to first generate any
|
||||||
// subobjects, and collect their offsets.
|
// subobjects, and collect their offsets.
|
||||||
std::vector<uoffset_t> offsets;
|
std::vector<uoffset_t> offsets;
|
||||||
auto fielddefs = objectdef.fields();
|
auto fielddefs = objectdef.fields();
|
||||||
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
||||||
auto &fielddef = **it;
|
auto& fielddef = **it;
|
||||||
// Skip if field is not present in the source.
|
// Skip if field is not present in the source.
|
||||||
if (!table.CheckField(fielddef.offset())) continue;
|
if (!table.CheckField(fielddef.offset())) continue;
|
||||||
uoffset_t offset = 0;
|
uoffset_t offset = 0;
|
||||||
@@ -644,7 +672,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case reflection::Obj: {
|
case reflection::Obj: {
|
||||||
auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index());
|
auto& subobjectdef = *schema.objects()->Get(fielddef.type()->index());
|
||||||
if (!subobjectdef.is_struct()) {
|
if (!subobjectdef.is_struct()) {
|
||||||
offset = CopyTable(fbb, schema, subobjectdef,
|
offset = CopyTable(fbb, schema, subobjectdef,
|
||||||
*GetFieldT(table, fielddef), use_string_pooling)
|
*GetFieldT(table, fielddef), use_string_pooling)
|
||||||
@@ -653,7 +681,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case reflection::Union: {
|
case reflection::Union: {
|
||||||
auto &subobjectdef = GetUnionType(schema, objectdef, fielddef, table);
|
auto& subobjectdef = GetUnionType(schema, objectdef, fielddef, table);
|
||||||
offset = CopyTable(fbb, schema, subobjectdef,
|
offset = CopyTable(fbb, schema, subobjectdef,
|
||||||
*GetFieldT(table, fielddef), use_string_pooling)
|
*GetFieldT(table, fielddef), use_string_pooling)
|
||||||
.o;
|
.o;
|
||||||
@@ -661,7 +689,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
}
|
}
|
||||||
case reflection::Vector: {
|
case reflection::Vector: {
|
||||||
auto vec =
|
auto vec =
|
||||||
table.GetPointer<const Vector<Offset<Table>> *>(fielddef.offset());
|
table.GetPointer<const Vector<Offset<Table>>*>(fielddef.offset());
|
||||||
auto element_base_type = fielddef.type()->element();
|
auto element_base_type = fielddef.type()->element();
|
||||||
auto elemobjectdef =
|
auto elemobjectdef =
|
||||||
element_base_type == reflection::Obj
|
element_base_type == reflection::Obj
|
||||||
@@ -669,8 +697,8 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
: nullptr;
|
: nullptr;
|
||||||
switch (element_base_type) {
|
switch (element_base_type) {
|
||||||
case reflection::String: {
|
case reflection::String: {
|
||||||
std::vector<Offset<const String *>> elements(vec->size());
|
std::vector<Offset<const String*>> elements(vec->size());
|
||||||
auto vec_s = reinterpret_cast<const Vector<Offset<String>> *>(vec);
|
auto vec_s = reinterpret_cast<const Vector<Offset<String>>*>(vec);
|
||||||
for (uoffset_t i = 0; i < vec_s->size(); i++) {
|
for (uoffset_t i = 0; i < vec_s->size(); i++) {
|
||||||
elements[i] = use_string_pooling
|
elements[i] = use_string_pooling
|
||||||
? fbb.CreateSharedString(vec_s->Get(i)).o
|
? fbb.CreateSharedString(vec_s->Get(i)).o
|
||||||
@@ -681,7 +709,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
}
|
}
|
||||||
case reflection::Obj: {
|
case reflection::Obj: {
|
||||||
if (!elemobjectdef->is_struct()) {
|
if (!elemobjectdef->is_struct()) {
|
||||||
std::vector<Offset<const Table *>> elements(vec->size());
|
std::vector<Offset<const Table*>> elements(vec->size());
|
||||||
for (uoffset_t i = 0; i < vec->size(); i++) {
|
for (uoffset_t i = 0; i < vec->size(); i++) {
|
||||||
elements[i] = CopyTable(fbb, schema, *elemobjectdef,
|
elements[i] = CopyTable(fbb, schema, *elemobjectdef,
|
||||||
*vec->Get(i), use_string_pooling);
|
*vec->Get(i), use_string_pooling);
|
||||||
@@ -707,19 +735,21 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
default: // Scalars.
|
default: // Scalars.
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (offset) { offsets.push_back(offset); }
|
if (offset) {
|
||||||
|
offsets.push_back(offset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Now we can build the actual table from either offsets or scalar data.
|
// Now we can build the actual table from either offsets or scalar data.
|
||||||
auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign())
|
auto start = objectdef.is_struct() ? fbb.StartStruct(objectdef.minalign())
|
||||||
: fbb.StartTable();
|
: fbb.StartTable();
|
||||||
size_t offset_idx = 0;
|
size_t offset_idx = 0;
|
||||||
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
for (auto it = fielddefs->begin(); it != fielddefs->end(); ++it) {
|
||||||
auto &fielddef = **it;
|
auto& fielddef = **it;
|
||||||
if (!table.CheckField(fielddef.offset())) continue;
|
if (!table.CheckField(fielddef.offset())) continue;
|
||||||
auto base_type = fielddef.type()->base_type();
|
auto base_type = fielddef.type()->base_type();
|
||||||
switch (base_type) {
|
switch (base_type) {
|
||||||
case reflection::Obj: {
|
case reflection::Obj: {
|
||||||
auto &subobjectdef = *schema.objects()->Get(fielddef.type()->index());
|
auto& subobjectdef = *schema.objects()->Get(fielddef.type()->index());
|
||||||
if (subobjectdef.is_struct()) {
|
if (subobjectdef.is_struct()) {
|
||||||
CopyInline(fbb, fielddef, table, subobjectdef.minalign(),
|
CopyInline(fbb, fielddef, table, subobjectdef.minalign(),
|
||||||
subobjectdef.bytesize());
|
subobjectdef.bytesize());
|
||||||
@@ -748,17 +778,17 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Verify(const reflection::Schema &schema, const reflection::Object &root,
|
bool Verify(const reflection::Schema& schema, const reflection::Object& root,
|
||||||
const uint8_t *const buf, const size_t length,
|
const uint8_t* const buf, const size_t length,
|
||||||
const uoffset_t max_depth, const uoffset_t max_tables) {
|
const uoffset_t max_depth, const uoffset_t max_tables) {
|
||||||
Verifier v(buf, length, max_depth, max_tables);
|
Verifier v(buf, length, max_depth, max_tables);
|
||||||
return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf),
|
return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf),
|
||||||
/*required=*/true);
|
/*required=*/true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifySizePrefixed(const reflection::Schema &schema,
|
bool VerifySizePrefixed(const reflection::Schema& schema,
|
||||||
const reflection::Object &root,
|
const reflection::Object& root,
|
||||||
const uint8_t *const buf, const size_t length,
|
const uint8_t* const buf, const size_t length,
|
||||||
const uoffset_t max_depth, const uoffset_t max_tables) {
|
const uoffset_t max_depth, const uoffset_t max_tables) {
|
||||||
Verifier v(buf, length, max_depth, max_tables);
|
Verifier v(buf, length, max_depth, max_tables);
|
||||||
return VerifyObject(v, schema, root, flatbuffers::GetAnySizePrefixedRoot(buf),
|
return VerifyObject(v, schema, root, flatbuffers::GetAnySizePrefixedRoot(buf),
|
||||||
|
|||||||
121
src/util.cpp
121
src/util.cpp
@@ -58,12 +58,12 @@ namespace flatbuffers {
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
static bool FileExistsRaw(const char *name) {
|
static bool FileExistsRaw(const char* name) {
|
||||||
std::ifstream ifs(name);
|
std::ifstream ifs(name);
|
||||||
return ifs.good();
|
return ifs.good();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool LoadFileRaw(const char *name, bool binary, std::string *buf) {
|
static bool LoadFileRaw(const char* name, bool binary, std::string* buf) {
|
||||||
if (DirExists(name)) return false;
|
if (DirExists(name)) return false;
|
||||||
std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
|
std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
|
||||||
if (!ifs.is_open()) return false;
|
if (!ifs.is_open()) return false;
|
||||||
@@ -86,7 +86,7 @@ static bool LoadFileRaw(const char *name, bool binary, std::string *buf) {
|
|||||||
LoadFileFunction g_load_file_function = LoadFileRaw;
|
LoadFileFunction g_load_file_function = LoadFileRaw;
|
||||||
FileExistsFunction g_file_exists_function = FileExistsRaw;
|
FileExistsFunction g_file_exists_function = FileExistsRaw;
|
||||||
|
|
||||||
static std::string ToCamelCase(const std::string &input, bool is_upper) {
|
static std::string ToCamelCase(const std::string& input, bool is_upper) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (size_t i = 0; i < input.length(); i++) {
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
if (!i && input[i] == '_') {
|
if (!i && input[i] == '_') {
|
||||||
@@ -105,7 +105,7 @@ static std::string ToCamelCase(const std::string &input, bool is_upper) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string ToSnakeCase(const std::string &input, bool screaming) {
|
static std::string ToSnakeCase(const std::string& input, bool screaming) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (size_t i = 0; i < input.length(); i++) {
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -127,14 +127,16 @@ static std::string ToSnakeCase(const std::string &input, bool screaming) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToAll(const std::string &input,
|
std::string ToAll(const std::string& input,
|
||||||
std::function<char(const char)> transform) {
|
std::function<char(const char)> transform) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (size_t i = 0; i < input.length(); i++) { s += transform(input[i]); }
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
|
s += transform(input[i]);
|
||||||
|
}
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string CamelToSnake(const std::string &input) {
|
std::string CamelToSnake(const std::string& input) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (size_t i = 0; i < input.length(); i++) {
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
@@ -156,7 +158,7 @@ std::string CamelToSnake(const std::string &input) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string DasherToSnake(const std::string &input) {
|
std::string DasherToSnake(const std::string& input) {
|
||||||
std::string s;
|
std::string s;
|
||||||
for (size_t i = 0; i < input.length(); i++) {
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
if (input[i] == '-') {
|
if (input[i] == '-') {
|
||||||
@@ -168,11 +170,11 @@ std::string DasherToSnake(const std::string &input) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ToDasher(const std::string &input) {
|
std::string ToDasher(const std::string& input) {
|
||||||
std::string s;
|
std::string s;
|
||||||
char p = 0;
|
char p = 0;
|
||||||
for (size_t i = 0; i < input.length(); i++) {
|
for (size_t i = 0; i < input.length(); i++) {
|
||||||
char const &c = input[i];
|
char const& c = input[i];
|
||||||
if (c == '_') {
|
if (c == '_') {
|
||||||
if (i > 0 && p != kPathSeparator &&
|
if (i > 0 && p != kPathSeparator &&
|
||||||
// The following is a special case to ignore digits after a _. This is
|
// The following is a special case to ignore digits after a _. This is
|
||||||
@@ -190,7 +192,7 @@ std::string ToDasher(const std::string &input) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Converts foo_bar_123baz_456 to foo_bar123_baz456
|
// Converts foo_bar_123baz_456 to foo_bar123_baz456
|
||||||
std::string SnakeToSnake2(const std::string &s) {
|
std::string SnakeToSnake2(const std::string& s) {
|
||||||
if (s.length() <= 1) return s;
|
if (s.length() <= 1) return s;
|
||||||
std::string result;
|
std::string result;
|
||||||
result.reserve(s.size());
|
result.reserve(s.size());
|
||||||
@@ -212,17 +214,17 @@ std::string SnakeToSnake2(const std::string &s) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool LoadFile(const char *name, bool binary, std::string *buf) {
|
bool LoadFile(const char* name, bool binary, std::string* buf) {
|
||||||
FLATBUFFERS_ASSERT(g_load_file_function);
|
FLATBUFFERS_ASSERT(g_load_file_function);
|
||||||
return g_load_file_function(name, binary, buf);
|
return g_load_file_function(name, binary, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool FileExists(const char *name) {
|
bool FileExists(const char* name) {
|
||||||
FLATBUFFERS_ASSERT(g_file_exists_function);
|
FLATBUFFERS_ASSERT(g_file_exists_function);
|
||||||
return g_file_exists_function(name);
|
return g_file_exists_function(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DirExists(const char *name) {
|
bool DirExists(const char* name) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@@ -252,7 +254,7 @@ FileExistsFunction SetFileExistsFunction(
|
|||||||
return previous_function;
|
return previous_function;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SaveFile(const char *name, const char *buf, size_t len, bool binary) {
|
bool SaveFile(const char* name, const char* buf, size_t len, bool binary) {
|
||||||
std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
|
std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
|
||||||
if (!ofs.is_open()) return false;
|
if (!ofs.is_open()) return false;
|
||||||
ofs.write(buf, len);
|
ofs.write(buf, len);
|
||||||
@@ -264,30 +266,30 @@ bool SaveFile(const char *name, const char *buf, size_t len, bool binary) {
|
|||||||
// on Windows when paths are string-compared.
|
// on Windows when paths are string-compared.
|
||||||
|
|
||||||
static const char kPathSeparatorWindows = '\\';
|
static const char kPathSeparatorWindows = '\\';
|
||||||
static const char *PathSeparatorSet = "\\/"; // Intentionally no ':'
|
static const char* PathSeparatorSet = "\\/"; // Intentionally no ':'
|
||||||
|
|
||||||
std::string StripExtension(const std::string &filepath) {
|
std::string StripExtension(const std::string& filepath) {
|
||||||
size_t i = filepath.find_last_of('.');
|
size_t i = filepath.find_last_of('.');
|
||||||
return i != std::string::npos ? filepath.substr(0, i) : filepath;
|
return i != std::string::npos ? filepath.substr(0, i) : filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetExtension(const std::string &filepath) {
|
std::string GetExtension(const std::string& filepath) {
|
||||||
size_t i = filepath.find_last_of('.');
|
size_t i = filepath.find_last_of('.');
|
||||||
return i != std::string::npos ? filepath.substr(i + 1) : "";
|
return i != std::string::npos ? filepath.substr(i + 1) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StripPath(const std::string &filepath) {
|
std::string StripPath(const std::string& filepath) {
|
||||||
size_t i = filepath.find_last_of(PathSeparatorSet);
|
size_t i = filepath.find_last_of(PathSeparatorSet);
|
||||||
return i != std::string::npos ? filepath.substr(i + 1) : filepath;
|
return i != std::string::npos ? filepath.substr(i + 1) : filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StripFileName(const std::string &filepath) {
|
std::string StripFileName(const std::string& filepath) {
|
||||||
size_t i = filepath.find_last_of(PathSeparatorSet);
|
size_t i = filepath.find_last_of(PathSeparatorSet);
|
||||||
return i != std::string::npos ? filepath.substr(0, i) : "";
|
return i != std::string::npos ? filepath.substr(0, i) : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string StripPrefix(const std::string &filepath,
|
std::string StripPrefix(const std::string& filepath,
|
||||||
const std::string &prefix_to_remove) {
|
const std::string& prefix_to_remove) {
|
||||||
if (!strncmp(filepath.c_str(), prefix_to_remove.c_str(),
|
if (!strncmp(filepath.c_str(), prefix_to_remove.c_str(),
|
||||||
prefix_to_remove.size())) {
|
prefix_to_remove.size())) {
|
||||||
return filepath.substr(prefix_to_remove.size());
|
return filepath.substr(prefix_to_remove.size());
|
||||||
@@ -295,11 +297,11 @@ std::string StripPrefix(const std::string &filepath,
|
|||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ConCatPathFileName(const std::string &path,
|
std::string ConCatPathFileName(const std::string& path,
|
||||||
const std::string &filename) {
|
const std::string& filename) {
|
||||||
std::string filepath = path;
|
std::string filepath = path;
|
||||||
if (filepath.length()) {
|
if (filepath.length()) {
|
||||||
char &filepath_last_character = filepath.back();
|
char& filepath_last_character = filepath.back();
|
||||||
if (filepath_last_character == kPathSeparatorWindows) {
|
if (filepath_last_character == kPathSeparatorWindows) {
|
||||||
filepath_last_character = kPathSeparator;
|
filepath_last_character = kPathSeparator;
|
||||||
} else if (filepath_last_character != kPathSeparator) {
|
} else if (filepath_last_character != kPathSeparator) {
|
||||||
@@ -314,16 +316,16 @@ std::string ConCatPathFileName(const std::string &path,
|
|||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string PosixPath(const char *path) {
|
std::string PosixPath(const char* path) {
|
||||||
std::string p = path;
|
std::string p = path;
|
||||||
std::replace(p.begin(), p.end(), '\\', '/');
|
std::replace(p.begin(), p.end(), '\\', '/');
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
std::string PosixPath(const std::string &path) {
|
std::string PosixPath(const std::string& path) {
|
||||||
return PosixPath(path.c_str());
|
return PosixPath(path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EnsureDirExists(const std::string &filepath) {
|
void EnsureDirExists(const std::string& filepath) {
|
||||||
auto parent = StripFileName(filepath);
|
auto parent = StripFileName(filepath);
|
||||||
if (parent.length()) EnsureDirExists(parent);
|
if (parent.length()) EnsureDirExists(parent);
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@@ -336,11 +338,13 @@ void EnsureDirExists(const std::string &filepath) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string FilePath(const std::string& project, const std::string& filePath, bool absolute) {
|
std::string FilePath(const std::string& project, const std::string& filePath,
|
||||||
return (absolute) ? AbsolutePath(filePath) : RelativeToRootPath(project, filePath);
|
bool absolute) {
|
||||||
|
return (absolute) ? AbsolutePath(filePath)
|
||||||
|
: RelativeToRootPath(project, filePath);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string AbsolutePath(const std::string &filepath) {
|
std::string AbsolutePath(const std::string& filepath) {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
|
|
||||||
#ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
|
#ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
|
||||||
@@ -365,16 +369,16 @@ std::string AbsolutePath(const std::string &filepath) {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string RelativeToRootPath(const std::string &project,
|
std::string RelativeToRootPath(const std::string& project,
|
||||||
const std::string &filepath) {
|
const std::string& filepath) {
|
||||||
std::string absolute_project = PosixPath(AbsolutePath(project));
|
std::string absolute_project = PosixPath(AbsolutePath(project));
|
||||||
if (absolute_project.back() != '/') absolute_project += "/";
|
if (absolute_project.back() != '/') absolute_project += "/";
|
||||||
std::string absolute_filepath = PosixPath(AbsolutePath(filepath));
|
std::string absolute_filepath = PosixPath(AbsolutePath(filepath));
|
||||||
|
|
||||||
// Find the first character where they disagree.
|
// Find the first character where they disagree.
|
||||||
// The previous directory is the lowest common ancestor;
|
// The previous directory is the lowest common ancestor;
|
||||||
const char *a = absolute_project.c_str();
|
const char* a = absolute_project.c_str();
|
||||||
const char *b = absolute_filepath.c_str();
|
const char* b = absolute_filepath.c_str();
|
||||||
size_t common_prefix_len = 0;
|
size_t common_prefix_len = 0;
|
||||||
while (*a != '\0' && *b != '\0' && *a == *b) {
|
while (*a != '\0' && *b != '\0' && *a == *b) {
|
||||||
if (*a == '/') common_prefix_len = a - absolute_project.c_str();
|
if (*a == '/') common_prefix_len = a - absolute_project.c_str();
|
||||||
@@ -383,7 +387,7 @@ std::string RelativeToRootPath(const std::string &project,
|
|||||||
}
|
}
|
||||||
// the number of ../ to prepend to b depends on the number of remaining
|
// the number of ../ to prepend to b depends on the number of remaining
|
||||||
// directories in A.
|
// directories in A.
|
||||||
const char *suffix = absolute_project.c_str() + common_prefix_len;
|
const char* suffix = absolute_project.c_str() + common_prefix_len;
|
||||||
size_t num_up = 0;
|
size_t num_up = 0;
|
||||||
while (*suffix != '\0')
|
while (*suffix != '\0')
|
||||||
if (*suffix++ == '/') num_up++;
|
if (*suffix++ == '/') num_up++;
|
||||||
@@ -416,21 +420,21 @@ ClassicLocale ClassicLocale::instance_;
|
|||||||
|
|
||||||
#endif // !FLATBUFFERS_LOCALE_INDEPENDENT
|
#endif // !FLATBUFFERS_LOCALE_INDEPENDENT
|
||||||
|
|
||||||
std::string RemoveStringQuotes(const std::string &s) {
|
std::string RemoveStringQuotes(const std::string& s) {
|
||||||
auto ch = *s.c_str();
|
auto ch = *s.c_str();
|
||||||
return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && (ch == s.back()))
|
return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && (ch == s.back()))
|
||||||
? s.substr(1, s.length() - 2)
|
? s.substr(1, s.length() - 2)
|
||||||
: s;
|
: s;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
|
bool SetGlobalTestLocale(const char* locale_name, std::string* _value) {
|
||||||
const auto the_locale = setlocale(LC_ALL, locale_name);
|
const auto the_locale = setlocale(LC_ALL, locale_name);
|
||||||
if (!the_locale) return false;
|
if (!the_locale) return false;
|
||||||
if (_value) *_value = std::string(the_locale);
|
if (_value) *_value = std::string(the_locale);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
|
bool ReadEnvironmentVariable(const char* var_name, std::string* _value) {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
__pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS
|
__pragma(warning(disable : 4996)); // _CRT_SECURE_NO_WARNINGS
|
||||||
#endif
|
#endif
|
||||||
@@ -440,7 +444,7 @@ bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ConvertCase(const std::string &input, Case output_case,
|
std::string ConvertCase(const std::string& input, Case output_case,
|
||||||
Case input_case) {
|
Case input_case) {
|
||||||
if (output_case == Case::kKeep) return input;
|
if (output_case == Case::kKeep) return input;
|
||||||
// The output cases expect snake_case inputs, so if we don't have that input
|
// The output cases expect snake_case inputs, so if we don't have that input
|
||||||
@@ -449,26 +453,39 @@ std::string ConvertCase(const std::string &input, Case output_case,
|
|||||||
case Case::kLowerCamel:
|
case Case::kLowerCamel:
|
||||||
case Case::kUpperCamel:
|
case Case::kUpperCamel:
|
||||||
return ConvertCase(CamelToSnake(input), output_case);
|
return ConvertCase(CamelToSnake(input), output_case);
|
||||||
case Case::kDasher: return ConvertCase(DasherToSnake(input), output_case);
|
case Case::kDasher:
|
||||||
case Case::kKeep: printf("WARNING: Converting from kKeep case.\n"); break;
|
return ConvertCase(DasherToSnake(input), output_case);
|
||||||
|
case Case::kKeep:
|
||||||
|
printf("WARNING: Converting from kKeep case.\n");
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
case Case::kSnake:
|
case Case::kSnake:
|
||||||
case Case::kScreamingSnake:
|
case Case::kScreamingSnake:
|
||||||
case Case::kAllLower:
|
case Case::kAllLower:
|
||||||
case Case::kAllUpper: break;
|
case Case::kAllUpper:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (output_case) {
|
switch (output_case) {
|
||||||
case Case::kUpperCamel: return ToCamelCase(input, true);
|
case Case::kUpperCamel:
|
||||||
case Case::kLowerCamel: return ToCamelCase(input, false);
|
return ToCamelCase(input, true);
|
||||||
case Case::kSnake: return input;
|
case Case::kLowerCamel:
|
||||||
case Case::kScreamingSnake: return ToSnakeCase(input, true);
|
return ToCamelCase(input, false);
|
||||||
case Case::kAllUpper: return ToAll(input, CharToUpper);
|
case Case::kSnake:
|
||||||
case Case::kAllLower: return ToAll(input, CharToLower);
|
return input;
|
||||||
case Case::kDasher: return ToDasher(input);
|
case Case::kScreamingSnake:
|
||||||
case Case::kSnake2: return SnakeToSnake2(input);
|
return ToSnakeCase(input, true);
|
||||||
|
case Case::kAllUpper:
|
||||||
|
return ToAll(input, CharToUpper);
|
||||||
|
case Case::kAllLower:
|
||||||
|
return ToAll(input, CharToLower);
|
||||||
|
case Case::kDasher:
|
||||||
|
return ToDasher(input);
|
||||||
|
case Case::kSnake2:
|
||||||
|
return SnakeToSnake2(input);
|
||||||
default:
|
default:
|
||||||
case Case::kUnknown: return input;
|
case Case::kUnknown:
|
||||||
|
return input;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
#include "alignment_test.h"
|
#include "alignment_test.h"
|
||||||
|
|
||||||
#include "tests/alignment_test_generated.h"
|
|
||||||
#include "flatbuffers/flatbuffer_builder.h"
|
#include "flatbuffers/flatbuffer_builder.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
#include "test_assert.h"
|
#include "test_assert.h"
|
||||||
|
#include "tests/alignment_test_generated.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace tests {
|
namespace tests {
|
||||||
@@ -14,8 +14,8 @@ void AlignmentTest() {
|
|||||||
BadAlignmentLarge large;
|
BadAlignmentLarge large;
|
||||||
Offset<OuterLarge> outer_large = CreateOuterLarge(builder, &large);
|
Offset<OuterLarge> outer_large = CreateOuterLarge(builder, &large);
|
||||||
|
|
||||||
BadAlignmentSmall *small;
|
BadAlignmentSmall* small;
|
||||||
Offset<Vector<const BadAlignmentSmall *>> small_offset =
|
Offset<Vector<const BadAlignmentSmall*>> small_offset =
|
||||||
builder.CreateUninitializedVectorOfStructs(9, &small);
|
builder.CreateUninitializedVectorOfStructs(9, &small);
|
||||||
(void)small; // We do not have to write data to trigger the test failure
|
(void)small; // We do not have to write data to trigger the test failure
|
||||||
|
|
||||||
@@ -27,22 +27,19 @@ void AlignmentTest() {
|
|||||||
Verifier verifier(builder.GetBufferPointer(), builder.GetSize());
|
Verifier verifier(builder.GetBufferPointer(), builder.GetSize());
|
||||||
TEST_ASSERT(verifier.VerifyBuffer<BadAlignmentRoot>(nullptr));
|
TEST_ASSERT(verifier.VerifyBuffer<BadAlignmentRoot>(nullptr));
|
||||||
|
|
||||||
|
|
||||||
// ============= Test Small Structs Vector misalignment ========
|
// ============= Test Small Structs Vector misalignment ========
|
||||||
|
|
||||||
builder.Clear();
|
builder.Clear();
|
||||||
|
|
||||||
// creating 5 structs with 2 bytes each
|
// creating 5 structs with 2 bytes each
|
||||||
// 10 bytes in total for Vector data is needed
|
// 10 bytes in total for Vector data is needed
|
||||||
std::vector<EvenSmallStruct> even_vector = { { 2, 1 }, { 3, 1 }, { 4, 1 } };
|
std::vector<EvenSmallStruct> even_vector = {{2, 1}, {3, 1}, {4, 1}};
|
||||||
std::vector<OddSmallStruct> odd_vector = { { 6, 5, 4 },
|
std::vector<OddSmallStruct> odd_vector = {{6, 5, 4}, {9, 8, 7}, {1, 2, 3}};
|
||||||
{ 9, 8, 7 },
|
|
||||||
{ 1, 2, 3 } };
|
|
||||||
// CreateVectorOfStructs is used in the generated CreateSmallStructsDirect()
|
// CreateVectorOfStructs is used in the generated CreateSmallStructsDirect()
|
||||||
// method, but we test it directly
|
// method, but we test it directly
|
||||||
Offset<Vector<const EvenSmallStruct *>> even_structs_offset =
|
Offset<Vector<const EvenSmallStruct*>> even_structs_offset =
|
||||||
builder.CreateVectorOfStructs<EvenSmallStruct>(even_vector);
|
builder.CreateVectorOfStructs<EvenSmallStruct>(even_vector);
|
||||||
Offset<Vector<const OddSmallStruct *>> odd_structs_offset =
|
Offset<Vector<const OddSmallStruct*>> odd_structs_offset =
|
||||||
builder.CreateVectorOfStructs<OddSmallStruct>(odd_vector);
|
builder.CreateVectorOfStructs<OddSmallStruct>(odd_vector);
|
||||||
Offset<SmallStructs> small_structs_root =
|
Offset<SmallStructs> small_structs_root =
|
||||||
CreateSmallStructs(builder, even_structs_offset, odd_structs_offset);
|
CreateSmallStructs(builder, even_structs_offset, odd_structs_offset);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace tests {
|
namespace tests {
|
||||||
|
|
||||||
void EvolutionTest(const std::string &tests_data_path) {
|
void EvolutionTest(const std::string& tests_data_path) {
|
||||||
// VS10 does not support typed enums, exclude from tests
|
// VS10 does not support typed enums, exclude from tests
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
||||||
const int NUM_VERSIONS = 2;
|
const int NUM_VERSIONS = 2;
|
||||||
@@ -83,8 +83,8 @@ void EvolutionTest(const std::string &tests_data_path) {
|
|||||||
void ConformTest() {
|
void ConformTest() {
|
||||||
const char ref[] = "table T { A:int; } enum E:byte { A }";
|
const char ref[] = "table T { A:int; } enum E:byte { A }";
|
||||||
|
|
||||||
auto test_conform = [](const char *ref, const char *test,
|
auto test_conform = [](const char* ref, const char* test,
|
||||||
const char *expected_err) {
|
const char* expected_err) {
|
||||||
flatbuffers::Parser parser1;
|
flatbuffers::Parser parser1;
|
||||||
TEST_EQ(parser1.Parse(ref), true);
|
TEST_EQ(parser1.Parse(ref), true);
|
||||||
flatbuffers::Parser parser2;
|
flatbuffers::Parser parser2;
|
||||||
@@ -112,11 +112,13 @@ void ConformTest() {
|
|||||||
"field renamed to different type: T2.df (renamed from T2.f)");
|
"field renamed to different type: T2.df (renamed from T2.f)");
|
||||||
|
|
||||||
// Check enum underlying type changes.
|
// Check enum underlying type changes.
|
||||||
test_conform("enum E:int32 {A}", "enum E: byte {A}", "underlying type differ for enum: E");
|
test_conform("enum E:int32 {A}", "enum E: byte {A}",
|
||||||
|
"underlying type differ for enum: E");
|
||||||
|
|
||||||
// Check union underlying type changes.
|
// Check union underlying type changes.
|
||||||
const char ref3[] = "table A {} table B {} union C {A, B}";
|
const char ref3[] = "table A {} table B {} union C {A, B}";
|
||||||
test_conform(ref3, "table A {} table B {} union C:int32 {A, B}", "underlying type differ for union: C");
|
test_conform(ref3, "table A {} table B {} union C:int32 {A, B}",
|
||||||
|
"underlying type differ for union: C");
|
||||||
|
|
||||||
// Check conformity for Offset64-related changes.
|
// Check conformity for Offset64-related changes.
|
||||||
{
|
{
|
||||||
@@ -151,7 +153,7 @@ void ConformTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnionDeprecationTest(const std::string &tests_data_path) {
|
void UnionDeprecationTest(const std::string& tests_data_path) {
|
||||||
const int NUM_VERSIONS = 2;
|
const int NUM_VERSIONS = 2;
|
||||||
std::string schemas[NUM_VERSIONS];
|
std::string schemas[NUM_VERSIONS];
|
||||||
std::string jsonfiles[NUM_VERSIONS];
|
std::string jsonfiles[NUM_VERSIONS];
|
||||||
|
|||||||
@@ -28,15 +28,15 @@ void FlexBuffersTest() {
|
|||||||
slb += "Fred";
|
slb += "Fred";
|
||||||
slb.IndirectFloat(4.0f);
|
slb.IndirectFloat(4.0f);
|
||||||
auto i_f = slb.LastValue();
|
auto i_f = slb.LastValue();
|
||||||
uint8_t blob[] = { 77 };
|
uint8_t blob[] = {77};
|
||||||
slb.Blob(blob, 1);
|
slb.Blob(blob, 1);
|
||||||
slb += false;
|
slb += false;
|
||||||
slb.ReuseValue(i_f);
|
slb.ReuseValue(i_f);
|
||||||
});
|
});
|
||||||
int ints[] = { 1, 2, 3 };
|
int ints[] = {1, 2, 3};
|
||||||
slb.Vector("bar", ints, 3);
|
slb.Vector("bar", ints, 3);
|
||||||
slb.FixedTypedVector("bar3", ints, 3);
|
slb.FixedTypedVector("bar3", ints, 3);
|
||||||
bool bools[] = { true, false, true, false };
|
bool bools[] = {true, false, true, false};
|
||||||
slb.Vector("bools", bools, 4);
|
slb.Vector("bools", bools, 4);
|
||||||
slb.Bool("bool", true);
|
slb.Bool("bool", true);
|
||||||
slb.Double("foo", 100);
|
slb.Double("foo", 100);
|
||||||
@@ -136,7 +136,8 @@ void FlexBuffersTest() {
|
|||||||
std::string jsonback_indented;
|
std::string jsonback_indented;
|
||||||
jroot.ToString(true, false, jsonback_indented, true, 0, " ");
|
jroot.ToString(true, false, jsonback_indented, true, 0, " ");
|
||||||
auto jsontest_indented =
|
auto jsontest_indented =
|
||||||
"{\n a: [\n 123,\n 456.0\n ],\n b: \"hello\",\n c: true,\n d: false\n}";
|
"{\n a: [\n 123,\n 456.0\n ],\n b: \"hello\",\n c: true,\n d: "
|
||||||
|
"false\n}";
|
||||||
TEST_EQ_STR(jsontest_indented, jsonback_indented.c_str());
|
TEST_EQ_STR(jsontest_indented, jsonback_indented.c_str());
|
||||||
|
|
||||||
slb.Clear();
|
slb.Clear();
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ uint32_t lcg_rand() {
|
|||||||
}
|
}
|
||||||
void lcg_reset() { lcg_seed = 48271; }
|
void lcg_reset() { lcg_seed = 48271; }
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
static void CompareTableFieldValue(flatbuffers::Table *table,
|
static void CompareTableFieldValue(flatbuffers::Table* table,
|
||||||
flatbuffers::voffset_t voffset, T val) {
|
flatbuffers::voffset_t voffset, T val) {
|
||||||
T read = table->GetField(voffset, static_cast<T>(0));
|
T read = table->GetField(voffset, static_cast<T>(0));
|
||||||
TEST_EQ(read, val);
|
TEST_EQ(read, val);
|
||||||
@@ -64,17 +64,39 @@ void FuzzTest1() {
|
|||||||
int choice = lcg_rand() % test_values_max;
|
int choice = lcg_rand() % test_values_max;
|
||||||
auto off = flatbuffers::FieldIndexToOffset(f);
|
auto off = flatbuffers::FieldIndexToOffset(f);
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 0: builder.AddElement<uint8_t>(off, bool_val, 0); break;
|
case 0:
|
||||||
case 1: builder.AddElement<int8_t>(off, char_val, 0); break;
|
builder.AddElement<uint8_t>(off, bool_val, 0);
|
||||||
case 2: builder.AddElement<uint8_t>(off, uchar_val, 0); break;
|
break;
|
||||||
case 3: builder.AddElement<int16_t>(off, short_val, 0); break;
|
case 1:
|
||||||
case 4: builder.AddElement<uint16_t>(off, ushort_val, 0); break;
|
builder.AddElement<int8_t>(off, char_val, 0);
|
||||||
case 5: builder.AddElement<int32_t>(off, int_val, 0); break;
|
break;
|
||||||
case 6: builder.AddElement<uint32_t>(off, uint_val, 0); break;
|
case 2:
|
||||||
case 7: builder.AddElement<int64_t>(off, long_val, 0); break;
|
builder.AddElement<uint8_t>(off, uchar_val, 0);
|
||||||
case 8: builder.AddElement<uint64_t>(off, ulong_val, 0); break;
|
break;
|
||||||
case 9: builder.AddElement<float>(off, float_val, 0); break;
|
case 3:
|
||||||
case 10: builder.AddElement<double>(off, double_val, 0); break;
|
builder.AddElement<int16_t>(off, short_val, 0);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
builder.AddElement<uint16_t>(off, ushort_val, 0);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
builder.AddElement<int32_t>(off, int_val, 0);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
builder.AddElement<uint32_t>(off, uint_val, 0);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
builder.AddElement<int64_t>(off, long_val, 0);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
builder.AddElement<uint64_t>(off, ulong_val, 0);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
builder.AddElement<float>(off, float_val, 0);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
builder.AddElement<double>(off, double_val, 0);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
objects[i] = builder.EndTable(start);
|
objects[i] = builder.EndTable(start);
|
||||||
@@ -83,28 +105,50 @@ void FuzzTest1() {
|
|||||||
|
|
||||||
lcg_reset(); // Reset.
|
lcg_reset(); // Reset.
|
||||||
|
|
||||||
uint8_t *eob = builder.GetCurrentBufferPointer() + builder.GetSize();
|
uint8_t* eob = builder.GetCurrentBufferPointer() + builder.GetSize();
|
||||||
|
|
||||||
// Test that all objects we generated are readable and return the
|
// Test that all objects we generated are readable and return the
|
||||||
// expected values. We generate random objects in the same order
|
// expected values. We generate random objects in the same order
|
||||||
// so this is deterministic.
|
// so this is deterministic.
|
||||||
for (int i = 0; i < num_fuzz_objects; i++) {
|
for (int i = 0; i < num_fuzz_objects; i++) {
|
||||||
auto table = reinterpret_cast<flatbuffers::Table *>(eob - objects[i]);
|
auto table = reinterpret_cast<flatbuffers::Table*>(eob - objects[i]);
|
||||||
for (flatbuffers::voffset_t f = 0; f < fields_per_object; f++) {
|
for (flatbuffers::voffset_t f = 0; f < fields_per_object; f++) {
|
||||||
int choice = lcg_rand() % test_values_max;
|
int choice = lcg_rand() % test_values_max;
|
||||||
flatbuffers::voffset_t off = flatbuffers::FieldIndexToOffset(f);
|
flatbuffers::voffset_t off = flatbuffers::FieldIndexToOffset(f);
|
||||||
switch (choice) {
|
switch (choice) {
|
||||||
case 0: CompareTableFieldValue(table, off, bool_val); break;
|
case 0:
|
||||||
case 1: CompareTableFieldValue(table, off, char_val); break;
|
CompareTableFieldValue(table, off, bool_val);
|
||||||
case 2: CompareTableFieldValue(table, off, uchar_val); break;
|
break;
|
||||||
case 3: CompareTableFieldValue(table, off, short_val); break;
|
case 1:
|
||||||
case 4: CompareTableFieldValue(table, off, ushort_val); break;
|
CompareTableFieldValue(table, off, char_val);
|
||||||
case 5: CompareTableFieldValue(table, off, int_val); break;
|
break;
|
||||||
case 6: CompareTableFieldValue(table, off, uint_val); break;
|
case 2:
|
||||||
case 7: CompareTableFieldValue(table, off, long_val); break;
|
CompareTableFieldValue(table, off, uchar_val);
|
||||||
case 8: CompareTableFieldValue(table, off, ulong_val); break;
|
break;
|
||||||
case 9: CompareTableFieldValue(table, off, float_val); break;
|
case 3:
|
||||||
case 10: CompareTableFieldValue(table, off, double_val); break;
|
CompareTableFieldValue(table, off, short_val);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
CompareTableFieldValue(table, off, ushort_val);
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
CompareTableFieldValue(table, off, int_val);
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
CompareTableFieldValue(table, off, uint_val);
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
CompareTableFieldValue(table, off, long_val);
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
CompareTableFieldValue(table, off, ulong_val);
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
CompareTableFieldValue(table, off, float_val);
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
CompareTableFieldValue(table, off, double_val);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,8 +175,8 @@ void FuzzTest2() {
|
|||||||
// Since we're generating schema and corresponding data in tandem,
|
// Since we're generating schema and corresponding data in tandem,
|
||||||
// this convenience function adds strings to both at once.
|
// this convenience function adds strings to both at once.
|
||||||
static void Add(RndDef (&definitions_l)[num_definitions],
|
static void Add(RndDef (&definitions_l)[num_definitions],
|
||||||
std::string &schema_l, const int instances_per_definition_l,
|
std::string& schema_l, const int instances_per_definition_l,
|
||||||
const char *schema_add, const char *instance_add,
|
const char* schema_add, const char* instance_add,
|
||||||
int definition) {
|
int definition) {
|
||||||
schema_l += schema_add;
|
schema_l += schema_add;
|
||||||
for (int i = 0; i < instances_per_definition_l; i++)
|
for (int i = 0; i < instances_per_definition_l; i++)
|
||||||
@@ -266,7 +310,7 @@ void FuzzTest2() {
|
|||||||
// from the binary and compare against the original.
|
// from the binary and compare against the original.
|
||||||
TEST_EQ(parser.Parse(schema.c_str()), true);
|
TEST_EQ(parser.Parse(schema.c_str()), true);
|
||||||
|
|
||||||
const std::string &json =
|
const std::string& json =
|
||||||
definitions[num_definitions - 1].instances[0] + "\n";
|
definitions[num_definitions - 1].instances[0] + "\n";
|
||||||
|
|
||||||
TEST_EQ(parser.Parse(json.c_str()), true);
|
TEST_EQ(parser.Parse(json.c_str()), true);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace tests {
|
|||||||
using namespace MyGame::Example;
|
using namespace MyGame::Example;
|
||||||
|
|
||||||
// Check stringify of an default enum value to json
|
// Check stringify of an default enum value to json
|
||||||
void JsonDefaultTest(const std::string &tests_data_path) {
|
void JsonDefaultTest(const std::string& tests_data_path) {
|
||||||
// load FlatBuffer schema (.fbs) from disk
|
// load FlatBuffer schema (.fbs) from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
|
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
|
||||||
@@ -23,8 +23,8 @@ void JsonDefaultTest(const std::string &tests_data_path) {
|
|||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
|
|
||||||
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
||||||
// create incomplete monster and store to json
|
// create incomplete monster and store to json
|
||||||
@@ -44,7 +44,7 @@ void JsonDefaultTest(const std::string &tests_data_path) {
|
|||||||
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
|
TEST_EQ(std::string::npos != jsongen.find("testf: 3.14159"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonEnumsTest(const std::string &tests_data_path) {
|
void JsonEnumsTest(const std::string& tests_data_path) {
|
||||||
// load FlatBuffer schema (.fbs) from disk
|
// load FlatBuffer schema (.fbs) from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
|
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
|
||||||
@@ -54,8 +54,8 @@ void JsonEnumsTest(const std::string &tests_data_path) {
|
|||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
parser.opts.output_enum_identifiers = true;
|
parser.opts.output_enum_identifiers = true;
|
||||||
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
||||||
flatbuffers::FlatBufferBuilder builder;
|
flatbuffers::FlatBufferBuilder builder;
|
||||||
@@ -83,7 +83,7 @@ void JsonEnumsTest(const std::string &tests_data_path) {
|
|||||||
TEST_EQ(std::string::npos != future_json.find("color: 13"), true);
|
TEST_EQ(std::string::npos != future_json.find("color: 13"), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonOptionalTest(const std::string &tests_data_path,
|
void JsonOptionalTest(const std::string& tests_data_path,
|
||||||
bool default_scalars) {
|
bool default_scalars) {
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
@@ -100,8 +100,8 @@ void JsonOptionalTest(const std::string &tests_data_path,
|
|||||||
|
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
|
|
||||||
// parse schema first, so we can use it to parse the data after
|
// parse schema first, so we can use it to parse the data after
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
@@ -124,17 +124,17 @@ void JsonOptionalTest(const std::string &tests_data_path,
|
|||||||
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
TEST_EQ_STR(jsongen.c_str(), jsonfile.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseIncorrectMonsterJsonTest(const std::string &tests_data_path) {
|
void ParseIncorrectMonsterJsonTest(const std::string& tests_data_path) {
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.bfbs").c_str(),
|
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.bfbs").c_str(),
|
||||||
true, &schemafile),
|
true, &schemafile),
|
||||||
true);
|
true);
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
flatbuffers::Verifier verifier(
|
flatbuffers::Verifier verifier(
|
||||||
reinterpret_cast<const uint8_t *>(schemafile.c_str()), schemafile.size());
|
reinterpret_cast<const uint8_t*>(schemafile.c_str()), schemafile.size());
|
||||||
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
||||||
TEST_EQ(
|
TEST_EQ(
|
||||||
parser.Deserialize(reinterpret_cast<const uint8_t *>(schemafile.c_str()),
|
parser.Deserialize(reinterpret_cast<const uint8_t*>(schemafile.c_str()),
|
||||||
schemafile.size()),
|
schemafile.size()),
|
||||||
true);
|
true);
|
||||||
TEST_EQ(parser.ParseJson("{name:\"monster\"}"), true);
|
TEST_EQ(parser.ParseJson("{name:\"monster\"}"), true);
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ using namespace keyfield::sample;
|
|||||||
void FixedSizedScalarKeyInStructTest() {
|
void FixedSizedScalarKeyInStructTest() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
std::vector<Baz> bazs;
|
std::vector<Baz> bazs;
|
||||||
uint8_t test_array1[4] = { 8, 2, 3, 0 };
|
uint8_t test_array1[4] = {8, 2, 3, 0};
|
||||||
uint8_t test_array2[4] = { 1, 2, 3, 4 };
|
uint8_t test_array2[4] = {1, 2, 3, 4};
|
||||||
uint8_t test_array3[4] = { 2, 2, 3, 4 };
|
uint8_t test_array3[4] = {2, 2, 3, 4};
|
||||||
uint8_t test_array4[4] = { 3, 2, 3, 4 };
|
uint8_t test_array4[4] = {3, 2, 3, 4};
|
||||||
bazs.push_back(Baz(flatbuffers::make_span(test_array1), 4));
|
bazs.push_back(Baz(flatbuffers::make_span(test_array1), 4));
|
||||||
bazs.push_back(Baz(flatbuffers::make_span(test_array2), 1));
|
bazs.push_back(Baz(flatbuffers::make_span(test_array2), 1));
|
||||||
bazs.push_back(Baz(flatbuffers::make_span(test_array3), 2));
|
bazs.push_back(Baz(flatbuffers::make_span(test_array3), 2));
|
||||||
@@ -27,10 +27,10 @@ void FixedSizedScalarKeyInStructTest() {
|
|||||||
|
|
||||||
auto test_string = fbb.CreateString("TEST");
|
auto test_string = fbb.CreateString("TEST");
|
||||||
|
|
||||||
float test_float_array1[3] = { 1.5, 2.5, 0 };
|
float test_float_array1[3] = {1.5, 2.5, 0};
|
||||||
float test_float_array2[3] = { 7.5, 2.5, 0 };
|
float test_float_array2[3] = {7.5, 2.5, 0};
|
||||||
float test_float_array3[3] = { 1.5, 2.5, -1 };
|
float test_float_array3[3] = {1.5, 2.5, -1};
|
||||||
float test_float_array4[3] = { -1.5, 2.5, 0 };
|
float test_float_array4[3] = {-1.5, 2.5, 0};
|
||||||
std::vector<Bar> bars;
|
std::vector<Bar> bars;
|
||||||
bars.push_back(Bar(flatbuffers::make_span(test_float_array1), 3));
|
bars.push_back(Bar(flatbuffers::make_span(test_float_array1), 3));
|
||||||
bars.push_back(Bar(flatbuffers::make_span(test_float_array2), 4));
|
bars.push_back(Bar(flatbuffers::make_span(test_float_array2), 4));
|
||||||
@@ -42,7 +42,7 @@ void FixedSizedScalarKeyInStructTest() {
|
|||||||
|
|
||||||
fbb.Finish(t);
|
fbb.Finish(t);
|
||||||
|
|
||||||
uint8_t *buf = fbb.GetBufferPointer();
|
uint8_t* buf = fbb.GetBufferPointer();
|
||||||
auto foo_table = GetFooTable(buf);
|
auto foo_table = GetFooTable(buf);
|
||||||
|
|
||||||
auto sorted_baz_vec = foo_table->d();
|
auto sorted_baz_vec = foo_table->d();
|
||||||
@@ -50,37 +50,37 @@ void FixedSizedScalarKeyInStructTest() {
|
|||||||
TEST_EQ(sorted_baz_vec->Get(3)->b(), 4);
|
TEST_EQ(sorted_baz_vec->Get(3)->b(), 4);
|
||||||
|
|
||||||
uint8_t test_array[4];
|
uint8_t test_array[4];
|
||||||
auto *key_array = &flatbuffers::CastToArray(test_array);
|
auto* key_array = &flatbuffers::CastToArray(test_array);
|
||||||
key_array->CopyFromSpan(flatbuffers::make_span(test_array1));
|
key_array->CopyFromSpan(flatbuffers::make_span(test_array1));
|
||||||
|
|
||||||
TEST_NOTNULL(sorted_baz_vec->LookupByKey(key_array));
|
TEST_NOTNULL(sorted_baz_vec->LookupByKey(key_array));
|
||||||
TEST_EQ(sorted_baz_vec->LookupByKey(key_array)->b(), 4);
|
TEST_EQ(sorted_baz_vec->LookupByKey(key_array)->b(), 4);
|
||||||
uint8_t array_int[4] = { 7, 2, 3, 0 };
|
uint8_t array_int[4] = {7, 2, 3, 0};
|
||||||
key_array->CopyFromSpan(flatbuffers::make_span(array_int));
|
key_array->CopyFromSpan(flatbuffers::make_span(array_int));
|
||||||
TEST_EQ(sorted_baz_vec->LookupByKey(key_array),
|
TEST_EQ(sorted_baz_vec->LookupByKey(key_array),
|
||||||
static_cast<const Baz *>(nullptr));
|
static_cast<const Baz*>(nullptr));
|
||||||
|
|
||||||
auto sorted_bar_vec = foo_table->e();
|
auto sorted_bar_vec = foo_table->e();
|
||||||
TEST_EQ(sorted_bar_vec->Get(0)->b(), 1);
|
TEST_EQ(sorted_bar_vec->Get(0)->b(), 1);
|
||||||
TEST_EQ(sorted_bar_vec->Get(3)->b(), 4);
|
TEST_EQ(sorted_bar_vec->Get(3)->b(), 4);
|
||||||
|
|
||||||
float test_float_array[3];
|
float test_float_array[3];
|
||||||
auto *key_float_array = &flatbuffers::CastToArray(test_float_array);
|
auto* key_float_array = &flatbuffers::CastToArray(test_float_array);
|
||||||
key_float_array->CopyFromSpan(flatbuffers::make_span(test_float_array1));
|
key_float_array->CopyFromSpan(flatbuffers::make_span(test_float_array1));
|
||||||
TEST_NOTNULL(sorted_bar_vec->LookupByKey(key_float_array));
|
TEST_NOTNULL(sorted_bar_vec->LookupByKey(key_float_array));
|
||||||
TEST_EQ(sorted_bar_vec->LookupByKey(key_float_array)->b(), 3);
|
TEST_EQ(sorted_bar_vec->LookupByKey(key_float_array)->b(), 3);
|
||||||
float array_float[3] = { -1, -2, -3 };
|
float array_float[3] = {-1, -2, -3};
|
||||||
key_float_array->CopyFromSpan(flatbuffers::make_span(array_float));
|
key_float_array->CopyFromSpan(flatbuffers::make_span(array_float));
|
||||||
TEST_EQ(sorted_bar_vec->LookupByKey(key_float_array),
|
TEST_EQ(sorted_bar_vec->LookupByKey(key_float_array),
|
||||||
static_cast<const Bar *>(nullptr));
|
static_cast<const Bar*>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructKeyInStructTest() {
|
void StructKeyInStructTest() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
std::vector<Apple> apples;
|
std::vector<Apple> apples;
|
||||||
float test_float_array1[3] = { 1.5, 2.5, 0 };
|
float test_float_array1[3] = {1.5, 2.5, 0};
|
||||||
float test_float_array2[3] = { 7.5, 2.5, 0 };
|
float test_float_array2[3] = {7.5, 2.5, 0};
|
||||||
float test_float_array3[3] = { 1.5, 2.5, -1 };
|
float test_float_array3[3] = {1.5, 2.5, -1};
|
||||||
apples.push_back(
|
apples.push_back(
|
||||||
Apple(2, Color(flatbuffers::make_span(test_float_array1), 3)));
|
Apple(2, Color(flatbuffers::make_span(test_float_array1), 3)));
|
||||||
apples.push_back(
|
apples.push_back(
|
||||||
@@ -100,7 +100,7 @@ void StructKeyInStructTest() {
|
|||||||
auto orc = foo_builder.Finish();
|
auto orc = foo_builder.Finish();
|
||||||
fbb.Finish(orc);
|
fbb.Finish(orc);
|
||||||
|
|
||||||
uint8_t *buf = fbb.GetBufferPointer();
|
uint8_t* buf = fbb.GetBufferPointer();
|
||||||
auto foo_table = GetFooTable(buf);
|
auto foo_table = GetFooTable(buf);
|
||||||
|
|
||||||
auto sorted_apple_vec = foo_table->f();
|
auto sorted_apple_vec = foo_table->f();
|
||||||
@@ -113,15 +113,15 @@ void StructKeyInStructTest() {
|
|||||||
2);
|
2);
|
||||||
TEST_EQ(sorted_apple_vec->LookupByKey(
|
TEST_EQ(sorted_apple_vec->LookupByKey(
|
||||||
Color(flatbuffers::make_span(test_float_array1), 0)),
|
Color(flatbuffers::make_span(test_float_array1), 0)),
|
||||||
static_cast<const Apple *>(nullptr));
|
static_cast<const Apple*>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void NestedStructKeyInStructTest() {
|
void NestedStructKeyInStructTest() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
std::vector<Fruit> fruits;
|
std::vector<Fruit> fruits;
|
||||||
float test_float_array1[3] = { 1.5, 2.5, 0 };
|
float test_float_array1[3] = {1.5, 2.5, 0};
|
||||||
float test_float_array2[3] = { 1.5, 2.5, 0 };
|
float test_float_array2[3] = {1.5, 2.5, 0};
|
||||||
float test_float_array3[3] = { 1.5, 2.5, -1 };
|
float test_float_array3[3] = {1.5, 2.5, -1};
|
||||||
|
|
||||||
fruits.push_back(
|
fruits.push_back(
|
||||||
Fruit(Apple(2, Color(flatbuffers::make_span(test_float_array1), 2)), 2));
|
Fruit(Apple(2, Color(flatbuffers::make_span(test_float_array1), 2)), 2));
|
||||||
@@ -140,7 +140,7 @@ void NestedStructKeyInStructTest() {
|
|||||||
|
|
||||||
auto orc = foo_builder.Finish();
|
auto orc = foo_builder.Finish();
|
||||||
fbb.Finish(orc);
|
fbb.Finish(orc);
|
||||||
uint8_t *buf = fbb.GetBufferPointer();
|
uint8_t* buf = fbb.GetBufferPointer();
|
||||||
auto foo_table = GetFooTable(buf);
|
auto foo_table = GetFooTable(buf);
|
||||||
|
|
||||||
auto sorted_fruit_vec = foo_table->g();
|
auto sorted_fruit_vec = foo_table->g();
|
||||||
@@ -154,34 +154,31 @@ void NestedStructKeyInStructTest() {
|
|||||||
1);
|
1);
|
||||||
TEST_EQ(sorted_fruit_vec->LookupByKey(
|
TEST_EQ(sorted_fruit_vec->LookupByKey(
|
||||||
Apple(1, Color(flatbuffers::make_span(test_float_array2), 1))),
|
Apple(1, Color(flatbuffers::make_span(test_float_array2), 1))),
|
||||||
static_cast<const Fruit *>(nullptr));
|
static_cast<const Fruit*>(nullptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedSizedStructArrayKeyInStructTest() {
|
void FixedSizedStructArrayKeyInStructTest() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
std::vector<Grain> grains;
|
std::vector<Grain> grains;
|
||||||
uint8_t test_char_array1[3] = { 'u', 's', 'a' };
|
uint8_t test_char_array1[3] = {'u', 's', 'a'};
|
||||||
uint8_t test_char_array2[3] = { 'c', 'h', 'n' };
|
uint8_t test_char_array2[3] = {'c', 'h', 'n'};
|
||||||
uint8_t test_char_array3[3] = { 'c', 'h', 'l' };
|
uint8_t test_char_array3[3] = {'c', 'h', 'l'};
|
||||||
uint8_t test_char_array4[3] = { 'f', 'r', 'a' };
|
uint8_t test_char_array4[3] = {'f', 'r', 'a'};
|
||||||
uint8_t test_char_array5[3] = { 'i', 'n', 'd' };
|
uint8_t test_char_array5[3] = {'i', 'n', 'd'};
|
||||||
uint8_t test_char_array6[3] = { 'i', 't', 'a' };
|
uint8_t test_char_array6[3] = {'i', 't', 'a'};
|
||||||
|
|
||||||
Rice test_rice_array1[3] = {
|
Rice test_rice_array1[3] = {
|
||||||
Rice(flatbuffers::make_span(test_char_array1), 2),
|
Rice(flatbuffers::make_span(test_char_array1), 2),
|
||||||
Rice(flatbuffers::make_span(test_char_array2), 1),
|
Rice(flatbuffers::make_span(test_char_array2), 1),
|
||||||
Rice(flatbuffers::make_span(test_char_array3), 2)
|
Rice(flatbuffers::make_span(test_char_array3), 2)};
|
||||||
};
|
|
||||||
Rice test_rice_array2[3] = {
|
Rice test_rice_array2[3] = {
|
||||||
Rice(flatbuffers::make_span(test_char_array4), 2),
|
Rice(flatbuffers::make_span(test_char_array4), 2),
|
||||||
Rice(flatbuffers::make_span(test_char_array5), 1),
|
Rice(flatbuffers::make_span(test_char_array5), 1),
|
||||||
Rice(flatbuffers::make_span(test_char_array6), 2)
|
Rice(flatbuffers::make_span(test_char_array6), 2)};
|
||||||
};
|
|
||||||
Rice test_rice_array3[3] = {
|
Rice test_rice_array3[3] = {
|
||||||
Rice(flatbuffers::make_span(test_char_array4), 2),
|
Rice(flatbuffers::make_span(test_char_array4), 2),
|
||||||
Rice(flatbuffers::make_span(test_char_array6), 1),
|
Rice(flatbuffers::make_span(test_char_array6), 1),
|
||||||
Rice(flatbuffers::make_span(test_char_array1), 2)
|
Rice(flatbuffers::make_span(test_char_array1), 2)};
|
||||||
};
|
|
||||||
|
|
||||||
grains.push_back(Grain(flatbuffers::make_span(test_rice_array1), 3));
|
grains.push_back(Grain(flatbuffers::make_span(test_rice_array1), 3));
|
||||||
grains.push_back(Grain(flatbuffers::make_span(test_rice_array2), 1));
|
grains.push_back(Grain(flatbuffers::make_span(test_rice_array2), 1));
|
||||||
@@ -196,7 +193,7 @@ void FixedSizedStructArrayKeyInStructTest() {
|
|||||||
|
|
||||||
auto orc = foo_builder.Finish();
|
auto orc = foo_builder.Finish();
|
||||||
fbb.Finish(orc);
|
fbb.Finish(orc);
|
||||||
uint8_t *buf = fbb.GetBufferPointer();
|
uint8_t* buf = fbb.GetBufferPointer();
|
||||||
auto foo_table = GetFooTable(buf);
|
auto foo_table = GetFooTable(buf);
|
||||||
|
|
||||||
auto sorted_grain_vec = foo_table->h();
|
auto sorted_grain_vec = foo_table->h();
|
||||||
@@ -207,13 +204,12 @@ void FixedSizedStructArrayKeyInStructTest() {
|
|||||||
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array1))
|
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array1))
|
||||||
->tag(),
|
->tag(),
|
||||||
3);
|
3);
|
||||||
Rice test_rice_array[3] = { Rice(flatbuffers::make_span(test_char_array3), 2),
|
Rice test_rice_array[3] = {Rice(flatbuffers::make_span(test_char_array3), 2),
|
||||||
Rice(flatbuffers::make_span(test_char_array2), 1),
|
Rice(flatbuffers::make_span(test_char_array2), 1),
|
||||||
Rice(flatbuffers::make_span(test_char_array1),
|
Rice(flatbuffers::make_span(test_char_array1), 2)};
|
||||||
2) };
|
|
||||||
TEST_EQ(
|
TEST_EQ(
|
||||||
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array)),
|
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array)),
|
||||||
static_cast<const Grain *>(nullptr));
|
static_cast<const Grain*>(nullptr));
|
||||||
TEST_EQ(
|
TEST_EQ(
|
||||||
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array1))
|
sorted_grain_vec->LookupByKey(&flatbuffers::CastToArray(test_rice_array1))
|
||||||
->tag(),
|
->tag(),
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ static const auto infinity_d = std::numeric_limits<double>::infinity();
|
|||||||
using namespace MyGame::Example;
|
using namespace MyGame::Example;
|
||||||
|
|
||||||
// example of how to build up a serialized buffer algorithmically:
|
// example of how to build up a serialized buffer algorithmically:
|
||||||
flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string& buffer) {
|
||||||
flatbuffers::FlatBufferBuilder builder;
|
flatbuffers::FlatBufferBuilder builder;
|
||||||
|
|
||||||
auto vec = Vec3(1, 2, 3, 0, Color_Red, Test(10, 20));
|
auto vec = Vec3(1, 2, 3, 0, Color_Red, Test(10, 20));
|
||||||
@@ -33,7 +33,7 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
|
|
||||||
// Use the initializer_list specialization of CreateVector.
|
// Use the initializer_list specialization of CreateVector.
|
||||||
auto inventory =
|
auto inventory =
|
||||||
builder.CreateVector<uint8_t>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 });
|
builder.CreateVector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||||
|
|
||||||
// Alternatively, create the vector first, and fill in data later:
|
// Alternatively, create the vector first, and fill in data later:
|
||||||
// unsigned char *inv_buf = nullptr;
|
// unsigned char *inv_buf = nullptr;
|
||||||
@@ -41,12 +41,12 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
// 10, &inv_buf);
|
// 10, &inv_buf);
|
||||||
// memcpy(inv_buf, inv_data, 10);
|
// memcpy(inv_buf, inv_data, 10);
|
||||||
|
|
||||||
Test tests[] = { Test(10, 20), Test(30, 40) };
|
Test tests[] = {Test(10, 20), Test(30, 40)};
|
||||||
auto testv = builder.CreateVectorOfStructs(tests, 2);
|
auto testv = builder.CreateVectorOfStructs(tests, 2);
|
||||||
|
|
||||||
// Create a vector of structures from a lambda.
|
// Create a vector of structures from a lambda.
|
||||||
auto testv2 = builder.CreateVectorOfStructs<Test>(
|
auto testv2 = builder.CreateVectorOfStructs<Test>(
|
||||||
2, [&](size_t i, Test *s) -> void { *s = tests[i]; });
|
2, [&](size_t i, Test* s) -> void { *s = tests[i]; });
|
||||||
|
|
||||||
// create monster with very few fields set:
|
// create monster with very few fields set:
|
||||||
// (same functionality as CreateMonster below, but sets fields manually)
|
// (same functionality as CreateMonster below, but sets fields manually)
|
||||||
@@ -69,9 +69,9 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
auto vecofstrings =
|
auto vecofstrings =
|
||||||
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(
|
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(
|
||||||
4,
|
4,
|
||||||
[](size_t i, flatbuffers::FlatBufferBuilder *b)
|
[](size_t i, flatbuffers::FlatBufferBuilder* b)
|
||||||
-> flatbuffers::Offset<flatbuffers::String> {
|
-> flatbuffers::Offset<flatbuffers::String> {
|
||||||
static const char *names[] = { "bob", "fred", "bob", "fred" };
|
static const char* names[] = {"bob", "fred", "bob", "fred"};
|
||||||
return b->CreateSharedString(names[i]);
|
return b->CreateSharedString(names[i]);
|
||||||
},
|
},
|
||||||
&builder);
|
&builder);
|
||||||
@@ -83,7 +83,7 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
auto vecofstrings2 = builder.CreateVectorOfStrings(names2);
|
auto vecofstrings2 = builder.CreateVectorOfStrings(names2);
|
||||||
|
|
||||||
// Creating vectors from types that are different from std::string
|
// Creating vectors from types that are different from std::string
|
||||||
std::vector<const char *> names3;
|
std::vector<const char*> names3;
|
||||||
names3.push_back("foo");
|
names3.push_back("foo");
|
||||||
names3.push_back("bar");
|
names3.push_back("bar");
|
||||||
builder.CreateVectorOfStrings(names3); // Also an accepted type
|
builder.CreateVectorOfStrings(names3); // Also an accepted type
|
||||||
@@ -96,11 +96,13 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Make sure the template deduces an initializer as std::vector<std::string>
|
// Make sure the template deduces an initializer as std::vector<std::string>
|
||||||
builder.CreateVectorOfStrings({ "hello", "world" });
|
builder.CreateVectorOfStrings({"hello", "world"});
|
||||||
|
|
||||||
// Create many vectors of strings
|
// Create many vectors of strings
|
||||||
std::vector<std::string> manyNames;
|
std::vector<std::string> manyNames;
|
||||||
for (auto i = 0; i < 100; i++) { manyNames.push_back("john_doe"); }
|
for (auto i = 0; i < 100; i++) {
|
||||||
|
manyNames.push_back("john_doe");
|
||||||
|
}
|
||||||
auto manyNamesVec = builder.CreateVectorOfStrings(manyNames);
|
auto manyNamesVec = builder.CreateVectorOfStrings(manyNames);
|
||||||
TEST_EQ(false, manyNamesVec.IsNull());
|
TEST_EQ(false, manyNamesVec.IsNull());
|
||||||
auto manyNamesVec2 =
|
auto manyNamesVec2 =
|
||||||
@@ -155,7 +157,7 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
flexbuild.Finish();
|
flexbuild.Finish();
|
||||||
auto flex = builder.CreateVector(flexbuild.GetBuffer());
|
auto flex = builder.CreateVector(flexbuild.GetBuffer());
|
||||||
// Test vector of enums.
|
// Test vector of enums.
|
||||||
Color colors[] = { Color_Blue, Color_Green };
|
Color colors[] = {Color_Blue, Color_Green};
|
||||||
// We use this special creation function because we have an array of
|
// We use this special creation function because we have an array of
|
||||||
// pre-C++11 (enum class) enums whose size likely is int, yet its declared
|
// pre-C++11 (enum class) enums whose size likely is int, yet its declared
|
||||||
// type in the schema is byte.
|
// type in the schema is byte.
|
||||||
@@ -184,14 +186,14 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
|
|
||||||
// return the buffer for the caller to use.
|
// return the buffer for the caller to use.
|
||||||
auto bufferpointer =
|
auto bufferpointer =
|
||||||
reinterpret_cast<const char *>(builder.GetBufferPointer());
|
reinterpret_cast<const char*>(builder.GetBufferPointer());
|
||||||
buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
|
buffer.assign(bufferpointer, bufferpointer + builder.GetSize());
|
||||||
|
|
||||||
return builder.Release();
|
return builder.Release();
|
||||||
}
|
}
|
||||||
|
|
||||||
// example of accessing a buffer loaded in memory:
|
// example of accessing a buffer loaded in memory:
|
||||||
void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
|
void AccessFlatBufferTest(const uint8_t* flatbuf, size_t length, bool pooled) {
|
||||||
// First, verify the buffers integrity (optional)
|
// First, verify the buffers integrity (optional)
|
||||||
flatbuffers::Verifier verifier(flatbuf, length);
|
flatbuffers::Verifier verifier(flatbuf, length);
|
||||||
std::vector<uint8_t> flex_reuse_tracker;
|
std::vector<uint8_t> flex_reuse_tracker;
|
||||||
@@ -238,7 +240,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
|
|||||||
auto inventory = monster->inventory();
|
auto inventory = monster->inventory();
|
||||||
TEST_EQ(VectorLength(inventory), 10UL); // Works even if inventory is null.
|
TEST_EQ(VectorLength(inventory), 10UL); // Works even if inventory is null.
|
||||||
TEST_NOTNULL(inventory);
|
TEST_NOTNULL(inventory);
|
||||||
unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
unsigned char inv_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
// Check compatibilty of iterators with STL.
|
// Check compatibilty of iterators with STL.
|
||||||
std::vector<unsigned char> inv_vec(inventory->begin(), inventory->end());
|
std::vector<unsigned char> inv_vec(inventory->begin(), inventory->end());
|
||||||
size_t n = 0;
|
size_t n = 0;
|
||||||
@@ -277,7 +279,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
|
|||||||
|
|
||||||
// Example of accessing a union:
|
// Example of accessing a union:
|
||||||
TEST_EQ(monster->test_type(), Any_Monster); // First make sure which it is.
|
TEST_EQ(monster->test_type(), Any_Monster); // First make sure which it is.
|
||||||
auto monster2 = reinterpret_cast<const Monster *>(monster->test());
|
auto monster2 = reinterpret_cast<const Monster*>(monster->test());
|
||||||
TEST_NOTNULL(monster2);
|
TEST_NOTNULL(monster2);
|
||||||
TEST_EQ_STR(monster2->name()->c_str(), "Fred");
|
TEST_EQ_STR(monster2->name()->c_str(), "Fred");
|
||||||
|
|
||||||
@@ -350,8 +352,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
|
|||||||
}
|
}
|
||||||
TEST_NOTNULL(vecofstructs->LookupByKey(0)); // test default value
|
TEST_NOTNULL(vecofstructs->LookupByKey(0)); // test default value
|
||||||
TEST_NOTNULL(vecofstructs->LookupByKey(3));
|
TEST_NOTNULL(vecofstructs->LookupByKey(3));
|
||||||
TEST_EQ(static_cast<const Ability *>(nullptr),
|
TEST_EQ(static_cast<const Ability*>(nullptr), vecofstructs->LookupByKey(5));
|
||||||
vecofstructs->LookupByKey(5));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto vec_of_stat = monster->scalar_key_sorted_tables()) {
|
if (auto vec_of_stat = monster->scalar_key_sorted_tables()) {
|
||||||
@@ -394,7 +395,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
|
|||||||
TEST_EQ(flatbuffers::AlignOf<Test>(), 2UL);
|
TEST_EQ(flatbuffers::AlignOf<Test>(), 2UL);
|
||||||
TEST_EQ(sizeof(Test), 4UL);
|
TEST_EQ(sizeof(Test), 4UL);
|
||||||
|
|
||||||
const flatbuffers::Vector<const Test *> *tests_array[] = {
|
const flatbuffers::Vector<const Test*>* tests_array[] = {
|
||||||
monster->test4(),
|
monster->test4(),
|
||||||
monster->test5(),
|
monster->test5(),
|
||||||
};
|
};
|
||||||
@@ -421,7 +422,7 @@ void AccessFlatBufferTest(const uint8_t *flatbuf, size_t length, bool pooled) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Change a FlatBuffer in-place, after it has been constructed.
|
// Change a FlatBuffer in-place, after it has been constructed.
|
||||||
void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
|
void MutateFlatBuffersTest(uint8_t* flatbuf, std::size_t length) {
|
||||||
// Get non-const pointer to root.
|
// Get non-const pointer to root.
|
||||||
auto monster = GetMutableMonster(flatbuf);
|
auto monster = GetMutableMonster(flatbuf);
|
||||||
|
|
||||||
@@ -451,7 +452,7 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
|
|||||||
|
|
||||||
// Mutate structs.
|
// Mutate structs.
|
||||||
auto pos = monster->mutable_pos();
|
auto pos = monster->mutable_pos();
|
||||||
auto &test3 = pos->mutable_test3(); // Struct inside a struct.
|
auto& test3 = pos->mutable_test3(); // Struct inside a struct.
|
||||||
test3.mutate_a(50); // Struct fields never fail.
|
test3.mutate_a(50); // Struct fields never fail.
|
||||||
TEST_EQ(test3.a(), 50);
|
TEST_EQ(test3.a(), 50);
|
||||||
test3.mutate_a(10);
|
test3.mutate_a(10);
|
||||||
@@ -480,7 +481,7 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
|
|||||||
|
|
||||||
// Mutate via LookupByKey
|
// Mutate via LookupByKey
|
||||||
TEST_NOTNULL(tables->MutableLookupByKey("Barney"));
|
TEST_NOTNULL(tables->MutableLookupByKey("Barney"));
|
||||||
TEST_EQ(static_cast<Monster *>(nullptr),
|
TEST_EQ(static_cast<Monster*>(nullptr),
|
||||||
tables->MutableLookupByKey("DoesntExist"));
|
tables->MutableLookupByKey("DoesntExist"));
|
||||||
TEST_EQ(tables->MutableLookupByKey("Barney")->hp(), 1000);
|
TEST_EQ(tables->MutableLookupByKey("Barney")->hp(), 1000);
|
||||||
TEST_EQ(tables->MutableLookupByKey("Barney")->mutate_hp(0), true);
|
TEST_EQ(tables->MutableLookupByKey("Barney")->mutate_hp(0), true);
|
||||||
@@ -493,18 +494,18 @@ void MutateFlatBuffersTest(uint8_t *flatbuf, std::size_t length) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Unpack a FlatBuffer into objects.
|
// Unpack a FlatBuffer into objects.
|
||||||
void ObjectFlatBuffersTest(uint8_t *flatbuf) {
|
void ObjectFlatBuffersTest(uint8_t* flatbuf) {
|
||||||
// Optional: we can specify resolver and rehasher functions to turn hashed
|
// Optional: we can specify resolver and rehasher functions to turn hashed
|
||||||
// strings into object pointers and back, to implement remote references
|
// strings into object pointers and back, to implement remote references
|
||||||
// and such.
|
// and such.
|
||||||
auto resolver = flatbuffers::resolver_function_t(
|
auto resolver = flatbuffers::resolver_function_t(
|
||||||
[](void **pointer_adr, flatbuffers::hash_value_t hash) {
|
[](void** pointer_adr, flatbuffers::hash_value_t hash) {
|
||||||
(void)pointer_adr;
|
(void)pointer_adr;
|
||||||
(void)hash;
|
(void)hash;
|
||||||
// Don't actually do anything, leave variable null.
|
// Don't actually do anything, leave variable null.
|
||||||
});
|
});
|
||||||
auto rehasher = flatbuffers::rehasher_function_t(
|
auto rehasher = flatbuffers::rehasher_function_t(
|
||||||
[](void *pointer) -> flatbuffers::hash_value_t {
|
[](void* pointer) -> flatbuffers::hash_value_t {
|
||||||
(void)pointer;
|
(void)pointer;
|
||||||
return 0;
|
return 0;
|
||||||
});
|
});
|
||||||
@@ -549,20 +550,20 @@ void ObjectFlatBuffersTest(uint8_t *flatbuf) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Utility function to check a Monster object.
|
// Utility function to check a Monster object.
|
||||||
void CheckMonsterObject(MonsterT *monster2) {
|
void CheckMonsterObject(MonsterT* monster2) {
|
||||||
TEST_EQ(monster2->hp, 80);
|
TEST_EQ(monster2->hp, 80);
|
||||||
TEST_EQ(monster2->mana, 150); // default
|
TEST_EQ(monster2->mana, 150); // default
|
||||||
TEST_EQ_STR(monster2->name.c_str(), "MyMonster");
|
TEST_EQ_STR(monster2->name.c_str(), "MyMonster");
|
||||||
|
|
||||||
auto &pos = monster2->pos;
|
auto& pos = monster2->pos;
|
||||||
TEST_NOTNULL(pos);
|
TEST_NOTNULL(pos);
|
||||||
TEST_EQ(pos->z(), 3);
|
TEST_EQ(pos->z(), 3);
|
||||||
TEST_EQ(pos->test3().a(), 10);
|
TEST_EQ(pos->test3().a(), 10);
|
||||||
TEST_EQ(pos->test3().b(), 20);
|
TEST_EQ(pos->test3().b(), 20);
|
||||||
|
|
||||||
auto &inventory = monster2->inventory;
|
auto& inventory = monster2->inventory;
|
||||||
TEST_EQ(inventory.size(), 10UL);
|
TEST_EQ(inventory.size(), 10UL);
|
||||||
unsigned char inv_data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
unsigned char inv_data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
for (auto it = inventory.begin(); it != inventory.end(); ++it)
|
for (auto it = inventory.begin(); it != inventory.end(); ++it)
|
||||||
TEST_EQ(*it, inv_data[it - inventory.begin()]);
|
TEST_EQ(*it, inv_data[it - inventory.begin()]);
|
||||||
|
|
||||||
@@ -572,24 +573,24 @@ void CheckMonsterObject(MonsterT *monster2) {
|
|||||||
TEST_NOTNULL(monster3);
|
TEST_NOTNULL(monster3);
|
||||||
TEST_EQ_STR(monster3->name.c_str(), "Fred");
|
TEST_EQ_STR(monster3->name.c_str(), "Fred");
|
||||||
|
|
||||||
auto &vecofstrings = monster2->testarrayofstring;
|
auto& vecofstrings = monster2->testarrayofstring;
|
||||||
TEST_EQ(vecofstrings.size(), 4U);
|
TEST_EQ(vecofstrings.size(), 4U);
|
||||||
TEST_EQ_STR(vecofstrings[0].c_str(), "bob");
|
TEST_EQ_STR(vecofstrings[0].c_str(), "bob");
|
||||||
TEST_EQ_STR(vecofstrings[1].c_str(), "fred");
|
TEST_EQ_STR(vecofstrings[1].c_str(), "fred");
|
||||||
|
|
||||||
auto &vecofstrings2 = monster2->testarrayofstring2;
|
auto& vecofstrings2 = monster2->testarrayofstring2;
|
||||||
TEST_EQ(vecofstrings2.size(), 2U);
|
TEST_EQ(vecofstrings2.size(), 2U);
|
||||||
TEST_EQ_STR(vecofstrings2[0].c_str(), "jane");
|
TEST_EQ_STR(vecofstrings2[0].c_str(), "jane");
|
||||||
TEST_EQ_STR(vecofstrings2[1].c_str(), "mary");
|
TEST_EQ_STR(vecofstrings2[1].c_str(), "mary");
|
||||||
|
|
||||||
auto &vecoftables = monster2->testarrayoftables;
|
auto& vecoftables = monster2->testarrayoftables;
|
||||||
TEST_EQ(vecoftables.size(), 3U);
|
TEST_EQ(vecoftables.size(), 3U);
|
||||||
TEST_EQ_STR(vecoftables[0]->name.c_str(), "Barney");
|
TEST_EQ_STR(vecoftables[0]->name.c_str(), "Barney");
|
||||||
TEST_EQ(vecoftables[0]->hp, 1000);
|
TEST_EQ(vecoftables[0]->hp, 1000);
|
||||||
TEST_EQ_STR(vecoftables[1]->name.c_str(), "Fred");
|
TEST_EQ_STR(vecoftables[1]->name.c_str(), "Fred");
|
||||||
TEST_EQ_STR(vecoftables[2]->name.c_str(), "Wilma");
|
TEST_EQ_STR(vecoftables[2]->name.c_str(), "Wilma");
|
||||||
|
|
||||||
auto &tests = monster2->test4;
|
auto& tests = monster2->test4;
|
||||||
TEST_EQ(tests[0].a(), 10);
|
TEST_EQ(tests[0].a(), 10);
|
||||||
TEST_EQ(tests[0].b(), 20);
|
TEST_EQ(tests[0].b(), 20);
|
||||||
TEST_EQ(tests[1].a(), 30);
|
TEST_EQ(tests[1].a(), 30);
|
||||||
@@ -634,7 +635,7 @@ void SizePrefixedTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestMonsterExtraFloats(const std::string &tests_data_path) {
|
void TestMonsterExtraFloats(const std::string& tests_data_path) {
|
||||||
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
||||||
TEST_EQ(is_quiet_nan(1.0), false);
|
TEST_EQ(is_quiet_nan(1.0), false);
|
||||||
TEST_EQ(is_quiet_nan(infinity_d), false);
|
TEST_EQ(is_quiet_nan(infinity_d), false);
|
||||||
@@ -652,8 +653,8 @@ void TestMonsterExtraFloats(const std::string &tests_data_path) {
|
|||||||
// Parse schema first, so we can use it to parse the data after.
|
// Parse schema first, so we can use it to parse the data after.
|
||||||
Parser parser;
|
Parser parser;
|
||||||
auto include_test_path = ConCatPathFileName(tests_data_path, "include_test");
|
auto include_test_path = ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
|
||||||
// Create empty extra and store to json.
|
// Create empty extra and store to json.
|
||||||
parser.opts.output_default_scalars_in_json = true;
|
parser.opts.output_default_scalars_in_json = true;
|
||||||
@@ -774,7 +775,7 @@ void TypeAliasesTest() {
|
|||||||
|
|
||||||
// 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(const std::string &tests_data_path, bool binary) {
|
void ParseAndGenerateTextTest(const std::string& tests_data_path, bool binary) {
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
std::string jsonfile;
|
std::string jsonfile;
|
||||||
@@ -790,19 +791,19 @@ void ParseAndGenerateTextTest(const std::string &tests_data_path, bool binary) {
|
|||||||
|
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
|
|
||||||
// parse schema first, so we can use it to parse the data after
|
// parse schema first, so we can use it to parse the data after
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
if (binary) {
|
if (binary) {
|
||||||
flatbuffers::Verifier verifier(
|
flatbuffers::Verifier verifier(
|
||||||
reinterpret_cast<const uint8_t *>(schemafile.c_str()),
|
reinterpret_cast<const uint8_t*>(schemafile.c_str()),
|
||||||
schemafile.size());
|
schemafile.size());
|
||||||
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
||||||
// auto schema = reflection::GetSchema(schemafile.c_str());
|
// auto schema = reflection::GetSchema(schemafile.c_str());
|
||||||
TEST_EQ(parser.Deserialize(
|
TEST_EQ(
|
||||||
reinterpret_cast<const uint8_t *>(schemafile.c_str()),
|
parser.Deserialize(reinterpret_cast<const uint8_t*>(schemafile.c_str()),
|
||||||
schemafile.size()),
|
schemafile.size()),
|
||||||
true);
|
true);
|
||||||
} else {
|
} else {
|
||||||
@@ -866,14 +867,14 @@ void ParseAndGenerateTextTest(const std::string &tests_data_path, bool binary) {
|
|||||||
TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
|
TEST_EQ_STR(jsongen_utf8.c_str(), jsonfile_utf8.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnPackTo(const uint8_t *flatbuf) {
|
void UnPackTo(const uint8_t* flatbuf) {
|
||||||
// Get a monster that has a name and no enemy
|
// Get a monster that has a name and no enemy
|
||||||
auto orig_monster = GetMonster(flatbuf);
|
auto orig_monster = GetMonster(flatbuf);
|
||||||
TEST_EQ_STR(orig_monster->name()->c_str(), "MyMonster");
|
TEST_EQ_STR(orig_monster->name()->c_str(), "MyMonster");
|
||||||
TEST_ASSERT(orig_monster->enemy() == nullptr);
|
TEST_ASSERT(orig_monster->enemy() == nullptr);
|
||||||
|
|
||||||
// Create an enemy
|
// Create an enemy
|
||||||
MonsterT *enemy = new MonsterT();
|
MonsterT* enemy = new MonsterT();
|
||||||
enemy->name = "Enemy";
|
enemy->name = "Enemy";
|
||||||
|
|
||||||
// And create another monster owning the enemy,
|
// And create another monster owning the enemy,
|
||||||
|
|||||||
@@ -3,19 +3,19 @@
|
|||||||
#include "native_type_test_generated.h"
|
#include "native_type_test_generated.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
Geometry::Vector3D Pack(const Native::Vector3D &obj) {
|
Geometry::Vector3D Pack(const Native::Vector3D& obj) {
|
||||||
return Geometry::Vector3D(obj.x, obj.y, obj.z);
|
return Geometry::Vector3D(obj.x, obj.y, obj.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
|
const Native::Vector3D UnPack(const Geometry::Vector3D& obj) {
|
||||||
return Native::Vector3D(obj.x(), obj.y(), obj.z());
|
return Native::Vector3D(obj.x(), obj.y(), obj.z());
|
||||||
}
|
}
|
||||||
|
|
||||||
Geometry::Vector3DAlt PackVector3DAlt(const Native::Vector3D &obj) {
|
Geometry::Vector3DAlt PackVector3DAlt(const Native::Vector3D& obj) {
|
||||||
return Geometry::Vector3DAlt(obj.x, obj.y, obj.z);
|
return Geometry::Vector3DAlt(obj.x, obj.y, obj.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt &obj) {
|
const Native::Vector3D UnPackVector3DAlt(const Geometry::Vector3DAlt& obj) {
|
||||||
return Native::Vector3D(obj.a(), obj.b(), obj.c());
|
return Native::Vector3D(obj.a(), obj.b(), obj.c());
|
||||||
}
|
}
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ void OptionalScalarsTest() {
|
|||||||
const bool has_null = schema->find("null") != std::string::npos;
|
const bool has_null = schema->find("null") != std::string::npos;
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
TEST_ASSERT(parser.Parse(schema->c_str()));
|
TEST_ASSERT(parser.Parse(schema->c_str()));
|
||||||
const auto *mana = parser.structs_.Lookup("Monster")->fields.Lookup("mana");
|
const auto* mana = parser.structs_.Lookup("Monster")->fields.Lookup("mana");
|
||||||
TEST_EQ(mana->IsOptional(), has_null);
|
TEST_EQ(mana->IsOptional(), has_null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,9 @@ static const auto infinity_f = std::numeric_limits<float>::infinity();
|
|||||||
static const auto infinity_d = std::numeric_limits<double>::infinity();
|
static const auto infinity_d = std::numeric_limits<double>::infinity();
|
||||||
|
|
||||||
// Test that parser errors are actually generated.
|
// Test that parser errors are actually generated.
|
||||||
static void TestError_(const char *src, const char *error_substr,
|
static void TestError_(const char* src, const char* error_substr,
|
||||||
bool strict_json, const char *file, int line,
|
bool strict_json, const char* file, int line,
|
||||||
const char *func) {
|
const char* func) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.strict_json = strict_json;
|
opts.strict_json = strict_json;
|
||||||
flatbuffers::Parser parser(opts);
|
flatbuffers::Parser parser(opts);
|
||||||
@@ -33,16 +33,16 @@ static void TestError_(const char *src, const char *error_substr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void TestError_(const char *src, const char *error_substr,
|
static void TestError_(const char* src, const char* error_substr,
|
||||||
const char *file, int line, const char *func) {
|
const char* file, int line, const char* func) {
|
||||||
TestError_(src, error_substr, false, file, line, func);
|
TestError_(src, error_substr, false, file, line, func);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
# define TestError(src, ...) \
|
#define TestError(src, ...) \
|
||||||
TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
|
TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __FUNCTION__)
|
||||||
#else
|
#else
|
||||||
# define TestError(src, ...) \
|
#define TestError(src, ...) \
|
||||||
TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __PRETTY_FUNCTION__)
|
TestError_(src, __VA_ARGS__, __FILE__, __LINE__, __PRETTY_FUNCTION__)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -462,13 +462,15 @@ void InvalidUTF8Test() {
|
|||||||
TestError(locale_ident.c_str(), "");
|
TestError(locale_ident.c_str(), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
T TestValue(const char *json, const char *type_name,
|
T TestValue(const char* json, const char* type_name,
|
||||||
const char *decls = nullptr) {
|
const char* decls = nullptr) {
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
parser.builder_.ForceDefaults(true); // return defaults
|
parser.builder_.ForceDefaults(true); // return defaults
|
||||||
auto check_default = json ? false : true;
|
auto check_default = json ? false : true;
|
||||||
if (check_default) { parser.opts.output_default_scalars_in_json = true; }
|
if (check_default) {
|
||||||
|
parser.opts.output_default_scalars_in_json = true;
|
||||||
|
}
|
||||||
// Simple schema.
|
// Simple schema.
|
||||||
std::string schema = std::string(decls ? decls : "") + "\n" +
|
std::string schema = std::string(decls ? decls : "") + "\n" +
|
||||||
"table X { y:" + std::string(type_name) +
|
"table X { y:" + std::string(type_name) +
|
||||||
@@ -486,7 +488,9 @@ T TestValue(const char *json, const char *type_name,
|
|||||||
parser.opts.indent_step = -1;
|
parser.opts.indent_step = -1;
|
||||||
TEST_NULL(GenText(parser, parser.builder_.GetBufferPointer(), &print_back));
|
TEST_NULL(GenText(parser, parser.builder_.GetBufferPointer(), &print_back));
|
||||||
// restore value from its default
|
// restore value from its default
|
||||||
if (check_default) { TEST_EQ(parser.Parse(print_back.c_str()), true); }
|
if (check_default) {
|
||||||
|
TEST_EQ(parser.Parse(print_back.c_str()), true);
|
||||||
|
}
|
||||||
|
|
||||||
auto root = flatbuffers::GetRoot<flatbuffers::Table>(
|
auto root = flatbuffers::GetRoot<flatbuffers::Table>(
|
||||||
parser.builder_.GetBufferPointer());
|
parser.builder_.GetBufferPointer());
|
||||||
@@ -796,7 +800,7 @@ void UnicodeSurrogatesTest() {
|
|||||||
true);
|
true);
|
||||||
auto root = flatbuffers::GetRoot<flatbuffers::Table>(
|
auto root = flatbuffers::GetRoot<flatbuffers::Table>(
|
||||||
parser.builder_.GetBufferPointer());
|
parser.builder_.GetBufferPointer());
|
||||||
auto string = root->GetPointer<flatbuffers::String *>(
|
auto string = root->GetPointer<flatbuffers::String*>(
|
||||||
flatbuffers::FieldIndexToOffset(0));
|
flatbuffers::FieldIndexToOffset(0));
|
||||||
TEST_EQ_STR(string->c_str(), "\xF0\x9F\x92\xA9");
|
TEST_EQ_STR(string->c_str(), "\xF0\x9F\x92\xA9");
|
||||||
}
|
}
|
||||||
@@ -843,9 +847,12 @@ void ParseUnionTest() {
|
|||||||
true);
|
true);
|
||||||
|
|
||||||
// Test union underlying type
|
// Test union underlying type
|
||||||
const char *source = "table A {} table B {} union U : int {A, B} table C {test_union: U; test_vector_of_union: [U];}";
|
const char* source =
|
||||||
|
"table A {} table B {} union U : int {A, B} table C {test_union: U; "
|
||||||
|
"test_vector_of_union: [U];}";
|
||||||
flatbuffers::Parser parser3;
|
flatbuffers::Parser parser3;
|
||||||
parser3.opts.lang_to_generate = flatbuffers::IDLOptions::kCpp | flatbuffers::IDLOptions::kTs;
|
parser3.opts.lang_to_generate =
|
||||||
|
flatbuffers::IDLOptions::kCpp | flatbuffers::IDLOptions::kTs;
|
||||||
TEST_EQ(parser3.Parse(source), true);
|
TEST_EQ(parser3.Parse(source), true);
|
||||||
|
|
||||||
parser3.opts.lang_to_generate &= flatbuffers::IDLOptions::kJava;
|
parser3.opts.lang_to_generate &= flatbuffers::IDLOptions::kJava;
|
||||||
@@ -898,7 +905,7 @@ void StringVectorDefaultsTest() {
|
|||||||
for (auto s = schemas.begin(); s < schemas.end(); s++) {
|
for (auto s = schemas.begin(); s < schemas.end(); s++) {
|
||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
TEST_ASSERT(parser.Parse(s->c_str()));
|
TEST_ASSERT(parser.Parse(s->c_str()));
|
||||||
const auto *mana = parser.structs_.Lookup("Monster")->fields.Lookup("mana");
|
const auto* mana = parser.structs_.Lookup("Monster")->fields.Lookup("mana");
|
||||||
TEST_EQ(mana->IsDefault(), true);
|
TEST_EQ(mana->IsDefault(), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,10 +7,10 @@
|
|||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace tests {
|
namespace tests {
|
||||||
|
|
||||||
void RunTest(const flatbuffers::IDLOptions &opts, const std::string &proto_path,
|
void RunTest(const flatbuffers::IDLOptions& opts, const std::string& proto_path,
|
||||||
const std::string &proto_file, const std::string &golden_file,
|
const std::string& proto_file, const std::string& golden_file,
|
||||||
const std::string import_proto_file) {
|
const std::string import_proto_file) {
|
||||||
const char *include_directories[] = { proto_path.c_str(), nullptr };
|
const char* include_directories[] = {proto_path.c_str(), nullptr};
|
||||||
|
|
||||||
// Parse proto.
|
// Parse proto.
|
||||||
flatbuffers::Parser parser(opts);
|
flatbuffers::Parser parser(opts);
|
||||||
@@ -48,7 +48,7 @@ void RunTest(const flatbuffers::IDLOptions &opts, const std::string &proto_path,
|
|||||||
TEST_EQ_STR(fbs.c_str(), golden_file.c_str());
|
TEST_EQ_STR(fbs.c_str(), golden_file.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test(const std::string &proto_path, const std::string &proto_file) {
|
void proto_test(const std::string& proto_path, const std::string& proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -63,8 +63,8 @@ void proto_test(const std::string &proto_path, const std::string &proto_file) {
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file);
|
RunTest(opts, proto_path, proto_file, golden_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_id(const std::string &proto_path,
|
void proto_test_id(const std::string& proto_path,
|
||||||
const std::string &proto_file) {
|
const std::string& proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -80,8 +80,8 @@ void proto_test_id(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file);
|
RunTest(opts, proto_path, proto_file, golden_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_union(const std::string &proto_path,
|
void proto_test_union(const std::string& proto_path,
|
||||||
const std::string &proto_file) {
|
const std::string& proto_file) {
|
||||||
// Parse proto with --oneof-union option.
|
// Parse proto with --oneof-union option.
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
@@ -96,8 +96,8 @@ void proto_test_union(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file);
|
RunTest(opts, proto_path, proto_file, golden_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_union_id(const std::string &proto_path,
|
void proto_test_union_id(const std::string& proto_path,
|
||||||
const std::string &proto_file) {
|
const std::string& proto_file) {
|
||||||
// Parse proto with --oneof-union option.
|
// Parse proto with --oneof-union option.
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
@@ -114,8 +114,8 @@ void proto_test_union_id(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file);
|
RunTest(opts, proto_path, proto_file, golden_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_union_suffix(const std::string &proto_path,
|
void proto_test_union_suffix(const std::string& proto_path,
|
||||||
const std::string &proto_file) {
|
const std::string& proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -131,8 +131,8 @@ void proto_test_union_suffix(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file);
|
RunTest(opts, proto_path, proto_file, golden_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_union_suffix_id(const std::string &proto_path,
|
void proto_test_union_suffix_id(const std::string& proto_path,
|
||||||
const std::string &proto_file) {
|
const std::string& proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -149,9 +149,9 @@ void proto_test_union_suffix_id(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file);
|
RunTest(opts, proto_path, proto_file, golden_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_include(const std::string &proto_path,
|
void proto_test_include(const std::string& proto_path,
|
||||||
const std::string &proto_file,
|
const std::string& proto_file,
|
||||||
const std::string &import_proto_file) {
|
const std::string& import_proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = true;
|
opts.include_dependence_headers = true;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -166,9 +166,9 @@ void proto_test_include(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_include_id(const std::string &proto_path,
|
void proto_test_include_id(const std::string& proto_path,
|
||||||
const std::string &proto_file,
|
const std::string& proto_file,
|
||||||
const std::string &import_proto_file) {
|
const std::string& import_proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = true;
|
opts.include_dependence_headers = true;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -184,9 +184,9 @@ void proto_test_include_id(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_include_union(const std::string &proto_path,
|
void proto_test_include_union(const std::string& proto_path,
|
||||||
const std::string &proto_file,
|
const std::string& proto_file,
|
||||||
const std::string &import_proto_file) {
|
const std::string& import_proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = true;
|
opts.include_dependence_headers = true;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -202,9 +202,9 @@ void proto_test_include_union(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void proto_test_include_union_id(const std::string &proto_path,
|
void proto_test_include_union_id(const std::string& proto_path,
|
||||||
const std::string &proto_file,
|
const std::string& proto_file,
|
||||||
const std::string &import_proto_file) {
|
const std::string& import_proto_file) {
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = true;
|
opts.include_dependence_headers = true;
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
@@ -221,8 +221,8 @@ void proto_test_include_union_id(const std::string &proto_path,
|
|||||||
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
RunTest(opts, proto_path, proto_file, golden_file, import_proto_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseCorruptedProto(const std::string &proto_path) {
|
void ParseCorruptedProto(const std::string& proto_path) {
|
||||||
const char *include_directories[] = { proto_path.c_str(), nullptr };
|
const char* include_directories[] = {proto_path.c_str(), nullptr};
|
||||||
|
|
||||||
flatbuffers::IDLOptions opts;
|
flatbuffers::IDLOptions opts;
|
||||||
opts.include_dependence_headers = true;
|
opts.include_dependence_headers = true;
|
||||||
@@ -282,7 +282,7 @@ void ParseCorruptedProto(const std::string &proto_path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Parse a .proto schema, output as .fbs
|
// Parse a .proto schema, output as .fbs
|
||||||
void ParseProtoTest(const std::string &tests_data_path) {
|
void ParseProtoTest(const std::string& tests_data_path) {
|
||||||
auto proto_path = tests_data_path + "prototest/";
|
auto proto_path = tests_data_path + "prototest/";
|
||||||
std::string proto_file;
|
std::string proto_file;
|
||||||
TEST_EQ(
|
TEST_EQ(
|
||||||
@@ -325,8 +325,7 @@ void ParseProtoBufAsciiTest() {
|
|||||||
// Similarly, in text output, it should omit these.
|
// Similarly, in text output, it should omit these.
|
||||||
std::string text;
|
std::string text;
|
||||||
auto err =
|
auto err =
|
||||||
flatbuffers::GenText(
|
flatbuffers::GenText(parser, parser.builder_.GetBufferPointer(), &text);
|
||||||
parser, parser.builder_.GetBufferPointer(), &text);
|
|
||||||
TEST_NULL(err);
|
TEST_NULL(err);
|
||||||
TEST_EQ_STR(text.c_str(),
|
TEST_EQ_STR(text.c_str(),
|
||||||
"{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n");
|
"{\n A [\n 1\n 2\n ]\n C {\n B: 2\n }\n}\n");
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
#include "reflection_test.h"
|
#include "reflection_test.h"
|
||||||
|
|
||||||
#include "tests/arrays_test_generated.h"
|
|
||||||
#include "flatbuffers/minireflect.h"
|
#include "flatbuffers/minireflect.h"
|
||||||
#include "flatbuffers/reflection.h"
|
#include "flatbuffers/reflection.h"
|
||||||
#include "flatbuffers/reflection_generated.h"
|
#include "flatbuffers/reflection_generated.h"
|
||||||
@@ -8,13 +7,14 @@
|
|||||||
#include "monster_test.h"
|
#include "monster_test.h"
|
||||||
#include "monster_test_generated.h"
|
#include "monster_test_generated.h"
|
||||||
#include "test_assert.h"
|
#include "test_assert.h"
|
||||||
|
#include "tests/arrays_test_generated.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
namespace tests {
|
namespace tests {
|
||||||
|
|
||||||
using namespace MyGame::Example;
|
using namespace MyGame::Example;
|
||||||
|
|
||||||
void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
void ReflectionTest(const std::string& tests_data_path, uint8_t* flatbuf,
|
||||||
size_t length) {
|
size_t length) {
|
||||||
// Load a binary schema.
|
// Load a binary schema.
|
||||||
std::string bfbsfile;
|
std::string bfbsfile;
|
||||||
@@ -24,11 +24,11 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
|
|
||||||
// Verify it, just in case:
|
// Verify it, just in case:
|
||||||
flatbuffers::Verifier verifier(
|
flatbuffers::Verifier verifier(
|
||||||
reinterpret_cast<const uint8_t *>(bfbsfile.c_str()), bfbsfile.length());
|
reinterpret_cast<const uint8_t*>(bfbsfile.c_str()), bfbsfile.length());
|
||||||
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
||||||
|
|
||||||
// Make sure the schema is what we expect it to be.
|
// Make sure the schema is what we expect it to be.
|
||||||
auto &schema = *reflection::GetSchema(bfbsfile.c_str());
|
auto& schema = *reflection::GetSchema(bfbsfile.c_str());
|
||||||
auto root_table = schema.root_table();
|
auto root_table = schema.root_table();
|
||||||
|
|
||||||
// Check the declaration files.
|
// Check the declaration files.
|
||||||
@@ -83,7 +83,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
auto fields = root_table->fields();
|
auto fields = root_table->fields();
|
||||||
auto hp_field_ptr = fields->LookupByKey("hp");
|
auto hp_field_ptr = fields->LookupByKey("hp");
|
||||||
TEST_NOTNULL(hp_field_ptr);
|
TEST_NOTNULL(hp_field_ptr);
|
||||||
auto &hp_field = *hp_field_ptr;
|
auto& hp_field = *hp_field_ptr;
|
||||||
TEST_EQ_STR(hp_field.name()->c_str(), "hp");
|
TEST_EQ_STR(hp_field.name()->c_str(), "hp");
|
||||||
TEST_EQ(hp_field.id(), 2);
|
TEST_EQ(hp_field.id(), 2);
|
||||||
TEST_EQ(hp_field.type()->base_type(), reflection::Short);
|
TEST_EQ(hp_field.type()->base_type(), reflection::Short);
|
||||||
@@ -108,7 +108,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
TEST_EQ(fields->LookupByKey("name")->optional(), false);
|
TEST_EQ(fields->LookupByKey("name")->optional(), false);
|
||||||
|
|
||||||
// Now use it to dynamically access a buffer.
|
// Now use it to dynamically access a buffer.
|
||||||
auto &root = *flatbuffers::GetAnyRoot(flatbuf);
|
auto& root = *flatbuffers::GetAnyRoot(flatbuf);
|
||||||
|
|
||||||
// Verify the buffer first using reflection based verification
|
// Verify the buffer first using reflection based verification
|
||||||
TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length),
|
TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), flatbuf, length),
|
||||||
@@ -169,7 +169,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
// First we put the FlatBuffer inside an std::vector.
|
// First we put the FlatBuffer inside an std::vector.
|
||||||
std::vector<uint8_t> resizingbuf(flatbuf, flatbuf + length);
|
std::vector<uint8_t> resizingbuf(flatbuf, flatbuf + length);
|
||||||
// Find the field we want to modify.
|
// Find the field we want to modify.
|
||||||
auto &name_field = *fields->LookupByKey("name");
|
auto& name_field = *fields->LookupByKey("name");
|
||||||
// Get the root.
|
// Get the root.
|
||||||
// This time we wrap the result from GetAnyRoot in a smartpointer that
|
// This time we wrap the result from GetAnyRoot in a smartpointer that
|
||||||
// will keep rroot valid as resizingbuf resizes.
|
// will keep rroot valid as resizingbuf resizes.
|
||||||
@@ -180,7 +180,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
// Here resizingbuf has changed, but rroot is still valid.
|
// Here resizingbuf has changed, but rroot is still valid.
|
||||||
TEST_EQ_STR(GetFieldS(**rroot, name_field)->c_str(), "totally new string");
|
TEST_EQ_STR(GetFieldS(**rroot, name_field)->c_str(), "totally new string");
|
||||||
// Now lets extend a vector by 100 elements (10 -> 110).
|
// Now lets extend a vector by 100 elements (10 -> 110).
|
||||||
auto &inventory_field = *fields->LookupByKey("inventory");
|
auto& inventory_field = *fields->LookupByKey("inventory");
|
||||||
auto rinventory = flatbuffers::piv(
|
auto rinventory = flatbuffers::piv(
|
||||||
flatbuffers::GetFieldV<uint8_t>(**rroot, inventory_field), resizingbuf);
|
flatbuffers::GetFieldV<uint8_t>(**rroot, inventory_field), resizingbuf);
|
||||||
flatbuffers::ResizeVector<uint8_t>(schema, 110, 50, *rinventory,
|
flatbuffers::ResizeVector<uint8_t>(schema, 110, 50, *rinventory,
|
||||||
@@ -193,7 +193,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
// FlatBuffer of its own, then add that to an existing FlatBuffer:
|
// FlatBuffer of its own, then add that to an existing FlatBuffer:
|
||||||
// As an example, let's add a string to an array of strings.
|
// As an example, let's add a string to an array of strings.
|
||||||
// First, find our field:
|
// First, find our field:
|
||||||
auto &testarrayofstring_field = *fields->LookupByKey("testarrayofstring");
|
auto& testarrayofstring_field = *fields->LookupByKey("testarrayofstring");
|
||||||
// Find the vector value:
|
// Find the vector value:
|
||||||
auto rtestarrayofstring = flatbuffers::piv(
|
auto rtestarrayofstring = flatbuffers::piv(
|
||||||
flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
|
flatbuffers::GetFieldV<flatbuffers::Offset<flatbuffers::String>>(
|
||||||
@@ -218,8 +218,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
|
TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
|
||||||
// Test integrity of all resize operations above.
|
// Test integrity of all resize operations above.
|
||||||
flatbuffers::Verifier resize_verifier(
|
flatbuffers::Verifier resize_verifier(
|
||||||
reinterpret_cast<const uint8_t *>(resizingbuf.data()),
|
reinterpret_cast<const uint8_t*>(resizingbuf.data()), resizingbuf.size());
|
||||||
resizingbuf.size());
|
|
||||||
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
|
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
|
||||||
|
|
||||||
// Test buffer is valid using reflection as well
|
// Test buffer is valid using reflection as well
|
||||||
@@ -249,7 +248,7 @@ void ReflectionTest(const std::string &tests_data_path, uint8_t *flatbuf,
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
|
void MiniReflectFlatBuffersTest(uint8_t* flatbuf) {
|
||||||
auto s =
|
auto s =
|
||||||
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
|
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
|
||||||
TEST_EQ_STR(
|
TEST_EQ_STR(
|
||||||
|
|||||||
227
tests/test.cpp
227
tests/test.cpp
@@ -47,7 +47,7 @@
|
|||||||
#include "tests/union_vector/union_vector_generated.h"
|
#include "tests/union_vector/union_vector_generated.h"
|
||||||
#include "union_underlying_type_test_generated.h"
|
#include "union_underlying_type_test_generated.h"
|
||||||
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
||||||
# include "tests/arrays_test_generated.h"
|
#include "tests/arrays_test_generated.h"
|
||||||
#endif
|
#endif
|
||||||
#if INCLUDE_64_BIT_TESTS
|
#if INCLUDE_64_BIT_TESTS
|
||||||
#include "tests/64bit/offset64_test.h"
|
#include "tests/64bit/offset64_test.h"
|
||||||
@@ -97,7 +97,7 @@ void TriviallyCopyableTest() {
|
|||||||
|
|
||||||
// Guard against -Wunused-function on platforms without file tests.
|
// Guard against -Wunused-function on platforms without file tests.
|
||||||
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
||||||
void GenerateTableTextTest(const std::string &tests_data_path) {
|
void GenerateTableTextTest(const std::string& tests_data_path) {
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
std::string jsonfile;
|
std::string jsonfile;
|
||||||
bool ok =
|
bool ok =
|
||||||
@@ -108,8 +108,8 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
|
|||||||
TEST_EQ(ok, true);
|
TEST_EQ(ok, true);
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
flatbuffers::IDLOptions opt;
|
flatbuffers::IDLOptions opt;
|
||||||
opt.indent_step = -1;
|
opt.indent_step = -1;
|
||||||
flatbuffers::Parser parser(opt);
|
flatbuffers::Parser parser(opt);
|
||||||
@@ -117,7 +117,7 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
|
|||||||
parser.Parse(jsonfile.c_str(), include_directories);
|
parser.Parse(jsonfile.c_str(), include_directories);
|
||||||
TEST_EQ(ok, true);
|
TEST_EQ(ok, true);
|
||||||
// Test root table
|
// Test root table
|
||||||
const Monster *monster = GetMonster(parser.builder_.GetBufferPointer());
|
const Monster* monster = GetMonster(parser.builder_.GetBufferPointer());
|
||||||
const auto abilities = monster->testarrayofsortedstruct();
|
const auto abilities = monster->testarrayofsortedstruct();
|
||||||
TEST_EQ(abilities->size(), 3);
|
TEST_EQ(abilities->size(), 3);
|
||||||
TEST_EQ(abilities->Get(0)->id(), 0);
|
TEST_EQ(abilities->Get(0)->id(), 0);
|
||||||
@@ -128,35 +128,33 @@ void GenerateTableTextTest(const std::string &tests_data_path) {
|
|||||||
TEST_EQ(abilities->Get(2)->distance(), 12);
|
TEST_EQ(abilities->Get(2)->distance(), 12);
|
||||||
|
|
||||||
std::string jsongen;
|
std::string jsongen;
|
||||||
auto result = GenTextFromTable(parser, monster, "MyGame.Example.Monster",
|
auto result =
|
||||||
&jsongen);
|
GenTextFromTable(parser, monster, "MyGame.Example.Monster", &jsongen);
|
||||||
TEST_NULL(result);
|
TEST_NULL(result);
|
||||||
// Test sub table
|
// Test sub table
|
||||||
const Vec3 *pos = monster->pos();
|
const Vec3* pos = monster->pos();
|
||||||
jsongen.clear();
|
jsongen.clear();
|
||||||
result = GenTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
|
result = GenTextFromTable(parser, pos, "MyGame.Example.Vec3", &jsongen);
|
||||||
TEST_NULL(result);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(
|
TEST_EQ_STR(
|
||||||
jsongen.c_str(),
|
jsongen.c_str(),
|
||||||
"{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
|
"{x: 1.0,y: 2.0,z: 3.0,test1: 3.0,test2: \"Green\",test3: {a: 5,b: 6}}");
|
||||||
const Test &test3 = pos->test3();
|
const Test& test3 = pos->test3();
|
||||||
jsongen.clear();
|
jsongen.clear();
|
||||||
result =
|
result = GenTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
|
||||||
GenTextFromTable(parser, &test3, "MyGame.Example.Test", &jsongen);
|
|
||||||
TEST_NULL(result);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
|
TEST_EQ_STR(jsongen.c_str(), "{a: 5,b: 6}");
|
||||||
const Test *test4 = monster->test4()->Get(0);
|
const Test* test4 = monster->test4()->Get(0);
|
||||||
jsongen.clear();
|
jsongen.clear();
|
||||||
result =
|
result = GenTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
|
||||||
GenTextFromTable(parser, test4, "MyGame.Example.Test", &jsongen);
|
|
||||||
TEST_NULL(result);
|
TEST_NULL(result);
|
||||||
TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
|
TEST_EQ_STR(jsongen.c_str(), "{a: 10,b: 20}");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MultiFileNameClashTest(const std::string &tests_data_path) {
|
void MultiFileNameClashTest(const std::string& tests_data_path) {
|
||||||
const auto name_clash_path =
|
const auto name_clash_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "name_clash_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "name_clash_test");
|
||||||
const char *include_directories[] = { name_clash_path.c_str() };
|
const char* include_directories[] = {name_clash_path.c_str()};
|
||||||
|
|
||||||
// Load valid 2 file Flatbuffer schema
|
// Load valid 2 file Flatbuffer schema
|
||||||
const auto valid_path =
|
const auto valid_path =
|
||||||
@@ -182,7 +180,7 @@ void MultiFileNameClashTest(const std::string &tests_data_path) {
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InvalidNestedFlatbufferTest(const std::string &tests_data_path) {
|
void InvalidNestedFlatbufferTest(const std::string& tests_data_path) {
|
||||||
// First, load and parse FlatBuffer schema (.fbs)
|
// First, load and parse FlatBuffer schema (.fbs)
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
|
TEST_EQ(flatbuffers::LoadFile((tests_data_path + "monster_test.fbs").c_str(),
|
||||||
@@ -190,8 +188,8 @@ void InvalidNestedFlatbufferTest(const std::string &tests_data_path) {
|
|||||||
true);
|
true);
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
flatbuffers::Parser parser1;
|
flatbuffers::Parser parser1;
|
||||||
TEST_EQ(parser1.Parse(schemafile.c_str(), include_directories), true);
|
TEST_EQ(parser1.Parse(schemafile.c_str(), include_directories), true);
|
||||||
|
|
||||||
@@ -201,7 +199,7 @@ void InvalidNestedFlatbufferTest(const std::string &tests_data_path) {
|
|||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void UnionVectorTest(const std::string &tests_data_path) {
|
void UnionVectorTest(const std::string& tests_data_path) {
|
||||||
// load FlatBuffer fbs schema and json.
|
// load FlatBuffer fbs schema and json.
|
||||||
std::string schemafile, jsonfile;
|
std::string schemafile, jsonfile;
|
||||||
TEST_EQ(flatbuffers::LoadFile(
|
TEST_EQ(flatbuffers::LoadFile(
|
||||||
@@ -249,7 +247,7 @@ void UnionVectorTest(const std::string &tests_data_path) {
|
|||||||
|
|
||||||
auto flat_movie = GetMovie(fbb.GetBufferPointer());
|
auto flat_movie = GetMovie(fbb.GetBufferPointer());
|
||||||
|
|
||||||
auto TestMovie = [](const Movie *movie) {
|
auto TestMovie = [](const Movie* movie) {
|
||||||
TEST_EQ(movie->main_character_type() == Character_Rapunzel, true);
|
TEST_EQ(movie->main_character_type() == Character_Rapunzel, true);
|
||||||
|
|
||||||
auto cts = movie->characters_type();
|
auto cts = movie->characters_type();
|
||||||
@@ -405,7 +403,7 @@ void EndianSwapTest() {
|
|||||||
void UninitializedVectorTest() {
|
void UninitializedVectorTest() {
|
||||||
flatbuffers::FlatBufferBuilder builder;
|
flatbuffers::FlatBufferBuilder builder;
|
||||||
|
|
||||||
Test *buf = nullptr;
|
Test* buf = nullptr;
|
||||||
auto vector_offset =
|
auto vector_offset =
|
||||||
builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
|
builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
|
||||||
TEST_NOTNULL(buf);
|
TEST_NOTNULL(buf);
|
||||||
@@ -550,8 +548,8 @@ void CreateSharedStringTest() {
|
|||||||
TEST_EQ(onetwo.o != two.o, true);
|
TEST_EQ(onetwo.o != two.o, true);
|
||||||
|
|
||||||
// Support for embedded nulls
|
// Support for embedded nulls
|
||||||
const char chars_b[] = { 'a', '\0', 'b' };
|
const char chars_b[] = {'a', '\0', 'b'};
|
||||||
const char chars_c[] = { 'a', '\0', 'c' };
|
const char chars_c[] = {'a', '\0', 'c'};
|
||||||
const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b));
|
const auto null_b1 = builder.CreateSharedString(chars_b, sizeof(chars_b));
|
||||||
const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c));
|
const auto null_c = builder.CreateSharedString(chars_c, sizeof(chars_c));
|
||||||
const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b));
|
const auto null_b2 = builder.CreateSharedString(chars_b, sizeof(chars_b));
|
||||||
@@ -560,8 +558,7 @@ void CreateSharedStringTest() {
|
|||||||
|
|
||||||
// Put the strings into an array for round trip verification.
|
// Put the strings into an array for round trip verification.
|
||||||
std::array<flatbuffers::Offset<flatbuffers::String>, 7> array = {
|
std::array<flatbuffers::Offset<flatbuffers::String>, 7> array = {
|
||||||
one1, two, one2, onetwo, null_b1, null_c, null_b2
|
one1, two, one2, onetwo, null_b1, null_c, null_b2};
|
||||||
};
|
|
||||||
const auto vector_offset =
|
const auto vector_offset =
|
||||||
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(array);
|
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(array);
|
||||||
MonsterBuilder monster_builder(builder);
|
MonsterBuilder monster_builder(builder);
|
||||||
@@ -570,12 +567,12 @@ void CreateSharedStringTest() {
|
|||||||
builder.Finish(monster_builder.Finish());
|
builder.Finish(monster_builder.Finish());
|
||||||
|
|
||||||
// Read the Monster back.
|
// Read the Monster back.
|
||||||
const auto *monster =
|
const auto* monster =
|
||||||
flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
|
flatbuffers::GetRoot<Monster>(builder.GetBufferPointer());
|
||||||
TEST_EQ_STR(monster->name()->c_str(), "two");
|
TEST_EQ_STR(monster->name()->c_str(), "two");
|
||||||
const auto *testarrayofstring = monster->testarrayofstring();
|
const auto* testarrayofstring = monster->testarrayofstring();
|
||||||
TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
|
TEST_EQ(testarrayofstring->size(), flatbuffers::uoffset_t(7));
|
||||||
const auto &a = *testarrayofstring;
|
const auto& a = *testarrayofstring;
|
||||||
TEST_EQ_STR(a[0]->c_str(), "one");
|
TEST_EQ_STR(a[0]->c_str(), "one");
|
||||||
TEST_EQ_STR(a[1]->c_str(), "two");
|
TEST_EQ_STR(a[1]->c_str(), "two");
|
||||||
TEST_EQ_STR(a[2]->c_str(), "one");
|
TEST_EQ_STR(a[2]->c_str(), "one");
|
||||||
@@ -617,7 +614,7 @@ void FlatbuffersSpanTest() {
|
|||||||
TEST_EQ(c3.size(), 0);
|
TEST_EQ(c3.size(), 0);
|
||||||
TEST_ASSERT(c1.empty() && c2.empty() && c3.empty());
|
TEST_ASSERT(c1.empty() && c2.empty() && c3.empty());
|
||||||
|
|
||||||
int i_data7[7] = { 0, 1, 2, 3, 4, 5, 6 };
|
int i_data7[7] = {0, 1, 2, 3, 4, 5, 6};
|
||||||
span<int, 7> i1(&i_data7[0], 7);
|
span<int, 7> i1(&i_data7[0], 7);
|
||||||
span<int> i2(i1); // make dynamic from static
|
span<int> i2(i1); // make dynamic from static
|
||||||
TEST_EQ(i1.size(), 7);
|
TEST_EQ(i1.size(), 7);
|
||||||
@@ -634,7 +631,7 @@ void FlatbuffersSpanTest() {
|
|||||||
span<const int> i7(i_data7);
|
span<const int> i7(i_data7);
|
||||||
TEST_EQ(i7.size(), 7);
|
TEST_EQ(i7.size(), 7);
|
||||||
// Check construction from a const array.
|
// Check construction from a const array.
|
||||||
const int i_cdata5[5] = { 4, 3, 2, 1, 0 };
|
const int i_cdata5[5] = {4, 3, 2, 1, 0};
|
||||||
span<const int, 5> i8(i_cdata5);
|
span<const int, 5> i8(i_cdata5);
|
||||||
span<const int> i9(i_cdata5);
|
span<const int> i9(i_cdata5);
|
||||||
TEST_EQ(i9.size(), 5);
|
TEST_EQ(i9.size(), 5);
|
||||||
@@ -646,32 +643,32 @@ void FlatbuffersSpanTest() {
|
|||||||
span<const int> i13(i_cdata5, 5);
|
span<const int> i13(i_cdata5, 5);
|
||||||
TEST_EQ(i13.size(), 5);
|
TEST_EQ(i13.size(), 5);
|
||||||
// Construction from std::array.
|
// Construction from std::array.
|
||||||
std::array<int, 6> i_arr6 = { { 0, 1, 2, 3, 4, 5 } };
|
std::array<int, 6> i_arr6 = {{0, 1, 2, 3, 4, 5}};
|
||||||
span<int, 6> i14(i_arr6);
|
span<int, 6> i14(i_arr6);
|
||||||
span<const int, 6> i15(i_arr6);
|
span<const int, 6> i15(i_arr6);
|
||||||
span<int> i16(i_arr6);
|
span<int> i16(i_arr6);
|
||||||
span<const int> i17(i_arr6);
|
span<const int> i17(i_arr6);
|
||||||
TEST_EQ(i17.size(), 6);
|
TEST_EQ(i17.size(), 6);
|
||||||
const std::array<int, 8> i_carr8 = { { 0, 1, 2, 3, 4, 5, 6, 7 } };
|
const std::array<int, 8> i_carr8 = {{0, 1, 2, 3, 4, 5, 6, 7}};
|
||||||
span<const int, 8> i18(i_carr8);
|
span<const int, 8> i18(i_carr8);
|
||||||
span<const int> i19(i_carr8);
|
span<const int> i19(i_carr8);
|
||||||
TEST_EQ(i18.size(), 8);
|
TEST_EQ(i18.size(), 8);
|
||||||
TEST_EQ(i19.size(), 8);
|
TEST_EQ(i19.size(), 8);
|
||||||
TEST_EQ(i19[7], 7);
|
TEST_EQ(i19[7], 7);
|
||||||
// Check compatibility with flatbuffers::Array.
|
// Check compatibility with flatbuffers::Array.
|
||||||
int fbs_int3_underlaying[3] = { 0 };
|
int fbs_int3_underlaying[3] = {0};
|
||||||
int fbs_int3_data[3] = { 1, 2, 3 };
|
int fbs_int3_data[3] = {1, 2, 3};
|
||||||
auto &fbs_int3 = flatbuffers::CastToArray(fbs_int3_underlaying);
|
auto& fbs_int3 = flatbuffers::CastToArray(fbs_int3_underlaying);
|
||||||
fbs_int3.CopyFromSpan(fbs_int3_data);
|
fbs_int3.CopyFromSpan(fbs_int3_data);
|
||||||
TEST_EQ(fbs_int3.Get(1), 2);
|
TEST_EQ(fbs_int3.Get(1), 2);
|
||||||
const int fbs_cint3_data[3] = { 2, 3, 4 };
|
const int fbs_cint3_data[3] = {2, 3, 4};
|
||||||
fbs_int3.CopyFromSpan(fbs_cint3_data);
|
fbs_int3.CopyFromSpan(fbs_cint3_data);
|
||||||
TEST_EQ(fbs_int3.Get(1), 3);
|
TEST_EQ(fbs_int3.Get(1), 3);
|
||||||
// Check with Array<Enum, N>
|
// Check with Array<Enum, N>
|
||||||
enum class Dummy : uint16_t { Zero = 0, One, Two };
|
enum class Dummy : uint16_t { Zero = 0, One, Two };
|
||||||
Dummy fbs_dummy3_underlaying[3] = {};
|
Dummy fbs_dummy3_underlaying[3] = {};
|
||||||
Dummy fbs_dummy3_data[3] = { Dummy::One, Dummy::Two, Dummy::Two };
|
Dummy fbs_dummy3_data[3] = {Dummy::One, Dummy::Two, Dummy::Two};
|
||||||
auto &fbs_dummy3 = flatbuffers::CastToArray(fbs_dummy3_underlaying);
|
auto& fbs_dummy3 = flatbuffers::CastToArray(fbs_dummy3_underlaying);
|
||||||
fbs_dummy3.CopyFromSpan(fbs_dummy3_data);
|
fbs_dummy3.CopyFromSpan(fbs_dummy3_data);
|
||||||
TEST_EQ(fbs_dummy3.Get(1), Dummy::Two);
|
TEST_EQ(fbs_dummy3.Get(1), Dummy::Two);
|
||||||
}
|
}
|
||||||
@@ -771,18 +768,20 @@ void FixedLengthArrayTest() {
|
|||||||
const size_t arr_size = sizeof(MyGame::Example::ArrayStruct);
|
const size_t arr_size = sizeof(MyGame::Example::ArrayStruct);
|
||||||
char non_zero_memory[arr_size];
|
char non_zero_memory[arr_size];
|
||||||
// set memory chunk of size ArrayStruct to 1's
|
// set memory chunk of size ArrayStruct to 1's
|
||||||
std::memset(static_cast<void *>(non_zero_memory), 1, arr_size);
|
std::memset(static_cast<void*>(non_zero_memory), 1, arr_size);
|
||||||
// after placement-new it should be all 0's
|
// after placement-new it should be all 0's
|
||||||
# if defined(_MSC_VER) && defined(_DEBUG)
|
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||||
# undef new
|
#undef new
|
||||||
# endif
|
#endif
|
||||||
MyGame::Example::ArrayStruct *ap =
|
MyGame::Example::ArrayStruct* ap =
|
||||||
new (non_zero_memory) MyGame::Example::ArrayStruct;
|
new (non_zero_memory) MyGame::Example::ArrayStruct;
|
||||||
# if defined(_MSC_VER) && defined(_DEBUG)
|
#if defined(_MSC_VER) && defined(_DEBUG)
|
||||||
# define new DEBUG_NEW
|
#define new DEBUG_NEW
|
||||||
# endif
|
#endif
|
||||||
(void)ap;
|
(void)ap;
|
||||||
for (size_t i = 0; i < arr_size; ++i) { TEST_EQ(non_zero_memory[i], 0); }
|
for (size_t i = 0; i < arr_size; ++i) {
|
||||||
|
TEST_EQ(non_zero_memory[i], 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
void FixedLengthArrayTest() {}
|
void FixedLengthArrayTest() {}
|
||||||
@@ -791,30 +790,29 @@ void FixedLengthArrayTest() {}
|
|||||||
#if !defined(FLATBUFFERS_SPAN_MINIMAL) && \
|
#if !defined(FLATBUFFERS_SPAN_MINIMAL) && \
|
||||||
(!defined(_MSC_VER) || _MSC_VER >= 1700)
|
(!defined(_MSC_VER) || _MSC_VER >= 1700)
|
||||||
void FixedLengthArrayConstructorTest() {
|
void FixedLengthArrayConstructorTest() {
|
||||||
const int32_t nested_a[2] = { 1, 2 };
|
const int32_t nested_a[2] = {1, 2};
|
||||||
MyGame::Example::TestEnum nested_c[2] = { MyGame::Example::TestEnum::A,
|
MyGame::Example::TestEnum nested_c[2] = {MyGame::Example::TestEnum::A,
|
||||||
MyGame::Example::TestEnum::B };
|
MyGame::Example::TestEnum::B};
|
||||||
const int64_t int64_2[2] = { -2, -1 };
|
const int64_t int64_2[2] = {-2, -1};
|
||||||
|
|
||||||
std::array<MyGame::Example::NestedStruct, 2> init_d = {
|
std::array<MyGame::Example::NestedStruct, 2> init_d = {
|
||||||
{ MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
{MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
||||||
nested_c, int64_2),
|
nested_c, int64_2),
|
||||||
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::A,
|
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::A,
|
||||||
nested_c,
|
nested_c,
|
||||||
std::array<int64_t, 2>{ { 12, 13 } }) }
|
std::array<int64_t, 2>{{12, 13}})}};
|
||||||
};
|
|
||||||
|
|
||||||
MyGame::Example::ArrayStruct arr_struct(
|
MyGame::Example::ArrayStruct arr_struct(
|
||||||
8.125,
|
8.125,
|
||||||
std::array<int32_t, 0xF>{
|
std::array<int32_t, 0xF>{
|
||||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
|
||||||
-17, init_d, 10, int64_2);
|
-17, init_d, 10, int64_2);
|
||||||
TEST_EQ(arr_struct.a(), 8.125);
|
TEST_EQ(arr_struct.a(), 8.125);
|
||||||
TEST_EQ(arr_struct.b()->Get(2), 3);
|
TEST_EQ(arr_struct.b()->Get(2), 3);
|
||||||
TEST_EQ(arr_struct.c(), -17);
|
TEST_EQ(arr_struct.c(), -17);
|
||||||
|
|
||||||
TEST_NOTNULL(arr_struct.d());
|
TEST_NOTNULL(arr_struct.d());
|
||||||
const auto &arr_d_0 = *arr_struct.d()->Get(0);
|
const auto& arr_d_0 = *arr_struct.d()->Get(0);
|
||||||
TEST_EQ(arr_d_0.a()->Get(0), 1);
|
TEST_EQ(arr_d_0.a()->Get(0), 1);
|
||||||
TEST_EQ(arr_d_0.a()->Get(1), 2);
|
TEST_EQ(arr_d_0.a()->Get(1), 2);
|
||||||
TEST_EQ(arr_d_0.b(), MyGame::Example::TestEnum::B);
|
TEST_EQ(arr_d_0.b(), MyGame::Example::TestEnum::B);
|
||||||
@@ -822,7 +820,7 @@ void FixedLengthArrayConstructorTest() {
|
|||||||
TEST_EQ(arr_d_0.c()->Get(1), MyGame::Example::TestEnum::B);
|
TEST_EQ(arr_d_0.c()->Get(1), MyGame::Example::TestEnum::B);
|
||||||
TEST_EQ(arr_d_0.d()->Get(0), -2);
|
TEST_EQ(arr_d_0.d()->Get(0), -2);
|
||||||
TEST_EQ(arr_d_0.d()->Get(1), -1);
|
TEST_EQ(arr_d_0.d()->Get(1), -1);
|
||||||
const auto &arr_d_1 = *arr_struct.d()->Get(1);
|
const auto& arr_d_1 = *arr_struct.d()->Get(1);
|
||||||
TEST_EQ(arr_d_1.a()->Get(0), 1);
|
TEST_EQ(arr_d_1.a()->Get(0), 1);
|
||||||
TEST_EQ(arr_d_1.a()->Get(1), 2);
|
TEST_EQ(arr_d_1.a()->Get(1), 2);
|
||||||
TEST_EQ(arr_d_1.b(), MyGame::Example::TestEnum::A);
|
TEST_EQ(arr_d_1.b(), MyGame::Example::TestEnum::A);
|
||||||
@@ -858,25 +856,24 @@ void FixedLengthArrayConstructorTest() {}
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
void FixedLengthArrayOperatorEqualTest() {
|
void FixedLengthArrayOperatorEqualTest() {
|
||||||
const int32_t nested_a[2] = { 1, 2 };
|
const int32_t nested_a[2] = {1, 2};
|
||||||
MyGame::Example::TestEnum nested_c[2] = { MyGame::Example::TestEnum::A,
|
MyGame::Example::TestEnum nested_c[2] = {MyGame::Example::TestEnum::A,
|
||||||
MyGame::Example::TestEnum::B };
|
MyGame::Example::TestEnum::B};
|
||||||
|
|
||||||
MyGame::Example::TestEnum nested_cc[2] = { MyGame::Example::TestEnum::A,
|
MyGame::Example::TestEnum nested_cc[2] = {MyGame::Example::TestEnum::A,
|
||||||
MyGame::Example::TestEnum::C };
|
MyGame::Example::TestEnum::C};
|
||||||
const int64_t int64_2[2] = { -2, -1 };
|
const int64_t int64_2[2] = {-2, -1};
|
||||||
|
|
||||||
std::array<MyGame::Example::NestedStruct, 2> init_d = {
|
std::array<MyGame::Example::NestedStruct, 2> init_d = {
|
||||||
{ MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
{MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
||||||
nested_c, int64_2),
|
nested_c, int64_2),
|
||||||
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
MyGame::Example::NestedStruct(nested_a, MyGame::Example::TestEnum::B,
|
||||||
nested_c,
|
nested_c,
|
||||||
std::array<int64_t, 2>{ { -2, -1 } }) }
|
std::array<int64_t, 2>{{-2, -1}})}};
|
||||||
};
|
|
||||||
|
|
||||||
auto different = MyGame::Example::NestedStruct(
|
auto different = MyGame::Example::NestedStruct(
|
||||||
nested_a, MyGame::Example::TestEnum::B, nested_cc,
|
nested_a, MyGame::Example::TestEnum::B, nested_cc,
|
||||||
std::array<int64_t, 2>{ { -2, -1 } });
|
std::array<int64_t, 2>{{-2, -1}});
|
||||||
|
|
||||||
TEST_ASSERT(init_d[0] == init_d[1]);
|
TEST_ASSERT(init_d[0] == init_d[1]);
|
||||||
TEST_ASSERT(init_d[0] != different);
|
TEST_ASSERT(init_d[0] != different);
|
||||||
@@ -885,21 +882,20 @@ void FixedLengthArrayOperatorEqualTest() {
|
|||||||
MyGame::Example::ArrayStruct(
|
MyGame::Example::ArrayStruct(
|
||||||
8.125,
|
8.125,
|
||||||
std::array<int32_t, 0xF>{
|
std::array<int32_t, 0xF>{
|
||||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
|
||||||
-17, init_d, 10, int64_2),
|
-17, init_d, 10, int64_2),
|
||||||
|
|
||||||
MyGame::Example::ArrayStruct(
|
MyGame::Example::ArrayStruct(
|
||||||
8.125,
|
8.125,
|
||||||
std::array<int32_t, 0xF>{
|
std::array<int32_t, 0xF>{
|
||||||
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
|
||||||
-17, init_d, 10, int64_2),
|
-17, init_d, 10, int64_2),
|
||||||
|
|
||||||
MyGame::Example::ArrayStruct(
|
MyGame::Example::ArrayStruct(
|
||||||
8.125,
|
8.125,
|
||||||
std::array<int32_t, 0xF>{
|
std::array<int32_t, 0xF>{
|
||||||
{ 1000, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } },
|
{1000, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}},
|
||||||
-17, init_d, 10, int64_2)
|
-17, init_d, 10, int64_2)};
|
||||||
};
|
|
||||||
|
|
||||||
TEST_ASSERT(arr_struct[0] == arr_struct[1]);
|
TEST_ASSERT(arr_struct[0] == arr_struct[1]);
|
||||||
TEST_ASSERT(arr_struct[1] != arr_struct[2]);
|
TEST_ASSERT(arr_struct[1] != arr_struct[2]);
|
||||||
@@ -935,12 +931,12 @@ void NativeTypeTest() {
|
|||||||
TEST_EQ(dstDataT->position_inline.z, 6.0f);
|
TEST_EQ(dstDataT->position_inline.z, 6.0f);
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i) {
|
for (int i = 0; i < N; ++i) {
|
||||||
const Native::Vector3D &v = dstDataT->vectors[i];
|
const Native::Vector3D& v = dstDataT->vectors[i];
|
||||||
TEST_EQ(v.x, 10 * i + 0.1f);
|
TEST_EQ(v.x, 10 * i + 0.1f);
|
||||||
TEST_EQ(v.y, 10 * i + 0.2f);
|
TEST_EQ(v.y, 10 * i + 0.2f);
|
||||||
TEST_EQ(v.z, 10 * i + 0.3f);
|
TEST_EQ(v.z, 10 * i + 0.3f);
|
||||||
|
|
||||||
const Native::Vector3D &v2 = dstDataT->vectors_alt[i];
|
const Native::Vector3D& v2 = dstDataT->vectors_alt[i];
|
||||||
TEST_EQ(v2.x, 20 * i + 0.1f);
|
TEST_EQ(v2.x, 20 * i + 0.1f);
|
||||||
TEST_EQ(v2.y, 20 * i + 0.2f);
|
TEST_EQ(v2.y, 20 * i + 0.2f);
|
||||||
TEST_EQ(v2.z, 20 * i + 0.3f);
|
TEST_EQ(v2.z, 20 * i + 0.3f);
|
||||||
@@ -950,8 +946,8 @@ void NativeTypeTest() {
|
|||||||
// Guard against -Wunused-function on platforms without file tests.
|
// Guard against -Wunused-function on platforms without file tests.
|
||||||
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
||||||
// VS10 does not support typed enums, exclude from tests
|
// VS10 does not support typed enums, exclude from tests
|
||||||
# if !defined(_MSC_VER) || _MSC_VER >= 1700
|
#if !defined(_MSC_VER) || _MSC_VER >= 1700
|
||||||
void FixedLengthArrayJsonTest(const std::string &tests_data_path, bool binary) {
|
void FixedLengthArrayJsonTest(const std::string& tests_data_path, bool binary) {
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
std::string jsonfile;
|
std::string jsonfile;
|
||||||
@@ -969,15 +965,15 @@ void FixedLengthArrayJsonTest(const std::string &tests_data_path, bool binary) {
|
|||||||
flatbuffers::Parser parserOrg, parserGen;
|
flatbuffers::Parser parserOrg, parserGen;
|
||||||
if (binary) {
|
if (binary) {
|
||||||
flatbuffers::Verifier verifier(
|
flatbuffers::Verifier verifier(
|
||||||
reinterpret_cast<const uint8_t *>(schemafile.c_str()),
|
reinterpret_cast<const uint8_t*>(schemafile.c_str()),
|
||||||
schemafile.size());
|
schemafile.size());
|
||||||
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
TEST_EQ(reflection::VerifySchemaBuffer(verifier), true);
|
||||||
TEST_EQ(parserOrg.Deserialize(
|
TEST_EQ(parserOrg.Deserialize(
|
||||||
reinterpret_cast<const uint8_t *>(schemafile.c_str()),
|
reinterpret_cast<const uint8_t*>(schemafile.c_str()),
|
||||||
schemafile.size()),
|
schemafile.size()),
|
||||||
true);
|
true);
|
||||||
TEST_EQ(parserGen.Deserialize(
|
TEST_EQ(parserGen.Deserialize(
|
||||||
reinterpret_cast<const uint8_t *>(schemafile.c_str()),
|
reinterpret_cast<const uint8_t*>(schemafile.c_str()),
|
||||||
schemafile.size()),
|
schemafile.size()),
|
||||||
true);
|
true);
|
||||||
} else {
|
} else {
|
||||||
@@ -1012,7 +1008,7 @@ void FixedLengthArrayJsonTest(const std::string &tests_data_path, bool binary) {
|
|||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FixedLengthArraySpanTest(const std::string &tests_data_path) {
|
void FixedLengthArraySpanTest(const std::string& tests_data_path) {
|
||||||
// load FlatBuffer schema (.fbs) and JSON from disk
|
// load FlatBuffer schema (.fbs) and JSON from disk
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
std::string jsonfile;
|
std::string jsonfile;
|
||||||
@@ -1028,7 +1024,7 @@ void FixedLengthArraySpanTest(const std::string &tests_data_path) {
|
|||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
TEST_EQ(parser.Parse(schemafile.c_str()), true);
|
TEST_EQ(parser.Parse(schemafile.c_str()), true);
|
||||||
TEST_EQ(parser.Parse(jsonfile.c_str()), true);
|
TEST_EQ(parser.Parse(jsonfile.c_str()), true);
|
||||||
auto &fbb = parser.builder_;
|
auto& fbb = parser.builder_;
|
||||||
auto verifier = flatbuffers::Verifier(fbb.GetBufferPointer(), fbb.GetSize());
|
auto verifier = flatbuffers::Verifier(fbb.GetBufferPointer(), fbb.GetSize());
|
||||||
TEST_EQ(true, VerifyArrayTableBuffer(verifier));
|
TEST_EQ(true, VerifyArrayTableBuffer(verifier));
|
||||||
|
|
||||||
@@ -1048,8 +1044,8 @@ void FixedLengthArraySpanTest(const std::string &tests_data_path) {
|
|||||||
TEST_ASSERT(const_d[1] == mutable_d[1]);
|
TEST_ASSERT(const_d[1] == mutable_d[1]);
|
||||||
mutable_d[0] = const_d[0]; // mutate
|
mutable_d[0] = const_d[0]; // mutate
|
||||||
// test scalars
|
// test scalars
|
||||||
auto &const_nested = const_d[0];
|
auto& const_nested = const_d[0];
|
||||||
auto &mutable_nested = mutable_d[0];
|
auto& mutable_nested = mutable_d[0];
|
||||||
static_assert(sizeof(MyGame::Example::TestEnum) == sizeof(uint8_t),
|
static_assert(sizeof(MyGame::Example::TestEnum) == sizeof(uint8_t),
|
||||||
"TestEnum's underlaying type must by byte");
|
"TestEnum's underlaying type must by byte");
|
||||||
TEST_NOTNULL(const_nested.d());
|
TEST_NOTNULL(const_nested.d());
|
||||||
@@ -1069,7 +1065,7 @@ void FixedLengthArraySpanTest(const std::string &tests_data_path) {
|
|||||||
std::equal(const_d_c.begin(), const_d_c.end(), mutable_d_c.begin()));
|
std::equal(const_d_c.begin(), const_d_c.end(), mutable_d_c.begin()));
|
||||||
}
|
}
|
||||||
// test little endian array of int32
|
// test little endian array of int32
|
||||||
# if FLATBUFFERS_LITTLEENDIAN
|
#if FLATBUFFERS_LITTLEENDIAN
|
||||||
{
|
{
|
||||||
flatbuffers::span<const int32_t, 2> const_d_a =
|
flatbuffers::span<const int32_t, 2> const_d_a =
|
||||||
flatbuffers::make_span(*const_nested.a());
|
flatbuffers::make_span(*const_nested.a());
|
||||||
@@ -1084,14 +1080,14 @@ void FixedLengthArraySpanTest(const std::string &tests_data_path) {
|
|||||||
TEST_ASSERT(
|
TEST_ASSERT(
|
||||||
std::equal(const_d_a.begin(), const_d_a.end(), mutable_d_a.begin()));
|
std::equal(const_d_a.begin(), const_d_a.end(), mutable_d_a.begin()));
|
||||||
}
|
}
|
||||||
# endif
|
#endif
|
||||||
}
|
}
|
||||||
# else
|
#else
|
||||||
void FixedLengthArrayJsonTest(bool /*binary*/) {}
|
void FixedLengthArrayJsonTest(bool /*binary*/) {}
|
||||||
void FixedLengthArraySpanTest() {}
|
void FixedLengthArraySpanTest() {}
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
void TestEmbeddedBinarySchema(const std::string &tests_data_path) {
|
void TestEmbeddedBinarySchema(const std::string& tests_data_path) {
|
||||||
// load JSON from disk
|
// load JSON from disk
|
||||||
std::string jsonfile;
|
std::string jsonfile;
|
||||||
TEST_EQ(flatbuffers::LoadFile(
|
TEST_EQ(flatbuffers::LoadFile(
|
||||||
@@ -1139,7 +1135,8 @@ void TestEmbeddedBinarySchema(const std::string &tests_data_path) {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
template<typename T> void EmbeddedSchemaAccessByType() {
|
template <typename T>
|
||||||
|
void EmbeddedSchemaAccessByType() {
|
||||||
// Get the binary schema from the Type itself.
|
// Get the binary schema from the Type itself.
|
||||||
// Verify the schema is OK.
|
// Verify the schema is OK.
|
||||||
flatbuffers::Verifier verifierEmbeddedSchema(
|
flatbuffers::Verifier verifierEmbeddedSchema(
|
||||||
@@ -1240,7 +1237,7 @@ void NestedVerifierTest() {
|
|||||||
|
|
||||||
// Purposely invalidate the nested flatbuffer setting its length to 0, an
|
// Purposely invalidate the nested flatbuffer setting its length to 0, an
|
||||||
// invalid length.
|
// invalid length.
|
||||||
uint8_t *invalid_nested_buffer = nullptr;
|
uint8_t* invalid_nested_buffer = nullptr;
|
||||||
auto nested_monster_bytes = builder.CreateVector(invalid_nested_buffer, 0);
|
auto nested_monster_bytes = builder.CreateVector(invalid_nested_buffer, 0);
|
||||||
|
|
||||||
auto name = builder.CreateString("OuterMonster");
|
auto name = builder.CreateString("OuterMonster");
|
||||||
@@ -1257,8 +1254,8 @@ void NestedVerifierTest() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class T, class Container>
|
template <class T, class Container>
|
||||||
void TestIterators(const std::vector<T> &expected, const Container &tested) {
|
void TestIterators(const std::vector<T>& expected, const Container& tested) {
|
||||||
TEST_ASSERT(tested.rbegin().base() == tested.end());
|
TEST_ASSERT(tested.rbegin().base() == tested.end());
|
||||||
TEST_ASSERT(tested.crbegin().base() == tested.cend());
|
TEST_ASSERT(tested.crbegin().base() == tested.cend());
|
||||||
TEST_ASSERT(tested.rend().base() == tested.begin());
|
TEST_ASSERT(tested.rend().base() == tested.begin());
|
||||||
@@ -1266,14 +1263,14 @@ void TestIterators(const std::vector<T> &expected, const Container &tested) {
|
|||||||
|
|
||||||
size_t k = 0;
|
size_t k = 0;
|
||||||
for (auto it = tested.begin(); it != tested.end(); ++it, ++k) {
|
for (auto it = tested.begin(); it != tested.end(); ++it, ++k) {
|
||||||
const auto &e = expected.at(k);
|
const auto& e = expected.at(k);
|
||||||
TEST_EQ(*it, e);
|
TEST_EQ(*it, e);
|
||||||
}
|
}
|
||||||
TEST_EQ(k, expected.size());
|
TEST_EQ(k, expected.size());
|
||||||
|
|
||||||
k = expected.size();
|
k = expected.size();
|
||||||
for (auto it = tested.rbegin(); it != tested.rend(); ++it, --k) {
|
for (auto it = tested.rbegin(); it != tested.rend(); ++it, --k) {
|
||||||
const auto &e = expected.at(k - 1);
|
const auto& e = expected.at(k - 1);
|
||||||
TEST_EQ(*it, e);
|
TEST_EQ(*it, e);
|
||||||
}
|
}
|
||||||
TEST_EQ(k, 0);
|
TEST_EQ(k, 0);
|
||||||
@@ -1282,19 +1279,19 @@ void TestIterators(const std::vector<T> &expected, const Container &tested) {
|
|||||||
void FlatbuffersIteratorsTest() {
|
void FlatbuffersIteratorsTest() {
|
||||||
{
|
{
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
const std::vector<unsigned char> inv_data = { 1, 2, 3 };
|
const std::vector<unsigned char> inv_data = {1, 2, 3};
|
||||||
{
|
{
|
||||||
auto mon_name = fbb.CreateString("MyMonster"); // key, mandatory
|
auto mon_name = fbb.CreateString("MyMonster"); // key, mandatory
|
||||||
auto inv_vec = fbb.CreateVector(inv_data);
|
auto inv_vec = fbb.CreateVector(inv_data);
|
||||||
auto empty_i64_vec =
|
auto empty_i64_vec =
|
||||||
fbb.CreateVector(static_cast<const int64_t *>(nullptr), 0);
|
fbb.CreateVector(static_cast<const int64_t*>(nullptr), 0);
|
||||||
MonsterBuilder mb(fbb);
|
MonsterBuilder mb(fbb);
|
||||||
mb.add_name(mon_name);
|
mb.add_name(mon_name);
|
||||||
mb.add_inventory(inv_vec);
|
mb.add_inventory(inv_vec);
|
||||||
mb.add_vector_of_longs(empty_i64_vec);
|
mb.add_vector_of_longs(empty_i64_vec);
|
||||||
FinishMonsterBuffer(fbb, mb.Finish());
|
FinishMonsterBuffer(fbb, mb.Finish());
|
||||||
}
|
}
|
||||||
const auto &mon = *flatbuffers::GetRoot<Monster>(fbb.GetBufferPointer());
|
const auto& mon = *flatbuffers::GetRoot<Monster>(fbb.GetBufferPointer());
|
||||||
|
|
||||||
TEST_EQ_STR("MyMonster", mon.name()->c_str());
|
TEST_EQ_STR("MyMonster", mon.name()->c_str());
|
||||||
TEST_ASSERT(mon.inventory());
|
TEST_ASSERT(mon.inventory());
|
||||||
@@ -1308,10 +1305,10 @@ void FlatbuffersIteratorsTest() {
|
|||||||
MyGame::Example::ArrayStruct aStruct;
|
MyGame::Example::ArrayStruct aStruct;
|
||||||
MyGame::Example::FinishArrayTableBuffer(
|
MyGame::Example::FinishArrayTableBuffer(
|
||||||
fbb, MyGame::Example::CreateArrayTable(fbb, &aStruct));
|
fbb, MyGame::Example::CreateArrayTable(fbb, &aStruct));
|
||||||
const auto &array_table =
|
const auto& array_table =
|
||||||
*flatbuffers::GetRoot<ArrayTable>(fbb.GetBufferPointer());
|
*flatbuffers::GetRoot<ArrayTable>(fbb.GetBufferPointer());
|
||||||
TEST_ASSERT(array_table.a());
|
TEST_ASSERT(array_table.a());
|
||||||
auto &int_15 = *array_table.a()->b();
|
auto& int_15 = *array_table.a()->b();
|
||||||
TestIterators(std::vector<int>(15, 0), int_15);
|
TestIterators(std::vector<int>(15, 0), int_15);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1444,7 +1441,7 @@ void VectorSpanTest() {
|
|||||||
|
|
||||||
auto mloc = CreateMonster(
|
auto mloc = CreateMonster(
|
||||||
builder, nullptr, 0, 0, builder.CreateString("Monster"),
|
builder, nullptr, 0, 0, builder.CreateString("Monster"),
|
||||||
builder.CreateVector<uint8_t>({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }));
|
builder.CreateVector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9}));
|
||||||
|
|
||||||
FinishMonsterBuffer(builder, mloc);
|
FinishMonsterBuffer(builder, mloc);
|
||||||
|
|
||||||
@@ -1522,34 +1519,36 @@ void NativeInlineTableVectorTest() {
|
|||||||
auto offset = TestNativeInlineTable::Pack(fbb, &test);
|
auto offset = TestNativeInlineTable::Pack(fbb, &test);
|
||||||
fbb.Finish(offset);
|
fbb.Finish(offset);
|
||||||
|
|
||||||
auto *root =
|
auto* root =
|
||||||
flatbuffers::GetRoot<TestNativeInlineTable>(fbb.GetBufferPointer());
|
flatbuffers::GetRoot<TestNativeInlineTable>(fbb.GetBufferPointer());
|
||||||
TestNativeInlineTableT unpacked;
|
TestNativeInlineTableT unpacked;
|
||||||
root->UnPackTo(&unpacked);
|
root->UnPackTo(&unpacked);
|
||||||
|
|
||||||
for (int i = 0; i < 10; ++i) { TEST_ASSERT(unpacked.t[i] == test.t[i]); }
|
for (int i = 0; i < 10; ++i) {
|
||||||
|
TEST_ASSERT(unpacked.t[i] == test.t[i]);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_ASSERT(unpacked.t == test.t);
|
TEST_ASSERT(unpacked.t == test.t);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Guard against -Wunused-function on platforms without file tests.
|
// Guard against -Wunused-function on platforms without file tests.
|
||||||
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
#ifndef FLATBUFFERS_NO_FILE_TESTS
|
||||||
void DoNotRequireEofTest(const std::string &tests_data_path) {
|
void DoNotRequireEofTest(const std::string& tests_data_path) {
|
||||||
std::string schemafile;
|
std::string schemafile;
|
||||||
bool ok = flatbuffers::LoadFile(
|
bool ok = flatbuffers::LoadFile(
|
||||||
(tests_data_path + "monster_test.fbs").c_str(), false, &schemafile);
|
(tests_data_path + "monster_test.fbs").c_str(), false, &schemafile);
|
||||||
TEST_EQ(ok, true);
|
TEST_EQ(ok, true);
|
||||||
auto include_test_path =
|
auto include_test_path =
|
||||||
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
flatbuffers::ConCatPathFileName(tests_data_path, "include_test");
|
||||||
const char *include_directories[] = { tests_data_path.c_str(),
|
const char* include_directories[] = {tests_data_path.c_str(),
|
||||||
include_test_path.c_str(), nullptr };
|
include_test_path.c_str(), nullptr};
|
||||||
flatbuffers::IDLOptions opt;
|
flatbuffers::IDLOptions opt;
|
||||||
opt.require_json_eof = false;
|
opt.require_json_eof = false;
|
||||||
flatbuffers::Parser parser(opt);
|
flatbuffers::Parser parser(opt);
|
||||||
ok = parser.Parse(schemafile.c_str(), include_directories);
|
ok = parser.Parse(schemafile.c_str(), include_directories);
|
||||||
TEST_EQ(ok, true);
|
TEST_EQ(ok, true);
|
||||||
|
|
||||||
const char *str = R"(Some text at the beginning. {
|
const char* str = R"(Some text at the beginning. {
|
||||||
"name": "Blob",
|
"name": "Blob",
|
||||||
"hp": 5
|
"hp": 5
|
||||||
}{
|
}{
|
||||||
@@ -1558,11 +1557,11 @@ void DoNotRequireEofTest(const std::string &tests_data_path) {
|
|||||||
}
|
}
|
||||||
Some extra text at the end too.
|
Some extra text at the end too.
|
||||||
)";
|
)";
|
||||||
const char *tableStart = std::strchr(str, '{');
|
const char* tableStart = std::strchr(str, '{');
|
||||||
ok = parser.ParseJson(tableStart);
|
ok = parser.ParseJson(tableStart);
|
||||||
TEST_EQ(ok, true);
|
TEST_EQ(ok, true);
|
||||||
|
|
||||||
const Monster *monster = GetMonster(parser.builder_.GetBufferPointer());
|
const Monster* monster = GetMonster(parser.builder_.GetBufferPointer());
|
||||||
TEST_EQ_STR(monster->name()->c_str(), "Blob");
|
TEST_EQ_STR(monster->name()->c_str(), "Blob");
|
||||||
TEST_EQ(monster->hp(), 5);
|
TEST_EQ(monster->hp(), 5);
|
||||||
|
|
||||||
@@ -1602,14 +1601,12 @@ void UnionUnderlyingTypeTest() {
|
|||||||
auto offset = D::Pack(fbb, &buffer);
|
auto offset = D::Pack(fbb, &buffer);
|
||||||
fbb.Finish(offset);
|
fbb.Finish(offset);
|
||||||
|
|
||||||
auto *root =
|
auto* root = flatbuffers::GetRoot<D>(fbb.GetBufferPointer());
|
||||||
flatbuffers::GetRoot<D>(fbb.GetBufferPointer());
|
|
||||||
DT unpacked;
|
DT unpacked;
|
||||||
root->UnPackTo(&unpacked);
|
root->UnPackTo(&unpacked);
|
||||||
|
|
||||||
TEST_ASSERT(unpacked.test_union == buffer.test_union);
|
TEST_ASSERT(unpacked.test_union == buffer.test_union);
|
||||||
TEST_ASSERT(unpacked.test_vector_of_union == buffer.test_vector_of_union);
|
TEST_ASSERT(unpacked.test_vector_of_union == buffer.test_vector_of_union);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Offset64Tests() {
|
static void Offset64Tests() {
|
||||||
@@ -1626,14 +1623,14 @@ static void Offset64Tests() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
int FlatBufferTests(const std::string &tests_data_path) {
|
int FlatBufferTests(const std::string& tests_data_path) {
|
||||||
// Run our various test suites:
|
// Run our various test suites:
|
||||||
|
|
||||||
std::string rawbuf;
|
std::string rawbuf;
|
||||||
auto flatbuf1 = CreateFlatBufferTest(rawbuf);
|
auto flatbuf1 = CreateFlatBufferTest(rawbuf);
|
||||||
auto flatbuf = std::move(flatbuf1); // Test move assignment.
|
auto flatbuf = std::move(flatbuf1); // Test move assignment.
|
||||||
|
|
||||||
AccessFlatBufferTest(reinterpret_cast<const uint8_t *>(rawbuf.c_str()),
|
AccessFlatBufferTest(reinterpret_cast<const uint8_t*>(rawbuf.c_str()),
|
||||||
rawbuf.length());
|
rawbuf.length());
|
||||||
AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
|
AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
|
||||||
|
|
||||||
@@ -1745,7 +1742,7 @@ int FlatBufferTests(const std::string &tests_data_path) {
|
|||||||
} // namespace tests
|
} // namespace tests
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
int main(int argc, const char *argv[]) {
|
int main(int argc, const char* argv[]) {
|
||||||
std::string tests_data_path = "tests/";
|
std::string tests_data_path = "tests/";
|
||||||
|
|
||||||
for (int argi = 1; argi < argc; argi++) {
|
for (int argi = 1; argi < argc; argi++) {
|
||||||
|
|||||||
@@ -3,15 +3,15 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
# include <crtdbg.h>
|
#include <crtdbg.h>
|
||||||
# include <windows.h>
|
#include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int testing_fails = 0;
|
int testing_fails = 0;
|
||||||
static TestFailEventListener fail_listener_ = nullptr;
|
static TestFailEventListener fail_listener_ = nullptr;
|
||||||
|
|
||||||
void TestFail(const char *expval, const char *val, const char *exp,
|
void TestFail(const char* expval, const char* val, const char* exp,
|
||||||
const char *file, int line, const char *func) {
|
const char* file, int line, const char* func) {
|
||||||
TEST_OUTPUT_LINE("EXPECTED: \"%s\"", expval);
|
TEST_OUTPUT_LINE("EXPECTED: \"%s\"", expval);
|
||||||
TEST_OUTPUT_LINE("VALUE: \"%s\"", val);
|
TEST_OUTPUT_LINE("VALUE: \"%s\"", val);
|
||||||
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s in %s", file, line, exp,
|
TEST_OUTPUT_LINE("TEST FAILED: %s:%d, %s in %s", file, line, exp,
|
||||||
@@ -24,8 +24,8 @@ void TestFail(const char *expval, const char *val, const char *exp,
|
|||||||
assert(0); // ignored in Release if NDEBUG defined
|
assert(0); // ignored in Release if NDEBUG defined
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestEqStr(const char *expval, const char *val, const char *exp,
|
void TestEqStr(const char* expval, const char* val, const char* exp,
|
||||||
const char *file, int line, const char *func) {
|
const char* file, int line, const char* func) {
|
||||||
if (strcmp(expval, val) != 0) {
|
if (strcmp(expval, val) != 0) {
|
||||||
TestFail(expval, val, exp, file, line, func);
|
TestFail(expval, val, exp, file, line, func);
|
||||||
}
|
}
|
||||||
@@ -33,7 +33,7 @@ void TestEqStr(const char *expval, const char *val, const char *exp,
|
|||||||
|
|
||||||
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
|
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && defined(_MSC_VER) && \
|
||||||
defined(_DEBUG)
|
defined(_DEBUG)
|
||||||
# define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
|
#define FLATBUFFERS_MEMORY_LEAK_TRACKING_MSVC
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void InitTestEngine(TestFailEventListener listener) {
|
void InitTestEngine(TestFailEventListener listener) {
|
||||||
|
|||||||
@@ -11,16 +11,16 @@ struct OwnedAllocator : public DefaultAllocator {};
|
|||||||
|
|
||||||
class TestHeapBuilder : public FlatBufferBuilder {
|
class TestHeapBuilder : public FlatBufferBuilder {
|
||||||
private:
|
private:
|
||||||
TestHeapBuilder(const TestHeapBuilder &);
|
TestHeapBuilder(const TestHeapBuilder&);
|
||||||
TestHeapBuilder &operator=(const TestHeapBuilder &);
|
TestHeapBuilder& operator=(const TestHeapBuilder&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TestHeapBuilder() : FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
|
TestHeapBuilder() : FlatBufferBuilder(2048, new OwnedAllocator(), true) {}
|
||||||
|
|
||||||
TestHeapBuilder(TestHeapBuilder &&other)
|
TestHeapBuilder(TestHeapBuilder&& other)
|
||||||
: FlatBufferBuilder(std::move(other)) {}
|
: FlatBufferBuilder(std::move(other)) {}
|
||||||
|
|
||||||
TestHeapBuilder &operator=(TestHeapBuilder &&other) {
|
TestHeapBuilder& operator=(TestHeapBuilder&& other) {
|
||||||
FlatBufferBuilder::operator=(std::move(other));
|
FlatBufferBuilder::operator=(std::move(other));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@@ -34,27 +34,27 @@ struct AllocatorMember {
|
|||||||
struct GrpcLikeMessageBuilder : private AllocatorMember,
|
struct GrpcLikeMessageBuilder : private AllocatorMember,
|
||||||
public FlatBufferBuilder {
|
public FlatBufferBuilder {
|
||||||
private:
|
private:
|
||||||
GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder &);
|
GrpcLikeMessageBuilder(const GrpcLikeMessageBuilder&);
|
||||||
GrpcLikeMessageBuilder &operator=(const GrpcLikeMessageBuilder &);
|
GrpcLikeMessageBuilder& operator=(const GrpcLikeMessageBuilder&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GrpcLikeMessageBuilder()
|
GrpcLikeMessageBuilder()
|
||||||
: FlatBufferBuilder(1024, &member_allocator_, false) {}
|
: FlatBufferBuilder(1024, &member_allocator_, false) {}
|
||||||
|
|
||||||
GrpcLikeMessageBuilder(GrpcLikeMessageBuilder &&other)
|
GrpcLikeMessageBuilder(GrpcLikeMessageBuilder&& other)
|
||||||
: FlatBufferBuilder(1024, &member_allocator_, false) {
|
: FlatBufferBuilder(1024, &member_allocator_, false) {
|
||||||
// Default construct and swap idiom.
|
// Default construct and swap idiom.
|
||||||
Swap(other);
|
Swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
GrpcLikeMessageBuilder &operator=(GrpcLikeMessageBuilder &&other) {
|
GrpcLikeMessageBuilder& operator=(GrpcLikeMessageBuilder&& other) {
|
||||||
// Construct temporary and swap idiom
|
// Construct temporary and swap idiom
|
||||||
GrpcLikeMessageBuilder temp(std::move(other));
|
GrpcLikeMessageBuilder temp(std::move(other));
|
||||||
Swap(temp);
|
Swap(temp);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Swap(GrpcLikeMessageBuilder &other) {
|
void Swap(GrpcLikeMessageBuilder& other) {
|
||||||
// No need to swap member_allocator_ because it's stateless.
|
// No need to swap member_allocator_ because it's stateless.
|
||||||
FlatBufferBuilder::Swap(other);
|
FlatBufferBuilder::Swap(other);
|
||||||
// After swapping the FlatBufferBuilder, we swap back the allocator, which
|
// After swapping the FlatBufferBuilder, we swap back the allocator, which
|
||||||
@@ -67,23 +67,23 @@ struct GrpcLikeMessageBuilder : private AllocatorMember,
|
|||||||
};
|
};
|
||||||
|
|
||||||
flatbuffers::Offset<Monster> populate1(
|
flatbuffers::Offset<Monster> populate1(
|
||||||
flatbuffers::FlatBufferBuilder &builder) {
|
flatbuffers::FlatBufferBuilder& builder) {
|
||||||
auto name_offset = builder.CreateString(m1_name());
|
auto name_offset = builder.CreateString(m1_name());
|
||||||
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color());
|
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m1_color());
|
||||||
}
|
}
|
||||||
|
|
||||||
flatbuffers::Offset<Monster> populate2(
|
flatbuffers::Offset<Monster> populate2(
|
||||||
flatbuffers::FlatBufferBuilder &builder) {
|
flatbuffers::FlatBufferBuilder& builder) {
|
||||||
auto name_offset = builder.CreateString(m2_name());
|
auto name_offset = builder.CreateString(m2_name());
|
||||||
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color());
|
return CreateMonster(builder, nullptr, 0, 0, name_offset, 0, m2_color());
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *release_raw_base(flatbuffers::FlatBufferBuilder &fbb, size_t &size,
|
uint8_t* release_raw_base(flatbuffers::FlatBufferBuilder& fbb, size_t& size,
|
||||||
size_t &offset) {
|
size_t& offset) {
|
||||||
return fbb.ReleaseRaw(size, offset);
|
return fbb.ReleaseRaw(size, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
|
void free_raw(flatbuffers::grpc::MessageBuilder&, uint8_t*) {
|
||||||
// release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument
|
// release_raw_base calls FlatBufferBuilder::ReleaseRaw on the argument
|
||||||
// MessageBuilder. It's semantically wrong as MessageBuilder has its own
|
// MessageBuilder. It's semantically wrong as MessageBuilder has its own
|
||||||
// ReleaseRaw member function that takes three arguments. In such cases
|
// ReleaseRaw member function that takes three arguments. In such cases
|
||||||
@@ -94,26 +94,26 @@ void free_raw(flatbuffers::grpc::MessageBuilder &, uint8_t *) {
|
|||||||
// not occur with FlatBufferBuilder.
|
// not occur with FlatBufferBuilder.
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_raw(flatbuffers::FlatBufferBuilder &, uint8_t *buf) {
|
void free_raw(flatbuffers::FlatBufferBuilder&, uint8_t* buf) {
|
||||||
flatbuffers::DefaultAllocator().deallocate(buf, 0);
|
flatbuffers::DefaultAllocator().deallocate(buf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool verify(const flatbuffers::DetachedBuffer &buf,
|
bool verify(const flatbuffers::DetachedBuffer& buf,
|
||||||
const std::string &expected_name, Color color) {
|
const std::string& expected_name, Color color) {
|
||||||
const Monster *monster = flatbuffers::GetRoot<Monster>(buf.data());
|
const Monster* monster = flatbuffers::GetRoot<Monster>(buf.data());
|
||||||
return (monster->name()->str() == expected_name) &&
|
return (monster->name()->str() == expected_name) &&
|
||||||
(monster->color() == color);
|
(monster->color() == color);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool verify(const uint8_t *buf, size_t offset, const std::string &expected_name,
|
bool verify(const uint8_t* buf, size_t offset, const std::string& expected_name,
|
||||||
Color color) {
|
Color color) {
|
||||||
const Monster *monster = flatbuffers::GetRoot<Monster>(buf + offset);
|
const Monster* monster = flatbuffers::GetRoot<Monster>(buf + offset);
|
||||||
return (monster->name()->str() == expected_name) &&
|
return (monster->name()->str() == expected_name) &&
|
||||||
(monster->color() == color);
|
(monster->color() == color);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool release_n_verify(flatbuffers::FlatBufferBuilder &fbb,
|
bool release_n_verify(flatbuffers::FlatBufferBuilder& fbb,
|
||||||
const std::string &expected_name, Color color) {
|
const std::string& expected_name, Color color) {
|
||||||
flatbuffers::DetachedBuffer buf = fbb.Release();
|
flatbuffers::DetachedBuffer buf = fbb.Release();
|
||||||
return verify(buf, expected_name, color);
|
return verify(buf, expected_name, color);
|
||||||
}
|
}
|
||||||
@@ -131,8 +131,7 @@ void FlatBufferBuilderTest() {
|
|||||||
BuilderReuseTestSelector tests[4] = {
|
BuilderReuseTestSelector tests[4] = {
|
||||||
REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
|
REUSABLE_AFTER_RELEASE, REUSABLE_AFTER_RELEASE_RAW,
|
||||||
REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
|
REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN,
|
||||||
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
|
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN};
|
||||||
};
|
|
||||||
|
|
||||||
BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
|
BuilderReuseTests<FlatBufferBuilder, FlatBufferBuilder>::run_tests(
|
||||||
TestSelector(tests, tests + 4));
|
TestSelector(tests, tests + 4));
|
||||||
@@ -143,7 +142,7 @@ void FlatBufferBuilderTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// forward-declared in test_builder.h
|
// forward-declared in test_builder.h
|
||||||
void CheckTestGeneratedIsValid(const MyGame::Example::Color &);
|
void CheckTestGeneratedIsValid(const MyGame::Example::Color&);
|
||||||
|
|
||||||
// Link-time check using pointer type.
|
// Link-time check using pointer type.
|
||||||
void CheckTestGeneratedIsValid(const MyGame::Example::Color &) {}
|
void CheckTestGeneratedIsValid(const MyGame::Example::Color&) {}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ namespace flatbuffers {
|
|||||||
namespace tests {
|
namespace tests {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void NumericUtilsTestInteger(const char *lower, const char *upper) {
|
void NumericUtilsTestInteger(const char* lower, const char* upper) {
|
||||||
T x;
|
T x;
|
||||||
TEST_EQ(flatbuffers::StringToNumber("1q", &x), false);
|
TEST_EQ(flatbuffers::StringToNumber("1q", &x), false);
|
||||||
TEST_EQ(x, 0);
|
TEST_EQ(x, 0);
|
||||||
@@ -21,8 +21,8 @@ void NumericUtilsTestInteger(const char *lower, const char *upper) {
|
|||||||
TEST_EQ(x, expval);
|
TEST_EQ(x, expval);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template <typename T>
|
||||||
void NumericUtilsTestFloat(const char *lower, const char *upper) {
|
void NumericUtilsTestFloat(const char* lower, const char* upper) {
|
||||||
T f;
|
T f;
|
||||||
TEST_EQ(flatbuffers::StringToNumber("", &f), false);
|
TEST_EQ(flatbuffers::StringToNumber("", &f), false);
|
||||||
TEST_EQ(flatbuffers::StringToNumber("1q", &f), false);
|
TEST_EQ(flatbuffers::StringToNumber("1q", &f), false);
|
||||||
@@ -69,53 +69,51 @@ void UtilConvertCase() {
|
|||||||
std::vector<TestCase> cases;
|
std::vector<TestCase> cases;
|
||||||
|
|
||||||
// Tests for the common cases
|
// Tests for the common cases
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kUpperCamel,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kUpperCamel,
|
||||||
"TheQuickBrownFox" });
|
"TheQuickBrownFox"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kLowerCamel,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kLowerCamel,
|
||||||
"theQuickBrownFox" });
|
"theQuickBrownFox"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kSnake,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kSnake,
|
||||||
"the_quick_brown_fox" });
|
"the_quick_brown_fox"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kScreamingSnake,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kScreamingSnake,
|
||||||
"THE_QUICK_BROWN_FOX" });
|
"THE_QUICK_BROWN_FOX"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kAllLower,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kAllLower,
|
||||||
"the_quick_brown_fox" });
|
"the_quick_brown_fox"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kAllUpper,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kAllUpper,
|
||||||
"THE_QUICK_BROWN_FOX" });
|
"THE_QUICK_BROWN_FOX"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kUnknown,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kUnknown,
|
||||||
"the_quick_brown_fox" });
|
"the_quick_brown_fox"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kKeep,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kKeep,
|
||||||
"the_quick_brown_fox" });
|
"the_quick_brown_fox"});
|
||||||
cases.push_back({ "the_quick_brown_fox", flatbuffers::Case::kSnake2,
|
cases.push_back({"the_quick_brown_fox", flatbuffers::Case::kSnake2,
|
||||||
"the_quick_brown_fox" });
|
"the_quick_brown_fox"});
|
||||||
|
|
||||||
// Tests for some snake_cases where the _ is oddly placed or
|
// Tests for some snake_cases where the _ is oddly placed or
|
||||||
// missing.
|
// missing.
|
||||||
cases.push_back({ "single", flatbuffers::Case::kUpperCamel, "Single" });
|
cases.push_back({"single", flatbuffers::Case::kUpperCamel, "Single"});
|
||||||
cases.push_back({ "Single", flatbuffers::Case::kUpperCamel, "Single" });
|
cases.push_back({"Single", flatbuffers::Case::kUpperCamel, "Single"});
|
||||||
cases.push_back({ "_leading", flatbuffers::Case::kUpperCamel, "_Leading" });
|
cases.push_back({"_leading", flatbuffers::Case::kUpperCamel, "_Leading"});
|
||||||
cases.push_back(
|
cases.push_back({"trailing_", flatbuffers::Case::kUpperCamel, "Trailing_"});
|
||||||
{ "trailing_", flatbuffers::Case::kUpperCamel, "Trailing_" });
|
cases.push_back({"double__underscore", flatbuffers::Case::kUpperCamel,
|
||||||
cases.push_back({ "double__underscore", flatbuffers::Case::kUpperCamel,
|
"Double_underscore"});
|
||||||
"Double_underscore" });
|
cases.push_back({"single", flatbuffers::Case::kLowerCamel, "single"});
|
||||||
cases.push_back({ "single", flatbuffers::Case::kLowerCamel, "single" });
|
cases.push_back({"Single", flatbuffers::Case::kLowerCamel, "single"});
|
||||||
cases.push_back({ "Single", flatbuffers::Case::kLowerCamel, "single" });
|
cases.push_back({"_leading", flatbuffers::Case::kLowerCamel, "_Leading"});
|
||||||
cases.push_back({ "_leading", flatbuffers::Case::kLowerCamel, "_Leading" });
|
cases.push_back({"trailing_", flatbuffers::Case::kLowerCamel, "trailing_"});
|
||||||
cases.push_back(
|
cases.push_back({"double__underscore", flatbuffers::Case::kLowerCamel,
|
||||||
{ "trailing_", flatbuffers::Case::kLowerCamel, "trailing_" });
|
"double_underscore"});
|
||||||
cases.push_back({ "double__underscore", flatbuffers::Case::kLowerCamel,
|
|
||||||
"double_underscore" });
|
|
||||||
|
|
||||||
// Tests for some output snake_cases
|
// Tests for some output snake_cases
|
||||||
cases.push_back({ "single", flatbuffers::Case::kSnake, "single" });
|
cases.push_back({"single", flatbuffers::Case::kSnake, "single"});
|
||||||
cases.push_back({ "single", flatbuffers::Case::kScreamingSnake, "SINGLE" });
|
cases.push_back({"single", flatbuffers::Case::kScreamingSnake, "SINGLE"});
|
||||||
cases.push_back(
|
cases.push_back(
|
||||||
{ "_leading", flatbuffers::Case::kScreamingSnake, "_LEADING" });
|
{"_leading", flatbuffers::Case::kScreamingSnake, "_LEADING"});
|
||||||
cases.push_back(
|
cases.push_back(
|
||||||
{ "trailing_", flatbuffers::Case::kScreamingSnake, "TRAILING_" });
|
{"trailing_", flatbuffers::Case::kScreamingSnake, "TRAILING_"});
|
||||||
cases.push_back({ "double__underscore", flatbuffers::Case::kScreamingSnake,
|
cases.push_back({"double__underscore", flatbuffers::Case::kScreamingSnake,
|
||||||
"DOUBLE__UNDERSCORE" });
|
"DOUBLE__UNDERSCORE"});
|
||||||
|
|
||||||
for (auto &test_case : cases) {
|
for (auto& test_case : cases) {
|
||||||
TEST_EQ(test_case.expected_output,
|
TEST_EQ(test_case.expected_output,
|
||||||
flatbuffers::ConvertCase(test_case.input, test_case.output_case));
|
flatbuffers::ConvertCase(test_case.input, test_case.output_case));
|
||||||
}
|
}
|
||||||
@@ -132,38 +130,38 @@ void UtilConvertCase() {
|
|||||||
|
|
||||||
std::vector<TestCase> cases;
|
std::vector<TestCase> cases;
|
||||||
|
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "TheQuickBrownFox",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "TheQuickBrownFox",
|
||||||
flatbuffers::Case::kSnake, "the_quick_brown_fox" });
|
flatbuffers::Case::kSnake, "the_quick_brown_fox"});
|
||||||
cases.push_back({ flatbuffers::Case::kLowerCamel, "theQuickBrownFox",
|
cases.push_back({flatbuffers::Case::kLowerCamel, "theQuickBrownFox",
|
||||||
flatbuffers::Case::kSnake, "the_quick_brown_fox" });
|
flatbuffers::Case::kSnake, "the_quick_brown_fox"});
|
||||||
cases.push_back({ flatbuffers::Case::kSnake, "the_quick_brown_fox",
|
cases.push_back({flatbuffers::Case::kSnake, "the_quick_brown_fox",
|
||||||
flatbuffers::Case::kSnake, "the_quick_brown_fox" });
|
flatbuffers::Case::kSnake, "the_quick_brown_fox"});
|
||||||
cases.push_back({ flatbuffers::Case::kScreamingSnake, "THE_QUICK_BROWN_FOX",
|
cases.push_back({flatbuffers::Case::kScreamingSnake, "THE_QUICK_BROWN_FOX",
|
||||||
flatbuffers::Case::kSnake, "THE_QUICK_BROWN_FOX" });
|
flatbuffers::Case::kSnake, "THE_QUICK_BROWN_FOX"});
|
||||||
cases.push_back({ flatbuffers::Case::kAllUpper, "SINGLE",
|
cases.push_back({flatbuffers::Case::kAllUpper, "SINGLE",
|
||||||
flatbuffers::Case::kSnake, "SINGLE" });
|
flatbuffers::Case::kSnake, "SINGLE"});
|
||||||
cases.push_back({ flatbuffers::Case::kAllLower, "single",
|
cases.push_back({flatbuffers::Case::kAllLower, "single",
|
||||||
flatbuffers::Case::kSnake, "single" });
|
flatbuffers::Case::kSnake, "single"});
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "ABCtest",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "ABCtest",
|
||||||
flatbuffers::Case::kSnake, "abctest" });
|
flatbuffers::Case::kSnake, "abctest"});
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "tHe_qUiCk_BrOwN_fOx",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "tHe_qUiCk_BrOwN_fOx",
|
||||||
flatbuffers::Case::kKeep, "tHe_qUiCk_BrOwN_fOx" });
|
flatbuffers::Case::kKeep, "tHe_qUiCk_BrOwN_fOx"});
|
||||||
cases.push_back({ flatbuffers::Case::kLowerCamel, "theQuick12345Fox",
|
cases.push_back({flatbuffers::Case::kLowerCamel, "theQuick12345Fox",
|
||||||
flatbuffers::Case::kSnake, "the_quick_12345_fox" });
|
flatbuffers::Case::kSnake, "the_quick_12345_fox"});
|
||||||
cases.push_back({ flatbuffers::Case::kLowerCamel, "a12b34c45",
|
cases.push_back({flatbuffers::Case::kLowerCamel, "a12b34c45",
|
||||||
flatbuffers::Case::kSnake, "a_12b_34c_45" });
|
flatbuffers::Case::kSnake, "a_12b_34c_45"});
|
||||||
cases.push_back({ flatbuffers::Case::kLowerCamel, "a12b34c45",
|
cases.push_back({flatbuffers::Case::kLowerCamel, "a12b34c45",
|
||||||
flatbuffers::Case::kSnake2, "a12_b34_c45" });
|
flatbuffers::Case::kSnake2, "a12_b34_c45"});
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "Int32Stamped",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "Int32Stamped",
|
||||||
flatbuffers::Case::kSnake, "int_32_stamped" });
|
flatbuffers::Case::kSnake, "int_32_stamped"});
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "101DogsTest",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "101DogsTest",
|
||||||
flatbuffers::Case::kSnake, "101_dogs_test" });
|
flatbuffers::Case::kSnake, "101_dogs_test"});
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "Int32Stamped",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "Int32Stamped",
|
||||||
flatbuffers::Case::kScreamingSnake, "INT_32_STAMPED" });
|
flatbuffers::Case::kScreamingSnake, "INT_32_STAMPED"});
|
||||||
cases.push_back({ flatbuffers::Case::kUpperCamel, "101DogsTest",
|
cases.push_back({flatbuffers::Case::kUpperCamel, "101DogsTest",
|
||||||
flatbuffers::Case::kScreamingSnake, "101_DOGS_TEST" });
|
flatbuffers::Case::kScreamingSnake, "101_DOGS_TEST"});
|
||||||
|
|
||||||
for (auto &test_case : cases) {
|
for (auto& test_case : cases) {
|
||||||
TEST_EQ(test_case.expected_output,
|
TEST_EQ(test_case.expected_output,
|
||||||
flatbuffers::ConvertCase(test_case.input, test_case.output_case,
|
flatbuffers::ConvertCase(test_case.input, test_case.output_case,
|
||||||
test_case.input_case));
|
test_case.input_case));
|
||||||
|
|||||||
Reference in New Issue
Block a user