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:
Derek Bailey
2025-09-23 21:19:33 -07:00
committed by GitHub
parent 881eaab706
commit 0e047869da
84 changed files with 8178 additions and 6653 deletions

View File

@@ -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
... ...

View File

@@ -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 {

View File

@@ -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

View File

@@ -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();

View File

@@ -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(
decltype(static_cast<void (Stub::*)( std::is_member_function_pointer<
::grpc::ClientContext *, decltype(static_cast<void (Stub::*)(
const flatbuffers::grpc::Message<Monster> &, ::grpc::ClientContext*,
flatbuffers::grpc::Message<Stat> *, const flatbuffers::grpc::Message<Monster>&,
::grpc::ClientUnaryReactor *)>( flatbuffers::grpc::Message<Stat>*,
&Stub::async_Store))>::value, ::grpc::ClientUnaryReactor*)>(&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 &&

View File

@@ -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
@@ -351,15 +361,14 @@ void message_builder_tests() {
BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests(); BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
BuilderReuseTestSelector tests[6] = { BuilderReuseTestSelector tests[6] = {
// REUSABLE_AFTER_RELEASE, // Assertion failed: // REUSABLE_AFTER_RELEASE, // Assertion failed:
// (GRPC_SLICE_IS_EMPTY(slice_)) // (GRPC_SLICE_IS_EMPTY(slice_))
// REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == // REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p ==
// GRPC_SLICE_START_PTR(slice_) // GRPC_SLICE_START_PTR(slice_)
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));

View File

@@ -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,

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}; };

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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();
} }

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -41,14 +41,14 @@ 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
// sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align"). // sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
@@ -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);

View File

@@ -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 &params) : 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_;

View File

@@ -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

View File

@@ -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()) {

View File

@@ -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) {

View File

@@ -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,17 +340,14 @@ 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);
} }
bool IsOptional() const { return presence == kOptional; } bool IsOptional() const { return presence == kOptional; }
bool IsRequired() const { return presence == kRequired; } bool IsRequired() const { return presence == kRequired; }
@@ -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_

View File

@@ -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);

View File

@@ -47,28 +47,28 @@ inline bool IsLong(reflection::BaseType t) {
inline size_t GetTypeSize(reflection::BaseType base_type) { inline size_t GetTypeSize(reflection::BaseType base_type) {
// This needs to correspond to the BaseType enum. // This needs to correspond to the BaseType enum.
static size_t sizes[] = { static size_t sizes[] = {
0, // None 0, // None
1, // UType 1, // UType
1, // Bool 1, // Bool
1, // Byte 1, // Byte
1, // UByte 1, // UByte
2, // Short 2, // Short
2, // UShort 2, // UShort
4, // Int 4, // Int
4, // UInt 4, // UInt
8, // Long 8, // Long
8, // ULong 8, // ULong
4, // Float 4, // Float
8, // Double 8, // Double
4, // String 4, // String
4, // Vector 4, // Vector
4, // Obj 4, // Obj
4, // Union 4, // Union
0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds 0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds
// errors. // errors.
8, // Vector64 8, // Vector64
0 // MaxBaseType. This must be kept the last entry in this array. 0 // MaxBaseType. This must be kept the last entry in this array.
}; };
static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1, static_assert(sizeof(sizes) / sizeof(size_t) == reflection::MaxBaseType + 1,
"Size of sizes[] array does not match the count of BaseType " "Size of sizes[] array does not match the count of BaseType "
@@ -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);

View File

@@ -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_;
}; };

View File

@@ -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

View File

@@ -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];
}; };

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
} }

View File

@@ -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_;

View File

@@ -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)
@@ -80,7 +80,7 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
if (TrackVerifierBufferSize) { if (TrackVerifierBufferSize) {
auto upper_bound = elem + elem_len; auto upper_bound = elem + elem_len;
if (upper_bound_ < upper_bound) { if (upper_bound_ < upper_bound) {
upper_bound_ = upper_bound; upper_bound_ = upper_bound;
} }
} }
return Check(elem_len < size_ && elem <= size_ - elem_len); return Check(elem_len < size_ && elem <= size_ - elem_len);
@@ -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);
} }
@@ -303,7 +309,7 @@ class VerifierTemplate FLATBUFFERS_FINAL_CLASS {
uintptr_t size = upper_bound_; uintptr_t size = upper_bound_;
// Align the size to uoffset_t // Align the size to uoffset_t
size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1); size = (size - 1 + sizeof(uoffset_t)) & ~(sizeof(uoffset_t) - 1);
return (size > size_) ? 0 : size; return (size > size_) ? 0 : size;
} }
// Must use SizeVerifier, or (deprecated) turn on // Must use SizeVerifier, or (deprecated) turn on
// FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE, for this to work. // FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE, for this to work.
@@ -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);

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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 &region, 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 &region, const uint8_t *binary) {
return s; return s;
} }
template<> template <>
std::string ToValueString<std::string>(const BinaryRegion &region, 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 &region, 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 &region,
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 &region,
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 &region) { 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 &region, static void GenerateDocumentation(std::ostream& os, const BinaryRegion& region,
const BinarySection &section, 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 &region,
os << GenerateComment(region.comment, section); os << GenerateComment(region.comment, section);
} }
static void GenerateRegion(std::ostream &os, const BinaryRegion &region, static void GenerateRegion(std::ostream& os, const BinaryRegion& region,
const BinarySection &section, 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 &region,
} }
} }
static void GenerateSection(std::ostream &os, const BinarySection &section, 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 &section,
return; return;
} }
for (const BinaryRegion &region : 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 &section,
} // 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 &section : annotations_) { for (const auto& section : annotations_) {
for (const auto &region : 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 &section : annotations_) { for (const auto& section : annotations_) {
GenerateSection(ofs, section.second, binary_, output_config); GenerateSection(ofs, section.second, binary_, output_config);
} }

View File

@@ -39,38 +39,38 @@ 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,
/*fields=*/Case::kUpperCamel, /*fields=*/Case::kUpperCamel,
/*variables=*/Case::kLowerCamel, /*variables=*/Case::kLowerCamel,
/*variants=*/Case::kKeep, /*variants=*/Case::kKeep,
/*enum_variant_seperator=*/"", /*enum_variant_seperator=*/"",
/*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase, /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
/*namespaces=*/Case::kKeep, /*namespaces=*/Case::kKeep,
/*namespace_seperator=*/"__", /*namespace_seperator=*/"__",
/*object_prefix=*/"", /*object_prefix=*/"",
/*object_suffix=*/"", /*object_suffix=*/"",
/*keyword_prefix=*/"", /*keyword_prefix=*/"",
/*keyword_suffix=*/"_", /*keyword_suffix=*/"_",
/*filenames=*/Case::kKeep, /*filenames=*/Case::kKeep,
/*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));
} }

View File

@@ -40,53 +40,52 @@ namespace r = ::reflection;
std::set<std::string> NimKeywords() { std::set<std::string> NimKeywords() {
return { return {
"addr", "and", "as", "asm", "bind", "block", "addr", "and", "as", "asm", "bind", "block",
"break", "case", "cast", "concept", "const", "continue", "break", "case", "cast", "concept", "const", "continue",
"converter", "defer", "discard", "distinct", "div", "do", "converter", "defer", "discard", "distinct", "div", "do",
"elif", "else", "end", "enum", "except", "export", "elif", "else", "end", "enum", "except", "export",
"finally", "for", "from", "func", "if", "import", "finally", "for", "from", "func", "if", "import",
"in", "include", "interface", "is", "isnot", "iterator", "in", "include", "interface", "is", "isnot", "iterator",
"let", "macro", "method", "mixin", "mod", "nil", "let", "macro", "method", "mixin", "mod", "nil",
"not", "notin", "object", "of", "or", "out", "not", "notin", "object", "of", "or", "out",
"proc", "ptr", "raise", "ref", "return", "shl", "proc", "ptr", "raise", "ref", "return", "shl",
"shr", "static", "template", "try", "tuple", "type", "shr", "static", "template", "try", "tuple", "type",
"using", "var", "when", "while", "xor", "yield", "using", "var", "when", "while", "xor", "yield",
}; };
} }
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,
/*fields=*/Case::kLowerCamel, /*fields=*/Case::kLowerCamel,
/*variable=*/Case::kLowerCamel, /*variable=*/Case::kLowerCamel,
/*variants=*/Case::kUpperCamel, /*variants=*/Case::kUpperCamel,
/*enum_variant_seperator=*/".", /*enum_variant_seperator=*/".",
/*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase, /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
/*namespaces=*/Case::kKeep, /*namespaces=*/Case::kKeep,
/*namespace_seperator=*/"/", /*namespace_seperator=*/"/",
/*object_prefix=*/"", /*object_prefix=*/"",
/*object_suffix=*/"T", /*object_suffix=*/"T",
/*keyword_prefix=*/"", /*keyword_prefix=*/"",
/*keyword_suffix=*/"_", /*keyword_suffix=*/"_",
/*filenames=*/Case::kKeep, /*filenames=*/Case::kKeep,
/*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));
} }

View File

@@ -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 &region) { 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> &regions, 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 &current_section : sections_) { for (auto& current_section : sections_) {
BinarySection &section = 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 &region = 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 &current_section : sections_) { for (auto& current_section : sections_) {
BinarySection &section = 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 &section_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_);
} }

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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 "
"includes as well. If the language uses a single file for output (by " "it "
"default the case for C++ and JS), all code will end up in this one " "includes as well. If the language uses a single file for output (by "
"file." }, "default the case for C++ and JS), all code will end up in this one "
{ "", "gen-json-emit", "", "file."},
"Generates encoding code which emits Flatbuffers into JSON" }, {"", "gen-json-emit", "",
{ "", "cpp-include", "", "Adds an #include in generated file." }, "Generates encoding code which emits Flatbuffers into JSON"},
{ "", "cpp-ptr-type", "T", {"", "cpp-include", "", "Adds an #include in generated file."},
"Set object API pointer type (default std::unique_ptr)." }, {"", "cpp-ptr-type", "T",
{ "", "cpp-str-type", "T", "Set object API pointer type (default std::unique_ptr)."},
"Set object API string type (default std::string). T::c_str(), T::length() " {"", "cpp-str-type", "T",
"and T::empty() must be supported. The custom type also needs to be " "Set object API string type (default std::string). T::c_str(), "
"constructible from std::string (see the --cpp-str-flex-ctor option to " "T::length() "
"change this behavior)" }, "and T::empty() must be supported. The custom type also needs to be "
{ "", "cpp-str-flex-ctor", "", "constructible from std::string (see the --cpp-str-flex-ctor option to "
"Don't construct custom string types by passing std::string from " "change this behavior)"},
"Flatbuffers, but (char* + length)." }, {"", "cpp-str-flex-ctor", "",
{ "", "cpp-field-case-style", "STYLE", "Don't construct custom string types by passing std::string from "
"Generate C++ fields using selected case style. Supported STYLE values: * " "Flatbuffers, but (char* + length)."},
"'unchanged' - leave unchanged (default) * 'upper' - schema snake_case " {"", "cpp-field-case-style", "STYLE",
"emits UpperCamel; * 'lower' - schema snake_case emits lowerCamel." }, "Generate C++ fields using selected case style. Supported STYLE values: * "
{ "", "cpp-std", "CPP_STD", "'unchanged' - leave unchanged (default) * 'upper' - schema snake_case "
"Generate a C++ code using features of selected C++ standard. Supported " "emits UpperCamel; * 'lower' - schema snake_case emits lowerCamel."},
"CPP_STD values: * 'c++0x' - generate code compatible with old compilers; " {"", "cpp-std", "CPP_STD",
"'c++11' - use C++11 code generator (default); * 'c++17' - use C++17 " "Generate a C++ code using features of selected C++ standard. Supported "
"features in generated code (experimental)." }, "CPP_STD values: * 'c++0x' - generate code compatible with old compilers; "
{ "", "cpp-static-reflection", "", "'c++11' - use C++11 code generator (default); * 'c++17' - use C++17 "
"When using C++17, generate extra code to provide compile-time (static) " "features in generated code (experimental)."},
"reflection of Flatbuffers types. Requires --cpp-std to be \"c++17\" or " {"", "cpp-static-reflection", "",
"higher." }, "When using C++17, generate extra code to provide compile-time (static) "
{ "", "object-prefix", "PREFIX", "reflection of Flatbuffers types. Requires --cpp-std to be \"c++17\" or "
"Customize class prefix for C++ object-based API." }, "higher."},
{ "", "object-suffix", "SUFFIX", {"", "object-prefix", "PREFIX",
"Customize class suffix for C++ object-based API. Default Value is " "Customize class prefix for C++ object-based API."},
"\"T\"." }, {"", "object-suffix", "SUFFIX",
{ "", "go-namespace", "", "Generate the overriding namespace in Golang." }, "Customize class suffix for C++ object-based API. Default Value is "
{ "", "go-import", "IMPORT", "\"T\"."},
"Generate the overriding import for flatbuffers in Golang (default is " {"", "go-namespace", "", "Generate the overriding namespace in Golang."},
"\"github.com/google/flatbuffers/go\")." }, {"", "go-import", "IMPORT",
{ "", "go-module-name", "", "Generate the overriding import for flatbuffers in Golang (default is "
"Prefix local import paths of generated go code with the module name" }, "\"github.com/google/flatbuffers/go\")."},
{ "", "raw-binary", "", {"", "go-module-name", "",
"Allow binaries without file_identifier to be read. This may crash flatc " "Prefix local import paths of generated go code with the module name"},
"given a mismatched schema." }, {"", "raw-binary", "",
{ "", "size-prefixed", "", "Input binaries are size prefixed buffers." }, "Allow binaries without file_identifier to be read. This may crash flatc "
{ "", "proto-namespace-suffix", "SUFFIX", "given a mismatched schema."},
"Add this namespace to any flatbuffers generated from protobufs." }, {"", "size-prefixed", "", "Input binaries are size prefixed buffers."},
{ "", "oneof-union", "", "Translate .proto oneofs to flatbuffer unions." }, {"", "proto-namespace-suffix", "SUFFIX",
{ "", "keep-proto-id", "", "Keep protobuf field ids in generated fbs file." }, "Add this namespace to any flatbuffers generated from protobufs."},
{ "", "proto-id-gap", "", {"", "oneof-union", "", "Translate .proto oneofs to flatbuffer unions."},
"Action that should be taken when a gap between protobuf ids found. " {"", "keep-proto-id", "", "Keep protobuf field ids in generated fbs file."},
"Supported values: * " {"", "proto-id-gap", "",
"'nop' - do not care about gap * 'warn' - A warning message will be shown " "Action that should be taken when a gap between protobuf ids found. "
"about the gap in protobuf ids" "Supported values: * "
"(default) " "'nop' - do not care about gap * 'warn' - A warning message will be shown "
"* 'error' - An error message will be shown and the fbs generation will be " "about the gap in protobuf ids"
"interrupted." }, "(default) "
{ "", "grpc", "", "Generate GRPC interfaces for the specified languages." }, "* 'error' - An error message will be shown and the fbs generation will "
{ "", "schema", "", "Serialize schemas instead of JSON (use with -b)." }, "be "
{ "", "bfbs-filenames", "PATH", "interrupted."},
"Sets the root path where reflection filenames in reflection.fbs are " {"", "grpc", "", "Generate GRPC interfaces for the specified languages."},
"relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c " {"", "schema", "", "Serialize schemas instead of JSON (use with -b)."},
"then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to the " {"", "bfbs-filenames", "PATH",
"directory of the first provided schema file." }, "Sets the root path where reflection filenames in reflection.fbs are "
{ "", "bfbs-absolute-paths", "", "Uses absolute paths instead of relative paths in the BFBS output." }, "relative to. The 'root' is denoted with `//`. E.g. if PATH=/a/b/c "
{ "", "bfbs-comments", "", "Add doc comments to the binary schema files." }, "then /a/d/e.fbs will be serialized as //../d/e.fbs. (PATH defaults to "
{ "", "bfbs-builtins", "", "the "
"Add builtin attributes to the binary schema files." }, "directory of the first provided schema file."},
{ "", "bfbs-gen-embed", "", {"", "bfbs-absolute-paths", "",
"Generate code to embed the bfbs schema to the source." }, "Uses absolute paths instead of relative paths in the BFBS output."},
{ "", "conform", "FILE", {"", "bfbs-comments", "", "Add doc comments to the binary schema files."},
"Specify a schema the following schemas should be an evolution of. Gives " {"", "bfbs-builtins", "",
"errors if not." }, "Add builtin attributes to the binary schema files."},
{ "", "conform-includes", "PATH", {"", "bfbs-gen-embed", "",
"Include path for the schema given with --conform PATH" }, "Generate code to embed the bfbs schema to the source."},
{ "", "filename-suffix", "SUFFIX", {"", "conform", "FILE",
"The suffix appended to the generated file names (Default is " "Specify a schema the following schemas should be an evolution of. Gives "
"'_generated')." }, "errors if not."},
{ "", "filename-ext", "EXT", {"", "conform-includes", "PATH",
"The extension appended to the generated file names. Default is " "Include path for the schema given with --conform PATH"},
"language-specific (e.g., '.h' for C++)" }, {"", "filename-suffix", "SUFFIX",
{ "", "include-prefix", "PATH", "The suffix appended to the generated file names (Default is "
"Prefix this PATH to any generated include statements." }, "'_generated')."},
{ "", "keep-prefix", "", {"", "filename-ext", "EXT",
"Keep original prefix of schema include statement." }, "The extension appended to the generated file names. Default is "
{ "", "reflect-types", "", "language-specific (e.g., '.h' for C++)"},
"Add minimal type reflection to code generation." }, {"", "include-prefix", "PATH",
{ "", "reflect-names", "", "Add minimal type/name reflection." }, "Prefix this PATH to any generated include statements."},
{ "", "rust-serialize", "", {"", "keep-prefix", "",
"Implement serde::Serialize on generated Rust types." }, "Keep original prefix of schema include statement."},
{ "", "rust-module-root-file", "", {"", "reflect-types", "",
"Generate rust code in individual files with a module root file." }, "Add minimal type reflection to code generation."},
{ "", "root-type", "T", "Select or override the default root_type." }, {"", "reflect-names", "", "Add minimal type/name reflection."},
{ "", "require-explicit-ids", "", {"", "rust-serialize", "",
"When parsing schemas, require explicit ids (id: x)." }, "Implement serde::Serialize on generated Rust types."},
{ "", "force-defaults", "", {"", "rust-module-root-file", "",
"Emit default values in binary output from JSON" }, "Generate rust code in individual files with a module root file."},
{ "", "force-empty", "", {"", "root-type", "T", "Select or override the default root_type."},
"When serializing from object API representation, force strings and " {"", "require-explicit-ids", "",
"vectors to empty rather than null." }, "When parsing schemas, require explicit ids (id: x)."},
{ "", "force-empty-vectors", "", {"", "force-defaults", "",
"When serializing from object API representation, force vectors to empty " "Emit default values in binary output from JSON"},
"rather than null." }, {"", "force-empty", "",
{ "", "flexbuffers", "", "When serializing from object API representation, force strings and "
"Used with \"binary\" and \"json\" options, it generates data using " "vectors to empty rather than null."},
"schema-less FlexBuffers." }, {"", "force-empty-vectors", "",
{ "", "no-warnings", "", "Inhibit all warnings messages." }, "When serializing from object API representation, force vectors to empty "
{ "", "warnings-as-errors", "", "Treat all warnings as errors." }, "rather than null."},
{ "", "cs-global-alias", "", {"", "flexbuffers", "",
"Prepend \"global::\" to all user generated csharp classes and " "Used with \"binary\" and \"json\" options, it generates data using "
"structs." }, "schema-less FlexBuffers."},
{ "", "cs-gen-json-serializer", "", {"", "no-warnings", "", "Inhibit all warnings messages."},
"Allows (de)serialization of JSON text in the Object API. (requires " {"", "warnings-as-errors", "", "Treat all warnings as errors."},
"--gen-object-api)." }, {"", "cs-global-alias", "",
{ "", "json-nested-bytes", "", "Prepend \"global::\" to all user generated csharp classes and "
"Allow a nested_flatbuffer field to be parsed as a vector of bytes " "structs."},
"in JSON, which is unsafe unless checked by a verifier afterwards." }, {"", "cs-gen-json-serializer", "",
{ "", "ts-flat-files", "", "Allows (de)serialization of JSON text in the Object API. (requires "
"Generate a single typescript file per .fbs file. Implies " "--gen-object-api)."},
"ts_entry_points." }, {"", "json-nested-bytes", "",
{ "", "ts-entry-points", "", "Allow a nested_flatbuffer field to be parsed as a vector of bytes "
"Generate entry point typescript per namespace. Implies gen-all." }, "in JSON, which is unsafe unless checked by a verifier afterwards."},
{ "", "annotate-sparse-vectors", "", "Don't annotate every vector element." }, {"", "ts-flat-files", "",
{ "", "annotate", "SCHEMA", "Generate a single typescript file per .fbs file. Implies "
"Annotate the provided BINARY_FILE with the specified SCHEMA file." }, "ts_entry_points."},
{ "", "no-leak-private-annotation", "", {"", "ts-entry-points", "",
"Prevents multiple type of annotations within a Fbs SCHEMA file. " "Generate entry point typescript per namespace. Implies gen-all."},
"Currently this is required to generate private types in Rust" }, {"", "annotate-sparse-vectors", "", "Don't annotate every vector element."},
{ "", "python-no-type-prefix-suffix", "", {"", "annotate", "SCHEMA",
"Skip emission of Python functions that are prefixed with typenames" }, "Annotate the provided BINARY_FILE with the specified SCHEMA file."},
{ "", "python-typing", "", "Generate Python type annotations" }, {"", "no-leak-private-annotation", "",
{ "", "python-version", "", "Generate code for the given Python version." }, "Prevents multiple type of annotations within a Fbs SCHEMA file. "
{ "", "python-decode-obj-api-strings", "", "Decode bytes to strings for the Python Object API"}, "Currently this is required to generate private types in Rust"},
{ "", "python-gen-numpy", "", "Whether to generate numpy helpers." }, {"", "python-no-type-prefix-suffix", "",
{ "", "ts-omit-entrypoint", "", "Skip emission of Python functions that are prefixed with typenames"},
"Omit emission of namespace entrypoint file" }, {"", "python-typing", "", "Generate Python type annotations"},
{ "", "file-names-only", "", {"", "python-version", "", "Generate code for the given Python version."},
"Print out generated file names without writing to the files" }, {"", "python-decode-obj-api-strings", "",
{ "", "grpc-filename-suffix", "SUFFIX", "Decode bytes to strings for the Python Object API"},
"The suffix for the generated file names (Default is '.fb')." }, {"", "python-gen-numpy", "", "Whether to generate numpy helpers."},
{ "", "grpc-additional-header", "", {"", "ts-omit-entrypoint", "",
"Additional headers to prepend to the generated files." }, "Omit emission of namespace entrypoint file"},
{ "", "grpc-use-system-headers", "", {"", "file-names-only", "",
"Use <> for headers included from the generated code." }, "Print out generated file names without writing to the files"},
{ "", "grpc-search-path", "PATH", "Prefix to any gRPC includes." }, {"", "grpc-filename-suffix", "SUFFIX",
{ "", "grpc-python-typed-handlers", "", "The suffix for the generated file names (Default is '.fb')."},
"The handlers will use the generated classes rather than raw bytes." }, {"", "grpc-additional-header", "",
{ "", "grpc-callback-api", "", "Additional headers to prepend to the generated files."},
"Generate gRPC code using the callback (reactor) API instead of legacy " {"", "grpc-use-system-headers", "",
"sync/async." }, "Use <> for headers included from the generated code."},
{"", "grpc-search-path", "PATH", "Prefix to any gRPC includes."},
{"", "grpc-python-typed-handlers", "",
"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 "
"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,

View File

@@ -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.

View File

@@ -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")

View File

@@ -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

View File

@@ -33,43 +33,45 @@ 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.
/*fields=*/Case::kLowerCamel, /*fields=*/Case::kLowerCamel,
/*variables=*/Case::kLowerCamel, /*variables=*/Case::kLowerCamel,
/*variants=*/Case::kKeep, /*variants=*/Case::kKeep,
/*enum_variant_seperator=*/".", /*enum_variant_seperator=*/".",
/*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase, /*escape_keywords=*/Namer::Config::Escape::AfterConvertingCase,
/*namespaces=*/Case::kSnake2, /*namespaces=*/Case::kSnake2,
/*namespace_seperator=*/".", /*namespace_seperator=*/".",
/*object_prefix=*/"", /*object_prefix=*/"",
/*object_suffix=*/"T", /*object_suffix=*/"T",
/*keyword_prefix=*/"$", /*keyword_prefix=*/"$",
/*keyword_suffix=*/"", /*keyword_suffix=*/"",
/*filenames=*/Case::kKeep, /*filenames=*/Case::kKeep,
/*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",
"dynamic", "implements", "set", "required", "while", "deferred", "hide", "rethrow",
"with", "do", "if", "return", "yield",
"dynamic", "implements", "set",
}; };
} }
} // namespace } // namespace
@@ -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;

View File

@@ -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

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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;

View File

@@ -38,56 +38,56 @@ 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,
/*fields=*/Case::kLowerCamel, /*fields=*/Case::kLowerCamel,
/*variables=*/Case::kLowerCamel, /*variables=*/Case::kLowerCamel,
/*variants=*/Case::kKeep, /*variants=*/Case::kKeep,
/*enum_variant_seperator=*/"", // I.e. Concatenate. /*enum_variant_seperator=*/"", // I.e. Concatenate.
/*escape_keywords=*/Namer::Config::Escape::BeforeConvertingCase, /*escape_keywords=*/Namer::Config::Escape::BeforeConvertingCase,
/*namespaces=*/Case::kKeep, /*namespaces=*/Case::kKeep,
/*namespace_seperator=*/"__", /*namespace_seperator=*/"__",
/*object_prefix=*/"", /*object_prefix=*/"",
/*object_suffix=*/"T", /*object_suffix=*/"T",
/*keyword_prefix=*/"", /*keyword_prefix=*/"",
/*keyword_suffix=*/"_", /*keyword_suffix=*/"_",
/*filenames=*/Case::kKeep, /*filenames=*/Case::kKeep,
/*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 &params, 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 &params, 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 &params, 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 &params, 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 &not_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()> &not_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

View File

@@ -29,38 +29,38 @@ 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",
"enum", "typeof", "var", "let", "pakfile", "switch", "enum", "typeof", "var", "let", "pakfile", "switch",
"case", "default", "namespace", "not", "and", "or", "case", "default", "namespace", "not", "and", "or",
"bool", "bool",
}; };
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;

View File

@@ -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

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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,8 +153,8 @@ 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++) {
// get union type from the prev field // get union type from the prev field
@@ -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) {
@@ -351,14 +367,16 @@ std::string GetAnyValueS(reflection::BaseType type, const uint8_t *data,
return "(table)"; return "(table)";
} }
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),

View File

@@ -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,19 +316,19 @@ 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
#ifdef _WIN32 #ifdef _WIN32
(void)_mkdir(filepath.c_str()); (void)_mkdir(filepath.c_str());
@@ -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;
} }
} }

View File

@@ -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);

View File

@@ -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];

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);

View File

@@ -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(),

View File

@@ -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,9 +395,9 @@ 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(),
}; };
for (size_t i = 0; i < sizeof(tests_array) / sizeof(tests_array[0]); ++i) { for (size_t i = 0; i < sizeof(tests_array) / sizeof(tests_array[0]); ++i) {
auto tests = tests_array[i]; auto tests = tests_array[i];
@@ -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,21 +791,21 @@ 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 {
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true); TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
} }
@@ -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,

View File

@@ -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

View File

@@ -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);
} }

View File

@@ -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,17 +33,17 @@ 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
static bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; } static bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
@@ -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,11 +847,14 @@ 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;
TEST_EQ(parser3.Parse(source), false); TEST_EQ(parser3.Parse(source), false);
} }
@@ -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);
} }
} }

View File

@@ -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");

View File

@@ -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(

View File

@@ -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,48 +856,46 @@ 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);
std::array<MyGame::Example::ArrayStruct, 3> arr_struct = { std::array<MyGame::Example::ArrayStruct, 3> arr_struct = {
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);
@@ -1578,38 +1577,36 @@ void DoNotRequireEofTest(const std::string &tests_data_path) {
#endif #endif
void UnionUnderlyingTypeTest() { void UnionUnderlyingTypeTest() {
using namespace UnionUnderlyingType; using namespace UnionUnderlyingType;
TEST_ASSERT(sizeof(ABC) == sizeof(uint32_t)); TEST_ASSERT(sizeof(ABC) == sizeof(uint32_t));
TEST_ASSERT(static_cast<int32_t>(ABC::A) == 555); TEST_ASSERT(static_cast<int32_t>(ABC::A) == 555);
TEST_ASSERT(static_cast<int32_t>(ABC::B) == 666); TEST_ASSERT(static_cast<int32_t>(ABC::B) == 666);
TEST_ASSERT(static_cast<int32_t>(ABC::C) == 777); TEST_ASSERT(static_cast<int32_t>(ABC::C) == 777);
DT buffer; DT buffer;
AT a; AT a;
a.a = 42; a.a = 42;
BT b; BT b;
b.b = "foo"; b.b = "foo";
CT c; CT c;
c.c = true; c.c = true;
buffer.test_union = ABCUnion(); buffer.test_union = ABCUnion();
buffer.test_union.Set(a); buffer.test_union.Set(a);
buffer.test_vector_of_union.resize(3); buffer.test_vector_of_union.resize(3);
buffer.test_vector_of_union[0].Set(a); buffer.test_vector_of_union[0].Set(a);
buffer.test_vector_of_union[1].Set(b); buffer.test_vector_of_union[1].Set(b);
buffer.test_vector_of_union[2].Set(c); buffer.test_vector_of_union[2].Set(c);
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
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_vector_of_union == buffer.test_vector_of_union);
TEST_ASSERT(unpacked.test_union == buffer.test_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++) {

View File

@@ -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) {

View File

@@ -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);
} }
@@ -129,10 +129,9 @@ void FlatBufferBuilderTest() {
BuilderTests<GrpcLikeMessageBuilder>::all_tests(); BuilderTests<GrpcLikeMessageBuilder>::all_tests();
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&) {}

View File

@@ -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));