Merge branch 'master' of github.com:google/flatbuffers

This commit is contained in:
Max Burke
2019-11-27 10:51:24 -08:00
110 changed files with 9887 additions and 5568 deletions

View File

@@ -1,6 +1,8 @@
Thank you for submitting a PR! Thank you for submitting a PR!
Please make sure you include the names of the affected language(s) in your PR title. Please delete this standard text once you've created your own description.
Make sure you include the names of the affected language(s) in your PR title.
This helps us get the correct maintainers to look at your issue. This helps us get the correct maintainers to look at your issue.
If you make changes to any of the code generators, be sure to run If you make changes to any of the code generators, be sure to run
@@ -11,6 +13,8 @@ If your PR includes C++ code, please adhere to the Google C++ Style Guide,
and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3), and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
so only some C++11 support is available. so only some C++11 support is available.
For any C++ changes, please make sure to run `sh src/clang-format-git.sh`
Include other details as appropriate. Include other details as appropriate.
Thanks! Thanks!

View File

@@ -15,10 +15,15 @@
# limitations under the License. # limitations under the License.
set -e set -e
# build flatc on debian once to speed up the test loop below docker build -t build_cpp_image -f tests/docker/Dockerfile.testing.cpp.debian_buster .
docker build -t build_flatc_debian_stretch -f tests/docker/Dockerfile.testing.build_flatc_debian_stretch . # Run tests with sanitizers (--cap-add SYS_PTRACE), both GCC and Clang.
BUILD_CONTAINER_ID=$(docker create --read-only build_flatc_debian_stretch) cpp_test_args="--cap-add SYS_PTRACE build_cpp_image sh ./tests/docker/cpp_test.run.sh Debug"
docker cp ${BUILD_CONTAINER_ID}:/code/flatc flatc_debian_stretch docker run --rm $cpp_test_args
docker run --rm --env CC=/usr/bin/clang --env CXX=/usr/bin/clang++ $cpp_test_args
# Build flatc on debian once to speed up the test loop below.
docker run --name flatc_container build_cpp_image sh ./tests/docker/build_flatc.run.sh Debug
# All dependent dockers refer to 'flatc_debian_stretch'.
docker cp flatc_container:/flatbuffers/flatc flatc_debian_stretch
for f in $(ls tests/docker/languages | sort) for f in $(ls tests/docker/languages | sort)
do do

14
BUILD
View File

@@ -22,7 +22,6 @@ cc_library(
srcs = [ srcs = [
"src/code_generators.cpp", "src/code_generators.cpp",
"src/idl_gen_fbs.cpp", "src/idl_gen_fbs.cpp",
"src/idl_gen_general.cpp",
"src/idl_gen_text.cpp", "src/idl_gen_text.cpp",
"src/idl_parser.cpp", "src/idl_parser.cpp",
"src/reflection.cpp", "src/reflection.cpp",
@@ -81,15 +80,19 @@ cc_binary(
"grpc/src/compiler/cpp_generator.h", "grpc/src/compiler/cpp_generator.h",
"grpc/src/compiler/go_generator.cc", "grpc/src/compiler/go_generator.cc",
"grpc/src/compiler/go_generator.h", "grpc/src/compiler/go_generator.h",
"grpc/src/compiler/python_generator.cc",
"grpc/src/compiler/python_generator.h",
"grpc/src/compiler/python_private_generator.h",
"grpc/src/compiler/java_generator.cc", "grpc/src/compiler/java_generator.cc",
"grpc/src/compiler/java_generator.h", "grpc/src/compiler/java_generator.h",
"grpc/src/compiler/schema_interface.h", "grpc/src/compiler/schema_interface.h",
"src/flatc_main.cpp", "src/flatc_main.cpp",
"src/idl_gen_cpp.cpp", "src/idl_gen_cpp.cpp",
"src/idl_gen_csharp.cpp",
"src/idl_gen_dart.cpp", "src/idl_gen_dart.cpp",
"src/idl_gen_general.cpp",
"src/idl_gen_go.cpp", "src/idl_gen_go.cpp",
"src/idl_gen_grpc.cpp", "src/idl_gen_grpc.cpp",
"src/idl_gen_java.cpp",
"src/idl_gen_js_ts.cpp", "src/idl_gen_js_ts.cpp",
"src/idl_gen_json_schema.cpp", "src/idl_gen_json_schema.cpp",
"src/idl_gen_kotlin.cpp", "src/idl_gen_kotlin.cpp",
@@ -132,11 +135,12 @@ cc_test(
"include/flatbuffers/registry.h", "include/flatbuffers/registry.h",
"src/code_generators.cpp", "src/code_generators.cpp",
"src/idl_gen_fbs.cpp", "src/idl_gen_fbs.cpp",
"src/idl_gen_general.cpp",
"src/idl_gen_text.cpp", "src/idl_gen_text.cpp",
"src/idl_parser.cpp", "src/idl_parser.cpp",
"src/reflection.cpp", "src/reflection.cpp",
"src/util.cpp", "src/util.cpp",
"tests/evolution_test/evolution_v1_generated.h",
"tests/evolution_test/evolution_v2_generated.h",
"tests/namespace_test/namespace_test1_generated.h", "tests/namespace_test/namespace_test1_generated.h",
"tests/namespace_test/namespace_test2_generated.h", "tests/namespace_test/namespace_test2_generated.h",
"tests/native_type_test_impl.cpp", "tests/native_type_test_impl.cpp",
@@ -157,6 +161,10 @@ cc_test(
":tests/arrays_test.bfbs", ":tests/arrays_test.bfbs",
":tests/arrays_test.fbs", ":tests/arrays_test.fbs",
":tests/arrays_test.golden", ":tests/arrays_test.golden",
":tests/evolution_test/evolution_v1.fbs",
":tests/evolution_test/evolution_v1.json",
":tests/evolution_test/evolution_v2.fbs",
":tests/evolution_test/evolution_v2.json",
":tests/include_test/include_test1.fbs", ":tests/include_test/include_test1.fbs",
":tests/include_test/sub/include_test2.fbs", ":tests/include_test/sub/include_test2.fbs",
":tests/monster_extra.fbs", ":tests/monster_extra.fbs",

View File

@@ -13,6 +13,8 @@ option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
ON) ON)
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler" option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
ON) ON)
option(FLATBUFFERS_STATIC_FLATC "Build flatbuffers compiler with -static flag"
OFF)
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON) option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF) option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
option(FLATBUFFERS_BUILD_SHAREDLIB option(FLATBUFFERS_BUILD_SHAREDLIB
@@ -81,10 +83,11 @@ set(FlatBuffers_Library_SRCS
set(FlatBuffers_Compiler_SRCS set(FlatBuffers_Compiler_SRCS
${FlatBuffers_Library_SRCS} ${FlatBuffers_Library_SRCS}
src/idl_gen_cpp.cpp src/idl_gen_cpp.cpp
src/idl_gen_csharp.cpp
src/idl_gen_dart.cpp src/idl_gen_dart.cpp
src/idl_gen_general.cpp
src/idl_gen_kotlin.cpp src/idl_gen_kotlin.cpp
src/idl_gen_go.cpp src/idl_gen_go.cpp
src/idl_gen_java.cpp
src/idl_gen_js_ts.cpp src/idl_gen_js_ts.cpp
src/idl_gen_php.cpp src/idl_gen_php.cpp
src/idl_gen_python.cpp src/idl_gen_python.cpp
@@ -103,6 +106,9 @@ set(FlatBuffers_Compiler_SRCS
grpc/src/compiler/go_generator.cc grpc/src/compiler/go_generator.cc
grpc/src/compiler/java_generator.h grpc/src/compiler/java_generator.h
grpc/src/compiler/java_generator.cc grpc/src/compiler/java_generator.cc
grpc/src/compiler/python_generator.h
grpc/src/compiler/python_private_generator.h
grpc/src/compiler/python_generator.cc
) )
set(FlatHash_SRCS set(FlatHash_SRCS
@@ -146,7 +152,6 @@ set(FlatBuffers_Sample_Text_SRCS
set(FlatBuffers_Sample_BFBS_SRCS set(FlatBuffers_Sample_BFBS_SRCS
${FlatBuffers_Library_SRCS} ${FlatBuffers_Library_SRCS}
src/idl_gen_general.cpp
samples/sample_bfbs.cpp samples/sample_bfbs.cpp
# file generated by running compiler on samples/monster.fbs # file generated by running compiler on samples/monster.fbs
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h ${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
@@ -292,6 +297,9 @@ if(FLATBUFFERS_BUILD_FLATC)
# Make flatc.exe not depend on runtime dlls for easy distribution. # Make flatc.exe not depend on runtime dlls for easy distribution.
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>) target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
endif() endif()
if(FLATBUFFERS_STATIC_FLATC AND NOT MSVC)
target_link_libraries(flatc PRIVATE -static)
endif()
endif() endif()
if(FLATBUFFERS_BUILD_FLATHASH) if(FLATBUFFERS_BUILD_FLATHASH)

View File

@@ -187,7 +187,7 @@
same "printed page" as the copyright notice for easier same "printed page" as the copyright notice for easier
identification within third-party archives. identification within third-party archives.
Copyright 2014 Google Inc. Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License"); Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. you may not use this file except in compliance with the License.

View File

@@ -53,8 +53,7 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
tests/test_builder.cpp \ tests/test_builder.cpp \
tests/native_type_test_impl.h \ tests/native_type_test_impl.h \
tests/native_type_test_impl.cpp \ tests/native_type_test_impl.cpp \
src/idl_gen_fbs.cpp \ src/idl_gen_fbs.cpp
src/idl_gen_general.cpp
LOCAL_LDLIBS := -llog -landroid -latomic LOCAL_LDLIBS := -llog -landroid -latomic
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
LOCAL_ARM_MODE := arm LOCAL_ARM_MODE := arm

View File

@@ -0,0 +1,639 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstring>
#include <fstream>
#include <iostream>
#include <map>
#include <memory>
#include <ostream>
#include <set>
#include <sstream>
#include <tuple>
#include <vector>
#include "flatbuffers/util.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_private_generator.h"
using std::make_pair;
using std::map;
using std::pair;
using std::replace;
using std::tuple;
using std::vector;
using std::set;
namespace grpc_python_generator {
grpc::string generator_file_name;
typedef map<grpc::string, grpc::string> StringMap;
typedef vector<grpc::string> StringVector;
typedef tuple<grpc::string, grpc::string> StringPair;
typedef set<StringPair> StringPairSet;
// Provides RAII indentation handling. Use as:
// {
// IndentScope raii_my_indent_var_name_here(my_py_printer);
// // constructor indented my_py_printer
// ...
// // destructor called at end of scope, un-indenting my_py_printer
// }
class IndentScope {
public:
explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
printer_->Indent();
}
~IndentScope() { printer_->Outdent(); }
private:
grpc_generator::Printer* printer_;
};
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
const grpc::string& to, bool replace_all) {
size_t pos = 0;
do {
pos = str.find(from, pos);
if (pos == grpc::string::npos) {
break;
}
str.replace(pos, from.length(), to);
pos += to.length();
} while (replace_all);
return str;
}
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
const grpc::string& to) {
return StringReplace(str, from, to, true);
}
grpc::string ModuleName(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string basename = flatbuffers::StripExtension(filename);
basename = StringReplace(basename, "-", "_");
basename = StringReplace(basename, "/", ".");
return import_prefix + basename + "_fb";
}
grpc::string ModuleAlias(const grpc::string& filename,
const grpc::string& import_prefix) {
grpc::string module_name = ModuleName(filename, import_prefix);
// We can't have dots in the module name, so we replace each with _dot_.
// But that could lead to a collision between a.b and a_dot_b, so we also
// duplicate each underscore.
module_name = StringReplace(module_name, "_", "__");
module_name = StringReplace(module_name, ".", "_dot_");
return module_name;
}
PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config_,
const grpc_generator::File* file_)
: config(config_), file(file_) {}
void PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This class was "
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
}
}
}
}
void PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class Beta$Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This class was "
"generated\n"
"only to ease transition from grpcio<0.15.0 to "
"grpcio>=0.15.0.\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print(method_dict,
"def $Method$(self, $ArgName$, timeout, metadata=None, "
"with_call=False, protocol_options=None):\n");
{
IndentScope raii_method_indent(out);
out->Print("raise NotImplementedError()\n");
}
if (!method->ServerStreaming()) {
out->Print(method_dict, "$Method$.future = None\n");
}
}
}
}
void PrivateGenerator::PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict,
"def beta_create_$Service$_server(servicer, pool=None, "
"pool_size=None, default_timeout=None, maximum_timeout=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This function was\n"
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
"\"\"\"\n");
StringMap method_implementation_constructors;
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
const grpc::string method_implementation_constructor =
grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
"inline";
grpc::string input_message_module_and_class = method->get_fb_builder();
grpc::string output_message_module_and_class = method->get_fb_builder();
method_implementation_constructors.insert(
make_pair(method->name(), method_implementation_constructor));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
// out->Print("request_deserializers = {\n");
// for (StringMap::iterator name_and_input_module_class_pair =
// input_message_modules_and_classes.begin();
// name_and_input_module_class_pair !=
// input_message_modules_and_classes.end();
// name_and_input_module_class_pair++) {
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
// method_dict["InputTypeModuleAndClass"] =
// name_and_input_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$InputTypeModuleAndClass$.FromString,\n");
// }
// out->Print("}\n");
// out->Print("response_serializers = {\n");
// for (StringMap::iterator name_and_output_module_class_pair =
// output_message_modules_and_classes.begin();
// name_and_output_module_class_pair !=
// output_message_modules_and_classes.end();
// name_and_output_module_class_pair++) {
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
// method_dict["OutputTypeModuleAndClass"] =
// name_and_output_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$OutputTypeModuleAndClass$.SerializeToString,\n");
// }
// out->Print("}\n");
out->Print("method_implementations = {\n");
for (StringMap::iterator name_and_implementation_constructor =
method_implementation_constructors.begin();
name_and_implementation_constructor !=
method_implementation_constructors.end();
name_and_implementation_constructor++) {
method_dict["Method"] = name_and_implementation_constructor->first;
method_dict["Constructor"] = name_and_implementation_constructor->second;
IndentScope raii_descriptions_indent(out);
const grpc::string method_name =
name_and_implementation_constructor->first;
out->Print(method_dict,
"(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
"face_utilities.$Constructor$(servicer.$Method$),\n");
}
out->Print("}\n");
out->Print(
"server_options = beta_implementations.server_options("
"thread_pool=pool, thread_pool_size=pool_size, "
"default_timeout=default_timeout, "
"maximum_timeout=maximum_timeout)\n");
out->Print(
"return beta_implementations.server(method_implementations, "
"options=server_options)\n");
//"request_deserializers=request_deserializers, "
//"response_serializers=response_serializers, "
}
}
void PrivateGenerator::PrintBetaStubFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print(dict,
"def beta_create_$Service$_stub(channel, host=None,"
" metadata_transformer=None, pool=None, pool_size=None):\n");
{
IndentScope raii_create_server_indent(out);
out->Print(
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
"\nIt is recommended to use the GA API (classes and functions in this\n"
"file not marked beta) for all further purposes. This function was\n"
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
"\"\"\"\n");
StringMap method_cardinalities;
StringMap input_message_modules_and_classes;
StringMap output_message_modules_and_classes;
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
const grpc::string method_cardinality =
grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") +
"_" +
grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
grpc::string input_message_module_and_class = method->get_fb_builder();
grpc::string output_message_module_and_class = method->get_fb_builder();
method_cardinalities.insert(
make_pair(method->name(), method_cardinality));
input_message_modules_and_classes.insert(
make_pair(method->name(), input_message_module_and_class));
output_message_modules_and_classes.insert(
make_pair(method->name(), output_message_module_and_class));
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
// out->Print("request_serializers = {\n");
// for (StringMap::iterator name_and_input_module_class_pair =
// input_message_modules_and_classes.begin();
// name_and_input_module_class_pair !=
// input_message_modules_and_classes.end();
// name_and_input_module_class_pair++) {
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
// method_dict["InputTypeModuleAndClass"] =
// name_and_input_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$InputTypeModuleAndClass$.SerializeToString,\n");
// }
// out->Print("}\n");
// out->Print("response_deserializers = {\n");
// for (StringMap::iterator name_and_output_module_class_pair =
// output_message_modules_and_classes.begin();
// name_and_output_module_class_pair !=
// output_message_modules_and_classes.end();
// name_and_output_module_class_pair++) {
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
// method_dict["OutputTypeModuleAndClass"] =
// name_and_output_module_class_pair->second;
// IndentScope raii_indent(out);
// out->Print(method_dict,
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
// "$OutputTypeModuleAndClass$.FromString,\n");
// }
// out->Print("}\n");
out->Print("cardinalities = {\n");
for (StringMap::iterator name_and_cardinality =
method_cardinalities.begin();
name_and_cardinality != method_cardinalities.end();
name_and_cardinality++) {
method_dict["Method"] = name_and_cardinality->first;
method_dict["Cardinality"] = name_and_cardinality->second;
IndentScope raii_descriptions_indent(out);
out->Print(method_dict,
"\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
}
out->Print("}\n");
out->Print(
"stub_options = beta_implementations.stub_options("
"host=host, metadata_transformer=metadata_transformer, "
"thread_pool=pool, thread_pool_size=pool_size)\n");
out->Print(method_dict,
"return beta_implementations.dynamic_stub(channel, "
"\'$PackageQualifiedServiceName$\', "
"cardinalities, options=stub_options)\n");
// "request_serializers=request_serializers, "
//"response_deserializers=response_deserializers, "
}
}
void PrivateGenerator::PrintStub(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap dict;
dict["Service"] = service->name();
out->Print("\n\n");
out->Print(dict, "class $Service$Stub(object):\n");
{
IndentScope raii_class_indent(out);
out->Print("\n");
out->Print("def __init__(self, channel):\n");
{
IndentScope raii_init_indent(out);
out->Print("\"\"\"Constructor.\n");
out->Print("\n");
out->Print("Args:\n");
{
IndentScope raii_args_indent(out);
out->Print("channel: A grpc.Channel.\n");
}
out->Print("\"\"\"\n");
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string multi_callable_constructor =
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
"_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary");
grpc::string request_module_and_class = method->get_fb_builder();
grpc::string response_module_and_class = method->get_fb_builder();
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MultiCallableConstructor"] = multi_callable_constructor;
out->Print(method_dict,
"self.$Method$ = channel.$MultiCallableConstructor$(\n");
{
method_dict["PackageQualifiedService"] =
package_qualified_service_name;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
IndentScope raii_first_attribute_indent(out);
IndentScope raii_second_attribute_indent(out);
out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
out->Print(method_dict,"\n");
out->Print(
method_dict,"\n");
out->Print(")\n");
}
}
}
}
}
void PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict, "class $Service$Servicer(object):\n");
{
IndentScope raii_class_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string arg_name =
method->ClientStreaming() ? "request_iterator" : "request";
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["ArgName"] = arg_name;
out->Print("\n");
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
{
IndentScope raii_method_indent(out);
out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
out->Print("context.set_details('Method not implemented!')\n");
out->Print("raise NotImplementedError('Method not implemented!')\n");
}
}
}
}
void PrivateGenerator::PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out) {
StringMap service_dict;
service_dict["Service"] = service->name();
out->Print("\n\n");
out->Print(service_dict,
"def add_$Service$Servicer_to_server(servicer, server):\n");
{
IndentScope raii_class_indent(out);
out->Print("rpc_method_handlers = {\n");
{
IndentScope raii_dict_first_indent(out);
IndentScope raii_dict_second_indent(out);
for (int i = 0; i < service->method_count(); ++i) {
auto method = service->method(i);
grpc::string method_handler_constructor =
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
"_" +
grpc::string(method->ServerStreaming() ? "stream" : "unary") +
"_rpc_method_handler";
grpc::string request_module_and_class = method->get_fb_builder();
grpc::string response_module_and_class = method->get_fb_builder();
StringMap method_dict;
method_dict["Method"] = method->name();
method_dict["MethodHandlerConstructor"] = method_handler_constructor;
method_dict["RequestModuleAndClass"] = request_module_and_class;
method_dict["ResponseModuleAndClass"] = response_module_and_class;
out->Print(method_dict,
"'$Method$': grpc.$MethodHandlerConstructor$(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print(method_dict, "servicer.$Method$,\n");
out->Print(
method_dict,"\n");
out->Print(
method_dict,
"\n");
}
out->Print("),\n");
}
}
StringMap method_dict;
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
out->Print("}\n");
out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
{
IndentScope raii_call_first_indent(out);
IndentScope raii_call_second_indent(out);
out->Print(method_dict,
"'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
}
out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
}
}
void PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.beta_package_root;
out->Print(var,
"from $Package$ import implementations as beta_implementations\n");
out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
out->Print("from grpc.framework.common import cardinality\n");
out->Print(
"from grpc.framework.interfaces.face import utilities as "
"face_utilities\n");
}
void PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
out->Print("\n");
StringPairSet imports_set;
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
for (int j = 0; j < service->method_count(); ++j) {
auto method = service.get()->method(j);
grpc::string input_type_file_name = method->get_fb_builder();
grpc::string input_module_name =
ModuleName(input_type_file_name, config.import_prefix);
grpc::string input_module_alias =
ModuleAlias(input_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(input_module_name, input_module_alias));
grpc::string output_type_file_name = method->get_fb_builder();
grpc::string output_module_name =
ModuleName(output_type_file_name, config.import_prefix);
grpc::string output_module_alias =
ModuleAlias(output_type_file_name, config.import_prefix);
imports_set.insert(
std::make_tuple(output_module_name, output_module_alias));
}
}
for (StringPairSet::iterator it = imports_set.begin();
it != imports_set.end(); ++it) {
var["ModuleName"] = std::get<0>(*it);
var["ModuleAlias"] = std::get<1>(*it);
out->Print(var, "import $ModuleName$ as $ModuleAlias$\n");
}
}
void PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
out->Print(file->additional_headers().c_str());
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
PrintStub(package_qualified_service_name, service.get(), out);
PrintServicer(service.get(), out);
PrintAddServicerToServer(package_qualified_service_name, service.get(),
out);
}
}
void PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
grpc::string package = file->package();
if (!package.empty()) {
package = package.append(".");
}
for (int i = 0; i < file->service_count(); ++i) {
auto service = file->service(i);
grpc::string package_qualified_service_name = package + service->name();
PrintBetaServicer(service.get(), out);
PrintBetaStub(service.get(), out);
PrintBetaServerFactory(package_qualified_service_name, service.get(), out);
PrintBetaStubFactory(package_qualified_service_name, service.get(), out);
}
}
grpc::string PrivateGenerator::GetGrpcServices() {
grpc::string output;
{
// Scope the output stream so it closes and finalizes output to the string.
auto out = file->CreatePrinter(&output);
out->Print(
"# Generated by the gRPC Python protocol compiler plugin. "
"DO NOT EDIT!\n");
StringMap var;
var["Package"] = config.grpc_package_root;
out->Print(var, "import $Package$\n");
PrintGAServices(out.get());
out->Print("try:\n");
{
IndentScope raii_dict_try_indent(out.get());
out->Print(
"# THESE ELEMENTS WILL BE DEPRECATED.\n"
"# Please use the generated *_pb2_grpc.py files instead.\n");
out->Print(var, "import $Package$\n");
PrintBetaPreamble(out.get());
PrintGAServices(out.get());
PrintBetaServices(out.get());
}
out->Print("except ImportError:\n");
{
IndentScope raii_dict_except_indent(out.get());
out->Print("pass");
}
}
return output;
}
} // namespace grpc_python_generator

View File

@@ -0,0 +1,55 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
#include <utility>
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
// Data pertaining to configuration of the generator with respect to anything
// that may be used internally at Google.
struct GeneratorConfiguration {
grpc::string grpc_package_root;
// TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
grpc::string beta_package_root;
// TODO(https://github.com/google/protobuf/issues/888): Drop this.
grpc::string import_prefix;
};
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H

View File

@@ -0,0 +1,87 @@
/*
*
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
*/
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
#include <iostream>
#include <vector>
#include "src/compiler/python_generator.h"
#include "src/compiler/schema_interface.h"
namespace grpc_python_generator {
// Tucks all generator state in an anonymous namespace away from
// PythonGrpcGenerator and the header file, mostly to encourage future changes
// to not require updates to the grpcio-tools C++ code part. Assumes that it is
// only ever used from a single thread.
struct PrivateGenerator {
const GeneratorConfiguration& config;
const grpc_generator::File* file;
PrivateGenerator(const GeneratorConfiguration& config,
const grpc_generator::File* file);
grpc::string GetGrpcServices();
private:
void PrintPreamble(grpc_generator::Printer* out);
void PrintBetaPreamble(grpc_generator::Printer* out);
void PrintGAServices(grpc_generator::Printer* out);
void PrintBetaServices(grpc_generator::Printer* out);
void PrintAddServicerToServer(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
void PrintServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintStub(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaServicer(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaServerFactory(
const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service, grpc_generator::Printer* out);
void PrintBetaStub(const grpc_generator::Service* service,
grpc_generator::Printer* out);
void PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
const grpc_generator::Service* service,
grpc_generator::Printer* out);
};
} // namespace grpc_python_generator
#endif // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H

View File

@@ -34,11 +34,11 @@
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H #ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H #define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
#include "src/compiler/config.h"
#include <memory> #include <memory>
#include <vector> #include <vector>
#include "src/compiler/config.h"
#ifndef GRPC_CUSTOM_STRING #ifndef GRPC_CUSTOM_STRING
# include <string> # include <string>
# define GRPC_CUSTOM_STRING std::string # define GRPC_CUSTOM_STRING std::string
@@ -79,6 +79,9 @@ struct Method : public CommentHolder {
virtual grpc::string get_input_type_name() const = 0; virtual grpc::string get_input_type_name() const = 0;
virtual grpc::string get_output_type_name() const = 0; virtual grpc::string get_output_type_name() const = 0;
virtual grpc::string get_fb_builder() const = 0;
virtual bool NoStreaming() const = 0; virtual bool NoStreaming() const = 0;
virtual bool ClientStreaming() const = 0; virtual bool ClientStreaming() const = 0;
virtual bool ServerStreaming() const = 0; virtual bool ServerStreaming() const = 0;

View File

@@ -96,7 +96,7 @@ public class JavaGrpcTest {
if (monster.hp() > maxHp.get()) { if (monster.hp() > maxHp.get()) {
// Found a monster of higher hit points. // Found a monster of higher hit points.
maxHp.set(monster.hp()); maxHp.set(monster.hp());
maxHpMonsterName.set(monster.name()); maxHpMonsterName.set(monster.name());
maxHpCount.set(1); maxHpCount.set(1);
} }
else if (monster.hp() == maxHp.get()) { else if (monster.hp() == maxHp.get()) {
@@ -141,7 +141,7 @@ public class JavaGrpcTest {
channel = ManagedChannelBuilder.forAddress("localhost", port) channel = ManagedChannelBuilder.forAddress("localhost", port)
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid // Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
// needing certificates. // needing certificates.
.usePlaintext(true) .usePlaintext()
.directExecutor() .directExecutor()
.build(); .build();
blockingStub = MonsterStorageGrpc.newBlockingStub(channel); blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
@@ -177,7 +177,7 @@ public class JavaGrpcTest {
final CountDownLatch streamAlive = new CountDownLatch(1); final CountDownLatch streamAlive = new CountDownLatch(1);
StreamObserver<Stat> statObserver = new StreamObserver<Stat>() { StreamObserver<Stat> statObserver = new StreamObserver<Stat>() {
public void onCompleted() { public void onCompleted() {
streamAlive.countDown(); streamAlive.countDown();
} }
public void onError(Throwable ex) { } public void onError(Throwable ex) { }

View File

@@ -14,17 +14,17 @@
* limitations under the License. * limitations under the License.
*/ */
#include <thread>
#include <grpc++/grpc++.h> #include <grpc++/grpc++.h>
#include <thread>
#include "monster_test.grpc.fb.h" #include "monster_test.grpc.fb.h"
#include "monster_test_generated.h" #include "monster_test_generated.h"
#include "test_assert.h" #include "test_assert.h"
using namespace MyGame::Example; using namespace MyGame::Example;
using flatbuffers::grpc::MessageBuilder;
using flatbuffers::FlatBufferBuilder; using flatbuffers::FlatBufferBuilder;
using flatbuffers::grpc::MessageBuilder;
void message_builder_tests(); void message_builder_tests();
@@ -97,8 +97,7 @@ void RunServer() {
server_instance->Wait(); server_instance->Wait();
} }
template <class Builder> template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
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,8 +118,7 @@ void StoreRPC(MonsterStorage::Stub *stub) {
} }
} }
template <class Builder> template<class Builder> void RetrieveRPC(MonsterStorage::Stub *stub) {
void RetrieveRPC(MonsterStorage::Stub *stub) {
Builder fbb; Builder fbb;
grpc::ClientContext context; grpc::ClientContext context;
fbb.Clear(); fbb.Clear();
@@ -155,7 +153,6 @@ int grpc_server_test() {
RetrieveRPC<MessageBuilder>(stub.get()); RetrieveRPC<MessageBuilder>(stub.get());
RetrieveRPC<FlatBufferBuilder>(stub.get()); RetrieveRPC<FlatBufferBuilder>(stub.get());
#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION #if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
{ {
// Test that an invalid request errors out correctly // Test that an invalid request errors out correctly
@@ -181,7 +178,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();
@@ -193,4 +190,3 @@ int main(int /*argc*/, const char * /*argv*/ []) {
return 1; return 1;
} }
} }

174
grpc/tests/grpctest.py Normal file
View File

@@ -0,0 +1,174 @@
from __future__ import print_function
import os
import sys
import grpc
import flatbuffers
from concurrent import futures
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'tests'))
import MyGame.Example.Monster as Monster
import MyGame.Example.Stat as Stat
import MyGame.Example.Vec3 as Vec3
import MyGame.Example.Test as Test
import MyGame.Example.monster_test_grpc_fb as monster_grpc_fb
test_stat_id = "test_stat_id"
test_stat_val = 8
test_stat_count = 1
test_monster_name1 = "test_monster_name1"
test_monster_name2 = "test_monster_name2"
test_string = "test_string"
test_color = 2
test_X = 3.0
test_Y = 2.0
test_Z = 6.0
test_test1 = 4.0
test_a = 8
test_b = 5
test_hp = 67
test_inventory = [1, 1, 2, 3, 5, 8]
test_testtype = 4
test_monsters_name_retrieve = ["big_monster", "small_monster"]
test_no_of_monsters = 2
class MonsterStorage(monster_grpc_fb.MonsterStorageServicer):
def Store(self, request, context):
m = Monster.Monster().GetRootAsMonster(request, 0)
assert m.Name().decode("utf-8") == test_monster_name1
assert m.Pos().X() == test_X
assert m.Pos().Y() == test_Y
assert m.Pos().Z() == test_Z
assert m.Pos().Test1() == test_test1
assert m.Pos().Test2() == test_color
test3 = Test.Test()
assert m.Pos().Test3(test3).A() == test_a
assert m.Pos().Test3(test3).B() == test_b
assert m.Hp() == test_hp
assert m.Color() == test_color
assert m.InventoryLength() == len(test_inventory)
for i in range(0, len(test_inventory)):
assert m.Inventory(i) == test_inventory[len(test_inventory)-i -1]
assert m.TestType() == test_testtype
assert m.Test() is not None
table = m.Test()
m2 = Monster.Monster()
m2.Init(table.Bytes, table.Pos)
assert m2.Name().decode("utf-8") == test_monster_name2
m3 = m.Enemy()
assert m3.Name().decode("utf-8") == test_monster_name2
assert m.Testarrayofstring(0).decode("utf-8") == test_string
b = flatbuffers.Builder(0)
i = b.CreateString(test_stat_id)
Stat.StatStart(b)
Stat.StatAddId(b, i)
Stat.StatAddVal(b, test_stat_val)
Stat.StatAddCount(b, test_stat_count)
b.Finish(Stat.StatEnd(b))
return bytes(b.Output())
def Retrieve(self, request, context):
s = Stat.Stat().GetRootAsStat(request, 0)
no_of_monsters = test_no_of_monsters
for i in range(0, no_of_monsters):
b = flatbuffers.Builder(0)
i = b.CreateString(test_monsters_name_retrieve[i])
Monster.MonsterStart(b)
Monster.MonsterAddName(b, i)
b.Finish(Monster.MonsterEnd(b))
yield bytes(b.Output())
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server)
server.add_insecure_port('[::]:50051')
server.start()
run()
def run():
channel = grpc.insecure_channel('127.0.0.1:50051')
stub = monster_grpc_fb.MonsterStorageStub(channel)
b = flatbuffers.Builder(0)
name2 = b.CreateString(test_monster_name2)
name1 = b.CreateString(test_monster_name1)
Monster.MonsterStart(b)
Monster.MonsterAddName(b, name2)
monster2 = Monster.MonsterEnd(b)
test1 = b.CreateString(test_string)
Monster.MonsterStartInventoryVector(b, len(test_inventory))
for i in range(0, len(test_inventory)):
b.PrependByte(test_inventory[i])
inv = b.EndVector(len(test_inventory))
Monster.MonsterStartTest4Vector(b, 2)
Test.CreateTest(b, 10, 20)
Test.CreateTest(b, 30, 40)
test4 = b.EndVector(2)
Monster.MonsterStartTestarrayofstringVector(b, 1)
b.PrependUOffsetTRelative(test1)
test_array_of_string = b.EndVector(1)
Monster.MonsterStart(b)
Monster.MonsterAddHp(b, test_hp)
Monster.MonsterAddName(b, name1)
Monster.MonsterAddColor(b, test_color)
pos = Vec3.CreateVec3(b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b)
Monster.MonsterAddPos(b, pos)
Monster.MonsterAddInventory(b, inv)
Monster.MonsterAddTestType(b, test_testtype)
Monster.MonsterAddTest(b, monster2)
Monster.MonsterAddTest4(b, test4)
Monster.MonsterAddEnemy(b, monster2)
Monster.MonsterAddTestarrayofstring(b, test_array_of_string)
monster = Monster.MonsterEnd(b)
b.Finish(monster)
stat_response = stub.Store(bytes(b.Output()))
s = Stat.Stat().GetRootAsStat(stat_response, 0)
assert s.Id().decode("utf-8") == test_stat_id
assert s.Val() == test_stat_val
assert s.Count() == test_stat_count
monster_reponses = stub.Retrieve(stat_response)
count = 0
for monster_reponse in monster_reponses:
m = Monster.Monster().GetRootAsMonster(monster_reponse, 0)
assert m.Name().decode("utf-8") == test_monsters_name_retrieve[count]
count = count + 1
if __name__ == '__main__':
serve()

View File

@@ -3,22 +3,27 @@
#include "test_assert.h" #include "test_assert.h"
#include "test_builder.h" #include "test_builder.h"
using MyGame::Example::Vec3;
using MyGame::Example::CreateStat;
using MyGame::Example::Any_NONE; using MyGame::Example::Any_NONE;
using MyGame::Example::CreateStat;
using MyGame::Example::Vec3;
bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) { bool verify(flatbuffers::grpc::Message<Monster> &msg,
const std::string &expected_name, Color color) {
const Monster *monster = msg.GetRoot(); const Monster *monster = msg.GetRoot();
return (monster->name()->str() == expected_name) && (monster->color() == color); return (monster->name()->str() == expected_name) &&
(monster->color() == color);
} }
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) { bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
const std::string &expected_name, Color color) {
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>(); flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
const Monster *monster = msg.GetRoot(); const Monster *monster = msg.GetRoot();
return (monster->name()->str() == expected_name) && (monster->color() == color); return (monster->name()->str() == expected_name) &&
(monster->color() == color);
} }
void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst) { void builder_move_assign_after_releaseraw_test(
flatbuffers::grpc::MessageBuilder dst) {
auto root_offset1 = populate1(dst); auto root_offset1 = populate1(dst);
dst.Finish(root_offset1); dst.Finish(root_offset1);
size_t size, offset; size_t size, offset;
@@ -36,12 +41,11 @@ void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder
grpc_slice_unref(slice); grpc_slice_unref(slice);
} }
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(TestSelector selector) { static void builder_reusable_after_release_message_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { TestSelector selector) {
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;
@@ -54,12 +58,10 @@ 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)) { if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
return;
}
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in SliceAllocator::allocate // FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
// in the second iteration. // SliceAllocator::allocate in the second iteration.
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
std::vector<flatbuffers::DetachedBuffer> buffers; std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -72,9 +74,7 @@ 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)) { if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
return;
}
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
for (int i = 0; i < 5; ++i) { for (int i = 0; i < 5; ++i) {
@@ -88,13 +88,13 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
} }
} }
static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_release_and_move_assign_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { TestSelector selector) {
return; if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
}
// FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_)) // FIXME: Release-move_assign loop fails assert(p ==
// in DetachedBuffer destructor after all the iterations // GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
// iterations
flatbuffers::grpc::MessageBuilder dst; flatbuffers::grpc::MessageBuilder dst;
std::vector<flatbuffers::DetachedBuffer> buffers; std::vector<flatbuffers::DetachedBuffer> buffers;
@@ -113,7 +113,8 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
} }
} }
static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_release_message_and_move_assign_test(
TestSelector selector) {
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) { if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
return; return;
} }
@@ -135,10 +136,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
} }
} }
static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) { static void builder_reusable_after_releaseraw_and_move_assign_test(
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { TestSelector selector) {
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) {
@@ -175,11 +175,11 @@ void slice_allocator_tests() {
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;
flatbuffers::grpc::SliceAllocator sa2(std::move(sa1)); flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
// buf should not be deleted after move-construct // buf should not be deleted after move-construct
TEST_EQ_FUNC(buf[0], 100); TEST_EQ_FUNC(buf[0], 100);
TEST_EQ_FUNC(buf[size-1], 200); TEST_EQ_FUNC(buf[size - 1], 200);
// buf is freed here // buf is freed here
} }
@@ -194,13 +194,16 @@ void slice_allocator_tests() {
} }
} }
/// This function does not populate exactly the first half of the table. But it could. /// This function does not populate exactly the first half of the table. But it
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper, flatbuffers::Offset<flatbuffers::String> name_offset) { /// could.
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
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);
} }
/// This function does not populate exactly the second half of the table. But it could. /// This function does not populate exactly the second half of the table. But it
/// 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);
@@ -208,83 +211,97 @@ void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
wrapper.add_pos(&vec3); wrapper.add_pos(&vec3);
} }
/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in the MonsterBuilder object. /// This function is a hack to update the FlatBufferBuilder reference (fbb_) in
/// This function will break if fbb_ is not the first member in MonsterBuilder. In that case, some offset must be added. /// the MonsterBuilder object. This function will break if fbb_ is not the first
/// This function is used exclusively for testing correctness of move operations between FlatBufferBuilders. /// member in MonsterBuilder. In that case, some offset must be added. This
/// If MonsterBuilder had a fbb_ pointer, this hack would be unnecessary. That involves a code-generator change though. /// function is used exclusively for testing correctness of move operations
void test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder &monsterBuilder, /// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
flatbuffers::grpc::MessageBuilder &mb) { /// would be unnecessary. That involves a code-generator change though.
void test_only_hack_update_fbb_reference(
MyGame::Example::MonsterBuilder &monsterBuilder,
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 MessageBuilder DURING /// This test validates correctness of move conversion of FlatBufferBuilder to a
/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half /// MessageBuilder DURING a table construction. Half of the table is constructed
/// of the table is constructed using a MessageBuilder. /// using FlatBufferBuilder and the other half of the table is constructed using
/// a MessageBuilder.
void builder_move_ctor_conversion_before_finish_half_n_half_table_test() { void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) { for (size_t initial_size = 4; initial_size <= 2048; initial_size *= 2) {
flatbuffers::FlatBufferBuilder fbb(initial_size); flatbuffers::FlatBufferBuilder fbb(initial_size);
auto name_offset = fbb.CreateString(m1_name); auto name_offset = fbb.CreateString(m1_name);
MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder MyGame::Example::MonsterBuilder monsterBuilder(
fbb); // starts a table in FlatBufferBuilder
populate_first_half(monsterBuilder, name_offset); populate_first_half(monsterBuilder, name_offset);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb)); flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
populate_second_half(monsterBuilder); populate_second_half(monsterBuilder);
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color)); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);
} }
} }
/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table. /// This test populates a COMPLETE inner table before move conversion and later
/// populates more members in the outer table.
void builder_move_ctor_conversion_before_finish_test() { void builder_move_ctor_conversion_before_finish_test() {
for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) { for (size_t initial_size = 4; initial_size <= 2048; initial_size *= 2) {
flatbuffers::FlatBufferBuilder fbb(initial_size); flatbuffers::FlatBufferBuilder fbb(initial_size);
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0); auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
flatbuffers::grpc::MessageBuilder mb(std::move(fbb)); flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset); auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color,
Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset); mb.Finish(monster_offset);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color)); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);
} }
} }
/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING /// This test validates correctness of move conversion of FlatBufferBuilder to a
/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half /// MessageBuilder DURING a table construction. Half of the table is constructed
/// of the table is constructed using a MessageBuilder. /// using FlatBufferBuilder and the other half of the table is constructed using
/// a MessageBuilder.
void builder_move_assign_conversion_before_finish_half_n_half_table_test() { void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
for (int i = 0;i < 5; ++i) { for (int i = 0; i < 5; ++i) {
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
auto name_offset = fbb.CreateString(m1_name); auto name_offset = fbb.CreateString(m1_name);
MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder MyGame::Example::MonsterBuilder monsterBuilder(
fbb); // starts a table in FlatBufferBuilder
populate_first_half(monsterBuilder, name_offset); populate_first_half(monsterBuilder, name_offset);
mb = std::move(fbb); mb = std::move(fbb);
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
populate_second_half(monsterBuilder); populate_second_half(monsterBuilder);
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color)); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);
} }
} }
/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table. /// This test populates a COMPLETE inner table before move conversion and later
/// populates more members in the outer table.
void builder_move_assign_conversion_before_finish_test() { void builder_move_assign_conversion_before_finish_test() {
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
for (int i = 0;i < 5; ++i) { for (int i = 0; i < 5; ++i) {
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0); auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
mb = std::move(fbb); mb = std::move(fbb);
auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset); auto monster_offset =
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color,
Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
mb.Finish(monster_offset); mb.Finish(monster_offset);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color)); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);
} }
} }
/// This test populates data, finishes the buffer, and does move conversion after. /// This test populates data, finishes the buffer, and does move conversion
/// after.
void builder_move_ctor_conversion_after_finish_test() { void builder_move_ctor_conversion_after_finish_test() {
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(populate1(fbb)); fbb.Finish(populate1(fbb));
@@ -293,12 +310,13 @@ void builder_move_ctor_conversion_after_finish_test() {
TEST_EQ_FUNC(fbb.GetSize(), 0); TEST_EQ_FUNC(fbb.GetSize(), 0);
} }
/// This test populates data, finishes the buffer, and does move conversion after. /// This test populates data, finishes the buffer, and does move conversion
/// after.
void builder_move_assign_conversion_after_finish_test() { void builder_move_assign_conversion_after_finish_test() {
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
flatbuffers::grpc::MessageBuilder mb; flatbuffers::grpc::MessageBuilder mb;
for (int i = 0;i < 5; ++i) { for (int i = 0; i < 5; ++i) {
fbb.Finish(populate1(fbb)); fbb.Finish(populate1(fbb));
mb = std::move(fbb); mb = std::move(fbb);
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color)); TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
@@ -307,15 +325,15 @@ void builder_move_assign_conversion_after_finish_test() {
} }
void message_builder_tests() { void message_builder_tests() {
using flatbuffers::grpc::MessageBuilder;
using flatbuffers::FlatBufferBuilder; using flatbuffers::FlatBufferBuilder;
using flatbuffers::grpc::MessageBuilder;
slice_allocator_tests(); slice_allocator_tests();
#ifndef __APPLE__ #ifndef __APPLE__
builder_move_ctor_conversion_before_finish_half_n_half_table_test(); builder_move_ctor_conversion_before_finish_half_n_half_table_test();
builder_move_assign_conversion_before_finish_half_n_half_table_test(); builder_move_assign_conversion_before_finish_half_n_half_table_test();
#endif // __APPLE__ #endif // __APPLE__
builder_move_ctor_conversion_before_finish_test(); builder_move_ctor_conversion_before_finish_test();
builder_move_assign_conversion_before_finish_test(); builder_move_assign_conversion_before_finish_test();
@@ -326,15 +344,18 @@ 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: (GRPC_SLICE_IS_EMPTY(slice_)) // REUSABLE_AFTER_RELEASE, // Assertion failed:
//REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == GRPC_SLICE_START_PTR(slice_) // (GRPC_SLICE_IS_EMPTY(slice_))
// REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p ==
// GRPC_SLICE_START_PTR(slice_)
REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
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(TestSelector(tests, tests+6)); BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+6)); TestSelector(tests, tests + 6));
BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(
TestSelector(tests, tests + 6));
} }

View File

@@ -242,7 +242,7 @@ namespace flatbuffers {
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage: // Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
// - __supress_ubsan__("undefined") // - __supress_ubsan__("undefined")
// - __supress_ubsan__("signed-integer-overflow") // - __supress_ubsan__("signed-integer-overflow")
#if defined(__clang__) #if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
#define __supress_ubsan__(type) __attribute__((no_sanitize(type))) #define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409) #elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
#define __supress_ubsan__(type) __attribute__((no_sanitize_undefined)) #define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
@@ -296,7 +296,7 @@ typedef uint16_t voffset_t;
typedef uintmax_t largest_scalar_t; typedef uintmax_t largest_scalar_t;
// In 32bits, this evaluates to 2GB - 1 // In 32bits, this evaluates to 2GB - 1
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1) #define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
// We support aligning the contents of buffers up to this size. // We support aligning the contents of buffers up to this size.
#define FLATBUFFERS_MAX_ALIGNMENT 16 #define FLATBUFFERS_MAX_ALIGNMENT 16

View File

@@ -19,6 +19,7 @@
#include <map> #include <map>
#include <sstream> #include <sstream>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
namespace flatbuffers { namespace flatbuffers {
@@ -95,8 +96,7 @@ class BaseGenerator {
protected: protected:
BaseGenerator(const Parser &parser, const std::string &path, BaseGenerator(const Parser &parser, const std::string &path,
const std::string &file_name, const std::string &file_name, std::string qualifying_start,
std::string qualifying_start,
std::string qualifying_separator) std::string qualifying_separator)
: parser_(parser), : parser_(parser),
path_(path), path_(path),

View File

@@ -20,7 +20,7 @@
#include "flatbuffers/base.h" #include "flatbuffers/base.h"
#if defined(FLATBUFFERS_NAN_DEFAULTS) #if defined(FLATBUFFERS_NAN_DEFAULTS)
#include <cmath> # include <cmath>
#endif #endif
namespace flatbuffers { namespace flatbuffers {
@@ -203,11 +203,10 @@ template<typename T, typename IT> struct VectorIterator {
const uint8_t *data_; const uint8_t *data_;
}; };
template<typename Iterator> struct VectorReverseIterator : template<typename Iterator>
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) {}
typename Iterator::value_type operator*() const { typename Iterator::value_type operator*() const {
return *(std::reverse_iterator<Iterator>::current); return *(std::reverse_iterator<Iterator>::current);
@@ -277,10 +276,14 @@ template<typename T> class Vector {
const_iterator end() const { return const_iterator(Data(), size()); } const_iterator end() const { return const_iterator(Data(), size()); }
reverse_iterator rbegin() { return reverse_iterator(end() - 1); } reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
const_reverse_iterator rbegin() const { return const_reverse_iterator(end() - 1); } const_reverse_iterator rbegin() const {
return const_reverse_iterator(end() - 1);
}
reverse_iterator rend() { return reverse_iterator(begin() - 1); } reverse_iterator rend() { return reverse_iterator(begin() - 1); }
const_reverse_iterator rend() const { return const_reverse_iterator(begin() - 1); } const_reverse_iterator rend() const {
return const_reverse_iterator(begin() - 1);
}
const_iterator cbegin() const { return begin(); } const_iterator cbegin() const { return begin(); }
@@ -403,7 +406,8 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
// 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 {
typedef typedef
typename flatbuffers::integral_constant<bool, flatbuffers::is_scalar<T>::value> typename flatbuffers::integral_constant<bool,
flatbuffers::is_scalar<T>::value>
scalar_tag; scalar_tag;
typedef typedef
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
@@ -449,9 +453,7 @@ template<typename T, uint16_t length> class Array {
} }
// 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) { void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, 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_; }
@@ -544,13 +546,13 @@ struct String : public Vector<char> {
// 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() : "";
} }
@@ -587,9 +589,9 @@ 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, void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
uint8_t *new_p, size_t new_size, size_t new_size, size_t in_use_back,
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,
in_use_back); in_use_back);
memcpy(new_p, old_p, in_use_front); memcpy(new_p, old_p, in_use_front);
@@ -603,13 +605,9 @@ class DefaultAllocator : public Allocator {
return new uint8_t[size]; return new uint8_t[size];
} }
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
delete[] p;
}
static void dealloc(void *p, size_t) { static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
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,
@@ -622,18 +620,19 @@ inline uint8_t *Allocate(Allocator *allocator, size_t 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) allocator->deallocate(p, size); if (allocator)
else DefaultAllocator().deallocate(p, size); allocator->deallocate(p, size);
else
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 return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
? allocator->reallocate_downward(old_p, old_size, new_size, in_use_back, in_use_front)
in_use_back, in_use_front) : DefaultAllocator().reallocate_downward(
: DefaultAllocator().reallocate_downward(old_p, old_size, new_size, old_p, old_size, new_size, in_use_back, in_use_front);
in_use_back, in_use_front);
} }
// DetachedBuffer is a finished flatbuffer memory region, detached from its // DetachedBuffer is a finished flatbuffer memory region, detached from its
@@ -678,8 +677,7 @@ class DetachedBuffer {
#if !defined(FLATBUFFERS_CPP98_STL) #if !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
DetachedBuffer &operator=(DetachedBuffer &&other) { DetachedBuffer &operator=(DetachedBuffer &&other) {
if (this == &other) if (this == &other) return *this;
return *this;
destroy(); destroy();
@@ -737,7 +735,7 @@ class DetachedBuffer {
#endif // !defined(FLATBUFFERS_CPP98_STL) #endif // !defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
protected: protected:
Allocator *allocator_; Allocator *allocator_;
bool own_allocator_; bool own_allocator_;
uint8_t *buf_; uint8_t *buf_;
@@ -769,10 +767,8 @@ protected:
// Essentially, this supports 2 std::vectors in a single buffer. // Essentially, this supports 2 std::vectors in a single buffer.
class vector_downward { class vector_downward {
public: public:
explicit vector_downward(size_t initial_size, explicit vector_downward(size_t initial_size, Allocator *allocator,
Allocator *allocator, bool own_allocator, size_t buffer_minalign)
bool own_allocator,
size_t buffer_minalign)
: allocator_(allocator), : allocator_(allocator),
own_allocator_(own_allocator), own_allocator_(own_allocator),
initial_size_(initial_size), initial_size_(initial_size),
@@ -788,15 +784,15 @@ class vector_downward {
#else #else
vector_downward(vector_downward &other) vector_downward(vector_downward &other)
#endif // defined(FLATBUFFERS_CPP98_STL) #endif // defined(FLATBUFFERS_CPP98_STL)
// clang-format on // clang-format on
: allocator_(other.allocator_), : allocator_(other.allocator_),
own_allocator_(other.own_allocator_), own_allocator_(other.own_allocator_),
initial_size_(other.initial_size_), initial_size_(other.initial_size_),
buffer_minalign_(other.buffer_minalign_), buffer_minalign_(other.buffer_minalign_),
reserved_(other.reserved_), reserved_(other.reserved_),
buf_(other.buf_), buf_(other.buf_),
cur_(other.cur_), cur_(other.cur_),
scratch_(other.scratch_) { scratch_(other.scratch_) {
// No change in other.allocator_ // No change in other.allocator_
// No change in other.initial_size_ // No change in other.initial_size_
// No change in other.buffer_minalign_ // No change in other.buffer_minalign_
@@ -840,9 +836,7 @@ class vector_downward {
clear_scratch(); clear_scratch();
} }
void clear_scratch() { void clear_scratch() { scratch_ = buf_; }
scratch_ = buf_;
}
void clear_allocator() { void clear_allocator() {
if (own_allocator_ && allocator_) { delete allocator_; } if (own_allocator_ && allocator_) { delete allocator_; }
@@ -995,8 +989,8 @@ class vector_downward {
auto old_reserved = reserved_; auto old_reserved = reserved_;
auto old_size = size(); auto old_size = size();
auto old_scratch_size = scratch_size(); auto old_scratch_size = scratch_size();
reserved_ += (std::max)(len, reserved_ +=
old_reserved ? old_reserved / 2 : initial_size_); (std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1); reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
if (buf_) { if (buf_) {
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_, buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
@@ -1021,13 +1015,13 @@ const T *data(const std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so // Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior. // we need it to be non-null to avoid undefined behavior.
static uint8_t t; static uint8_t t;
return v.empty() ? reinterpret_cast<const T*>(&t) : &v.front(); return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
} }
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) { template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
// Eventually the returned pointer gets passed down to memcpy, so // Eventually the returned pointer gets passed down to memcpy, so
// we need it to be non-null to avoid undefined behavior. // we need it to be non-null to avoid undefined behavior.
static uint8_t t; static uint8_t t;
return v.empty() ? reinterpret_cast<T*>(&t) : &v.front(); return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
} }
/// @endcond /// @endcond
@@ -1054,11 +1048,10 @@ class FlatBufferBuilder {
/// minimum alignment upon reallocation. Only needed if you intend to store /// minimum alignment upon reallocation. Only needed if you intend to store
/// types with custom alignment AND you wish to read the buffer in-place /// types with custom alignment AND you wish to read the buffer in-place
/// directly after creation. /// directly after creation.
explicit FlatBufferBuilder(size_t initial_size = 1024, explicit FlatBufferBuilder(
Allocator *allocator = nullptr, size_t initial_size = 1024, Allocator *allocator = nullptr,
bool own_allocator = false, bool own_allocator = false,
size_t buffer_minalign = size_t buffer_minalign = AlignOf<largest_scalar_t>())
AlignOf<largest_scalar_t>())
: buf_(initial_size, allocator, own_allocator, buffer_minalign), : buf_(initial_size, allocator, own_allocator, buffer_minalign),
num_field_loc(0), num_field_loc(0),
max_voffset_(0), max_voffset_(0),
@@ -1161,8 +1154,8 @@ class FlatBufferBuilder {
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards! /// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
/// @return A `FlatBuffer` that owns the buffer and its allocator and /// @return A `FlatBuffer` that owns the buffer and its allocator and
/// behaves similar to a `unique_ptr` with a deleter. /// behaves similar to a `unique_ptr` with a deleter.
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead"))
ReleaseBufferPointer() { DetachedBuffer ReleaseBufferPointer() {
Finished(); Finished();
return buf_.release(); return buf_.release();
} }
@@ -1181,7 +1174,8 @@ class FlatBufferBuilder {
/// `FlatBuffer` starts. /// `FlatBuffer` starts.
/// @return A raw pointer to the start of the memory block containing /// @return A raw pointer to the start of the memory block containing
/// the serialized `FlatBuffer`. /// the serialized `FlatBuffer`.
/// @remark If the allocator is owned, it gets deleted when the destructor is called.. /// @remark If the allocator is owned, it gets deleted when the destructor is
/// called..
uint8_t *ReleaseRaw(size_t &size, size_t &offset) { uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
Finished(); Finished();
return buf_.release_raw(size, offset); return buf_.release_raw(size, offset);
@@ -1210,8 +1204,9 @@ class FlatBufferBuilder {
/// @brief In order to save space, fields that are set to their default value /// @brief In order to save space, fields that are set to their default value
/// don't get serialized into the buffer. /// don't get serialized into the buffer.
/// @param[in] fd When set to `true`, always serializes default values that are set. /// @param[in] fd When set to `true`, always serializes default values that
/// Optional fields which are not set explicitly, will still not be serialized. /// are set. Optional fields which are not set explicitly, will still not be
/// serialized.
void ForceDefaults(bool fd) { force_defaults_ = fd; } void ForceDefaults(bool fd) { force_defaults_ = fd; }
/// @brief By default vtables are deduped in order to save space. /// @brief By default vtables are deduped in order to save space.
@@ -1369,7 +1364,7 @@ class FlatBufferBuilder {
it += sizeof(uoffset_t)) { it += sizeof(uoffset_t)) {
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it); auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr)); auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
auto vt2_size = *vt2; auto vt2_size = ReadScalar<voffset_t>(vt2);
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue; if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
vt_use = *vt_offset_ptr; vt_use = *vt_offset_ptr;
buf_.pop(GetSize() - vtableoffsetloc); buf_.pop(GetSize() - vtableoffsetloc);
@@ -1759,7 +1754,7 @@ class FlatBufferBuilder {
/// `vector`. /// `vector`.
/// @tparam T The data type of the `std::vector` struct elements. /// @tparam T The data type of the `std::vector` struct elements.
/// @tparam S The data type of the `std::vector` native struct elements. /// @tparam S The data type of the `std::vector` native struct elements.
/// @param[in]] v A const reference to the `std::vector` of structs to /// @param[in] v A const reference to the `std::vector` of structs to
/// serialize into the buffer as a `vector`. /// serialize into the buffer as a `vector`.
/// @return Returns a typed `Offset` into the serialized data indicating /// @return Returns a typed `Offset` into the serialized data indicating
/// where the vector is stored. /// where the vector is stored.
@@ -1835,7 +1830,7 @@ class FlatBufferBuilder {
extern T Pack(const S &); extern T Pack(const S &);
typedef T (*Pack_t)(const S &); typedef T (*Pack_t)(const S &);
std::vector<T> vv(len); std::vector<T> vv(len);
std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack)); std::transform(v, v + len, vv.begin(), static_cast<Pack_t &>(Pack));
return CreateVectorOfSortedStructs<T>(vv, len); return CreateVectorOfSortedStructs<T>(vv, len);
} }
@@ -1916,12 +1911,12 @@ class FlatBufferBuilder {
} }
template<typename T> template<typename T>
Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) { Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
T **buf) {
return CreateUninitializedVector(len, sizeof(T), return CreateUninitializedVector(len, sizeof(T),
reinterpret_cast<uint8_t **>(buf)); reinterpret_cast<uint8_t **>(buf));
} }
// @brief Create a vector of scalar type T given as input a vector of scalar // @brief Create a vector of scalar type T given as input a vector of scalar
// type U, useful with e.g. pre "enum class" enums, or any existing scalar // type U, useful with e.g. pre "enum class" enums, or any existing scalar
// data of the wrong type. // data of the wrong type.
@@ -1970,8 +1965,7 @@ class FlatBufferBuilder {
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }
protected: protected:
// You shouldn't really be copying instances of this class. // You shouldn't really be copying instances of this class.
FlatBufferBuilder(const FlatBufferBuilder &); FlatBufferBuilder(const FlatBufferBuilder &);
FlatBufferBuilder &operator=(const FlatBufferBuilder &); FlatBufferBuilder &operator=(const FlatBufferBuilder &);
@@ -2024,8 +2018,8 @@ protected:
bool operator()(const Offset<String> &a, const Offset<String> &b) const { bool operator()(const Offset<String> &a, const Offset<String> &b) const {
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o)); auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o)); auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
return StringLessThan(stra->data(), stra->size(), return StringLessThan(stra->data(), stra->size(), strb->data(),
strb->data(), strb->size()); strb->size());
} }
const vector_downward *buf_; const vector_downward *buf_;
}; };
@@ -2089,13 +2083,15 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
/// 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, bool size_prefixed = false) { inline const char *GetBufferIdentifier(const void *buf,
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, bool size_prefixed = false) { inline bool BufferHasIdentifier(const void *buf, const char *identifier,
bool size_prefixed = false) {
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier, return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
FlatBufferBuilder::kFileIdentifierLength) == 0; FlatBufferBuilder::kFileIdentifierLength) == 0;
} }
@@ -2112,8 +2108,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
num_tables_(0), num_tables_(0),
max_tables_(_max_tables), max_tables_(_max_tables),
upper_bound_(0), upper_bound_(0),
check_alignment_(_check_alignment) check_alignment_(_check_alignment) {
{
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE); FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
} }
@@ -2162,8 +2157,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len); return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
} }
template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off) template<typename T>
const { bool Verify(const uint8_t *base, voffset_t elem_off) const {
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T)); return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
} }
@@ -2186,16 +2181,15 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
// Verify a pointer (may be NULL) to string. // Verify a pointer (may be NULL) to string.
bool VerifyString(const String *str) const { bool VerifyString(const String *str) const {
size_t end; size_t end;
return !str || return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
(VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str), 1, &end) &&
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.
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size, bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
size_t *end = nullptr) const { size_t *end = nullptr) const {
auto veco = static_cast<size_t>(vec - buf_); auto veco = static_cast<size_t>(vec - buf_);
// Check we can read the size field. // Check we can read the size field.
if (!Verify<uoffset_t>(veco)) return false; if (!Verify<uoffset_t>(veco)) return false;
@@ -2230,8 +2224,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
return true; return true;
} }
__supress_ubsan__("unsigned-integer-overflow") __supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
bool VerifyTableStart(const uint8_t *table) { const uint8_t *table) {
// Check the vtable offset. // Check the vtable offset.
auto tableo = static_cast<size_t>(table - buf_); auto tableo = static_cast<size_t>(table - buf_);
if (!Verify<soffset_t>(tableo)) return false; if (!Verify<soffset_t>(tableo)) return false;
@@ -2246,9 +2240,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
template<typename T> template<typename T>
bool VerifyBufferFromStart(const char *identifier, size_t start) { bool VerifyBufferFromStart(const char *identifier, size_t start) {
if (identifier && if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
(size_ < 2 * sizeof(flatbuffers::uoffset_t) || !BufferHasIdentifier(buf_ + start, identifier))) {
!BufferHasIdentifier(buf_ + start, identifier))) {
return false; return false;
} }
@@ -2496,8 +2489,8 @@ class Table {
uint8_t data_[1]; uint8_t data_[1];
}; };
template<typename T> void FlatBufferBuilder::Required(Offset<T> table, template<typename T>
voffset_t field) { void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o)); auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0; bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
// If this fails, the caller will show what field needs to be set. // If this fails, the caller will show what field needs to be set.
@@ -2544,7 +2537,9 @@ 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.
inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); } inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
return ReadScalar<uoffset_t>(buf);
}
// Base class for native objects (FlatBuffer data de-serialized into native // Base class for native objects (FlatBuffer data de-serialized into native
// C++ data structures). // C++ data structures).
@@ -2687,10 +2682,10 @@ 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 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.

View File

@@ -17,6 +17,7 @@
#include <functional> #include <functional>
#include <limits> #include <limits>
#include <string> #include <string>
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"

View File

@@ -339,12 +339,12 @@ class Map : public Vector {
template<typename T> template<typename T>
void AppendToString(std::string &s, T &&v, bool keys_quoted) { void AppendToString(std::string &s, T &&v, bool keys_quoted) {
s += "[ "; s += "[ ";
for (size_t i = 0; i < v.size(); i++) { for (size_t i = 0; i < v.size(); i++) {
if (i) s += ", "; if (i) s += ", ";
v[i].ToString(true, keys_quoted, s); v[i].ToString(true, keys_quoted, s);
} }
s += " ]"; s += " ]";
} }
class Reference { class Reference {
@@ -386,13 +386,17 @@ class Reference {
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; } bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
bool IsUntypedVector() const { return type_ == FBT_VECTOR; } bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); } bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); } bool IsFixedTypedVector() const {
bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());} return flexbuffers::IsFixedTypedVector(type_);
}
bool IsAnyVector() const {
return (IsTypedVector() || IsFixedTypedVector() || IsVector());
}
bool IsMap() const { return type_ == FBT_MAP; } bool IsMap() const { return type_ == FBT_MAP; }
bool IsBlob() const { return type_ == FBT_BLOB; } bool IsBlob() const { return type_ == FBT_BLOB; }
bool AsBool() const { bool AsBool() const {
return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_) return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
: AsUInt64()) != 0; : AsUInt64()) != 0;
} }
// Reads any type as a int64_t. Never fails, does most sensible conversion. // Reads any type as a int64_t. Never fails, does most sensible conversion.
@@ -555,7 +559,8 @@ class Reference {
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted); AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
} else if (IsBlob()) { } else if (IsBlob()) {
auto blob = AsBlob(); auto blob = AsBlob();
flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false); flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
blob.size(), &s, true, false);
} else { } else {
s += "(?)"; s += "(?)";
} }
@@ -729,9 +734,15 @@ template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); } template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); } template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); } template<> inline uint16_t Reference::As<uint16_t>() const {
template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); } return AsUInt16();
template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); } }
template<> inline uint32_t Reference::As<uint32_t>() const {
return AsUInt32();
}
template<> inline uint64_t Reference::As<uint64_t>() const {
return AsUInt64();
}
template<> inline double Reference::As<double>() const { return AsDouble(); } template<> inline double Reference::As<double>() const { return AsDouble(); }
template<> inline float Reference::As<float>() const { return AsFloat(); } template<> inline float Reference::As<float>() const { return AsFloat(); }
@@ -920,9 +931,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Bool(b); Bool(b);
} }
void IndirectInt(int64_t i) { void IndirectInt(int64_t i) { PushIndirect(i, FBT_INDIRECT_INT, WidthI(i)); }
PushIndirect(i, FBT_INDIRECT_INT, WidthI(i));
}
void IndirectInt(const char *key, int64_t i) { void IndirectInt(const char *key, int64_t i) {
Key(key); Key(key);
IndirectInt(i); IndirectInt(i);
@@ -1214,9 +1223,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// Works on any data type. // Works on any data type.
struct Value; struct Value;
Value LastValue() { return stack_.back(); } Value LastValue() { return stack_.back(); }
void ReuseValue(Value v) { void ReuseValue(Value v) { stack_.push_back(v); }
stack_.push_back(v);
}
void ReuseValue(const char *key, Value v) { void ReuseValue(const char *key, Value v) {
Key(key); Key(key);
ReuseValue(v); ReuseValue(v);
@@ -1462,7 +1469,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed, Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
bool fixed, const Value *keys = nullptr) { bool fixed, const Value *keys = nullptr) {
FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported. FLATBUFFERS_ASSERT(
!fixed ||
typed); // typed=false, fixed=true combination is not supported.
// Figure out smallest bit width we can store this vector with. // Figure out smallest bit width we can store this vector with.
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len)); auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
auto prefix_elems = 1; auto prefix_elems = 1;
@@ -1542,7 +1551,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
typedef std::pair<size_t, size_t> StringOffset; typedef std::pair<size_t, size_t> StringOffset;
struct StringOffsetCompare { struct StringOffsetCompare {
explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {} explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
: buf_(&buf) {}
bool operator()(const StringOffset &a, const StringOffset &b) const { bool operator()(const StringOffset &a, const StringOffset &b) const {
auto stra = reinterpret_cast<const char *>( auto stra = reinterpret_cast<const char *>(
flatbuffers::vector_data(*buf_) + a.first); flatbuffers::vector_data(*buf_) + a.first);
@@ -1562,8 +1572,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
} // namespace flexbuffers } // namespace flexbuffers
# if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(pop) # pragma warning(pop)
# endif #endif
#endif // FLATBUFFERS_FLEXBUFFERS_H_ #endif // FLATBUFFERS_FLEXBUFFERS_H_

View File

@@ -88,8 +88,7 @@ class SliceAllocator : public Allocator {
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) : slice_(grpc_empty_slice()) {
: slice_(grpc_empty_slice()) {
// default-construct and swap idiom // default-construct and swap idiom
swap(other); swap(other);
} }
@@ -164,34 +163,36 @@ class MessageBuilder : private detail::SliceAllocatorMember,
public FlatBufferBuilder { public FlatBufferBuilder {
public: public:
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, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc) explicit MessageBuilder(FlatBufferBuilder &&src,
: FlatBufferBuilder(1024, &slice_allocator_, false) { void (*dealloc)(void *,
size_t) = &DefaultAllocator::dealloc)
: 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_new_with_len(buf, capacity, dealloc); slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
} } else {
else {
slice_allocator_.slice_ = grpc_empty_slice(); slice_allocator_.slice_ = grpc_empty_slice();
} }
} }
/// Move-assign a FlatBufferBuilder to a MessageBuilder. /// Move-assign a FlatBufferBuilder to a MessageBuilder.
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported. /// Only FlatBufferBuilder with default allocator (basically, nullptr) is
/// 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));
@@ -209,10 +210,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
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 restores // After swapping the FlatBufferBuilder, we swap back the allocator, which
// the original allocator back in place. This is necessary because MessageBuilder's // restores the original allocator back in place. This is necessary because
// allocator is its own member (SliceAllocatorMember). The allocator passed to // MessageBuilder's allocator is its own member (SliceAllocatorMember). The
// FlatBufferBuilder::vector_downward must point to this member. // allocator passed to FlatBufferBuilder::vector_downward must point to this
// member.
buf_.swap_allocator(other.buf_); buf_.swap_allocator(other.buf_);
} }
@@ -232,10 +234,10 @@ class MessageBuilder : private detail::SliceAllocatorMember,
// 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
auto msg_size = buf_.size(); // size of msg auto msg_size = buf_.size(); // size of msg
// Do some sanity checks on data/size // Do some sanity checks on data/size
FLATBUFFERS_ASSERT(msg_data); FLATBUFFERS_ASSERT(msg_data);
FLATBUFFERS_ASSERT(msg_size); FLATBUFFERS_ASSERT(msg_size);

View File

@@ -57,17 +57,17 @@ template<typename T> T HashFnv1a(const char *input) {
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> struct NamedHashFunction {
const char *name; const char *name;
typedef T (*HashFunction)(const char *); typedef T (*HashFunction)(const char *);
@@ -75,7 +75,7 @@ template <typename T> struct NamedHashFunction {
}; };
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> },
}; };

View File

@@ -91,6 +91,20 @@ switch (type) {
} }
*/ */
// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation
// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed).
// In the above example, only CTYPE is used to generate the code, it can be rewritten:
/*
switch (type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
case BASE_TYPE_ ## ENUM: \
// do something specific to CTYPE here
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD
}
*/
#define FLATBUFFERS_GEN_TYPES(TD) \ #define FLATBUFFERS_GEN_TYPES(TD) \
FLATBUFFERS_GEN_TYPES_SCALAR(TD) \ FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
FLATBUFFERS_GEN_TYPES_POINTER(TD) \ FLATBUFFERS_GEN_TYPES_POINTER(TD) \
@@ -101,17 +115,15 @@ switch (type) {
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic. __extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
#endif #endif
enum BaseType { enum BaseType {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ #define FLATBUFFERS_TD(ENUM, ...) \
RTYPE, KTYPE) \ BASE_TYPE_ ## ENUM,
BASE_TYPE_ ## ENUM,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
}; };
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
RTYPE, KTYPE) \ static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \ "define largest_scalar_t as " #CTYPE);
"define largest_scalar_t as " #CTYPE);
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
@@ -338,50 +350,12 @@ struct StructDef : public Definition {
flatbuffers::unique_ptr<std::string> original_location; flatbuffers::unique_ptr<std::string> original_location;
}; };
inline bool IsStruct(const Type &type) {
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
}
inline bool IsVector(const Type &type) {
return type.base_type == BASE_TYPE_VECTOR;
}
inline bool IsArray(const Type &type) {
return type.base_type == BASE_TYPE_ARRAY;
}
inline bool IsSeries(const Type &type) {
return IsVector(type) || IsArray(type);
}
inline bool IsEnum(const Type &type) {
return type.enum_def != nullptr && IsInteger(type.base_type);
}
inline size_t InlineSize(const Type &type) {
return IsStruct(type)
? type.struct_def->bytesize
: (IsArray(type)
? InlineSize(type.VectorType()) * type.fixed_length
: SizeOf(type.base_type));
}
inline size_t InlineAlignment(const Type &type) {
if (IsStruct(type)) {
return type.struct_def->minalign;
} else if (IsArray(type)) {
return IsStruct(type.VectorType()) ? type.struct_def->minalign
: SizeOf(type.element);
} else {
return SizeOf(type.base_type);
}
}
struct EnumDef; struct EnumDef;
struct EnumValBuilder; struct EnumValBuilder;
struct EnumVal { struct EnumVal {
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(const Parser &parser, const reflection::EnumVal *val); bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
@@ -460,6 +434,48 @@ struct EnumDef : public Definition {
SymbolTable<EnumVal> vals; SymbolTable<EnumVal> vals;
}; };
inline bool IsStruct(const Type &type) {
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
}
inline bool IsUnion(const Type &type) {
return type.enum_def != nullptr && type.enum_def->is_union;
}
inline bool IsVector(const Type &type) {
return type.base_type == BASE_TYPE_VECTOR;
}
inline bool IsArray(const Type &type) {
return type.base_type == BASE_TYPE_ARRAY;
}
inline bool IsSeries(const Type &type) {
return IsVector(type) || IsArray(type);
}
inline bool IsEnum(const Type &type) {
return type.enum_def != nullptr && IsInteger(type.base_type);
}
inline size_t InlineSize(const Type &type) {
return IsStruct(type)
? type.struct_def->bytesize
: (IsArray(type)
? InlineSize(type.VectorType()) * type.fixed_length
: SizeOf(type.base_type));
}
inline size_t InlineAlignment(const Type &type) {
if (IsStruct(type)) {
return type.struct_def->minalign;
} else if (IsArray(type)) {
return IsStruct(type.VectorType()) ? type.struct_def->minalign
: SizeOf(type.element);
} else {
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;
} }
@@ -475,7 +491,8 @@ inline bool EqualByName(const Type &a, const Type &b) {
} }
struct RPCCall : public Definition { struct RPCCall : public Definition {
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
const Parser &parser) const;
bool Deserialize(Parser &parser, const reflection::RPCCall *call); bool Deserialize(Parser &parser, const reflection::RPCCall *call);
@@ -483,7 +500,8 @@ struct RPCCall : public Definition {
}; };
struct ServiceDef : public Definition { struct ServiceDef : public Definition {
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const; Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
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;
@@ -717,9 +735,7 @@ class Parser : public ParserState {
source_(nullptr), source_(nullptr),
anonymous_counter(0), anonymous_counter(0),
recurse_protection_counter(0) { recurse_protection_counter(0) {
if (opts.force_defaults) { if (opts.force_defaults) { builder_.ForceDefaults(true); }
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_);
@@ -790,9 +806,9 @@ class Parser : public ParserState {
// 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.
@@ -849,16 +865,19 @@ class Parser : public ParserState {
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(Value &val, FieldDef *field, FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
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, bool check, Value &e, FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
BaseType req, bool *destmatch); bool check, Value &e, BaseType req,
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field); bool *destmatch);
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, bool check_now); FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result); bool check_now);
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
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);
@@ -866,8 +885,7 @@ class Parser : public ParserState {
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, FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
bool is_union,
EnumDef **dest); EnumDef **dest);
FLATBUFFERS_CHECKED_ERROR ParseDecl(); FLATBUFFERS_CHECKED_ERROR ParseDecl();
FLATBUFFERS_CHECKED_ERROR ParseService(); FLATBUFFERS_CHECKED_ERROR ParseService();
@@ -883,16 +901,15 @@ class Parser : public ParserState {
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 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 CheckClash(std::vector<FieldDef*> &fields, FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
StructDef *struct_def, StructDef *struct_def,
const char *suffix, const char *suffix, BaseType baseType);
BaseType baseType);
bool SupportsAdvancedUnionFeatures() const; bool SupportsAdvancedUnionFeatures() const;
bool SupportsAdvancedArrayFeatures() const; bool SupportsAdvancedArrayFeatures() const;
@@ -909,7 +926,7 @@ class Parser : public ParserState {
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_;
@@ -952,159 +969,145 @@ extern std::string MakeScreamingCamel(const std::string &in);
// strict_json adds "quotes" around field names if true. // strict_json adds "quotes" around field names if true.
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8 // If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
// byte arrays in String values), returns false. // byte arrays in String values), returns false.
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 bool GenerateText(const Parser &parser, extern bool GenerateText(const Parser &parser, const void *flatbuffer,
const void *flatbuffer,
std::string *text); std::string *text);
extern bool GenerateTextFile(const Parser &parser, extern bool GenerateTextFile(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate binary files from a given FlatBuffer, and a given Parser // Generate binary files from a given FlatBuffer, and a given Parser
// object that has been populated with the corresponding schema. // object that has been populated with the corresponding schema.
// See idl_gen_general.cpp. // See code_generators.cpp.
extern bool GenerateBinary(const Parser &parser, extern bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a C++ header from the definitions in the Parser object. // Generate a C++ header from the definitions in the Parser object.
// See idl_gen_cpp. // See idl_gen_cpp.
extern bool GenerateCPP(const Parser &parser, extern bool GenerateCPP(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
extern bool GenerateDart(const Parser &parser, // Generate C# files from the definitions in the Parser object.
const std::string &path, // See idl_gen_csharp.cpp.
extern bool GenerateCSharp(const Parser &parser, const std::string &path,
const std::string &file_name);
extern bool GenerateDart(const Parser &parser, const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate JavaScript or TypeScript code from the definitions in the Parser object. // Generate Java files from the definitions in the Parser object.
// See idl_gen_js. // See idl_gen_java.cpp.
extern bool GenerateJSTS(const Parser &parser, extern bool GenerateJava(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
// Generate JavaScript or TypeScript code from the definitions in the Parser
// object. See idl_gen_js.
extern bool GenerateJSTS(const Parser &parser, const std::string &path,
const std::string &file_name);
// Generate Go files from the definitions in the Parser object. // Generate Go files from the definitions in the Parser object.
// See idl_gen_go.cpp. // See idl_gen_go.cpp.
extern bool GenerateGo(const Parser &parser, extern bool GenerateGo(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Php code from the definitions in the Parser object. // Generate Php code from the definitions in the Parser object.
// See idl_gen_php. // See idl_gen_php.
extern bool GeneratePhp(const Parser &parser, extern bool GeneratePhp(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Python files from the definitions in the Parser object. // Generate Python files from the definitions in the Parser object.
// See idl_gen_python.cpp. // See idl_gen_python.cpp.
extern bool GeneratePython(const Parser &parser, extern bool GeneratePython(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Lobster files from the definitions in the Parser object. // Generate Lobster files from the definitions in the Parser object.
// See idl_gen_lobster.cpp. // See idl_gen_lobster.cpp.
extern bool GenerateLobster(const Parser &parser, extern bool GenerateLobster(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Lua files from the definitions in the Parser object. // Generate Lua files from the definitions in the Parser object.
// See idl_gen_lua.cpp. // See idl_gen_lua.cpp.
extern bool GenerateLua(const Parser &parser, extern bool GenerateLua(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
// Generate Rust files from the definitions in the Parser object. // Generate Rust files from the definitions in the Parser object.
// See idl_gen_rust.cpp. // See idl_gen_rust.cpp.
extern bool GenerateRust(const Parser &parser, extern bool GenerateRust(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Json schema file // Generate Json schema file
// See idl_gen_json_schema.cpp. // See idl_gen_json_schema.cpp.
extern bool GenerateJsonSchema(const Parser &parser, extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
extern bool GenerateKotlin(const Parser &parser, const std::string &path, extern bool GenerateKotlin(const Parser &parser, const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate Java/C#/.. files from the definitions in the Parser object.
// See idl_gen_general.cpp.
extern bool GenerateGeneral(const Parser &parser,
const std::string &path,
const std::string &file_name);
// Generate a schema file from the internal representation, useful after // Generate a schema file from the internal representation, useful after
// parsing a .proto schema. // parsing a .proto schema.
extern std::string GenerateFBS(const Parser &parser, extern std::string GenerateFBS(const Parser &parser,
const std::string &file_name); const std::string &file_name);
extern bool GenerateFBS(const Parser &parser, extern bool GenerateFBS(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated JavaScript or TypeScript code. // Generate a make rule for the generated JavaScript or TypeScript code.
// See idl_gen_js.cpp. // See idl_gen_js.cpp.
extern std::string JSTSMakeRule(const Parser &parser, extern std::string JSTSMakeRule(const Parser &parser, const std::string &path,
const std::string &path, const std::string &file_name);
const std::string &file_name);
// Generate a make rule for the generated C++ header. // Generate a make rule for the generated C++ header.
// See idl_gen_cpp.cpp. // See idl_gen_cpp.cpp.
extern std::string CPPMakeRule(const Parser &parser, extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Dart code // Generate a make rule for the generated Dart code
// see idl_gen_dart.cpp // see idl_gen_dart.cpp
extern std::string DartMakeRule(const Parser &parser, extern std::string DartMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Rust code. // Generate a make rule for the generated Rust code.
// See idl_gen_rust.cpp. // See idl_gen_rust.cpp.
extern std::string RustMakeRule(const Parser &parser, extern std::string RustMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated Java/C#/... files. // Generate a make rule for generated Java or C# files.
// See idl_gen_general.cpp. // See code_generators.cpp.
extern std::string GeneralMakeRule(const Parser &parser, extern std::string JavaCSharpMakeRule(const Parser &parser,
const std::string &path, const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate a make rule for the generated text (JSON) files. // Generate a make rule for the generated text (JSON) files.
// See idl_gen_text.cpp. // See idl_gen_text.cpp.
extern std::string TextMakeRule(const Parser &parser, extern std::string TextMakeRule(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_names); const std::string &file_names);
// Generate a make rule for the generated binary files. // Generate a make rule for the generated binary files.
// See idl_gen_general.cpp. // See code_generators.cpp.
extern std::string BinaryMakeRule(const Parser &parser, extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
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, bool GenerateCppGRPC(const Parser &parser, const std::string &path,
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, bool GenerateGoGRPC(const Parser &parser, const std::string &path,
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, bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
const std::string &path,
const std::string &file_name); const std::string &file_name);
// Generate GRPC Python interfaces.
// See idl_gen_grpc.cpp.
bool GeneratePythonGRPC(const Parser &parser,
const std::string &path,
const std::string &file_name);
} // namespace flatbuffers } // namespace flatbuffers
#endif // FLATBUFFERS_IDL_H_ #endif // FLATBUFFERS_IDL_H_

View File

@@ -88,7 +88,8 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
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: return static_cast<size_t>(type_table->values[type_table->num_elems]); case ST_STRUCT:
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;

View File

@@ -228,7 +228,7 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
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

View File

@@ -96,13 +96,13 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
} }
}; };
template <> class numeric_limits<float> : template <> class numeric_limits<float> :
public std::numeric_limits<float> { public std::numeric_limits<float> {
public: public:
static float lowest() { return -FLT_MAX; } static float lowest() { return -FLT_MAX; }
}; };
template <> class numeric_limits<double> : template <> class numeric_limits<double> :
public std::numeric_limits<double> { public std::numeric_limits<double> {
public: public:
static double lowest() { return -DBL_MAX; } static double lowest() { return -DBL_MAX; }
@@ -138,18 +138,20 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T, typename U> using is_same = std::is_same<T,U>; template <typename T, typename U> using is_same = std::is_same<T,U>;
template <typename T> using is_floating_point = std::is_floating_point<T>; template <typename T> using is_floating_point = std::is_floating_point<T>;
template <typename T> using is_unsigned = std::is_unsigned<T>; template <typename T> using is_unsigned = std::is_unsigned<T>;
template <typename T> using is_enum = std::is_enum<T>;
template <typename T> using make_unsigned = std::make_unsigned<T>; template <typename T> using make_unsigned = std::make_unsigned<T>;
template<bool B, class T, class F> template<bool B, class T, class F>
using conditional = std::conditional<B, T, F>; using conditional = std::conditional<B, T, F>;
template<class T, T v> template<class T, T v>
using integral_constant = std::integral_constant<T, v>; using integral_constant = std::integral_constant<T, v>;
#else #else
// Map C++ TR1 templates defined by stlport. // Map C++ TR1 templates defined by stlport.
template <typename T> using is_scalar = std::tr1::is_scalar<T>; template <typename T> using is_scalar = std::tr1::is_scalar<T>;
template <typename T, typename U> using is_same = std::tr1::is_same<T,U>; template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
template <typename T> using is_floating_point = template <typename T> using is_floating_point =
std::tr1::is_floating_point<T>; std::tr1::is_floating_point<T>;
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>; template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
template <typename T> using is_enum = std::tr1::is_enum<T>;
// Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned. // Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
template<typename T> struct make_unsigned { template<typename T> struct make_unsigned {
static_assert(is_unsigned<T>::value, "Specialization not implemented!"); static_assert(is_unsigned<T>::value, "Specialization not implemented!");
@@ -165,7 +167,7 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
using conditional = std::tr1::conditional<B, T, F>; using conditional = std::tr1::conditional<B, T, F>;
template<class T, T v> template<class T, T v>
using integral_constant = std::tr1::integral_constant<T, v>; using integral_constant = std::tr1::integral_constant<T, v>;
#endif // !FLATBUFFERS_CPP98_STL #endif // !FLATBUFFERS_CPP98_STL
#else #else
// MSVC 2010 doesn't support C++11 aliases. // MSVC 2010 doesn't support C++11 aliases.
template <typename T> struct is_scalar : public std::is_scalar<T> {}; template <typename T> struct is_scalar : public std::is_scalar<T> {};
@@ -173,6 +175,7 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <typename T> struct is_floating_point : template <typename T> struct is_floating_point :
public std::is_floating_point<T> {}; public std::is_floating_point<T> {};
template <typename T> struct is_unsigned : public std::is_unsigned<T> {}; template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
template <typename T> struct is_enum : public std::is_enum<T> {};
template <typename T> struct make_unsigned : public std::make_unsigned<T> {}; template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
template<bool B, class T, class F> template<bool B, class T, class F>
struct conditional : public std::conditional<B, T, F> {}; struct conditional : public std::conditional<B, T, F> {};
@@ -280,6 +283,23 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) { template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
return reinterpret_cast<intptr_t>(x.get()) == y; return reinterpret_cast<intptr_t>(x.get()) == y;
} }
template <class T> bool operator!=(const unique_ptr<T>& x, decltype(nullptr)) {
return !!x;
}
template <class T> bool operator!=(decltype(nullptr), const unique_ptr<T>& x) {
return !!x;
}
template <class T> bool operator==(const unique_ptr<T>& x, decltype(nullptr)) {
return !x;
}
template <class T> bool operator==(decltype(nullptr), const unique_ptr<T>& x) {
return !x;
}
#endif // !FLATBUFFERS_CPP98_STL #endif // !FLATBUFFERS_CPP98_STL
} // namespace flatbuffers } // namespace flatbuffers

View File

@@ -17,10 +17,10 @@
#ifndef FLATBUFFERS_UTIL_H_ #ifndef FLATBUFFERS_UTIL_H_
#define FLATBUFFERS_UTIL_H_ #define FLATBUFFERS_UTIL_H_
#include "flatbuffers/base.h"
#include <errno.h> #include <errno.h>
#include "flatbuffers/base.h"
#ifndef FLATBUFFERS_PREFER_PRINTF #ifndef FLATBUFFERS_PREFER_PRINTF
# include <sstream> # include <sstream>
#else // FLATBUFFERS_PREFER_PRINTF #else // FLATBUFFERS_PREFER_PRINTF

View File

@@ -29,12 +29,12 @@ local getAlignSize = compat.GetAlignSize
local function vtableEqual(a, objectStart, b) local function vtableEqual(a, objectStart, b)
UOffsetT:EnforceNumber(objectStart) UOffsetT:EnforceNumber(objectStart)
if (#a * VOffsetT.bytewidth) ~= #b then if (#a * 2) ~= #b then
return false return false
end end
for i, elem in ipairs(a) do for i, elem in ipairs(a) do
local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * VOffsetT.bytewidth) local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * 2)
if x ~= 0 or elem ~= 0 then if x ~= 0 or elem ~= 0 then
local y = objectStart - elem local y = objectStart - elem
if x ~= y then if x ~= y then
@@ -60,6 +60,23 @@ function m.New(initialSize)
return o return o
end end
-- Clears the builder and resets the state. It does not actually clear the backing binary array, it just reuses it as
-- needed. This is a performant way to use the builder for multiple constructions without the overhead of multiple
-- builder allocations.
function mt:Clear()
self.finished = false
self.nested = false
self.minalign = 1
self.currentVTable = nil
self.objectEnd = nil
self.head = #self.bytes -- place the head at the end of the binary array
-- clear vtables instead of making a new table
local vtable = self.vtables
local vtableCount = #vtable
for i=1,vtableCount do vtable[i] = nil end
end
function mt:Output(full) function mt:Output(full)
assert(self.finished, "Builder Not Finished") assert(self.finished, "Builder Not Finished")
if full then if full then
@@ -104,7 +121,7 @@ function mt:WriteVtable()
local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1) local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1)
local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1) local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1)
local metadata = VtableMetadataFields * VOffsetT.bytewidth local metadata = VtableMetadataFields * 2
local vt2End = vt2Start + vt2Len local vt2End = vt2Start + vt2Len
local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End) local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End)
@@ -133,7 +150,7 @@ function mt:WriteVtable()
self:PrependVOffsetT(objectSize) self:PrependVOffsetT(objectSize)
local vBytes = #self.currentVTable + VtableMetadataFields local vBytes = #self.currentVTable + VtableMetadataFields
vBytes = vBytes * VOffsetT.bytewidth vBytes = vBytes * 2
self:PrependVOffsetT(vBytes) self:PrependVOffsetT(vBytes)
local objectStart = #self.bytes - objectOffset local objectStart = #self.bytes - objectOffset
@@ -208,17 +225,17 @@ function mt:Prep(size, additionalBytes)
end end
function mt:PrependSOffsetTRelative(off) function mt:PrependSOffsetTRelative(off)
self:Prep(SOffsetT.bytewidth, 0) self:Prep(4, 0)
assert(off <= self:Offset(), "Offset arithmetic error") assert(off <= self:Offset(), "Offset arithmetic error")
local off2 = self:Offset() - off + SOffsetT.bytewidth local off2 = self:Offset() - off + 4
self:Place(off2, SOffsetT) self:Place(off2, SOffsetT)
end end
function mt:PrependUOffsetTRelative(off) function mt:PrependUOffsetTRelative(off)
self:Prep(UOffsetT.bytewidth, 0) self:Prep(4, 0)
local soffset = self:Offset() local soffset = self:Offset()
if off <= soffset then if off <= soffset then
local off2 = soffset - off + UOffsetT.bytewidth local off2 = soffset - off + 4
self:Place(off2, UOffsetT) self:Place(off2, UOffsetT)
else else
error("Offset arithmetic error") error("Offset arithmetic error")
@@ -228,8 +245,9 @@ end
function mt:StartVector(elemSize, numElements, alignment) function mt:StartVector(elemSize, numElements, alignment)
assert(not self.nested) assert(not self.nested)
self.nested = true self.nested = true
self:Prep(Uint32.bytewidth, elemSize * numElements) local elementSize = elemSize * numElements
self:Prep(alignment, elemSize * numElements) self:Prep(4, elementSize) -- Uint32 length
self:Prep(alignment, elementSize)
return self:Offset() return self:Offset()
end end
@@ -246,7 +264,7 @@ function mt:CreateString(s)
assert(type(s) == "string") assert(type(s) == "string")
self:Prep(UOffsetT.bytewidth, (#s + 1)*Uint8.bytewidth) self:Prep(4, #s + 1)
self:Place(0, Uint8) self:Place(0, Uint8)
local l = #s local l = #s
@@ -254,20 +272,21 @@ function mt:CreateString(s)
self.bytes:Set(s, self.head, self.head + l) self.bytes:Set(s, self.head, self.head + l)
return self:EndVector(#s) return self:EndVector(l)
end end
function mt:CreateByteVector(x) function mt:CreateByteVector(x)
assert(not self.nested) assert(not self.nested)
self.nested = true self.nested = true
self:Prep(UOffsetT.bytewidth, #x*Uint8.bytewidth)
local l = #x local l = #x
self:Prep(4, l)
self.head = self.head - l self.head = self.head - l
self.bytes:Set(x, self.head, self.head + l) self.bytes:Set(x, self.head, self.head + l)
return self:EndVector(#x) return self:EndVector(l)
end end
function mt:Slot(slotnum) function mt:Slot(slotnum)
@@ -278,12 +297,7 @@ end
local function finish(self, rootTable, sizePrefix) local function finish(self, rootTable, sizePrefix)
UOffsetT:EnforceNumber(rootTable) UOffsetT:EnforceNumber(rootTable)
local prepSize = UOffsetT.bytewidth self:Prep(self.minalign, sizePrefix and 8 or 4)
if sizePrefix then
prepSize = prepSize + Int32.bytewidth
end
self:Prep(self.minalign, prepSize)
self:PrependUOffsetTRelative(rootTable) self:PrependUOffsetTRelative(rootTable)
if sizePrefix then if sizePrefix then
local size = #self.bytes - self.head local size = #self.bytes - self.head
@@ -308,8 +322,9 @@ function mt:Prepend(flags, off)
end end
function mt:PrependSlot(flags, o, x, d) function mt:PrependSlot(flags, o, x, d)
flags:EnforceNumber(x) flags:EnforceNumbers(x,d)
flags:EnforceNumber(d) -- flags:EnforceNumber(x)
-- flags:EnforceNumber(d)
if x ~= d then if x ~= d then
self:Prepend(flags, x) self:Prepend(flags, x)
self:Slot(o) self:Slot(o)

View File

@@ -34,6 +34,20 @@ function type_mt:EnforceNumber(n)
error("Number is not in the valid range") error("Number is not in the valid range")
end end
function type_mt:EnforceNumbers(a,b)
-- duplicate code since the overhead of function calls
-- for such a popular method is time consuming
if not self.min_value and not self.max_value then
return
end
if self.min_value <= a and a <= self.max_value and self.min_value <= b and b <= self.max_value then
return
end
error("Number is not in the valid range")
end
function type_mt:EnforceNumberAndPack(n) function type_mt:EnforceNumberAndPack(n)
return bpack(self.packFmt, n) return bpack(self.packFmt, n)
end end
@@ -58,6 +72,7 @@ local bool_mt =
Unpack = function(self, buf, pos) return buf[pos] == "1" end, Unpack = function(self, buf, pos) return buf[pos] == "1" end,
ValidNumber = function(self, n) return true end, -- anything is a valid boolean in Lua ValidNumber = function(self, n) return true end, -- anything is a valid boolean in Lua
EnforceNumber = function(self, n) end, -- anything is a valid boolean in Lua EnforceNumber = function(self, n) end, -- anything is a valid boolean in Lua
EnforceNumbers = function(self, a, b) end, -- anything is a valid boolean in Lua
EnforceNumberAndPack = function(self, n) return self:Pack(value) end, EnforceNumberAndPack = function(self, n) return self:Pack(value) end,
} }

View File

@@ -6,69 +6,83 @@ local mt_name = "flatbuffers.view.mt"
local N = require("flatbuffers.numTypes") local N = require("flatbuffers.numTypes")
local binaryarray = require("flatbuffers.binaryarray") local binaryarray = require("flatbuffers.binaryarray")
local function enforceOffset(off)
if off < 0 or off > 42949672951 then
error("Offset is not valid")
end
end
local unpack = string.unpack
local function unPackUoffset(bytes, off)
return unpack("<I4", bytes.str, off + 1)
end
local function unPackVoffset(bytes, off)
return unpack("<I2", bytes.str, off + 1)
end
function m.New(buf, pos) function m.New(buf, pos)
N.UOffsetT:EnforceNumber(pos) enforceOffset(pos)
-- need to convert from a string buffer into -- need to convert from a string buffer into
-- a binary array -- a binary array
local o = { local o = {
bytes = type(buf) == "string" and binaryarray.New(buf) or buf, bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
pos = pos pos = pos,
} }
setmetatable(o, {__index = mt, __metatable = mt_name}) setmetatable(o, {__index = mt, __metatable = mt_name})
return o return o
end end
function mt:Offset(vtableOffset) function mt:Offset(vtableOffset)
local vtable = self.pos - self:Get(N.SOffsetT, self.pos) local vtable = self.vtable
local vtableEnd = self:Get(N.VOffsetT, vtable) if not vtable then
if vtableOffset < vtableEnd then vtable = self.pos - self:Get(N.SOffsetT, self.pos)
return self:Get(N.VOffsetT, vtable + vtableOffset) self.vtable = vtable
self.vtableEnd = self:Get(N.VOffsetT, vtable)
end
if vtableOffset < self.vtableEnd then
return unPackVoffset(self.bytes, vtable + vtableOffset)
end end
return 0 return 0
end end
function mt:Indirect(off) function mt:Indirect(off)
N.UOffsetT:EnforceNumber(off) enforceOffset(off)
return off + N.UOffsetT:Unpack(self.bytes, off) return off + unPackUoffset(self.bytes, off)
end end
function mt:String(off) function mt:String(off)
N.UOffsetT:EnforceNumber(off) enforceOffset(off)
off = off + N.UOffsetT:Unpack(self.bytes, off) off = off + unPackUoffset(self.bytes, off)
local start = off + N.UOffsetT.bytewidth local start = off + 4
local length = N.UOffsetT:Unpack(self.bytes, off) local length = unPackUoffset(self.bytes, off)
return self.bytes:Slice(start, start+length) return self.bytes:Slice(start, start+length)
end end
function mt:VectorLen(off) function mt:VectorLen(off)
N.UOffsetT:EnforceNumber(off) enforceOffset(off)
off = off + self.pos off = off + self.pos
off = off + N.UOffsetT:Unpack(self.bytes, off) off = off + unPackUoffset(self.bytes, off)
return N.UOffsetT:Unpack(self.bytes, off) return unPackUoffset(self.bytes, off)
end end
function mt:Vector(off) function mt:Vector(off)
N.UOffsetT:EnforceNumber(off) enforceOffset(off)
off = off + self.pos off = off + self.pos
local x = off + self:Get(N.UOffsetT, off) return off + self:Get(N.UOffsetT, off) + 4
x = x + N.UOffsetT.bytewidth
return x
end end
function mt:Union(t2, off) function mt:Union(t2, off)
assert(getmetatable(t2) == mt_name) assert(getmetatable(t2) == mt_name)
N.UOffsetT:EnforceNumber(off) enforceOffset(off)
off = off + self.pos off = off + self.pos
t2.pos = off + self:Get(N.UOffsetT, off) t2.pos = off + self:Get(N.UOffsetT, off)
t2.bytes = self.bytes t2.bytes = self.bytes
end end
function mt:Get(flags, off) function mt:Get(flags, off)
N.UOffsetT:EnforceNumber(off) enforceOffset(off)
return flags:Unpack(self.bytes, off) return flags:Unpack(self.bytes, off)
end end
@@ -85,8 +99,7 @@ function mt:GetSlot(slot, d, validatorFlags)
end end
function mt:GetVOffsetTSlot(slot, d) function mt:GetVOffsetTSlot(slot, d)
N.VOffsetT:EnforceNumber(slot) N.VOffsetT:EnforceNumbers(slot, d)
N.VOffsetT:EnforceNumber(d)
local off = self:Offset(slot) local off = self:Offset(slot)
if off == 0 then if off == 0 then
return d return d

View File

@@ -10,4 +10,4 @@ keywords = ["flatbuffers", "serialization", "zero-copy"]
categories = ["encoding", "data-structures", "memory-management"] categories = ["encoding", "data-structures", "memory-management"]
[dependencies] [dependencies]
smallvec = "0.6" smallvec = "1.0"

View File

@@ -316,9 +316,6 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
MyGame::Sample::Equipment equipped_type() const { MyGame::Sample::Equipment equipped_type() const {
return static_cast<MyGame::Sample::Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0)); return static_cast<MyGame::Sample::Equipment>(GetField<uint8_t>(VT_EQUIPPED_TYPE, 0));
} }
bool mutate_equipped_type(MyGame::Sample::Equipment _equipped_type) {
return SetField<uint8_t>(VT_EQUIPPED_TYPE, static_cast<uint8_t>(_equipped_type), 0);
}
const void *equipped() const { const void *equipped() const {
return GetPointer<const void *>(VT_EQUIPPED); return GetPointer<const void *>(VT_EQUIPPED);
} }

View File

@@ -16,8 +16,7 @@
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
using namespace MyGame::Sample; using namespace MyGame::Sample;
@@ -30,7 +29,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
std::string bfbs_file; std::string bfbs_file;
bool ok = bool ok =
flatbuffers::LoadFile("tests/monster_test.fbs", false, &schema_file) && flatbuffers::LoadFile("tests/monster_test.fbs", false, &schema_file) &&
flatbuffers::LoadFile("tests/monsterdata_test.golden", false, &json_file) && flatbuffers::LoadFile("tests/monsterdata_test.golden", false,
&json_file) &&
flatbuffers::LoadFile("tests/monster_test.bfbs", true, &bfbs_file); flatbuffers::LoadFile("tests/monster_test.bfbs", true, &bfbs_file);
if (!ok) { if (!ok) {
printf("couldn't load files!\n"); printf("couldn't load files!\n");

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;

View File

@@ -16,14 +16,13 @@
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h". #include "monster_generated.h" // Already includes "flatbuffers/flatbuffers.h".
using namespace MyGame::Sample; 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;

6
src/clang-format-all.sh Normal file
View File

@@ -0,0 +1,6 @@
# Running it twice corrects some bugs in clang-format.
for run in {1..2}
do
clang-format -i -style=file include/flatbuffers/* src/*.cpp tests/*.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
done
git checkout include/flatbuffers/reflection_generated.h

6
src/clang-format-git.sh Normal file
View File

@@ -0,0 +1,6 @@
# Running it twice corrects some bugs in clang-format.
for run in {1..2}
do
git clang-format HEAD^ -- include/flatbuffers/* src/*.cpp tests/*.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
done
git checkout include/flatbuffers/reflection_generated.h

View File

@@ -1,2 +0,0 @@
clang-format -i -style=file include/flatbuffers/* src/*.cpp tests/test.cpp samples/*.cpp grpc/src/compiler/schema_interface.h grpc/tests/*.cpp
git checkout include/flatbuffers/reflection_generated.h

View File

@@ -15,12 +15,14 @@
*/ */
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include <assert.h> #include <assert.h>
#include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#include <cmath> #include <cmath>
#include "flatbuffers/base.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
@@ -285,6 +287,80 @@ std::string SimpleFloatConstantGenerator::NaN(float v) const {
return this->NaN(static_cast<double>(v)); return this->NaN(static_cast<double>(v));
} }
std::string JavaCSharpMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
FLATBUFFERS_ASSERT(parser.opts.lang == IDLOptions::kJava ||
parser.opts.lang == IDLOptions::kCSharp);
std::string file_extension =
(parser.opts.lang == IDLOptions::kJava) ? ".java" : ".cs";
std::string make_rule;
for (auto it = parser.enums_.vec.begin(); it != parser.enums_.vec.end();
++it) {
auto &enum_def = **it;
if (!make_rule.empty()) make_rule += " ";
std::string directory =
BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
make_rule += directory + enum_def.name + file_extension;
}
for (auto it = parser.structs_.vec.begin(); it != parser.structs_.vec.end();
++it) {
auto &struct_def = **it;
if (!make_rule.empty()) make_rule += " ";
std::string directory = BaseGenerator::NamespaceDir(
parser, path, *struct_def.defined_namespace);
make_rule += directory + struct_def.name + file_extension;
}
make_rule += ": ";
auto included_files = parser.GetIncludedFilesRecursive(file_name);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
make_rule += " " + *it;
}
return make_rule;
}
std::string BinaryFileName(const Parser &parser, const std::string &path,
const std::string &file_name) {
auto ext = parser.file_extension_.length() ? parser.file_extension_ : "bin";
return path + file_name + "." + ext;
}
bool GenerateBinary(const Parser &parser, const std::string &path,
const std::string &file_name) {
if (parser.opts.use_flexbuffers) {
auto data_vec = parser.flex_builder_.GetBuffer();
auto data_ptr = reinterpret_cast<char *>(data(data_vec));
return !parser.flex_builder_.GetSize() ||
flatbuffers::SaveFile(
BinaryFileName(parser, path, file_name).c_str(), data_ptr,
parser.flex_builder_.GetSize(), true);
}
return !parser.builder_.GetSize() ||
flatbuffers::SaveFile(
BinaryFileName(parser, path, file_name).c_str(),
reinterpret_cast<char *>(parser.builder_.GetBufferPointer()),
parser.builder_.GetSize(), true);
}
std::string BinaryMakeRule(const Parser &parser, const std::string &path,
const std::string &file_name) {
if (!parser.builder_.GetSize()) return "";
std::string filebase =
flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
std::string make_rule =
BinaryFileName(parser, path, filebase) + ": " + file_name;
auto included_files =
parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
for (auto it = included_files.begin(); it != included_files.end(); ++it) {
make_rule += " " + *it;
}
return make_rule;
}
} // namespace flatbuffers } // namespace flatbuffers
#if defined(_MSC_VER) #if defined(_MSC_VER)

View File

@@ -42,7 +42,7 @@ 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);
} }
} }
@@ -402,7 +402,8 @@ int FlatCompiler::Compile(int argc, const char **argv) {
"\" matches the schema, use --raw-binary to read this file" "\" matches the schema, use --raw-binary to read this file"
" anyway."); " anyway.");
} else if (!flatbuffers::BufferHasIdentifier( } else if (!flatbuffers::BufferHasIdentifier(
contents.c_str(), parser->file_identifier_.c_str(), opts.size_prefixed)) { contents.c_str(), parser->file_identifier_.c_str(),
opts.size_prefixed)) {
Error("binary \"" + filename + Error("binary \"" + filename +
"\" does not have expected file_identifier \"" + "\" does not have expected file_identifier \"" +
parser->file_identifier_ + parser->file_identifier_ +
@@ -435,8 +436,7 @@ int FlatCompiler::Compile(int argc, const char **argv) {
} }
} else { } else {
ParseFile(*parser.get(), filename, contents, include_directories); ParseFile(*parser.get(), filename, contents, include_directories);
if (!opts.use_flexbuffers && !is_schema && if (!is_schema && !parser->builder_.GetSize()) {
!parser->builder_.GetSize()) {
// If a file doesn't end in .fbs, it must be json/binary. Ensure we // If a file doesn't end in .fbs, it must be json/binary. Ensure we
// didn't just parse a schema with a different extension. // didn't just parse a schema with a different extension.
Error("input file is neither json nor a .fbs (schema) file: " + Error("input file is neither json nor a .fbs (schema) file: " +
@@ -470,11 +470,16 @@ int FlatCompiler::Compile(int argc, const char **argv) {
params_.generators[i].lang_name + " for " + filebase); params_.generators[i].lang_name + " for " + filebase);
} }
} else { } else {
std::string make_rule = params_.generators[i].make_rule( if (params_.generators[i].make_rule == nullptr) {
*parser.get(), output_path, filename); Error(std::string("Cannot generate make rule for ") +
if (!make_rule.empty()) params_.generators[i].lang_name);
printf("%s\n", } else {
flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str()); std::string make_rule = params_.generators[i].make_rule(
*parser.get(), output_path, filename);
if (!make_rule.empty())
printf("%s\n",
flatbuffers::WordWrap(make_rule, 80, " ", " \\").c_str());
}
} }
if (grpc_enabled) { if (grpc_enabled) {
if (params_.generators[i].generateGRPC != nullptr) { if (params_.generators[i].generateGRPC != nullptr) {

View File

@@ -54,48 +54,47 @@ int main(int argc, const char *argv[]) {
"Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule }, "Generate C++ headers for tables/structs", flatbuffers::CPPMakeRule },
{ flatbuffers::GenerateGo, "-g", "--go", "Go", true, { flatbuffers::GenerateGo, "-g", "--go", "Go", true,
flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo, flatbuffers::GenerateGoGRPC, flatbuffers::IDLOptions::kGo,
"Generate Go files for tables/structs", flatbuffers::GeneralMakeRule }, "Generate Go files for tables/structs", nullptr },
{ flatbuffers::GenerateGeneral, "-j", "--java", "Java", true, { flatbuffers::GenerateJava, "-j", "--java", "Java", true,
flatbuffers::GenerateJavaGRPC, flatbuffers::IDLOptions::kJava, flatbuffers::GenerateJavaGRPC, flatbuffers::IDLOptions::kJava,
"Generate Java classes for tables/structs", "Generate Java classes for tables/structs",
flatbuffers::GeneralMakeRule }, flatbuffers::JavaCSharpMakeRule },
{ flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr, { flatbuffers::GenerateJSTS, "-s", "--js", "JavaScript", true, nullptr,
flatbuffers::IDLOptions::kJs, flatbuffers::IDLOptions::kJs,
"Generate JavaScript code for tables/structs", flatbuffers::JSTSMakeRule }, "Generate JavaScript code for tables/structs",
flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr, { flatbuffers::GenerateDart, "-d", "--dart", "Dart", true, nullptr,
flatbuffers::IDLOptions::kDart, flatbuffers::IDLOptions::kDart,
"Generate Dart classes for tables/structs", flatbuffers::DartMakeRule }, "Generate Dart classes for tables/structs", flatbuffers::DartMakeRule },
{ flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr, { flatbuffers::GenerateJSTS, "-T", "--ts", "TypeScript", true, nullptr,
flatbuffers::IDLOptions::kTs, flatbuffers::IDLOptions::kTs,
"Generate TypeScript code for tables/structs", flatbuffers::JSTSMakeRule }, "Generate TypeScript code for tables/structs",
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#", true, nullptr, flatbuffers::JSTSMakeRule },
{ flatbuffers::GenerateCSharp, "-n", "--csharp", "C#", true, nullptr,
flatbuffers::IDLOptions::kCSharp, flatbuffers::IDLOptions::kCSharp,
"Generate C# classes for tables/structs", flatbuffers::GeneralMakeRule }, "Generate C# classes for tables/structs",
{ flatbuffers::GeneratePython, "-p", "--python", "Python", true, nullptr, flatbuffers::JavaCSharpMakeRule },
flatbuffers::IDLOptions::kPython, { flatbuffers::GeneratePython, "-p", "--python", "Python", true,
"Generate Python files for tables/structs", flatbuffers::GeneratePythonGRPC, flatbuffers::IDLOptions::kPython,
flatbuffers::GeneralMakeRule }, "Generate Python files for tables/structs", nullptr },
{ flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true, nullptr, { flatbuffers::GenerateLobster, nullptr, "--lobster", "Lobster", true,
flatbuffers::IDLOptions::kLobster, nullptr, flatbuffers::IDLOptions::kLobster,
"Generate Lobster files for tables/structs", "Generate Lobster files for tables/structs", nullptr },
flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr, { flatbuffers::GenerateLua, "-l", "--lua", "Lua", true, nullptr,
flatbuffers::IDLOptions::kLua, flatbuffers::IDLOptions::kLua, "Generate Lua files for tables/structs",
"Generate Lua files for tables/structs", nullptr },
flatbuffers::GeneralMakeRule },
{ flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr, { flatbuffers::GenerateRust, "-r", "--rust", "Rust", true, nullptr,
flatbuffers::IDLOptions::kRust, flatbuffers::IDLOptions::kRust, "Generate Rust files for tables/structs",
"Generate Rust files for tables/structs",
flatbuffers::RustMakeRule }, flatbuffers::RustMakeRule },
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr, { flatbuffers::GeneratePhp, nullptr, "--php", "PHP", true, nullptr,
flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs", flatbuffers::IDLOptions::kPhp, "Generate PHP files for tables/structs",
flatbuffers::GeneralMakeRule }, nullptr },
{ flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr, { flatbuffers::GenerateKotlin, nullptr, "--kotlin", "Kotlin", true, nullptr,
flatbuffers::IDLOptions::kKotlin, "Generate Kotlin classes for tables/structs", flatbuffers::IDLOptions::kKotlin,
flatbuffers::GeneralMakeRule }, "Generate Kotlin classes for tables/structs", nullptr },
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema", { flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema",
true, nullptr, flatbuffers::IDLOptions::kJsonSchema, true, nullptr, flatbuffers::IDLOptions::kJsonSchema,
"Generate Json schema", flatbuffers::GeneralMakeRule }, "Generate Json schema", nullptr },
}; };
flatbuffers::FlatCompiler::InitParams params; flatbuffers::FlatCompiler::InitParams params;

View File

@@ -15,9 +15,11 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include "flatbuffers/hash.h" #include "flatbuffers/hash.h"
enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x }; enum OutputFormat { kDecimal, kHexadecimal, kHexadecimal0x };
@@ -35,7 +37,7 @@ int main(int argc, char *argv[]) {
} }
printf(" 32 bit:\n"); printf(" 32 bit:\n");
size = sizeof(flatbuffers::kHashFunctions32) / size = sizeof(flatbuffers::kHashFunctions32) /
sizeof(flatbuffers::kHashFunctions32[0]); sizeof(flatbuffers::kHashFunctions32[0]);
for (size_t i = 0; i < size; ++i) { for (size_t i = 0; i < size; ++i) {
printf(" * %s\n", flatbuffers::kHashFunctions32[i].name); printf(" * %s\n", flatbuffers::kHashFunctions32[i].name);
} }

View File

@@ -16,13 +16,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
// Pedantic warning free version of toupper(). // Pedantic warning free version of toupper().
@@ -208,9 +208,7 @@ class CppGenerator : public BaseGenerator {
for (std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) { for (std::size_t i = 0; i < parser_.opts.cpp_includes.size(); ++i) {
code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\""; code_ += "#include \"" + parser_.opts.cpp_includes[i] + "\"";
} }
if (!parser_.opts.cpp_includes.empty()) { if (!parser_.opts.cpp_includes.empty()) { code_ += ""; }
code_ += "";
}
} }
std::string EscapeKeyword(const std::string &name) const { std::string EscapeKeyword(const std::string &name) const {
@@ -547,11 +545,10 @@ class CppGenerator : public BaseGenerator {
std::string GenTypeBasic(const Type &type, bool user_facing_type) const { std::string GenTypeBasic(const Type &type, bool user_facing_type) const {
// clang-format off // clang-format off
static const char *const ctypename[] = { static const char *const ctypename[] = {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
RTYPE, KTYPE) \ #CTYPE,
#CTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
}; };
// clang-format on // clang-format on
if (user_facing_type) { if (user_facing_type) {
@@ -577,7 +574,9 @@ class CppGenerator : public BaseGenerator {
} }
case BASE_TYPE_UNION: case BASE_TYPE_UNION:
// fall through // fall through
default: { return "void"; } default: {
return "void";
}
} }
} }
@@ -696,7 +695,9 @@ class CppGenerator : public BaseGenerator {
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
return type.enum_def->name + "Union"; return type.enum_def->name + "Union";
} }
default: { return GenTypeBasic(type, true); } default: {
return GenTypeBasic(type, true);
}
} }
} }
@@ -1163,7 +1164,8 @@ class CppGenerator : public BaseGenerator {
code_ += " void Set(T&& val) {"; code_ += " void Set(T&& val) {";
code_ += " using RT = typename std::remove_reference<T>::type;"; code_ += " using RT = typename std::remove_reference<T>::type;";
code_ += " Reset();"; code_ += " Reset();";
code_ += " type = {{NAME}}Traits<typename RT::TableType>::enum_value;"; code_ +=
" type = {{NAME}}Traits<typename RT::TableType>::enum_value;";
code_ += " if (type != {{NONE}}) {"; code_ += " if (type != {{NONE}}) {";
code_ += " value = new RT(std::forward<T>(val));"; code_ += " value = new RT(std::forward<T>(val));";
code_ += " }"; code_ += " }";
@@ -1276,7 +1278,8 @@ class CppGenerator : public BaseGenerator {
" auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);"; " auto ptr = reinterpret_cast<const {{TYPE}} *>(obj);";
if (ev.union_type.base_type == BASE_TYPE_STRUCT) { if (ev.union_type.base_type == BASE_TYPE_STRUCT) {
if (ev.union_type.struct_def->fixed) { if (ev.union_type.struct_def->fixed) {
code_ += " return verifier.Verify<{{TYPE}}>(static_cast<const " code_ +=
" return verifier.Verify<{{TYPE}}>(static_cast<const "
"uint8_t *>(obj), 0);"; "uint8_t *>(obj), 0);";
} else { } else {
code_ += getptr; code_ += getptr;
@@ -1295,7 +1298,7 @@ class CppGenerator : public BaseGenerator {
code_ += " }"; code_ += " }";
} }
} }
code_ += " default: return true;"; // unknown values are OK. code_ += " default: return true;"; // unknown values are OK.
code_ += " }"; code_ += " }";
code_ += "}"; code_ += "}";
code_ += ""; code_ += "";
@@ -1763,7 +1766,9 @@ class CppGenerator : public BaseGenerator {
} }
break; break;
} }
default: { break; } default: {
break;
}
} }
} }
@@ -1925,7 +1930,8 @@ class CppGenerator : public BaseGenerator {
} }
} }
if (parser_.opts.mutable_buffer) { if (parser_.opts.mutable_buffer &&
!(is_scalar && IsUnion(field.value.type))) {
if (is_scalar) { if (is_scalar) {
const auto type = GenTypeWire(field.value.type, "", false); const auto type = GenTypeWire(field.value.type, "", false);
code_.SetValue("SET_FN", "SetField<" + type + ">"); code_.SetValue("SET_FN", "SetField<" + type + ">");
@@ -2901,8 +2907,8 @@ class CppGenerator : public BaseGenerator {
} else if (IsArray(field.value.type)) { } else if (IsArray(field.value.type)) {
auto underlying = GenTypeGet(field.value.type, "", "", "", false); auto underlying = GenTypeGet(field.value.type, "", "", "", false);
code_ += " flatbuffers::Array<" + mut_field_type + ", " + code_ += " flatbuffers::Array<" + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) + NumToString(field.value.type.fixed_length) + "> *" +
"> *" + "mutable_{{FIELD_NAME}}() {"; "mutable_{{FIELD_NAME}}() {";
code_ += " return reinterpret_cast<flatbuffers::Array<" + code_ += " return reinterpret_cast<flatbuffers::Array<" +
mut_field_type + ", " + mut_field_type + ", " +
NumToString(field.value.type.fixed_length) + NumToString(field.value.type.fixed_length) +

1181
src/idl_gen_csharp.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -71,9 +71,7 @@ class DartGenerator : public BaseGenerator {
"// ignore_for_file: unused_import, unused_field, " "// ignore_for_file: unused_import, unused_field, "
"unused_local_variable\n\n"; "unused_local_variable\n\n";
if (!kv->first.empty()) { if (!kv->first.empty()) { code += "library " + kv->first + ";\n\n"; }
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 +
@@ -87,16 +85,20 @@ class DartGenerator : public BaseGenerator {
++kv2) { ++kv2) {
if (kv2->first != kv->first) { if (kv2->first != kv->first) {
code += "import '" + code += "import '" +
GeneratedFileName("./", file_name_ + (!kv2->first.empty() ? "_" + kv2->first : "")) + GeneratedFileName(
"./", file_name_ +
(!kv2->first.empty() ? "_" + kv2->first : "")) +
"' as " + ImportAliasName(kv2->first) + ";\n"; "' as " + ImportAliasName(kv2->first) + ";\n";
} }
} }
code += "\n"; code += "\n";
code += kv->second; code += kv->second;
if (!SaveFile( if (!SaveFile(GeneratedFileName(
GeneratedFileName(path_, file_name_ + (!kv->first.empty() ? "_" + kv->first : "")).c_str(), path_, file_name_ +
code, false)) { (!kv->first.empty() ? "_" + kv->first : ""))
.c_str(),
code, false)) {
return false; return false;
} }
} }
@@ -117,9 +119,7 @@ class DartGenerator : public BaseGenerator {
} }
static std::string BuildNamespaceName(const Namespace &ns) { static std::string BuildNamespaceName(const Namespace &ns) {
if (ns.components.empty()) { if (ns.components.empty()) { return ""; }
return "";
}
std::stringstream sstream; std::stringstream sstream;
std::copy(ns.components.begin(), ns.components.end() - 1, std::copy(ns.components.begin(), ns.components.end() - 1,
std::ostream_iterator<std::string>(sstream, ".")); std::ostream_iterator<std::string>(sstream, "."));
@@ -139,7 +139,8 @@ class DartGenerator : public BaseGenerator {
return ret; return ret;
} }
void GenIncludeDependencies(std::string* code, const std::string& the_namespace) { void GenIncludeDependencies(std::string *code,
const std::string &the_namespace) {
for (auto it = parser_.included_files_.begin(); for (auto it = parser_.included_files_.begin();
it != parser_.included_files_.end(); ++it) { it != parser_.included_files_.end(); ++it) {
if (it->second.empty()) continue; if (it->second.empty()) continue;
@@ -147,7 +148,11 @@ class DartGenerator : public BaseGenerator {
auto noext = flatbuffers::StripExtension(it->second); auto noext = flatbuffers::StripExtension(it->second);
auto basename = flatbuffers::StripPath(noext); auto basename = flatbuffers::StripPath(noext);
*code += "import '" + GeneratedFileName("", basename + (the_namespace == "" ? "" : "_" + the_namespace)) + "';\n"; *code +=
"import '" +
GeneratedFileName(
"", basename + (the_namespace == "" ? "" : "_" + the_namespace)) +
"';\n";
} }
} }
@@ -798,7 +803,8 @@ class DartGenerator : public BaseGenerator {
} }
code += "\n : null;\n"; code += "\n : null;\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) { } else if (field.value.type.base_type == BASE_TYPE_STRING) {
code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) + ");\n"; code += " = fbBuilder.writeString(_" + MakeCamel(field.name, false) +
");\n";
} else { } else {
code += " = _" + MakeCamel(field.name, false) + code += " = _" + MakeCamel(field.name, false) +
"?.getOrCreateOffset(fbBuilder);\n"; "?.getOrCreateOffset(fbBuilder);\n";

File diff suppressed because it is too large Load Diff

View File

@@ -43,7 +43,7 @@ static std::string GeneratedFileName(const std::string &path,
namespace go { namespace go {
// see https://golang.org/ref/spec#Keywords // see https://golang.org/ref/spec#Keywords
static const char * const g_golang_keywords[] = { static const char *const g_golang_keywords[] = {
"break", "default", "func", "interface", "select", "case", "defer", "break", "default", "func", "interface", "select", "case", "defer",
"go", "map", "struct", "chan", "else", "goto", "package", "go", "map", "struct", "chan", "else", "goto", "package",
"switch", "const", "fallthrough", "if", "range", "type", "continue", "switch", "const", "fallthrough", "if", "range", "type", "continue",
@@ -75,15 +75,23 @@ class GoGenerator : public BaseGenerator {
bool generate() { bool generate() {
std::string one_file_code; std::string one_file_code;
bool needs_imports = false;
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) {
tracked_imported_namespaces_.clear(); tracked_imported_namespaces_.clear();
needs_imports = false;
std::string enumcode; std::string enumcode;
GenEnum(**it, &enumcode); GenEnum(**it, &enumcode);
if ((*it)->is_union && parser_.opts.generate_object_based_api) {
GenNativeUnion(**it, &enumcode);
GenNativeUnionPack(**it, &enumcode);
GenNativeUnionUnPack(**it, &enumcode);
needs_imports = true;
}
if (parser_.opts.one_file) { if (parser_.opts.one_file) {
one_file_code += enumcode; one_file_code += enumcode;
} else { } else {
if (!SaveType(**it, enumcode, false, true)) return false; if (!SaveType(**it, enumcode, needs_imports, true)) return false;
} }
} }
@@ -143,7 +151,8 @@ class GoGenerator : public BaseGenerator {
// Construct the name of the type for this enum. // Construct the name of the type for this enum.
std::string GetEnumTypeName(const EnumDef &enum_def) { std::string GetEnumTypeName(const EnumDef &enum_def) {
return WrapInNameSpaceAndTrack(enum_def.defined_namespace, GoIdentity(enum_def.name)); return WrapInNameSpaceAndTrack(enum_def.defined_namespace,
GoIdentity(enum_def.name));
} }
// Create a type for the enum values. // Create a type for the enum values.
@@ -214,7 +223,7 @@ class GoGenerator : public BaseGenerator {
code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n"; code += "\tif s, ok := EnumNames" + enum_def.name + "[v]; ok {\n";
code += "\t\treturn s\n"; code += "\t\treturn s\n";
code += "\t}\n"; code += "\t}\n";
code += "\treturn \""+ enum_def.name; code += "\treturn \"" + enum_def.name;
code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n"; code += "(\" + strconv.FormatInt(int64(v), 10) + \")\"\n";
code += "}\n\n"; code += "}\n\n";
} }
@@ -317,23 +326,21 @@ class GoGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, 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);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name); code += " " + MakeCamel(field.name);
code += "() " + TypeName(field) + " {\n"; code += "() " + TypeName(field) + " {\n";
code += "\treturn " + CastToEnum( code += "\treturn " +
field.value.type, CastToEnum(field.value.type,
getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" + getter + "(rcv._tab.Pos + flatbuffers.UOffsetT(" +
NumToString(field.value.offset) + "))"); NumToString(field.value.offset) + "))");
code += "\n}\n"; code += "\n}\n";
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
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);
@@ -350,8 +357,7 @@ class GoGenerator : 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 StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += " " + MakeCamel(field.name); code += " " + MakeCamel(field.name);
@@ -369,8 +375,7 @@ class GoGenerator : 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 StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -392,8 +397,7 @@ class GoGenerator : public BaseGenerator {
} }
// Get the value of a string. // Get the value of a string.
void GetStringField(const StructDef &struct_def, void GetStringField(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -420,8 +424,7 @@ class GoGenerator : 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, 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();
@@ -453,10 +456,11 @@ class GoGenerator : public BaseGenerator {
code += "(j int) " + TypeName(field) + " "; code += "(j int) " + TypeName(field) + " ";
code += OffsetPrefix(field); code += OffsetPrefix(field);
code += "\t\ta := rcv._tab.Vector(o)\n"; code += "\t\ta := rcv._tab.Vector(o)\n";
code += "\t\treturn " + CastToEnum( code += "\t\treturn " +
field.value.type, CastToEnum(field.value.type,
GenGetter(field.value.type) + "(a + flatbuffers.UOffsetT(j*" + GenGetter(field.value.type) +
NumToString(InlineSize(vectortype)) + "))"); "(a + flatbuffers.UOffsetT(j*" +
NumToString(InlineSize(vectortype)) + "))");
code += "\n\t}\n"; code += "\n\t}\n";
if (vectortype.base_type == BASE_TYPE_STRING) { if (vectortype.base_type == BASE_TYPE_STRING) {
code += "\treturn nil\n"; code += "\treturn nil\n";
@@ -510,8 +514,8 @@ class GoGenerator : 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, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
const char *nameprefix, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", "; code += "\tbuilder.Prep(" + NumToString(struct_def.minalign) + ", ";
code += NumToString(struct_def.bytesize) + ")\n"; code += NumToString(struct_def.bytesize) + ")\n";
@@ -525,7 +529,9 @@ class GoGenerator : public BaseGenerator {
(nameprefix + (field.name + "_")).c_str(), code_ptr); (nameprefix + (field.name + "_")).c_str(), code_ptr);
} else { } else {
code += "\tbuilder.Prepend" + GenMethod(field) + "("; code += "\tbuilder.Prepend" + GenMethod(field) + "(";
code += CastToBaseType(field.value.type, nameprefix + GoIdentity(field.name)) + ")\n"; code += CastToBaseType(field.value.type,
nameprefix + GoIdentity(field.name)) +
")\n";
} }
} }
} }
@@ -574,8 +580,8 @@ class GoGenerator : 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.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "func " + struct_def.name + "Start"; code += "func " + struct_def.name + "Start";
code += MakeCamel(field.name); code += MakeCamel(field.name);
@@ -604,8 +610,8 @@ class GoGenerator : public BaseGenerator {
} }
// Generate a struct field getter, conditioned on its child type(s). // Generate a struct field getter, conditioned on its child type(s).
void GenStructAccessor(const StructDef &struct_def, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
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, "");
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -622,7 +628,9 @@ class GoGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, 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_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -646,8 +654,7 @@ class GoGenerator : public BaseGenerator {
// Mutate the value of a struct's scalar. // Mutate the value of a struct's scalar.
void MutateScalarFieldOfStruct(const StructDef &struct_def, void MutateScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type; std::string setter = "rcv._tab.Mutate" + type;
@@ -661,8 +668,7 @@ class GoGenerator : public BaseGenerator {
// Mutate the value of a table's scalar. // Mutate the value of a table's scalar.
void MutateScalarFieldOfTable(const StructDef &struct_def, void MutateScalarFieldOfTable(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
std::string type = MakeCamel(GenTypeBasic(field.value.type)); std::string type = MakeCamel(GenTypeBasic(field.value.type));
std::string setter = "rcv._tab.Mutate" + type + "Slot"; std::string setter = "rcv._tab.Mutate" + type + "Slot";
@@ -739,6 +745,9 @@ class GoGenerator : public BaseGenerator {
cur_name_space_ = struct_def.defined_namespace; cur_name_space_ = struct_def.defined_namespace;
GenComment(struct_def.doc_comment, code_ptr, nullptr); GenComment(struct_def.doc_comment, code_ptr, nullptr);
if (parser_.opts.generate_object_based_api) {
GenNativeStruct(struct_def, code_ptr);
}
BeginClass(struct_def, code_ptr); BeginClass(struct_def, code_ptr);
if (!struct_def.fixed) { if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as // Generate a special accessor for the table that has been declared as
@@ -771,6 +780,336 @@ class GoGenerator : public BaseGenerator {
} }
} }
void GenNativeStruct(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "type " + NativeName(struct_def) + " struct {\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
if (field.deprecated) continue;
if (IsScalar(field.value.type.base_type) &&
field.value.type.enum_def != nullptr &&
field.value.type.enum_def->is_union)
continue;
code += "\t" + MakeCamel(field.name) + " " +
NativeType(field.value.type) + "\n";
}
code += "}\n\n";
if (!struct_def.fixed) {
GenNativeTablePack(struct_def, code_ptr);
GenNativeTableUnPack(struct_def, code_ptr);
} else {
GenNativeStructPack(struct_def, code_ptr);
GenNativeStructUnPack(struct_def, code_ptr);
}
}
void GenNativeUnion(const EnumDef &enum_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "type " + NativeName(enum_def) + " struct {\n";
code += "\tType " + enum_def.name + "\n";
code += "\tValue interface{}\n";
code += "}\n\n";
}
void GenNativeUnionPack(const EnumDef &enum_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func " + enum_def.name + "Pack(builder *flatbuffers.Builder, t *" +
NativeName(enum_def) + ") flatbuffers.UOffsetT {\n";
code += "\tif t == nil {\n\t\treturn 0\n\t}\n";
code += "\tswitch t.Type {\n";
for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end();
++it2) {
const EnumVal &ev = **it2;
if (ev.IsZero()) continue;
code += "\tcase " + enum_def.name + ev.name + ":\n";
code += "\t\treturn " +
WrapInNameSpaceAndTrack(*ev.union_type.struct_def) +
"Pack(builder, t.Value.(" + NativeType(ev.union_type) + "))\n";
}
code += "\t}\n";
code += "\treturn 0\n";
code += "}\n\n";
}
void GenNativeUnionUnPack(const EnumDef &enum_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func " + enum_def.name + "UnPack(t " + enum_def.name +
", table flatbuffers.Table) *" + NativeName(enum_def) + " {\n";
code += "\tswitch t {\n";
for (auto it2 = enum_def.Vals().begin(); it2 != enum_def.Vals().end();
++it2) {
const EnumVal &ev = **it2;
if (ev.IsZero()) continue;
code += "\tcase " + enum_def.name + ev.name + ":\n";
code += "\t\tx := " + ev.union_type.struct_def->name + "{_tab: table}\n";
code += "\t\treturn &" +
WrapInNameSpaceAndTrack(enum_def.defined_namespace,
NativeName(enum_def)) +
"{ Type: " + enum_def.name + ev.name + ", Value: x.UnPack() }\n";
}
code += "\t}\n";
code += "\treturn nil\n";
code += "}\n\n";
}
void GenNativeTablePack(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func " + struct_def.name +
"Pack(builder *flatbuffers.Builder, t *" + NativeName(struct_def) +
") flatbuffers.UOffsetT {\n";
code += "\tif t == nil { return 0 }\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
if (field.deprecated) continue;
if (IsScalar(field.value.type.base_type)) continue;
std::string offset = MakeCamel(field.name, false) + "Offset";
if (field.value.type.base_type == BASE_TYPE_STRING) {
code += "\t" + offset + " := builder.CreateString(t." +
MakeCamel(field.name) + ")\n";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
field.value.type.element == BASE_TYPE_UCHAR &&
field.value.type.enum_def == nullptr) {
code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
code += "\tif t." + MakeCamel(field.name) + " != nil {\n";
code += "\t\t" + offset + " = builder.CreateByteString(t." +
MakeCamel(field.name) + ")\n";
code += "\t}\n";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += "\t" + offset + " := flatbuffers.UOffsetT(0)\n";
code += "\tif t." + MakeCamel(field.name) + " != nil {\n";
std::string length = MakeCamel(field.name, false) + "Length";
std::string offsets = MakeCamel(field.name, false) + "Offsets";
code += "\t\t" + length + " := len(t." + MakeCamel(field.name) + ")\n";
if (field.value.type.element == BASE_TYPE_STRING) {
code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " +
length + ")\n";
code += "\t\tfor j := 0; j < " + length + "; j++ {\n";
code += "\t\t\t" + offsets + "[j] = builder.CreateString(t." +
MakeCamel(field.name) + "[j])\n";
code += "\t\t}\n";
} else if (field.value.type.element == BASE_TYPE_STRUCT &&
!field.value.type.struct_def->fixed) {
code += "\t\t" + offsets + " := make([]flatbuffers.UOffsetT, " +
length + ")\n";
code += "\t\tfor j := 0; j < " + length + "; j++ {\n";
code += "\t\t\t" + offsets + "[j] = " +
WrapInNameSpaceAndTrack(*field.value.type.struct_def) +
"Pack(builder, t." + MakeCamel(field.name) + "[j])\n";
code += "\t\t}\n";
}
code += "\t\t" + struct_def.name + "Start" + MakeCamel(field.name) +
"Vector(builder, " + length + ")\n";
code += "\t\tfor j := " + length + " - 1; j >= 0; j-- {\n";
if (IsScalar(field.value.type.element)) {
code += "\t\t\tbuilder.Prepend" +
MakeCamel(GenTypeBasic(field.value.type.VectorType())) + "(" +
CastToBaseType(field.value.type.VectorType(),
"t." + MakeCamel(field.name) + "[j]") +
")\n";
} else if (field.value.type.element == BASE_TYPE_STRUCT &&
field.value.type.struct_def->fixed) {
code += "\t\t\t" +
WrapInNameSpaceAndTrack(*field.value.type.struct_def) +
"Pack(builder, t." + MakeCamel(field.name) + "[j])\n";
} else {
code += "\t\t\tbuilder.PrependUOffsetT(" + offsets + "[j])\n";
}
code += "\t\t}\n";
code += "\t\t" + offset + " = builder.EndVector(" + length + ")\n";
code += "\t}\n";
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
if (field.value.type.struct_def->fixed) continue;
code += "\t" + offset +
" := " + WrapInNameSpaceAndTrack(*field.value.type.struct_def) +
"Pack(builder, t." + MakeCamel(field.name) + ")\n";
} else if (field.value.type.base_type == BASE_TYPE_UNION) {
code += "\t" + offset +
" := " + WrapInNameSpaceAndTrack(*field.value.type.enum_def) +
"Pack(builder, t." + MakeCamel(field.name) + ")\n";
code += "\t\n";
} else {
FLATBUFFERS_ASSERT(0);
}
}
code += "\t" + struct_def.name + "Start(builder)\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
if (field.deprecated) continue;
std::string offset = MakeCamel(field.name, false) + "Offset";
if (IsScalar(field.value.type.base_type)) {
if (field.value.type.enum_def == nullptr ||
!field.value.type.enum_def->is_union) {
code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) +
"(builder, t." + MakeCamel(field.name) + ")\n";
}
} else {
if (field.value.type.base_type == BASE_TYPE_STRUCT &&
field.value.type.struct_def->fixed) {
code += "\t" + offset + " := " +
WrapInNameSpaceAndTrack(*field.value.type.struct_def) +
"Pack(builder, t." + MakeCamel(field.name) + ")\n";
} else if (field.value.type.enum_def != nullptr &&
field.value.type.enum_def->is_union) {
code += "\tif t." + MakeCamel(field.name) + " != nil {\n";
code += "\t\t" + struct_def.name + "Add" +
MakeCamel(field.name + UnionTypeFieldSuffix()) +
"(builder, t." + MakeCamel(field.name) + ".Type)\n";
code += "\t}\n";
}
code += "\t" + struct_def.name + "Add" + MakeCamel(field.name) +
"(builder, " + offset + ")\n";
}
}
code += "\treturn " + struct_def.name + "End(builder)\n";
code += "}\n\n";
}
void GenNativeTableUnPack(const StructDef &struct_def,
std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
NativeName(struct_def) + ") {\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
if (field.deprecated) continue;
std::string field_name_camel = MakeCamel(field.name);
std::string length = MakeCamel(field.name, false) + "Length";
if (IsScalar(field.value.type.base_type)) {
if (field.value.type.enum_def != nullptr &&
field.value.type.enum_def->is_union)
continue;
code +=
"\tt." + field_name_camel + " = rcv." + field_name_camel + "()\n";
} else if (field.value.type.base_type == BASE_TYPE_STRING) {
code += "\tt." + field_name_camel + " = string(rcv." +
field_name_camel + "())\n";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR &&
field.value.type.element == BASE_TYPE_UCHAR &&
field.value.type.enum_def == nullptr) {
code += "\tt." + field_name_camel + " = rcv." + field_name_camel +
"Bytes()\n";
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += "\t" + length + " := rcv." + field_name_camel + "Length()\n";
code += "\tt." + field_name_camel + " = make(" +
NativeType(field.value.type) + ", " + length + ")\n";
code += "\tfor j := 0; j < " + length + "; j++ {\n";
if (field.value.type.element == BASE_TYPE_STRUCT) {
code += "\t\tx := " + field.value.type.struct_def->name + "{}\n";
code += "\t\trcv." + field_name_camel + "(&x, j)\n";
}
code += "\t\tt." + field_name_camel + "[j] = ";
if (IsScalar(field.value.type.element)) {
code += "rcv." + field_name_camel + "(j)";
} else if (field.value.type.element == BASE_TYPE_STRING) {
code += "string(rcv." + field_name_camel + "(j))";
} else if (field.value.type.element == BASE_TYPE_STRUCT) {
code += "x.UnPack()";
} else {
// TODO(iceboy): Support vector of unions.
FLATBUFFERS_ASSERT(0);
}
code += "\n";
code += "\t}\n";
} else if (field.value.type.base_type == BASE_TYPE_STRUCT) {
code += "\tt." + field_name_camel + " = rcv." + field_name_camel +
"(nil).UnPack()\n";
} else if (field.value.type.base_type == BASE_TYPE_UNION) {
const EnumDef &enum_def = *field.value.type.enum_def;
std::string field_table = MakeCamel(field.name, false) + "Table";
code += "\t" + field_table + " := flatbuffers.Table{}\n";
code +=
"\tif rcv." + MakeCamel(field.name) + "(&" + field_table + ") {\n";
code += "\t\tt." + field_name_camel + " = " + enum_def.name +
"UnPack(rcv." + MakeCamel(field.name + UnionTypeFieldSuffix()) +
"(), " + field_table + ")\n";
code += "\t}\n";
} else {
FLATBUFFERS_ASSERT(0);
}
}
code += "}\n\n";
code += "func (rcv *" + struct_def.name + ") UnPack() *" +
NativeName(struct_def) + " {\n";
code += "\tif rcv == nil { return nil }\n";
code += "\tt := &" + NativeName(struct_def) + "{}\n";
code += "\trcv.UnPackTo(t)\n";
code += "\treturn t\n";
code += "}\n\n";
}
void GenNativeStructPack(const StructDef &struct_def, std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func " + struct_def.name +
"Pack(builder *flatbuffers.Builder, t *" + NativeName(struct_def) +
") flatbuffers.UOffsetT {\n";
code += "\tif t == nil { return 0 }\n";
code += "\treturn Create" + struct_def.name + "(builder";
StructPackArgs(struct_def, "", code_ptr);
code += ")\n";
code += "}\n";
}
void StructPackArgs(const StructDef &struct_def, const char *nameprefix,
std::string *code_ptr) {
std::string &code = *code_ptr;
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
if (field.value.type.base_type == BASE_TYPE_STRUCT) {
StructPackArgs(*field.value.type.struct_def,
(nameprefix + MakeCamel(field.name) + ".").c_str(),
code_ptr);
} else {
code += std::string(", t.") + nameprefix + MakeCamel(field.name);
}
}
}
void GenNativeStructUnPack(const StructDef &struct_def,
std::string *code_ptr) {
std::string &code = *code_ptr;
code += "func (rcv *" + struct_def.name + ") UnPackTo(t *" +
NativeName(struct_def) + ") {\n";
for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) {
const FieldDef &field = **it;
if (field.value.type.base_type == BASE_TYPE_STRUCT) {
code += "\tt." + MakeCamel(field.name) + " = rcv." +
MakeCamel(field.name) + "(nil).UnPack()\n";
} else {
code += "\tt." + MakeCamel(field.name) + " = rcv." +
MakeCamel(field.name) + "()\n";
}
}
code += "}\n\n";
code += "func (rcv *" + struct_def.name + ") UnPack() *" +
NativeName(struct_def) + " {\n";
code += "\tif rcv == nil { return nil }\n";
code += "\tt := &" + NativeName(struct_def) + "{}\n";
code += "\trcv.UnPackTo(t)\n";
code += "\treturn t\n";
code += "}\n\n";
}
// 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;
@@ -782,7 +1121,7 @@ class GoGenerator : public BaseGenerator {
GenEnumType(enum_def, code_ptr); GenEnumType(enum_def, code_ptr);
BeginEnum(code_ptr); BeginEnum(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; const EnumVal &ev = **it;
GenComment(ev.doc_comment, code_ptr, nullptr, "\t"); GenComment(ev.doc_comment, code_ptr, nullptr, "\t");
EnumMember(enum_def, ev, max_name_length, code_ptr); EnumMember(enum_def, ev, max_name_length, code_ptr);
} }
@@ -790,14 +1129,13 @@ class GoGenerator : public BaseGenerator {
BeginEnumNames(enum_def, code_ptr); BeginEnumNames(enum_def, 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; const EnumVal &ev = **it;
EnumNameMember(enum_def, ev, max_name_length, code_ptr); EnumNameMember(enum_def, ev, max_name_length, code_ptr);
} }
EndEnumNames(code_ptr); EndEnumNames(code_ptr);
BeginEnumValues(enum_def, code_ptr); BeginEnumValues(enum_def, code_ptr);
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
++it) {
auto &ev = **it; auto &ev = **it;
EnumValueMember(enum_def, ev, max_name_length, code_ptr); EnumValueMember(enum_def, ev, max_name_length, code_ptr);
} }
@@ -824,15 +1162,14 @@ class GoGenerator : public BaseGenerator {
} }
std::string GenTypeBasic(const Type &type) { std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ static const char *ctypename[] = {
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, ...) \
#GTYPE, #GTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// clang-format on
}; };
// clang-format on
return ctypename[type.base_type]; return ctypename[type.base_type];
} }
@@ -848,9 +1185,7 @@ class GoGenerator : public BaseGenerator {
} }
std::string GenTypeGet(const Type &type) { std::string GenTypeGet(const Type &type) {
if (type.enum_def != nullptr) { if (type.enum_def != nullptr) { return GetEnumTypeName(*type.enum_def); }
return GetEnumTypeName(*type.enum_def);
}
return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type); return IsScalar(type.base_type) ? GenTypeBasic(type) : GenTypePointer(type);
} }
@@ -880,11 +1215,44 @@ class GoGenerator : public BaseGenerator {
std::string GenConstant(const FieldDef &field) { std::string GenConstant(const FieldDef &field) {
switch (field.value.type.base_type) { switch (field.value.type.base_type) {
case BASE_TYPE_BOOL: return field.value.constant == "0" ? "false" : "true";; case BASE_TYPE_BOOL:
return field.value.constant == "0" ? "false" : "true";
default: return field.value.constant; default: return field.value.constant;
} }
} }
std::string NativeName(const StructDef &struct_def) {
return parser_.opts.object_prefix + struct_def.name +
parser_.opts.object_suffix;
}
std::string NativeName(const EnumDef &enum_def) {
return parser_.opts.object_prefix + enum_def.name +
parser_.opts.object_suffix;
}
std::string NativeType(const Type &type) {
if (IsScalar(type.base_type)) {
if (type.enum_def == nullptr) {
return GenTypeBasic(type);
} else {
return GetEnumTypeName(*type.enum_def);
}
} else if (type.base_type == BASE_TYPE_STRING) {
return "string";
} else if (type.base_type == BASE_TYPE_VECTOR) {
return "[]" + NativeType(type.VectorType());
} else if (type.base_type == BASE_TYPE_STRUCT) {
return "*" + WrapInNameSpaceAndTrack(type.struct_def->defined_namespace,
NativeName(*type.struct_def));
} else if (type.base_type == BASE_TYPE_UNION) {
return "*" + WrapInNameSpaceAndTrack(type.enum_def->defined_namespace,
NativeName(*type.enum_def));
}
FLATBUFFERS_ASSERT(0);
return std::string();
}
// 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) {
BeginBuilderArgs(struct_def, code_ptr); BeginBuilderArgs(struct_def, code_ptr);
@@ -898,13 +1266,12 @@ class GoGenerator : public BaseGenerator {
void BeginFile(const std::string &name_space_name, const bool needs_imports, void BeginFile(const std::string &name_space_name, const bool needs_imports,
const bool is_enum, std::string *code_ptr) { const bool is_enum, std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code = code + "// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n"; code = code +
"// Code generated by the FlatBuffers compiler. DO NOT EDIT.\n\n";
code += "package " + name_space_name + "\n\n"; code += "package " + name_space_name + "\n\n";
if (needs_imports) { if (needs_imports) {
code += "import (\n"; code += "import (\n";
if (is_enum) { if (is_enum) { code += "\t\"strconv\"\n\n"; }
code += "\t\"strconv\"\n\n";
}
if (!parser_.opts.go_import.empty()) { if (!parser_.opts.go_import.empty()) {
code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n"; code += "\tflatbuffers \"" + parser_.opts.go_import + "\"\n";
} else { } else {
@@ -913,17 +1280,14 @@ class GoGenerator : public BaseGenerator {
if (tracked_imported_namespaces_.size() > 0) { if (tracked_imported_namespaces_.size() > 0) {
code += "\n"; code += "\n";
for (auto it = tracked_imported_namespaces_.begin(); for (auto it = tracked_imported_namespaces_.begin();
it != tracked_imported_namespaces_.end(); it != tracked_imported_namespaces_.end(); ++it) {
++it) { code += "\t" + NamespaceImportName(*it) + " \"" +
code += "\t" + NamespaceImportName(*it) + " \"" + \ NamespaceImportPath(*it) + "\"\n";
NamespaceImportPath(*it) + "\"\n";
} }
} }
code += ")\n\n"; code += ")\n\n";
} else { } else {
if (is_enum) { if (is_enum) { code += "import \"strconv\"\n\n"; }
code += "import \"strconv\"\n\n";
}
} }
} }
@@ -991,8 +1355,7 @@ class GoGenerator : public BaseGenerator {
static size_t MaxNameLength(const EnumDef &enum_def) { static size_t MaxNameLength(const EnumDef &enum_def) {
size_t max = 0; size_t max = 0;
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
++it) {
max = std::max((*it)->name.length(), max); max = std::max((*it)->name.length(), max);
} }
return max; return max;

View File

@@ -20,10 +20,11 @@
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include "src/compiler/cpp_generator.h" #include "src/compiler/cpp_generator.h"
#include "src/compiler/go_generator.h" #include "src/compiler/go_generator.h"
#include "src/compiler/java_generator.h" #include "src/compiler/java_generator.h"
#include "src/compiler/python_generator.h"
#include "src/compiler/python_private_generator.h"
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
@@ -35,9 +36,7 @@ namespace flatbuffers {
class FlatBufMethod : public grpc_generator::Method { class FlatBufMethod : public grpc_generator::Method {
public: public:
enum Streaming { enum Streaming { kNone, kClient, kServer, kBiDi };
kNone, kClient, kServer, kBiDi
};
FlatBufMethod(const RPCCall *method) : method_(method) { FlatBufMethod(const RPCCall *method) : method_(method) {
streaming_ = kNone; streaming_ = kNone;
@@ -80,6 +79,10 @@ class FlatBufMethod : public grpc_generator::Method {
return true; return true;
} }
std::string get_fb_builder() const {
return "builder";
}
std::string input_type_name() const { return GRPCType(*method_->request); } std::string input_type_name() const { return GRPCType(*method_->request); }
std::string output_type_name() const { return GRPCType(*method_->response); } std::string output_type_name() const { return GRPCType(*method_->response); }
@@ -171,7 +174,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
void Outdent() { void Outdent() {
indent_--; indent_--;
FLATBUFFERS_ASSERT(indent_ >= 0); FLATBUFFERS_ASSERT(indent_ >= 0);
} }
private: private:
@@ -183,7 +186,7 @@ class FlatBufPrinter : public grpc_generator::Printer {
class FlatBufFile : public grpc_generator::File { class FlatBufFile : public grpc_generator::File {
public: public:
enum Language { enum Language {
kLanguageGo, kLanguageCpp, kLanguageJava kLanguageGo, kLanguageCpp, kLanguageJava, kLanguagePython
}; };
FlatBufFile(const Parser &parser, const std::string &file_name, FlatBufFile(const Parser &parser, const std::string &file_name,
@@ -229,6 +232,9 @@ class FlatBufFile : public grpc_generator::File {
case kLanguageJava: { case kLanguageJava: {
return "import com.google.flatbuffers.grpc.FlatbuffersUtils;"; return "import com.google.flatbuffers.grpc.FlatbuffersUtils;";
} }
case kLanguagePython: {
return "";
}
} }
return ""; return "";
} }
@@ -270,7 +276,8 @@ class GoGRPCGenerator : public flatbuffers::BaseGenerator {
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 = def->defined_namespace->GetFullyQualifiedName(""); // file.package(); p.service_prefix =
def->defined_namespace->GetFullyQualifiedName(""); // file.package();
std::string output = std::string output =
grpc_go_generator::GenerateServiceSource(&file, service.get(), &p); grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
std::string filename = std::string filename =
@@ -313,20 +320,20 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path,
std::string header_code = std::string header_code =
grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) + grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) + grpc_cpp_generator::GetHeaderIncludes(&fbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) + grpc_cpp_generator::GetHeaderServices(&fbfile, generator_parameters) +
grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters); grpc_cpp_generator::GetHeaderEpilogue(&fbfile, generator_parameters);
std::string source_code = std::string source_code =
grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourcePrologue(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourceIncludes(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) +
grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters); grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters);
return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(), return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(),
header_code, false) && header_code, false) &&
flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(), flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(),
source_code, false); source_code, false);
} }
class JavaGRPCGenerator : public flatbuffers::BaseGenerator { class JavaGRPCGenerator : public flatbuffers::BaseGenerator {
@@ -364,6 +371,38 @@ 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*/,
const std::string &file_name) {
int nservices = 0;
for (auto it = parser.services_.vec.begin(); it != parser.services_.vec.end();
++it) {
if (!(*it)->generated) nservices++;
}
if (!nservices) return true;
grpc_python_generator::GeneratorConfiguration config;
config.grpc_package_root = "grpc";
config.beta_package_root = "grpc.beta";
config.import_prefix = "";
FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguagePython);
grpc_python_generator::PrivateGenerator generator(config, &fbfile);
std::string code = generator.GetGrpcServices();
std::string namespace_dir;
auto &namespaces = parser.namespaces_.back()->components;
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
if (it != namespaces.begin()) namespace_dir += kPathSeparator;
namespace_dir += *it;
}
std::string grpc_py_filename =
namespace_dir + kPathSeparator + file_name + "_grpc_fb.py";
return flatbuffers::SaveFile(grpc_py_filename.c_str(), code, false);
}
} // namespace flatbuffers } // namespace flatbuffers
#if defined(_MSC_VER) #if defined(_MSC_VER)

1237
src/idl_gen_java.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -127,9 +127,7 @@ class JsTsGenerator : public BaseGenerator {
const auto &file = *it; const auto &file = *it;
const auto basename = const auto basename =
flatbuffers::StripPath(flatbuffers::StripExtension(file)); flatbuffers::StripPath(flatbuffers::StripExtension(file));
if (basename != file_name_) { if (basename != file_name_) { code += GenPrefixedImport(file, basename); }
code += GenPrefixedImport(file, basename);
}
} }
} }
@@ -309,14 +307,12 @@ class JsTsGenerator : public BaseGenerator {
result += " " + type_name; result += " " + type_name;
break; break;
} }
default: { result += " {" + type_name + "}"; } default: {
} result += " {" + type_name + "}";
if (!arg_name.empty()) { }
result += " " + arg_name;
}
if (include_newline) {
result += "\n";
} }
if (!arg_name.empty()) { result += " " + arg_name; }
if (include_newline) { result += "\n"; }
return result; return result;
} }
@@ -605,7 +601,8 @@ class JsTsGenerator : public BaseGenerator {
} }
void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr, void GenerateRootAccessor(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) { std::string &code, std::string &object_name,
bool size_prefixed) {
if (!struct_def.fixed) { if (!struct_def.fixed) {
GenDocComment(code_ptr, GenDocComment(code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") + GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
@@ -613,11 +610,13 @@ class JsTsGenerator : public BaseGenerator {
GenTypeAnnotation(kReturns, object_name, "", false)); GenTypeAnnotation(kReturns, object_name, "", false));
std::string sizePrefixed("SizePrefixed"); std::string sizePrefixed("SizePrefixed");
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As"); code += "static get" + (size_prefixed ? sizePrefixed : "") + "Root" +
Verbose(struct_def, "As");
code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name + code += "(bb:flatbuffers.ByteBuffer, obj?:" + object_name +
"):" + object_name + " {\n"; "):" + object_name + " {\n";
} else { } else {
code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") + "Root" + Verbose(struct_def, "As"); code += object_name + ".get" + (size_prefixed ? sizePrefixed : "") +
"Root" + Verbose(struct_def, "As");
code += " = function(bb, obj) {\n"; code += " = function(bb, obj) {\n";
} }
code += " return (obj || new " + object_name; code += " return (obj || new " + object_name;
@@ -627,21 +626,22 @@ class JsTsGenerator : public BaseGenerator {
} }
void GenerateFinisher(StructDef &struct_def, std::string *code_ptr, void GenerateFinisher(StructDef &struct_def, std::string *code_ptr,
std::string &code, std::string &object_name, bool size_prefixed) { std::string &code, std::string &object_name,
bool size_prefixed) {
if (parser_.root_struct_def_ == &struct_def) { if (parser_.root_struct_def_ == &struct_def) {
std::string sizePrefixed("SizePrefixed"); std::string sizePrefixed("SizePrefixed");
GenDocComment( GenDocComment(
code_ptr, code_ptr,
GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") + GenTypeAnnotation(kParam, "flatbuffers.Builder", "builder") +
GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", GenTypeAnnotation(kParam, "flatbuffers.Offset", "offset", false));
false));
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += "static finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer"; code += "static finish" + (size_prefixed ? sizePrefixed : "") +
code += Verbose(struct_def) + "Buffer";
"(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n"; code += "(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {\n";
} else { } else {
code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") + Verbose(struct_def) + "Buffer"; code += object_name + ".finish" + (size_prefixed ? sizePrefixed : "") +
Verbose(struct_def) + "Buffer";
code += " = function(builder, offset) {\n"; code += " = function(builder, offset) {\n";
} }
@@ -650,9 +650,7 @@ class JsTsGenerator : public BaseGenerator {
code += ", '" + parser_.file_identifier_ + "'"; code += ", '" + parser_.file_identifier_ + "'";
} }
if (size_prefixed) { if (size_prefixed) {
if (parser_.file_identifier_.empty()) { if (parser_.file_identifier_.empty()) { code += ", undefined"; }
code += ", undefined";
}
code += ", true"; code += ", true";
} }
code += ");\n"; code += ");\n";
@@ -682,7 +680,8 @@ class JsTsGenerator : public BaseGenerator {
code += " {\n"; code += " {\n";
if (lang_.language != IDLOptions::kTs) { if (lang_.language != IDLOptions::kTs) {
code += " /**\n"; code += " /**\n";
code += " * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", ""); code +=
" * " + GenTypeAnnotation(kType, "flatbuffers.ByteBuffer", "");
code += " */\n"; code += " */\n";
} }
code += " bb: flatbuffers.ByteBuffer|null = null;\n"; code += " bb: flatbuffers.ByteBuffer|null = null;\n";
@@ -752,10 +751,9 @@ class JsTsGenerator : public BaseGenerator {
// Generate the identifier check method // Generate the identifier check method
if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def && if (!struct_def.fixed && parser_.root_struct_def_ == &struct_def &&
!parser_.file_identifier_.empty()) { !parser_.file_identifier_.empty()) {
GenDocComment( GenDocComment(code_ptr,
code_ptr, GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") +
GenTypeAnnotation(kParam, "flatbuffers.ByteBuffer", "bb") + GenTypeAnnotation(kReturns, "boolean", "", false));
GenTypeAnnotation(kReturns, "boolean", "", false));
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += code +=
"static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean " "static bufferHasIdentifier(bb:flatbuffers.ByteBuffer):boolean "
@@ -872,7 +870,8 @@ class JsTsGenerator : public BaseGenerator {
code += ", " + GenBBAccess() + ") : null;\n"; code += ", " + GenBBAccess() + ") : null;\n";
} }
if (lang_.language == IDLOptions::kTs && !parser_.opts.generate_all) { if (lang_.language == IDLOptions::kTs &&
!parser_.opts.generate_all) {
imported_files.insert(field.value.type.struct_def->file); imported_files.insert(field.value.type.struct_def->file);
} }
@@ -1015,7 +1014,8 @@ class JsTsGenerator : public BaseGenerator {
} }
// Adds the mutable scalar value to the output // Adds the mutable scalar value to the output
if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer) { if (IsScalar(field.value.type.base_type) && parser.opts.mutable_buffer &&
!IsUnion(field.value.type)) {
std::string annotations = GenTypeAnnotation( std::string annotations = GenTypeAnnotation(
kParam, GenTypeName(field.value.type, true), "value"); kParam, GenTypeName(field.value.type, true), "value");
GenDocComment( GenDocComment(
@@ -1290,8 +1290,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (field.deprecated) if (field.deprecated) continue;
continue;
paramDoc += paramDoc +=
GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field)); GenTypeAnnotation(kParam, GetArgType(field), GetArgName(field));
} }
@@ -1311,8 +1310,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (field.deprecated) if (field.deprecated) continue;
continue;
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
code += ", " + GetArgName(field) + ":" + GetArgType(field); code += ", " + GetArgName(field) + ":" + GetArgType(field);
@@ -1336,8 +1334,7 @@ class JsTsGenerator : public BaseGenerator {
for (auto it = struct_def.fields.vec.begin(); for (auto it = struct_def.fields.vec.begin();
it != struct_def.fields.vec.end(); ++it) { it != struct_def.fields.vec.end(); ++it) {
const auto &field = **it; const auto &field = **it;
if (field.deprecated) if (field.deprecated) continue;
continue;
code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "("; code += " " + methodPrefix + ".add" + MakeCamel(field.name) + "(";
code += "builder, " + GetArgName(field) + ");\n"; code += "builder, " + GetArgName(field) + ");\n";
@@ -1346,14 +1343,11 @@ class JsTsGenerator : public BaseGenerator {
code += " return " + methodPrefix + ".end" + Verbose(struct_def) + code += " return " + methodPrefix + ".end" + Verbose(struct_def) +
"(builder);\n"; "(builder);\n";
code += "}\n"; code += "}\n";
if (lang_.language == IDLOptions::kJs) if (lang_.language == IDLOptions::kJs) code += "\n";
code += "\n";
} }
if (lang_.language == IDLOptions::kTs) { if (lang_.language == IDLOptions::kTs) {
if (!object_namespace.empty()) { if (!object_namespace.empty()) { code += "}\n"; }
code += "}\n";
}
code += "}\n"; code += "}\n";
} }
} }
@@ -1372,9 +1366,7 @@ class JsTsGenerator : public BaseGenerator {
return argname; return argname;
} }
std::string Verbose(const StructDef &struct_def, std::string Verbose(const StructDef &struct_def, const char *prefix = "") {
const char* prefix = "")
{
return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name; return parser_.opts.js_ts_short_names ? "" : prefix + struct_def.name;
} }
}; };

View File

@@ -15,6 +15,7 @@
*/ */
#include <iostream> #include <iostream>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
@@ -121,6 +122,7 @@ class JsonSchemaGenerator : public BaseGenerator {
: BaseGenerator(base_generator) {} : BaseGenerator(base_generator) {}
bool generate() { bool generate() {
if (parser_.root_struct_def_ == nullptr) { return false; }
code_.Clear(); code_.Clear();
code_ += "{"; code_ += "{";
code_ += " \"$schema\": \"http://json-schema.org/draft-04/schema#\","; code_ += " \"$schema\": \"http://json-schema.org/draft-04/schema#\",";

File diff suppressed because it is too large Load Diff

View File

@@ -27,14 +27,16 @@ 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 */, "_") {
static const char * const keywords[] = { static const char *const keywords[] = {
"nil", "true", "false", "return", "struct", "class", "import", "int", "nil", "true", "false", "return", "struct", "class",
"float", "string", "any", "def", "is", "from", "program", "private", "import", "int", "float", "string", "any", "def",
"coroutine", "resource", "enum", "typeof", "var", "let", "pakfile", "is", "from", "program", "private", "coroutine", "resource",
"switch", "case", "default", "namespace", "not", "and", "or", "bool", "enum", "typeof", "var", "let", "pakfile", "switch",
"case", "default", "namespace", "not", "and", "or",
"bool",
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -66,7 +68,8 @@ class LobsterGenerator : public BaseGenerator {
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 (IsScalar(type.base_type) && type.enum_def) return NormalizedName(*type.enum_def); if (IsScalar(type.base_type) && type.enum_def)
return NormalizedName(*type.enum_def);
if (!IsScalar(type.base_type)) return "flatbuffers_offset"; if (!IsScalar(type.base_type)) return "flatbuffers_offset";
return "int"; return "int";
} }
@@ -74,27 +77,27 @@ 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)
? MakeCamel(GenTypeBasic(type)) ? MakeCamel(GenTypeBasic(type))
: (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
static const char *ctypename[] = { static const char *ctypename[] = {
// clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \
#PTYPE, #PTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// clang-format on
}; };
// clang-format on
return ctypename[type.base_type]; return ctypename[type.base_type];
} }
// 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, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
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);
@@ -102,13 +105,12 @@ class LobsterGenerator : public BaseGenerator {
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
std::string acc; std::string acc;
if (struct_def.fixed) { if (struct_def.fixed) {
acc = "buf_.read_" + GenTypeName(field.value.type) + acc = "buf_.read_" + GenTypeName(field.value.type) + "_le(pos_ + " +
"_le(pos_ + " + offsets + ")"; offsets + ")";
} else { } else {
acc = "buf_.flatbuffers_field_" + acc = "buf_.flatbuffers_field_" + GenTypeName(field.value.type) +
GenTypeName(field.value.type) + "(pos_, " + offsets + ", " + "(pos_, " + offsets + ", " + field.value.constant + ")";
field.value.constant + ")";
} }
if (field.value.type.enum_def) if (field.value.type.enum_def)
acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")"; acc = NormalizedName(*field.value.type.enum_def) + "(" + acc + ")";
@@ -130,7 +132,8 @@ class LobsterGenerator : public BaseGenerator {
break; break;
} }
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
code += def + "():\n return buf_.flatbuffers_field_string(pos_, " + code += def +
"():\n return buf_.flatbuffers_field_string(pos_, " +
offsets + ")\n"; offsets + ")\n";
break; break;
case BASE_TYPE_VECTOR: { case BASE_TYPE_VECTOR: {
@@ -171,19 +174,20 @@ class LobsterGenerator : public BaseGenerator {
} }
if (field.value.type.base_type == BASE_TYPE_VECTOR) { if (field.value.type.base_type == BASE_TYPE_VECTOR) {
code += def + code += def +
"_length():\n return buf_.flatbuffers_field_vector_len(pos_, " + "_length():\n return "
"buf_.flatbuffers_field_vector_len(pos_, " +
offsets + ")\n"; offsets + ")\n";
} }
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
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(" +
NumToString(struct_def.fields.vec.size()) + ")\n return this\n"; NumToString(struct_def.fields.vec.size()) +
")\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;
@@ -209,8 +213,8 @@ class LobsterGenerator : public BaseGenerator {
auto vector_type = field.value.type.VectorType(); auto vector_type = field.value.type.VectorType();
auto alignment = InlineAlignment(vector_type); auto alignment = InlineAlignment(vector_type);
auto elem_size = InlineSize(vector_type); auto elem_size = InlineSize(vector_type);
code += NumToString(elem_size) + ", n_, " + NumToString(alignment) + code +=
")\n"; NumToString(elem_size) + ", n_, " + NumToString(alignment) + ")\n";
if (vector_type.base_type != BASE_TYPE_STRUCT || if (vector_type.base_type != BASE_TYPE_STRUCT ||
!vector_type.struct_def->fixed) { !vector_type.struct_def->fixed) {
code += "def " + NormalizedName(struct_def) + "Create" + code += "def " + NormalizedName(struct_def) + "Create" +
@@ -218,8 +222,7 @@ class LobsterGenerator : public BaseGenerator {
"Vector(b_:flatbuffers_builder, v_:[" + "Vector(b_:flatbuffers_builder, v_:[" +
LobsterType(vector_type) + "]):\n b_.StartVector(" + LobsterType(vector_type) + "]):\n b_.StartVector(" +
NumToString(elem_size) + ", v_.length, " + NumToString(elem_size) + ", v_.length, " +
NumToString(alignment) + NumToString(alignment) + ")\n reverse(v_) e_: b_.Prepend" +
")\n reverse(v_) e_: b_.Prepend" +
GenMethod(vector_type) + GenMethod(vector_type) +
"(e_)\n return b_.EndVector(v_.length)\n"; "(e_)\n return b_.EndVector(v_.length)\n";
} }
@@ -243,7 +246,7 @@ class LobsterGenerator : public BaseGenerator {
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);
@@ -252,8 +255,8 @@ class LobsterGenerator : public BaseGenerator {
if (!struct_def.fixed) { if (!struct_def.fixed) {
// Generate a special accessor for the table that has been declared as // Generate a special accessor for the table that has been declared as
// the root type. // the root type.
code += "def GetRootAs" + NormalizedName(struct_def) + "(buf:string): return " + code += "def GetRootAs" + NormalizedName(struct_def) +
NormalizedName(struct_def) + "(buf:string): return " + NormalizedName(struct_def) +
" { buf, buf.flatbuffers_indirect(0) }\n\n"; " { buf, buf.flatbuffers_indirect(0) }\n\n";
} }
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -283,8 +286,8 @@ 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, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
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;
@@ -293,7 +296,8 @@ class LobsterGenerator : public BaseGenerator {
// don't clash, and to make it obvious these arguments are constructing // don't clash, and to make it obvious these arguments are constructing
// a nested struct, prefix the name with the field name. // a nested struct, prefix the name with the field name.
StructBuilderArgs(*field.value.type.struct_def, StructBuilderArgs(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
code_ptr);
} else { } else {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += ", " + (nameprefix + NormalizedName(field)) + ":" + code += ", " + (nameprefix + NormalizedName(field)) + ":" +
@@ -304,8 +308,8 @@ 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, void StructBuilderBody(const StructDef &struct_def, const char *nameprefix,
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";
@@ -316,7 +320,8 @@ class LobsterGenerator : public BaseGenerator {
code += " b_.Pad(" + NumToString(field.padding) + ")\n"; code += " b_.Pad(" + NumToString(field.padding) + ")\n";
if (IsStruct(field.value.type)) { if (IsStruct(field.value.type)) {
StructBuilderBody(*field.value.type.struct_def, StructBuilderBody(*field.value.type.struct_def,
(nameprefix + (NormalizedName(field) + "_")).c_str(), code_ptr); (nameprefix + (NormalizedName(field) + "_")).c_str(),
code_ptr);
} else { } else {
code += " b_.Prepend" + GenMethod(field.value.type) + "(" + code += " b_.Prepend" + GenMethod(field.value.type) + "(" +
nameprefix + NormalizedName(field) + ")\n"; nameprefix + NormalizedName(field) + ")\n";
@@ -325,11 +330,10 @@ 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, 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 += "def Create" + NormalizedName(struct_def) + code +=
"(b_:flatbuffers_builder"; "def Create" + NormalizedName(struct_def) + "(b_:flatbuffers_builder";
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
code += "):\n"; code += "):\n";
StructBuilderBody(struct_def, "", code_ptr); StructBuilderBody(struct_def, "", code_ptr);
@@ -363,8 +367,8 @@ class LobsterGenerator : public BaseGenerator {
auto &struct_def = **it; auto &struct_def = **it;
GenStruct(struct_def, &code); GenStruct(struct_def, &code);
} }
return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), return SaveFile((path_ + file_name_ + "_generated.lobster").c_str(), code,
code, false); false);
} }
private: private:
@@ -375,7 +379,7 @@ class LobsterGenerator : public BaseGenerator {
} // namespace lobster } // namespace lobster
bool GenerateLobster(const Parser &parser, const std::string &path, 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();
} }

File diff suppressed because it is too large Load Diff

View File

@@ -826,7 +826,8 @@ class PhpGenerator : public BaseGenerator {
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 + "=>" + "\"" + ev.name + "\",\n"; code += Indent + Indent + enum_def.name + "::" + ev.name + "=>" + "\"" +
ev.name + "\",\n";
} }
code += Indent + ");\n\n"; code += Indent + ");\n\n";
@@ -859,15 +860,15 @@ class PhpGenerator : public BaseGenerator {
} }
static std::string GenTypeBasic(const Type &type) { static std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ static const char *ctypename[] = {
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
#NTYPE, CTYPE, JTYPE, GTYPE, NTYPE, ...) \
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) #NTYPE,
#undef FLATBUFFERS_TD FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
// clang-format on #undef FLATBUFFERS_TD
}; };
// clang-format on
return ctypename[type.base_type]; return ctypename[type.base_type];
} }

View File

@@ -17,14 +17,13 @@
// independent from idl_parser, since this code is not needed for most clients // independent from idl_parser, since this code is not needed for most clients
#include <string> #include <string>
#include <unordered_set>
#include "flatbuffers/code_generators.h" #include "flatbuffers/code_generators.h"
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
#include <unordered_set>
namespace flatbuffers { namespace flatbuffers {
namespace python { namespace python {
@@ -39,40 +38,12 @@ class PythonGenerator : public BaseGenerator {
: BaseGenerator(parser, path, file_name, "" /* not used */, : BaseGenerator(parser, path, file_name, "" /* not used */,
"" /* not used */), "" /* not used */),
float_const_gen_("float('nan')", "float('inf')", "float('-inf')") { float_const_gen_("float('nan')", "float('inf')", "float('-inf')") {
static const char * const keywords[] = { static const char *const keywords[] = {
"False", "False", "None", "True", "and", "as", "assert", "break",
"None", "class", "continue", "def", "del", "elif", "else", "except",
"True", "finally", "for", "from", "global", "if", "import", "in",
"and", "is", "lambda", "nonlocal", "not", "or", "pass", "raise",
"as", "return", "try", "while", "with", "yield"
"assert",
"break",
"class",
"continue",
"def",
"del",
"elif",
"else",
"except",
"finally",
"for",
"from",
"global",
"if",
"import",
"in",
"is",
"lambda",
"nonlocal",
"not",
"or",
"pass",
"raise",
"return",
"try",
"while",
"with",
"yield"
}; };
keywords_.insert(std::begin(keywords), std::end(keywords)); keywords_.insert(std::begin(keywords), std::end(keywords));
} }
@@ -81,9 +52,9 @@ class PythonGenerator : public BaseGenerator {
// this is the prefix code for that. // this is the prefix code for that.
std::string OffsetPrefix(const FieldDef &field) { std::string OffsetPrefix(const FieldDef &field) {
return "\n" + Indent + Indent + return "\n" + Indent + Indent +
"o = flatbuffers.number_types.UOffsetTFlags.py_type" + "o = flatbuffers.number_types.UOffsetTFlags.py_type" +
"(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" + "(self._tab.Offset(" + NumToString(field.value.offset) + "))\n" +
Indent + Indent + "if o != 0:\n"; Indent + Indent + "if o != 0:\n";
} }
// Begin a class declaration. // Begin a class declaration.
@@ -148,8 +119,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Initialize an existing object with other data, to avoid an allocation. // Initialize an existing object with other data, to avoid an allocation.
void InitializeExisting(const StructDef &struct_def, void InitializeExisting(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -172,8 +142,7 @@ class PythonGenerator : public BaseGenerator {
// Get the value of a struct's scalar. // Get the value of a struct's scalar.
void GetScalarFieldOfStruct(const StructDef &struct_def, void GetScalarFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, 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);
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -184,8 +153,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's scalar. // Get the value of a table's scalar.
void GetScalarFieldOfTable(const StructDef &struct_def, void GetScalarFieldOfTable(const StructDef &struct_def, const FieldDef &field,
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);
@@ -195,9 +163,7 @@ class PythonGenerator : public BaseGenerator {
code += OffsetPrefix(field); code += OffsetPrefix(field);
getter += "o + self._tab.Pos)"; getter += "o + self._tab.Pos)";
auto is_bool = IsBool(field.value.type.base_type); auto is_bool = IsBool(field.value.type.base_type);
if (is_bool) { if (is_bool) { getter = "bool(" + getter + ")"; }
getter = "bool(" + getter + ")";
}
code += Indent + Indent + Indent + "return " + getter + "\n"; code += Indent + Indent + Indent + "return " + getter + "\n";
std::string default_value; std::string default_value;
if (is_bool) { if (is_bool) {
@@ -213,8 +179,7 @@ class PythonGenerator : 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 StructDef &struct_def, void GetStructFieldOfStruct(const StructDef &struct_def,
const FieldDef &field, const FieldDef &field, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -250,8 +215,7 @@ class PythonGenerator : 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 StructDef &struct_def, void GetStructFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field,
std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
GenReceiver(struct_def, code_ptr); GenReceiver(struct_def, code_ptr);
@@ -296,7 +260,8 @@ class PythonGenerator : public BaseGenerator {
// TODO(rw): this works and is not the good way to it: // TODO(rw): this works and is not the good way to it:
bool is_native_table = TypeName(field) == "*flatbuffers.Table"; bool is_native_table = TypeName(field) == "*flatbuffers.Table";
if (is_native_table) { if (is_native_table) {
code += Indent + Indent + Indent + "from flatbuffers.table import Table\n"; code +=
Indent + Indent + Indent + "from flatbuffers.table import Table\n";
} else { } else {
code += Indent + Indent + Indent; code += Indent + Indent + Indent;
code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n"; code += "from ." + TypeName(field) + " import " + TypeName(field) + "\n";
@@ -309,8 +274,7 @@ class PythonGenerator : 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, 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();
@@ -388,8 +352,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Begin the creator function signature. // Begin the creator function signature.
void BeginBuilderArgs(const StructDef &struct_def, void BeginBuilderArgs(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";
@@ -399,10 +362,10 @@ class PythonGenerator : 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, void StructBuilderArgs(const StructDef &struct_def, const char *nameprefix,
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;
const auto &field_type = field.value.type; const auto &field_type = field.value.type;
const auto &type = const auto &type =
@@ -439,7 +402,7 @@ class PythonGenerator : public BaseGenerator {
indent + " builder.Prep(" + NumToString(struct_def.minalign) + ", "; indent + " builder.Prep(" + 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;
const auto &field_type = field.value.type; const auto &field_type = field.value.type;
const auto &type = const auto &type =
@@ -484,8 +447,7 @@ class PythonGenerator : public BaseGenerator {
} }
// Get the value of a table's starting offset. // Get the value of a table's starting offset.
void GetStartOfTable(const StructDef &struct_def, 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 += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += "(builder): "; code += "(builder): ";
@@ -495,11 +457,11 @@ class PythonGenerator : public BaseGenerator {
} }
// Set the value of a table's field. // Set the value of a table's field.
void BuildFieldOfTable(const StructDef &struct_def, void BuildFieldOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, const size_t offset, const size_t offset, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Add" + MakeCamel(NormalizedName(field)); code += "def " + NormalizedName(struct_def) + "Add" +
MakeCamel(NormalizedName(field));
code += "(builder, "; code += "(builder, ";
code += MakeCamel(NormalizedName(field), false); code += MakeCamel(NormalizedName(field), false);
code += "): "; code += "): ";
@@ -521,8 +483,8 @@ class PythonGenerator : 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.
void BuildVectorOfTable(const StructDef &struct_def, void BuildVectorOfTable(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "Start"; code += "def " + NormalizedName(struct_def) + "Start";
code += MakeCamel(NormalizedName(field)); code += MakeCamel(NormalizedName(field));
@@ -536,8 +498,7 @@ class PythonGenerator : 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, void GetEndOffsetOnTable(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
std::string &code = *code_ptr; std::string &code = *code_ptr;
code += "def " + NormalizedName(struct_def) + "End"; code += "def " + NormalizedName(struct_def) + "End";
code += "(builder): "; code += "(builder): ";
@@ -552,8 +513,8 @@ class PythonGenerator : 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, void GenStructAccessor(const StructDef &struct_def, const FieldDef &field,
const FieldDef &field, std::string *code_ptr) { std::string *code_ptr) {
GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str()); GenComment(field.doc_comment, code_ptr, &def_comment, Indent.c_str());
if (IsScalar(field.value.type.base_type)) { if (IsScalar(field.value.type.base_type)) {
if (struct_def.fixed) { if (struct_def.fixed) {
@@ -572,7 +533,9 @@ class PythonGenerator : public BaseGenerator {
GetStructFieldOfTable(struct_def, field, code_ptr); GetStructFieldOfTable(struct_def, field, code_ptr);
} }
break; break;
case BASE_TYPE_STRING: GetStringField(struct_def, field, code_ptr); break; case BASE_TYPE_STRING:
GetStringField(struct_def, 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_STRUCT) { if (vectortype.base_type == BASE_TYPE_STRUCT) {
@@ -593,12 +556,11 @@ class PythonGenerator : public BaseGenerator {
} }
// Generate table constructors, conditioned on its members' types. // Generate table constructors, conditioned on its members' types.
void GenTableBuilders(const StructDef &struct_def, void GenTableBuilders(const StructDef &struct_def, std::string *code_ptr) {
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;
@@ -635,7 +597,7 @@ class PythonGenerator : public BaseGenerator {
code += "\", size_prefixed=size_prefixed)\n"; code += "\", size_prefixed=size_prefixed)\n";
code += "\n"; code += "\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;
@@ -646,7 +608,7 @@ class PythonGenerator : public BaseGenerator {
// Generate a special accessor for the table that has been declared as // Generate a special accessor for the table that has been declared as
// the root type. // the root type.
NewRootTypeFromBuffer(struct_def, code_ptr); NewRootTypeFromBuffer(struct_def, code_ptr);
if (parser_.file_identifier_.length()){ if (parser_.file_identifier_.length()) {
// Generate a special function to test file_identifier // Generate a special function to test file_identifier
GenHasFileIdentifier(struct_def, code_ptr); GenHasFileIdentifier(struct_def, code_ptr);
} }
@@ -655,7 +617,7 @@ class PythonGenerator : public BaseGenerator {
// accessor object. This is to allow object reuse. // accessor object. This is to allow object reuse.
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;
@@ -693,7 +655,7 @@ class PythonGenerator : public BaseGenerator {
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType()); case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
default: default:
return "self._tab.Get(flatbuffers.number_types." + return "self._tab.Get(flatbuffers.number_types." +
MakeCamel(GenTypeGet(type)) + "Flags, "; MakeCamel(GenTypeGet(type)) + "Flags, ";
} }
} }
@@ -705,15 +667,15 @@ class PythonGenerator : public BaseGenerator {
} }
std::string GenTypeBasic(const Type &type) { std::string GenTypeBasic(const Type &type) {
static const char *ctypename[] = {
// clang-format off // clang-format off
static const char *ctypename[] = {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, ...) \
#PTYPE, #PTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// clang-format on
}; };
// clang-format on
return ctypename[IsArray(type) ? type.VectorType().base_type return ctypename[IsArray(type) ? type.VectorType().base_type
: type.base_type]; : type.base_type];
} }
@@ -738,8 +700,7 @@ class PythonGenerator : 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, void GenStructBuilder(const StructDef &struct_def, std::string *code_ptr) {
std::string *code_ptr) {
BeginBuilderArgs(struct_def, code_ptr); BeginBuilderArgs(struct_def, code_ptr);
StructBuilderArgs(struct_def, "", code_ptr); StructBuilderArgs(struct_def, "", code_ptr);
EndBuilderArgs(code_ptr); EndBuilderArgs(code_ptr);
@@ -807,6 +768,7 @@ class PythonGenerator : public BaseGenerator {
NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py"; NamespaceDir(*def.defined_namespace) + NormalizedName(def) + ".py";
return SaveFile(filename.c_str(), code, false); return SaveFile(filename.c_str(), code, false);
} }
private: private:
std::unordered_set<std::string> keywords_; std::unordered_set<std::string> keywords_;
const SimpleFloatConstantGenerator float_const_gen_; const SimpleFloatConstantGenerator float_const_gen_;

File diff suppressed because it is too large Load Diff

View File

@@ -142,8 +142,8 @@ bool Print<const void *>(const void *val, Type type, int indent,
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> *>(prev_val + auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(
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));
} }
auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true); auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true);
@@ -167,8 +167,7 @@ bool Print<const void *>(const void *val, Type type, int indent,
// Call PrintVector above specifically for each element type: // Call PrintVector above specifically for each element type:
// clang-format off // clang-format off
switch (vec_type.base_type) { switch (vec_type.base_type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
if (!PrintVector<CTYPE>( \ if (!PrintVector<CTYPE>( \
*reinterpret_cast<const Vector<CTYPE> *>(val), \ *reinterpret_cast<const Vector<CTYPE> *>(val), \
@@ -187,8 +186,7 @@ bool Print<const void *>(const void *val, Type type, int indent,
// Call PrintArray above specifically for each element type: // Call PrintArray above specifically for each element type:
// clang-format off // clang-format off
switch (vec_type.base_type) { switch (vec_type.base_type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
if (!PrintArray<CTYPE>( \ if (!PrintArray<CTYPE>( \
*reinterpret_cast<const Array<CTYPE, 0xFFFF> *>(val), \ *reinterpret_cast<const Array<CTYPE, 0xFFFF> *>(val), \
@@ -198,6 +196,7 @@ bool Print<const void *>(const void *val, Type type, int indent,
} \ } \
break; break;
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
// Arrays of scalars or structs are only possible.
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0); case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
@@ -205,9 +204,7 @@ bool Print<const void *>(const void *val, Type type, int indent,
// clang-format on // clang-format on
return true; return true;
} }
default: default: FLATBUFFERS_ASSERT(0); return false;
FLATBUFFERS_ASSERT(0);
return false;
} }
} }
@@ -287,20 +284,18 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
text += ":"; text += ":";
text += " "; text += " ";
switch (fd.value.type.base_type) { switch (fd.value.type.base_type) {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ case BASE_TYPE_ ## ENUM: \
case BASE_TYPE_ ## ENUM: \ if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
if (!GenField<CTYPE>(fd, table, struct_def.fixed, \ opts, indent + Indent(opts), _text)) { \
opts, indent + Indent(opts), _text)) { \ return false; \
return false; \ } \
} \ break;
break;
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// Generate drop-thru case statements for all pointer types: // Generate drop-thru case statements for all pointer types:
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: case BASE_TYPE_ ## ENUM:
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
@@ -310,7 +305,7 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
return false; return false;
} }
break; break;
// 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) {
@@ -330,15 +325,11 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
bool GenerateTextFromTable(const Parser &parser, const void *table, bool GenerateTextFromTable(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) { if (struct_def == nullptr) { return false; }
return false;
}
auto &text = *_text; auto &text = *_text;
text.reserve(1024); // Reduce amount of inevitable reallocs. text.reserve(1024); // Reduce amount of inevitable reallocs.
auto root = static_cast<const Table *>(table); auto root = static_cast<const Table *>(table);
if (!GenStruct(*struct_def, root, 0, parser.opts, &text)) { if (!GenStruct(*struct_def, root, 0, parser.opts, &text)) { return false; }
return false;
}
text += NewLine(parser.opts); text += NewLine(parser.opts);
return true; return true;
} }
@@ -348,9 +339,9 @@ bool GenerateText(const Parser &parser, const void *flatbuffer,
std::string *_text) { std::string *_text) {
std::string &text = *_text; std::string &text = *_text;
FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType() FLATBUFFERS_ASSERT(parser.root_struct_def_); // call SetRootType()
text.reserve(1024); // Reduce amount of inevitable reallocs. text.reserve(1024); // Reduce amount of inevitable reallocs.
auto root = parser.opts.size_prefixed ? auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
GetSizePrefixedRoot<Table>(flatbuffer) : GetRoot<Table>(flatbuffer); : GetRoot<Table>(flatbuffer);
if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) { if (!GenStruct(*parser.root_struct_def_, root, 0, parser.opts, _text)) {
return false; return false;
} }

View File

@@ -15,12 +15,11 @@
*/ */
#include <algorithm> #include <algorithm>
#include <cmath>
#include <list> #include <list>
#include <string> #include <string>
#include <utility> #include <utility>
#include <cmath>
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
@@ -38,26 +37,22 @@ const char *FLATBUFFERS_VERSION() {
const double kPi = 3.14159265358979323846; const double kPi = 3.14159265358979323846;
const char *const kTypeNames[] = {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ const char *const kTypeNames[] = {
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \
IDLTYPE, IDLTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// clang-format on
nullptr nullptr
}; };
const char kTypeSizes[] = { const char kTypeSizes[] = {
// clang-format off #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ sizeof(CTYPE),
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
sizeof(CTYPE),
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
// clang-format on
}; };
// clang-format on
// The enums in the reflection schema should match the ones we use internally. // The enums in the reflection schema should match the ones we use internally.
// Compare the last element to check if these go out of sync. // Compare the last element to check if these go out of sync.
@@ -114,8 +109,8 @@ std::string MakeScreamingCamel(const std::string &in) {
return s; return s;
} }
void DeserializeDoc( std::vector<std::string> &doc, void DeserializeDoc(std::vector<std::string> &doc,
const Vector<Offset<String>> *documentation) { const Vector<Offset<String>> *documentation) {
if (documentation == nullptr) return; if (documentation == nullptr) return;
for (uoffset_t index = 0; index < documentation->size(); index++) for (uoffset_t index = 0; index < documentation->size(); index++)
doc.push_back(documentation->Get(index)->str()); doc.push_back(documentation->Get(index)->str());
@@ -223,8 +218,7 @@ static std::string TokenToString(int t) {
#define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING, #define FLATBUFFERS_TOKEN(NAME, VALUE, STRING) STRING,
FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN) FLATBUFFERS_GEN_TOKENS(FLATBUFFERS_TOKEN)
#undef FLATBUFFERS_TOKEN #undef FLATBUFFERS_TOKEN
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
IDLTYPE, IDLTYPE,
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
@@ -399,7 +393,8 @@ CheckedError Parser::Next() {
"illegal Unicode sequence (unpaired high surrogate)"); "illegal Unicode sequence (unpaired high surrogate)");
} }
// reset if non-printable // reset if non-printable
attr_is_trivial_ascii_string_ &= check_ascii_range(*cursor_, ' ', '~'); attr_is_trivial_ascii_string_ &=
check_ascii_range(*cursor_, ' ', '~');
attribute_ += *cursor_++; attribute_ += *cursor_++;
} }
@@ -437,7 +432,7 @@ CheckedError Parser::Next() {
cursor_ += 2; cursor_ += 2;
break; break;
} }
FLATBUFFERS_FALLTHROUGH(); // else fall thru FLATBUFFERS_FALLTHROUGH(); // else fall thru
default: default:
const auto has_sign = (c == '+') || (c == '-'); const auto has_sign = (c == '+') || (c == '-');
// '-'/'+' and following identifier - can be a predefined constant like: // '-'/'+' and following identifier - can be a predefined constant like:
@@ -451,14 +446,15 @@ CheckedError Parser::Next() {
return NoError(); return NoError();
} }
auto dot_lvl = (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen auto dot_lvl =
if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum? (c == '.') ? 0 : 1; // dot_lvl==0 <=> exactly one '.' seen
if (!dot_lvl && !is_digit(*cursor_)) return NoError(); // enum?
// Parser accepts hexadecimal-floating-literal (see C++ 5.13.4). // Parser accepts hexadecimal-floating-literal (see C++ 5.13.4).
if (is_digit(c) || has_sign || !dot_lvl) { if (is_digit(c) || has_sign || !dot_lvl) {
const auto start = cursor_ - 1; const auto start = cursor_ - 1;
auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1; auto start_digits = !is_digit(c) ? cursor_ : cursor_ - 1;
if (!is_digit(c) && is_digit(*cursor_)){ if (!is_digit(c) && is_digit(*cursor_)) {
start_digits = cursor_; // see digit in cursor_ position start_digits = cursor_; // see digit in cursor_ position
c = *cursor_++; c = *cursor_++;
} }
// hex-float can't begind with '.' // hex-float can't begind with '.'
@@ -501,7 +497,8 @@ CheckedError Parser::Next() {
} }
std::string ch; std::string ch;
ch = c; ch = c;
if (false == check_ascii_range(c, ' ', '~')) ch = "code: " + NumToString(c); if (false == check_ascii_range(c, ' ', '~'))
ch = "code: " + NumToString(c);
return Error("illegal character: " + ch); return Error("illegal character: " + ch);
} }
} }
@@ -730,7 +727,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (!IsScalar(type.base_type) || if (!IsScalar(type.base_type) ||
(struct_def.fixed && field->value.constant != "0")) (struct_def.fixed && field->value.constant != "0"))
return Error( return Error(
"default values currently only supported for scalars in tables"); "default values currently only supported for scalars in tables");
} }
// Append .0 if the value has not it (skip hex and scientific floats). // Append .0 if the value has not it (skip hex and scientific floats).
// This suffix needed for generated C++ code. // This suffix needed for generated C++ code.
@@ -738,7 +735,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
auto &text = field->value.constant; auto &text = field->value.constant;
FLATBUFFERS_ASSERT(false == text.empty()); FLATBUFFERS_ASSERT(false == text.empty());
auto s = text.c_str(); auto s = text.c_str();
while(*s == ' ') s++; while (*s == ' ') s++;
if (*s == '-' || *s == '+') s++; if (*s == '-' || *s == '+') s++;
// 1) A float constants (nan, inf, pi, etc) is a kind of identifier. // 1) A float constants (nan, inf, pi, etc) is a kind of identifier.
// 2) A float number needn't ".0" at the end if it has exponent. // 2) A float number needn't ".0" at the end if it has exponent.
@@ -774,7 +771,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
field->deprecated = field->attributes.Lookup("deprecated") != nullptr; field->deprecated = field->attributes.Lookup("deprecated") != nullptr;
auto hash_name = field->attributes.Lookup("hash"); auto hash_name = field->attributes.Lookup("hash");
if (hash_name) { if (hash_name) {
switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element : type.base_type) { switch ((type.base_type == BASE_TYPE_VECTOR) ? type.element
: type.base_type) {
case BASE_TYPE_SHORT: case BASE_TYPE_SHORT:
case BASE_TYPE_USHORT: { case BASE_TYPE_USHORT: {
if (FindHashFunction16(hash_name->constant.c_str()) == nullptr) if (FindHashFunction16(hash_name->constant.c_str()) == nullptr)
@@ -798,7 +796,8 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
} }
default: default:
return Error( return Error(
"only short, ushort, int, uint, long and ulong data types support hashing."); "only short, ushort, int, uint, long and ulong data types support "
"hashing.");
} }
} }
auto cpp_type = field->attributes.Lookup("cpp_type"); auto cpp_type = field->attributes.Lookup("cpp_type");
@@ -817,8 +816,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->deprecated && struct_def.fixed) if (field->deprecated && struct_def.fixed)
return Error("can't deprecate fields in a struct"); return Error("can't deprecate fields in a struct");
field->required = field->attributes.Lookup("required") != nullptr; field->required = field->attributes.Lookup("required") != nullptr;
if (field->required && if (field->required && (struct_def.fixed || IsScalar(type.base_type)))
(struct_def.fixed || IsScalar(type.base_type)))
return Error("only non-scalar fields in tables may be 'required'"); return Error("only non-scalar fields in tables may be 'required'");
field->key = field->attributes.Lookup("key") != nullptr; field->key = field->attributes.Lookup("key") != nullptr;
if (field->key) { if (field->key) {
@@ -861,8 +859,7 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
if (field->attributes.Lookup("flexbuffer")) { if (field->attributes.Lookup("flexbuffer")) {
field->flexbuffer = true; field->flexbuffer = true;
uses_flexbuffers_ = true; uses_flexbuffers_ = true;
if (type.base_type != BASE_TYPE_VECTOR || if (type.base_type != BASE_TYPE_VECTOR || type.element != BASE_TYPE_UCHAR)
type.element != BASE_TYPE_UCHAR)
return Error("flexbuffer attribute may only apply to a vector of ubyte"); return Error("flexbuffer attribute may only apply to a vector of ubyte");
} }
@@ -902,8 +899,7 @@ CheckedError Parser::ParseComma() {
CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field, CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
size_t parent_fieldn, size_t parent_fieldn,
const StructDef *parent_struct_def, const StructDef *parent_struct_def,
uoffset_t count, uoffset_t count, bool inside_vector) {
bool inside_vector) {
switch (val.type.base_type) { switch (val.type.base_type) {
case BASE_TYPE_UNION: { case BASE_TYPE_UNION: {
FLATBUFFERS_ASSERT(field); FLATBUFFERS_ASSERT(field);
@@ -921,8 +917,8 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
uoffset_t offset; uoffset_t offset;
ECHECK(atot(elem->first.constant.c_str(), *this, &offset)); ECHECK(atot(elem->first.constant.c_str(), *this, &offset));
vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>( vector_of_union_types = reinterpret_cast<Vector<uint8_t> *>(
builder_.GetCurrentBufferPointer() + builder_.GetCurrentBufferPointer() + builder_.GetSize() -
builder_.GetSize() - offset); offset);
break; break;
} }
} else { } else {
@@ -964,8 +960,7 @@ CheckedError Parser::ParseAnyValue(Value &val, FieldDef *field,
} }
} }
if (constant.empty() && !vector_of_union_types) { if (constant.empty() && !vector_of_union_types) {
return Error("missing type field for this union value: " + return Error("missing type field for this union value: " + field->name);
field->name);
} }
uint8_t enum_idx; uint8_t enum_idx;
if (vector_of_union_types) { if (vector_of_union_types) {
@@ -1040,10 +1035,9 @@ void Parser::SerializeStruct(FlatBufferBuilder &builder,
builder.AddStructOffset(val.offset, builder.GetSize()); builder.AddStructOffset(val.offset, builder.GetSize());
} }
template <typename F> template<typename F>
CheckedError Parser::ParseTableDelimiters(size_t &fieldn, CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
const StructDef *struct_def, const StructDef *struct_def, F body) {
F body) {
// We allow tables both as JSON object{ .. } with field names // We allow tables both as JSON object{ .. } with field names
// or vector[..] with all fields in order // or vector[..] with all fields in order
char terminator = '}'; char terminator = '}';
@@ -1180,8 +1174,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
size == SizeOf(field_value.type.base_type)) { size == SizeOf(field_value.type.base_type)) {
switch (field_value.type.base_type) { switch (field_value.type.base_type) {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
builder_.Pad(field->padding); \ builder_.Pad(field->padding); \
if (struct_def.fixed) { \ if (struct_def.fixed) { \
@@ -1195,10 +1188,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
builder_.AddElement(field_value.offset, val, valdef); \ builder_.AddElement(field_value.offset, val, valdef); \
} \ } \
break; break;
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD); FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
builder_.Pad(field->padding); \ builder_.Pad(field->padding); \
if (IsStruct(field->value.type)) { \ if (IsStruct(field->value.type)) { \
@@ -1209,7 +1201,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
builder_.AddOffset(field_value.offset, val); \ builder_.AddOffset(field_value.offset, val); \
} \ } \
break; break;
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD); FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
case BASE_TYPE_ARRAY: case BASE_TYPE_ARRAY:
builder_.Pad(field->padding); builder_.Pad(field->padding);
@@ -1217,7 +1209,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
reinterpret_cast<const uint8_t*>(field_value.constant.c_str()), reinterpret_cast<const uint8_t*>(field_value.constant.c_str()),
InlineSize(field_value.type)); InlineSize(field_value.type));
break; break;
// clang-format on // clang-format on
} }
} }
} }
@@ -1243,7 +1235,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
return NoError(); return NoError();
} }
template <typename F> template<typename F>
CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) { CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
EXPECT('['); EXPECT('[');
for (;;) { for (;;) {
@@ -1259,12 +1251,10 @@ CheckedError Parser::ParseVectorDelimiters(uoffset_t &count, F body) {
static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) { static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) {
switch (ftype) { switch (ftype) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
PTYPE, RTYPE, KTYPE) \ case BASE_TYPE_##ENUM: return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
case BASE_TYPE_ ## ENUM: \
return ReadScalar<CTYPE>(a) < ReadScalar<CTYPE>(b);
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD) FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
case BASE_TYPE_STRING: case BASE_TYPE_STRING:
// Indirect offset pointer to string pointer. // Indirect offset pointer to string pointer.
a += ReadScalar<uoffset_t>(a); a += ReadScalar<uoffset_t>(a);
@@ -1278,21 +1268,21 @@ static bool CompareType(const uint8_t *a, const uint8_t *b, BaseType ftype) {
// See below for why we need our own sort :( // See below for why we need our own sort :(
template<typename T, typename F, typename S> template<typename T, typename F, typename S>
void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) { void SimpleQsort(T *begin, T *end, size_t width, F comparator, S swapper) {
if (end - begin <= static_cast<ptrdiff_t>(width)) return; if (end - begin <= static_cast<ptrdiff_t>(width)) return;
auto l = begin + width; auto l = begin + width;
auto r = end; auto r = end;
while (l < r) { while (l < r) {
if (comparator(begin, l)) { if (comparator(begin, l)) {
r -= width; r -= width;
swapper(l, r); swapper(l, r);
} else { } else {
l++; l++;
}
} }
l -= width; }
swapper(begin, l); l -= width;
SimpleQsort(begin, l, width, comparator, swapper); swapper(begin, l);
SimpleQsort(r, end, width, comparator, swapper); SimpleQsort(begin, l, width, comparator, swapper);
SimpleQsort(r, end, width, comparator, swapper);
} }
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue, CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
@@ -1316,8 +1306,7 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
auto &val = field_stack_.back().first; auto &val = field_stack_.back().first;
switch (val.type.base_type) { switch (val.type.base_type) {
// clang-format off // clang-format off
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE,...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \ if (IsStruct(val.type)) SerializeStruct(*val.type.struct_def, val); \
else { \ else { \
@@ -1359,46 +1348,49 @@ CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue,
static BaseType ftype = key->value.type.base_type; static BaseType ftype = key->value.type.base_type;
if (type.struct_def->fixed) { if (type.struct_def->fixed) {
auto v = reinterpret_cast<VectorOfAny *>( auto v =
builder_.GetCurrentBufferPointer()); reinterpret_cast<VectorOfAny *>(builder_.GetCurrentBufferPointer());
SimpleQsort<uint8_t>(v->Data(), SimpleQsort<uint8_t>(
v->Data() + v->size() * type.struct_def->bytesize, v->Data(), v->Data() + v->size() * type.struct_def->bytesize,
type.struct_def->bytesize, type.struct_def->bytesize,
[](const uint8_t *a, const uint8_t *b) -> bool { [](const uint8_t *a, const uint8_t *b) -> bool {
return CompareType(a + offset, b + offset, ftype); return CompareType(a + offset, b + offset, ftype);
}, [&](uint8_t *a, uint8_t *b) { },
// FIXME: faster? [&](uint8_t *a, uint8_t *b) {
for (size_t i = 0; i < type.struct_def->bytesize; i++) { // FIXME: faster?
std::swap(a[i], b[i]); for (size_t i = 0; i < type.struct_def->bytesize; i++) {
} std::swap(a[i], b[i]);
}); }
});
} else { } else {
auto v = reinterpret_cast<Vector<Offset<Table>> *>( auto v = reinterpret_cast<Vector<Offset<Table>> *>(
builder_.GetCurrentBufferPointer()); builder_.GetCurrentBufferPointer());
// Here also can't use std::sort. We do have an iterator type for it, // Here also can't use std::sort. We do have an iterator type for it,
// but it is non-standard as it will dereference the offsets, and thus // but it is non-standard as it will dereference the offsets, and thus
// can't be used to swap elements. // can't be used to swap elements.
SimpleQsort<Offset<Table>>(v->data(), v->data() + v->size(), 1, SimpleQsort<Offset<Table>>(
[](const Offset<Table> *_a, const Offset<Table> *_b) -> bool { v->data(), v->data() + v->size(), 1,
// Indirect offset pointer to table pointer. [](const Offset<Table> *_a, const Offset<Table> *_b) -> bool {
auto a = reinterpret_cast<const uint8_t *>(_a) + // Indirect offset pointer to table pointer.
ReadScalar<uoffset_t>(_a); auto a = reinterpret_cast<const uint8_t *>(_a) +
auto b = reinterpret_cast<const uint8_t *>(_b) + ReadScalar<uoffset_t>(_a);
ReadScalar<uoffset_t>(_b); auto b = reinterpret_cast<const uint8_t *>(_b) +
// Fetch field address from table. ReadScalar<uoffset_t>(_b);
a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset); // Fetch field address from table.
b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset); a = reinterpret_cast<const Table *>(a)->GetAddressOf(offset);
return CompareType(a, b, ftype); b = reinterpret_cast<const Table *>(b)->GetAddressOf(offset);
}, [&](Offset<Table> *a, Offset<Table> *b) { return CompareType(a, b, ftype);
// These are serialized offsets, so are relative where they are },
// stored in memory, so compute the distance between these pointers: [&](Offset<Table> *a, Offset<Table> *b) {
ptrdiff_t diff = (b - a) * sizeof(Offset<Table>); // These are serialized offsets, so are relative where they are
assert(diff >= 0); // Guaranteed by SimpleQsort. // stored in memory, so compute the distance between these pointers:
auto udiff = static_cast<uoffset_t>(diff); ptrdiff_t diff = (b - a) * sizeof(Offset<Table>);
a->o = EndianScalar(ReadScalar<uoffset_t>(a) - udiff); assert(diff >= 0); // Guaranteed by SimpleQsort.
b->o = EndianScalar(ReadScalar<uoffset_t>(b) + udiff); auto udiff = static_cast<uoffset_t>(diff);
std::swap(*a, *b); a->o = EndianScalar(ReadScalar<uoffset_t>(a) - udiff);
}); b->o = EndianScalar(ReadScalar<uoffset_t>(b) + udiff);
std::swap(*a, *b);
});
} }
} }
return NoError(); return NoError();
@@ -1428,8 +1420,7 @@ CheckedError Parser::ParseArray(Value &array) {
auto &val = *it; auto &val = *it;
// clang-format off // clang-format off
switch (val.type.base_type) { switch (val.type.base_type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_ ## ENUM: \ case BASE_TYPE_ ## ENUM: \
if (IsStruct(val.type)) { \ if (IsStruct(val.type)) { \
SerializeStruct(builder, *val.type.struct_def, val); \ SerializeStruct(builder, *val.type.struct_def, val); \
@@ -1478,12 +1469,11 @@ CheckedError Parser::ParseNestedFlatbuffer(Value &val, FieldDef *field,
nested_parser.enums_.dict.clear(); nested_parser.enums_.dict.clear();
nested_parser.enums_.vec.clear(); nested_parser.enums_.vec.clear();
if (!ok) { if (!ok) { ECHECK(Error(nested_parser.error_)); }
ECHECK(Error(nested_parser.error_));
}
// Force alignment for nested flatbuffer // Force alignment for nested flatbuffer
builder_.ForceVectorAlignment(nested_parser.builder_.GetSize(), sizeof(uint8_t), builder_.ForceVectorAlignment(
nested_parser.builder_.GetBufferMinAlignment()); nested_parser.builder_.GetSize(), sizeof(uint8_t),
nested_parser.builder_.GetBufferMinAlignment());
auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(), auto off = builder_.CreateVector(nested_parser.builder_.GetBufferPointer(),
nested_parser.builder_.GetSize()); nested_parser.builder_.GetSize());
@@ -1499,7 +1489,7 @@ CheckedError Parser::ParseMetaData(SymbolTable<Value> *attributes) {
auto name = attribute_; auto name = attribute_;
if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant))) if (false == (Is(kTokenIdentifier) || Is(kTokenStringConstant)))
return Error("attribute name must be either identifier or string: " + return Error("attribute name must be either identifier or string: " +
name); name);
if (known_attributes_.find(name) == known_attributes_.end()) if (known_attributes_.find(name) == known_attributes_.end())
return Error("user define attributes must be declared before use: " + return Error("user define attributes must be declared before use: " +
name); name);
@@ -1648,10 +1638,10 @@ template<typename T> inline void SingleValueRepack(Value &e, T val) {
} }
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Normilaze defaults NaN to unsigned quiet-NaN(0). // Normilaze defaults NaN to unsigned quiet-NaN(0).
static inline void SingleValueRepack(Value& e, float val) { static inline void SingleValueRepack(Value &e, float val) {
if (val != val) e.constant = "nan"; if (val != val) e.constant = "nan";
} }
static inline void SingleValueRepack(Value& e, double val) { static inline void SingleValueRepack(Value &e, double val) {
if (val != val) e.constant = "nan"; if (val != val) e.constant = "nan";
} }
#endif #endif
@@ -1774,7 +1764,7 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
"' to value of <" + std::string(kTypeNames[in_type]) + "> type."; "' to value of <" + std::string(kTypeNames[in_type]) + "> type.";
return Error(msg); return Error(msg);
} }
const auto match_type = e.type.base_type; // may differ from in_type const auto match_type = e.type.base_type; // may differ from in_type
// The check_now flag must be true when parse a fbs-schema. // The check_now flag must be true when parse a fbs-schema.
// This flag forces to check default scalar values or metadata of field. // This flag forces to check default scalar values or metadata of field.
// For JSON parser the flag should be false. // For JSON parser the flag should be false.
@@ -1782,14 +1772,13 @@ CheckedError Parser::ParseSingleValue(const std::string *name, Value &e,
if (check_now && IsScalar(match_type)) { if (check_now && IsScalar(match_type)) {
// clang-format off // clang-format off
switch (match_type) { switch (match_type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, RTYPE, KTYPE) \ case BASE_TYPE_ ## ENUM: {\
case BASE_TYPE_ ## ENUM: {\ CTYPE val; \
CTYPE val; \ ECHECK(atot(e.constant.c_str(), *this, &val)); \
ECHECK(atot(e.constant.c_str(), *this, &val)); \ SingleValueRepack(e, val); \
SingleValueRepack(e, val); \ break; }
break; } FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD);
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
default: break; default: break;
} }
@@ -2018,13 +2007,12 @@ struct EnumValBuilder {
FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) { FLATBUFFERS_CHECKED_ERROR ValidateValue(int64_t *ev, bool next) {
// clang-format off // clang-format off
switch (enum_def.underlying_type.base_type) { switch (enum_def.underlying_type.base_type) {
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \ #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
PTYPE, RTYPE, KTYPE) \
case BASE_TYPE_##ENUM: { \ case BASE_TYPE_##ENUM: { \
if (!IsInteger(BASE_TYPE_##ENUM)) break; \ if (!IsInteger(BASE_TYPE_##ENUM)) break; \
return ValidateImpl<BASE_TYPE_##ENUM, CTYPE>(ev, next ? 1 : 0); \ return ValidateImpl<BASE_TYPE_##ENUM, CTYPE>(ev, next ? 1 : 0); \
} }
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD); FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
#undef FLATBUFFERS_TD #undef FLATBUFFERS_TD
default: break; default: break;
} }
@@ -2210,11 +2198,10 @@ CheckedError Parser::CheckClash(std::vector<FieldDef *> &fields,
bool Parser::SupportsAdvancedUnionFeatures() const { bool Parser::SupportsAdvancedUnionFeatures() const {
return opts.lang_to_generate != 0 && return opts.lang_to_generate != 0 &&
(opts.lang_to_generate & ~(IDLOptions::kCpp | IDLOptions::kJs | (opts.lang_to_generate &
IDLOptions::kTs | IDLOptions::kPhp | ~(IDLOptions::kCpp | IDLOptions::kJs | IDLOptions::kTs |
IDLOptions::kJava | IDLOptions::kCSharp | IDLOptions::kPhp | IDLOptions::kJava | IDLOptions::kCSharp |
IDLOptions::kKotlin | IDLOptions::kKotlin | IDLOptions::kBinary)) == 0;
IDLOptions::kBinary)) == 0;
} }
bool Parser::SupportsAdvancedArrayFeatures() const { bool Parser::SupportsAdvancedArrayFeatures() const {
@@ -2486,8 +2473,8 @@ CheckedError Parser::StartEnum(const std::string &enum_name, bool is_union,
if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name), if (enums_.Add(current_namespace_->GetFullyQualifiedName(enum_name),
&enum_def)) &enum_def))
return Error("enum already exists: " + enum_name); return Error("enum already exists: " + enum_name);
enum_def.underlying_type.base_type = is_union ? BASE_TYPE_UTYPE enum_def.underlying_type.base_type =
: BASE_TYPE_INT; is_union ? BASE_TYPE_UTYPE : BASE_TYPE_INT;
enum_def.underlying_type.enum_def = &enum_def; enum_def.underlying_type.enum_def = &enum_def;
if (dest) *dest = &enum_def; if (dest) *dest = &enum_def;
return NoError(); return NoError();
@@ -2623,8 +2610,8 @@ CheckedError Parser::ParseProtoFields(StructDef *struct_def, bool isextend,
if (oneof_type.base_type != BASE_TYPE_STRUCT || if (oneof_type.base_type != BASE_TYPE_STRUCT ||
!oneof_type.struct_def || oneof_type.struct_def->fixed) !oneof_type.struct_def || oneof_type.struct_def->fixed)
return Error("oneof '" + name + return Error("oneof '" + name +
"' cannot be mapped to a union because member '" + "' cannot be mapped to a union because member '" +
oneof_field.name + "' is not a table type."); oneof_field.name + "' is not a table type.");
EnumValBuilder evb(*this, *oneof_union); EnumValBuilder evb(*this, *oneof_union);
auto ev = evb.CreateEnumerator(oneof_type.struct_def->name); auto ev = evb.CreateEnumerator(oneof_type.struct_def->name);
ev->union_type = oneof_type; ev->union_type = oneof_type;
@@ -2989,9 +2976,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
// entered into included_files_. // entered into included_files_.
// This is recursive, but only go as deep as the number of include // This is recursive, but only go as deep as the number of include
// statements. // statements.
if (source_filename) { if (source_filename) { included_files_.erase(source_filename); }
included_files_.erase(source_filename);
}
return DoParse(source, include_paths, source_filename, return DoParse(source, include_paths, source_filename,
include_filename); include_filename);
} }
@@ -3015,9 +3000,9 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
uoffset_t toff; uoffset_t toff;
ECHECK(ParseTable(*root_struct_def_, nullptr, &toff)); ECHECK(ParseTable(*root_struct_def_, nullptr, &toff));
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(Offset<Table>(toff), file_identifier_.length() builder_.FinishSizePrefixed(
? file_identifier_.c_str() Offset<Table>(toff),
: nullptr); file_identifier_.length() ? file_identifier_.c_str() : nullptr);
} else { } else {
builder_.Finish(Offset<Table>(toff), file_identifier_.length() builder_.Finish(Offset<Table>(toff), file_identifier_.length()
? file_identifier_.c_str() ? file_identifier_.c_str()
@@ -3038,8 +3023,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
if (opts.root_type.empty()) { if (opts.root_type.empty()) {
if (!SetRootType(root_type.c_str())) if (!SetRootType(root_type.c_str()))
return Error("unknown root type: " + root_type); return Error("unknown root type: " + root_type);
if (root_struct_def_->fixed) if (root_struct_def_->fixed) return Error("root type must be a table");
return Error("root type must be a table");
} }
EXPECT(';'); EXPECT(';');
} else if (IsIdent("file_identifier")) { } else if (IsIdent("file_identifier")) {
@@ -3144,10 +3128,9 @@ void Parser::Serialize() {
auto fiid__ = builder_.CreateString(file_identifier_); auto fiid__ = builder_.CreateString(file_identifier_);
auto fext__ = builder_.CreateString(file_extension_); auto fext__ = builder_.CreateString(file_extension_);
auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets); auto serv__ = builder_.CreateVectorOfSortedTables(&service_offsets);
auto schema_offset = auto schema_offset = reflection::CreateSchema(
reflection::CreateSchema(builder_, objs__, enum__, fiid__, fext__, builder_, objs__, enum__, fiid__, fext__,
(root_struct_def_ ? root_struct_def_->serialized_location : 0), (root_struct_def_ ? root_struct_def_->serialized_location : 0), serv__);
serv__);
if (opts.size_prefixed) { if (opts.size_prefixed) {
builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier()); builder_.FinishSizePrefixed(schema_offset, reflection::SchemaIdentifier());
} else { } else {
@@ -3193,22 +3176,20 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets); auto flds__ = builder->CreateVectorOfSortedTables(&field_offsets);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateObject(*builder, name__, flds__, fixed, return reflection::CreateObject(*builder, name__, flds__, fixed,
static_cast<int>(minalign), static_cast<int>(minalign),
static_cast<int>(bytesize), static_cast<int>(bytesize), attr__, docs__);
attr__, docs__);
} }
bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) { bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
if (!DeserializeAttributes(parser, object->attributes())) if (!DeserializeAttributes(parser, object->attributes())) return false;
return false;
DeserializeDoc(doc_comment, object->documentation()); DeserializeDoc(doc_comment, object->documentation());
name = parser.UnqualifiedName(object->name()->str()); name = parser.UnqualifiedName(object->name()->str());
predecl = false; predecl = false;
sortbysize = attributes.Lookup("original_order") == nullptr && !fixed; sortbysize = attributes.Lookup("original_order") == nullptr && !fixed;
const auto& of = *(object->fields()); const auto &of = *(object->fields());
auto indexes = std::vector<uoffset_t>(of.size()); auto indexes = std::vector<uoffset_t>(of.size());
for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i; for (uoffset_t i = 0; i < of.size(); i++) indexes[of.Get(i)->id()] = i;
size_t tmp_struct_size = 0; size_t tmp_struct_size = 0;
@@ -3224,9 +3205,7 @@ bool StructDef::Deserialize(Parser &parser, const reflection::Object *object) {
// Recompute padding since that's currently not serialized. // Recompute padding since that's currently not serialized.
auto size = InlineSize(field_def->value.type); auto size = InlineSize(field_def->value.type);
auto next_field = auto next_field =
i + 1 < indexes.size() i + 1 < indexes.size() ? of.Get(indexes[i + 1]) : nullptr;
? of.Get(indexes[i+1])
: nullptr;
tmp_struct_size += size; tmp_struct_size += size;
field_def->padding = field_def->padding =
next_field ? (next_field->offset() - field_def->value.offset) - size next_field ? (next_field->offset() - field_def->value.offset) - size
@@ -3245,9 +3224,10 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
auto type__ = value.type.Serialize(builder); auto type__ = value.type.Serialize(builder);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateField(*builder, name__, type__, id, value.offset, return reflection::CreateField(
*builder, name__, type__, id, value.offset,
// Is uint64>max(int64) tested? // Is uint64>max(int64) tested?
IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0, IsInteger(value.type.base_type) ? StringToInt(value.constant.c_str()) : 0,
// result may be platform-dependent if underlying is float (not double) // result may be platform-dependent if underlying is float (not double)
@@ -3261,8 +3241,7 @@ Offset<reflection::Field> FieldDef::Serialize(FlatBufferBuilder *builder,
bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) { bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
name = field->name()->str(); name = field->name()->str();
defined_namespace = parser.current_namespace_; defined_namespace = parser.current_namespace_;
if (!value.type.Deserialize(parser, field->type())) if (!value.type.Deserialize(parser, field->type())) return false;
return false;
value.offset = field->offset(); value.offset = field->offset();
if (IsInteger(value.type.base_type)) { if (IsInteger(value.type.base_type)) {
value.constant = NumToString(field->default_integer()); value.constant = NumToString(field->default_integer());
@@ -3276,8 +3255,7 @@ bool FieldDef::Deserialize(Parser &parser, const reflection::Field *field) {
deprecated = field->deprecated(); deprecated = field->deprecated();
required = field->required(); required = field->required();
key = field->key(); key = field->key();
if (!DeserializeAttributes(parser, field->attributes())) if (!DeserializeAttributes(parser, field->attributes())) return false;
return false;
// TODO: this should probably be handled by a separate attribute // TODO: this should probably be handled by a separate attribute
if (attributes.Lookup("flexbuffer")) { if (attributes.Lookup("flexbuffer")) {
flexbuffer = true; flexbuffer = true;
@@ -3301,18 +3279,16 @@ Offset<reflection::RPCCall> RPCCall::Serialize(FlatBufferBuilder *builder,
auto name__ = builder->CreateString(name); auto name__ = builder->CreateString(name);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateRPCCall(*builder, name__, return reflection::CreateRPCCall(
request->serialized_location, *builder, name__, request->serialized_location,
response->serialized_location, response->serialized_location, attr__, docs__);
attr__, docs__);
} }
bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) { bool RPCCall::Deserialize(Parser &parser, const reflection::RPCCall *call) {
name = call->name()->str(); name = call->name()->str();
if (!DeserializeAttributes(parser, call->attributes())) if (!DeserializeAttributes(parser, call->attributes())) return false;
return false;
DeserializeDoc(doc_comment, call->documentation()); DeserializeDoc(doc_comment, call->documentation());
request = parser.structs_.Lookup(call->request()->name()->str()); request = parser.structs_.Lookup(call->request()->name()->str());
response = parser.structs_.Lookup(call->response()->name()->str()); response = parser.structs_.Lookup(call->response()->name()->str());
@@ -3331,8 +3307,8 @@ Offset<reflection::Service> ServiceDef::Serialize(FlatBufferBuilder *builder,
auto call__ = builder->CreateVector(servicecall_offsets); auto call__ = builder->CreateVector(servicecall_offsets);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateService(*builder, name__, call__, attr__, docs__); return reflection::CreateService(*builder, name__, call__, attr__, docs__);
} }
@@ -3349,8 +3325,7 @@ bool ServiceDef::Deserialize(Parser &parser,
} }
} }
} }
if (!DeserializeAttributes(parser, service->attributes())) if (!DeserializeAttributes(parser, service->attributes())) return false;
return false;
DeserializeDoc(doc_comment, service->documentation()); DeserializeDoc(doc_comment, service->documentation());
return true; return true;
} }
@@ -3367,8 +3342,8 @@ Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
auto type__ = underlying_type.Serialize(builder); auto type__ = underlying_type.Serialize(builder);
auto attr__ = SerializeAttributes(builder, parser); auto attr__ = SerializeAttributes(builder, parser);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateEnum(*builder, name__, vals__, is_union, type__, return reflection::CreateEnum(*builder, name__, vals__, is_union, type__,
attr__, docs__); attr__, docs__);
} }
@@ -3387,8 +3362,7 @@ bool EnumDef::Deserialize(Parser &parser, const reflection::Enum *_enum) {
if (!underlying_type.Deserialize(parser, _enum->underlying_type())) { if (!underlying_type.Deserialize(parser, _enum->underlying_type())) {
return false; return false;
} }
if (!DeserializeAttributes(parser, _enum->attributes())) if (!DeserializeAttributes(parser, _enum->attributes())) return false;
return false;
DeserializeDoc(doc_comment, _enum->documentation()); DeserializeDoc(doc_comment, _enum->documentation());
return true; return true;
} }
@@ -3398,9 +3372,10 @@ Offset<reflection::EnumVal> EnumVal::Serialize(FlatBufferBuilder *builder,
auto name__ = builder->CreateString(name); auto name__ = builder->CreateString(name);
auto type__ = union_type.Serialize(builder); auto type__ = union_type.Serialize(builder);
auto docs__ = parser.opts.binary_schema_comments auto docs__ = parser.opts.binary_schema_comments
? builder->CreateVectorOfStrings(doc_comment) ? builder->CreateVectorOfStrings(doc_comment)
: 0; : 0;
return reflection::CreateEnumVal(*builder, name__, value, return reflection::CreateEnumVal(
*builder, name__, value,
union_type.struct_def ? union_type.struct_def->serialized_location : 0, union_type.struct_def ? union_type.struct_def->serialized_location : 0,
type__, docs__); type__, docs__);
} }
@@ -3409,8 +3384,7 @@ bool EnumVal::Deserialize(const Parser &parser,
const reflection::EnumVal *val) { const reflection::EnumVal *val) {
name = val->name()->str(); name = val->name()->str();
value = val->value(); value = val->value();
if (!union_type.Deserialize(parser, val->union_type())) if (!union_type.Deserialize(parser, val->union_type())) return false;
return false;
DeserializeDoc(doc_comment, val->documentation()); DeserializeDoc(doc_comment, val->documentation());
return true; return true;
} }
@@ -3432,8 +3406,7 @@ bool Type::Deserialize(const Parser &parser, const reflection::Type *type) {
bool is_series = type->base_type() == reflection::Vector || bool is_series = type->base_type() == reflection::Vector ||
type->base_type() == reflection::Array; type->base_type() == reflection::Array;
if (type->base_type() == reflection::Obj || if (type->base_type() == reflection::Obj ||
(is_series && (is_series && type->element() == reflection::Obj)) {
type->element() == reflection::Obj)) {
if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) { if (static_cast<size_t>(type->index()) < parser.structs_.vec.size()) {
struct_def = parser.structs_.vec[type->index()]; struct_def = parser.structs_.vec[type->index()];
struct_def->refcount++; struct_def->refcount++;
@@ -3474,8 +3447,7 @@ Definition::SerializeAttributes(FlatBufferBuilder *builder,
bool Definition::DeserializeAttributes( bool Definition::DeserializeAttributes(
Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) { Parser &parser, const Vector<Offset<reflection::KeyValue>> *attrs) {
if (attrs == nullptr) if (attrs == nullptr) return true;
return true;
for (uoffset_t i = 0; i < attrs->size(); ++i) { for (uoffset_t i = 0; i < attrs->size(); ++i) {
auto kv = attrs->Get(i); auto kv = attrs->Get(i);
auto value = new Value(); auto value = new Value();
@@ -3495,7 +3467,7 @@ bool Definition::DeserializeAttributes(
bool Parser::Deserialize(const uint8_t *buf, const size_t size) { bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size); flatbuffers::Verifier verifier(reinterpret_cast<const uint8_t *>(buf), size);
bool size_prefixed = false; bool size_prefixed = false;
if(!reflection::SchemaBufferHasIdentifier(buf)) { if (!reflection::SchemaBufferHasIdentifier(buf)) {
if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(), if (!flatbuffers::BufferHasIdentifier(buf, reflection::SchemaIdentifier(),
true)) true))
return false; return false;
@@ -3504,9 +3476,7 @@ bool Parser::Deserialize(const uint8_t *buf, const size_t size) {
} }
auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer auto verify_fn = size_prefixed ? &reflection::VerifySizePrefixedSchemaBuffer
: &reflection::VerifySchemaBuffer; : &reflection::VerifySchemaBuffer;
if (!verify_fn(verifier)) { if (!verify_fn(verifier)) { return false; }
return false;
}
auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf) auto schema = size_prefixed ? reflection::GetSizePrefixedSchema(buf)
: reflection::GetSchema(buf); : reflection::GetSchema(buf);
return Deserialize(schema); return Deserialize(schema);
@@ -3555,7 +3525,7 @@ bool Parser::Deserialize(const reflection::Schema *schema) {
auto struct_def = structs_.Lookup(qualified_name); auto struct_def = structs_.Lookup(qualified_name);
struct_def->defined_namespace = struct_def->defined_namespace =
GetNamespace(qualified_name, namespaces_, namespaces_index); GetNamespace(qualified_name, namespaces_, namespaces_index);
if (!struct_def->Deserialize(*this, * it)) { return false; } if (!struct_def->Deserialize(*this, *it)) { return false; }
if (schema->root_table() == *it) { root_struct_def_ = struct_def; } if (schema->root_table() == *it) { root_struct_def_ = struct_def; }
} }
for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) { for (auto it = schema->enums()->begin(); it != schema->enums()->end(); ++it) {

View File

@@ -15,6 +15,7 @@
*/ */
#include "flatbuffers/reflection.h" #include "flatbuffers/reflection.h"
#include "flatbuffers/util.h" #include "flatbuffers/util.h"
// Helper functionality for reflection. // Helper functionality for reflection.
@@ -431,8 +432,8 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
break; break;
} }
} }
FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
default: { // Scalars and structs. default: { // Scalars and structs.
auto element_size = GetTypeSize(element_base_type); auto element_size = GetTypeSize(element_base_type);
if (elemobjectdef && elemobjectdef->is_struct()) if (elemobjectdef && elemobjectdef->is_struct())
element_size = elemobjectdef->bytesize(); element_size = elemobjectdef->bytesize();
@@ -466,7 +467,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
break; break;
} }
} }
FLATBUFFERS_FALLTHROUGH(); // fall thru FLATBUFFERS_FALLTHROUGH(); // fall thru
case reflection::Union: case reflection::Union:
case reflection::String: case reflection::String:
case reflection::Vector: case reflection::Vector:
@@ -495,9 +496,8 @@ bool VerifyStruct(flatbuffers::Verifier &v,
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.Verify(reinterpret_cast<const uint8_t *>(&parent_table),
v.Verify(reinterpret_cast<const uint8_t *>(&parent_table), offset, offset, obj.bytesize());
obj.bytesize());
} }
bool VerifyVectorOfStructs(flatbuffers::Verifier &v, bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
@@ -535,9 +535,8 @@ bool VerifyUnion(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
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;
} }
} }
@@ -597,27 +596,24 @@ bool VerifyVector(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
} }
case reflection::Union: { case reflection::Union: {
auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(table, auto vec = flatbuffers::GetFieldV<flatbuffers::Offset<uint8_t>>(
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> *> auto type_vec = table.GetPointer<Vector<uint8_t> *>(vec_field.offset() -
(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
auto utype = type_vec->Get(j); auto utype = type_vec->Get(j);
auto elem = vec->Get(j); auto elem = vec->Get(j);
if (!VerifyUnion(v, schema, utype, elem, vec_field)) if (!VerifyUnion(v, schema, utype, elem, vec_field)) return false;
return false;
} }
return true; return true;
} }
case reflection::Vector: case reflection::Vector:
case reflection::None: case reflection::None:
default: default: FLATBUFFERS_ASSERT(false); return false;
FLATBUFFERS_ASSERT(false);
return false;
} }
} }
@@ -663,8 +659,7 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
} }
break; break;
case reflection::Vector: case reflection::Vector:
if (!VerifyVector(v, schema, *table, *field_def)) if (!VerifyVector(v, schema, *table, *field_def)) return false;
return false;
break; break;
case reflection::Obj: { case reflection::Obj: {
auto child_obj = schema.objects()->Get(field_def->type()->index()); auto child_obj = schema.objects()->Get(field_def->type()->index());
@@ -687,15 +682,11 @@ bool VerifyObject(flatbuffers::Verifier &v, const reflection::Schema &schema,
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)) { if (!VerifyUnion(v, schema, utype, uval, *field_def)) { return false; }
return false;
}
break; break;
} }
default: default: FLATBUFFERS_ASSERT(false); break;
FLATBUFFERS_ASSERT(false);
break;
} }
} }

View File

@@ -242,9 +242,9 @@ bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
} }
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
auto env_str = std::getenv(var_name); auto env_str = std::getenv(var_name);
if (!env_str) return false; if (!env_str) return false;
if (_value) *_value = std::string(env_str); if (_value) *_value = std::string(env_str);

View File

@@ -156,11 +156,7 @@ namespace FlatBuffers.Test
Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null); Assert.IsTrue(monster.TestarrayoftablesByKey("Barney") != null);
Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null); Assert.IsTrue(monster.TestarrayoftablesByKey("Wilma") != null);
// testType is an existing field and mutating it should succeed // testType is an existing field
Assert.AreEqual(monster.TestType, Any.Monster);
Assert.AreEqual(monster.MutateTestType(Any.NONE), true);
Assert.AreEqual(monster.TestType, Any.NONE);
Assert.AreEqual(monster.MutateTestType(Any.Monster), true);
Assert.AreEqual(monster.TestType, Any.Monster); Assert.AreEqual(monster.TestType, Any.Monster);
//mutate the inventory vector //mutate the inventory vector

View File

@@ -20,7 +20,7 @@ go_path=${test_dir}/go_gen
go_src=${go_path}/src go_src=${go_path}/src
# Emit Go code for the example schema in the test dir: # Emit Go code for the example schema in the test dir:
../flatc -g -I include_test monster_test.fbs ../flatc -g --gen-object-api -I include_test monster_test.fbs
# Go requires a particular layout of files in order to link multiple packages. # Go requires a particular layout of files in order to link multiple packages.
# Copy flatbuffer Go files to their own package directories to compile the # Copy flatbuffer Go files to their own package directories to compile the

View File

@@ -1,18 +1,3 @@
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import static com.google.flatbuffers.Constants.*; import static com.google.flatbuffers.Constants.*;
@@ -36,6 +21,24 @@ import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
/*
* Copyright 2014 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class JavaTest { class JavaTest {
public static void main(String[] args) { public static void main(String[] args) {
@@ -438,10 +441,6 @@ class JavaTest {
// testType is an existing field and mutating it should succeed // testType is an existing field and mutating it should succeed
TestEq(monster.testType(), (byte)Any.Monster); TestEq(monster.testType(), (byte)Any.Monster);
TestEq(monster.mutateTestType(Any.NONE), true);
TestEq(monster.testType(), (byte)Any.NONE);
TestEq(monster.mutateTestType(Any.Monster), true);
TestEq(monster.testType(), (byte)Any.Monster);
//mutate the inventory vector //mutate the inventory vector
TestEq(monster.mutateInventory(0, 1), true); TestEq(monster.mutateInventory(0, 1), true);

View File

@@ -6,6 +6,27 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type AbilityT struct {
Id uint32
Distance uint32
}
func AbilityPack(builder *flatbuffers.Builder, t *AbilityT) flatbuffers.UOffsetT {
if t == nil { return 0 }
return CreateAbility(builder, t.Id, t.Distance)
}
func (rcv *Ability) UnPackTo(t *AbilityT) {
t.Id = rcv.Id()
t.Distance = rcv.Distance()
}
func (rcv *Ability) UnPack() *AbilityT {
if rcv == nil { return nil }
t := &AbilityT{}
rcv.UnPackTo(t)
return t
}
type Ability struct { type Ability struct {
_tab flatbuffers.Struct _tab flatbuffers.Struct
} }

View File

@@ -2,7 +2,13 @@
package Example package Example
import "strconv" import (
"strconv"
flatbuffers "github.com/google/flatbuffers/go"
MyGame__Example2 "MyGame/Example2"
)
type Any byte type Any byte
@@ -33,3 +39,38 @@ func (v Any) String() string {
} }
return "Any(" + strconv.FormatInt(int64(v), 10) + ")" return "Any(" + strconv.FormatInt(int64(v), 10) + ")"
} }
type AnyT struct {
Type Any
Value interface{}
}
func AnyPack(builder *flatbuffers.Builder, t *AnyT) flatbuffers.UOffsetT {
if t == nil {
return 0
}
switch t.Type {
case AnyMonster:
return MonsterPack(builder, t.Value.(*MonsterT))
case AnyTestSimpleTableWithEnum:
return TestSimpleTableWithEnumPack(builder, t.Value.(*TestSimpleTableWithEnumT))
case AnyMyGame_Example2_Monster:
return MyGame__Example2.MonsterPack(builder, t.Value.(*MyGame__Example2.MonsterT))
}
return 0
}
func AnyUnPack(t Any, table flatbuffers.Table) *AnyT {
switch t {
case AnyMonster:
x := Monster{_tab: table}
return &AnyT{ Type: AnyMonster, Value: x.UnPack() }
case AnyTestSimpleTableWithEnum:
x := TestSimpleTableWithEnum{_tab: table}
return &AnyT{ Type: AnyTestSimpleTableWithEnum, Value: x.UnPack() }
case AnyMyGame_Example2_Monster:
x := Monster{_tab: table}
return &AnyT{ Type: AnyMyGame_Example2_Monster, Value: x.UnPack() }
}
return nil
}

View File

@@ -2,7 +2,11 @@
package Example package Example
import "strconv" import (
"strconv"
flatbuffers "github.com/google/flatbuffers/go"
)
type AnyAmbiguousAliases byte type AnyAmbiguousAliases byte
@@ -33,3 +37,38 @@ func (v AnyAmbiguousAliases) String() string {
} }
return "AnyAmbiguousAliases(" + strconv.FormatInt(int64(v), 10) + ")" return "AnyAmbiguousAliases(" + strconv.FormatInt(int64(v), 10) + ")"
} }
type AnyAmbiguousAliasesT struct {
Type AnyAmbiguousAliases
Value interface{}
}
func AnyAmbiguousAliasesPack(builder *flatbuffers.Builder, t *AnyAmbiguousAliasesT) flatbuffers.UOffsetT {
if t == nil {
return 0
}
switch t.Type {
case AnyAmbiguousAliasesM1:
return MonsterPack(builder, t.Value.(*MonsterT))
case AnyAmbiguousAliasesM2:
return MonsterPack(builder, t.Value.(*MonsterT))
case AnyAmbiguousAliasesM3:
return MonsterPack(builder, t.Value.(*MonsterT))
}
return 0
}
func AnyAmbiguousAliasesUnPack(t AnyAmbiguousAliases, table flatbuffers.Table) *AnyAmbiguousAliasesT {
switch t {
case AnyAmbiguousAliasesM1:
x := Monster{_tab: table}
return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM1, Value: x.UnPack() }
case AnyAmbiguousAliasesM2:
x := Monster{_tab: table}
return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM2, Value: x.UnPack() }
case AnyAmbiguousAliasesM3:
x := Monster{_tab: table}
return &AnyAmbiguousAliasesT{ Type: AnyAmbiguousAliasesM3, Value: x.UnPack() }
}
return nil
}

View File

@@ -2,7 +2,13 @@
package Example package Example
import "strconv" import (
"strconv"
flatbuffers "github.com/google/flatbuffers/go"
MyGame__Example2 "MyGame/Example2"
)
type AnyUniqueAliases byte type AnyUniqueAliases byte
@@ -33,3 +39,38 @@ func (v AnyUniqueAliases) String() string {
} }
return "AnyUniqueAliases(" + strconv.FormatInt(int64(v), 10) + ")" return "AnyUniqueAliases(" + strconv.FormatInt(int64(v), 10) + ")"
} }
type AnyUniqueAliasesT struct {
Type AnyUniqueAliases
Value interface{}
}
func AnyUniqueAliasesPack(builder *flatbuffers.Builder, t *AnyUniqueAliasesT) flatbuffers.UOffsetT {
if t == nil {
return 0
}
switch t.Type {
case AnyUniqueAliasesM:
return MonsterPack(builder, t.Value.(*MonsterT))
case AnyUniqueAliasesTS:
return TestSimpleTableWithEnumPack(builder, t.Value.(*TestSimpleTableWithEnumT))
case AnyUniqueAliasesM2:
return MyGame__Example2.MonsterPack(builder, t.Value.(*MyGame__Example2.MonsterT))
}
return 0
}
func AnyUniqueAliasesUnPack(t AnyUniqueAliases, table flatbuffers.Table) *AnyUniqueAliasesT {
switch t {
case AnyUniqueAliasesM:
x := Monster{_tab: table}
return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesM, Value: x.UnPack() }
case AnyUniqueAliasesTS:
x := TestSimpleTableWithEnum{_tab: table}
return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesTS, Value: x.UnPack() }
case AnyUniqueAliasesM2:
x := Monster{_tab: table}
return &AnyUniqueAliasesT{ Type: AnyUniqueAliasesM2, Value: x.UnPack() }
}
return nil
}

View File

@@ -44,7 +44,6 @@ public struct Monster : IFlatbufferObject
public MyGame.Example.Color Color { get { int o = __p.__offset(16); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Blue; } } public MyGame.Example.Color Color { get { int o = __p.__offset(16); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Color.Blue; } }
public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } } public bool MutateColor(MyGame.Example.Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)color); return true; } else { return false; } }
public MyGame.Example.Any TestType { get { int o = __p.__offset(18); return o != 0 ? (MyGame.Example.Any)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Any.NONE; } } public MyGame.Example.Any TestType { get { int o = __p.__offset(18); return o != 0 ? (MyGame.Example.Any)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.Any.NONE; } }
public bool MutateTestType(MyGame.Example.Any test_type) { int o = __p.__offset(18); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)test_type); return true; } else { return false; } }
public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; } public TTable? Test<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(20); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
public MyGame.Example.Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; } public MyGame.Example.Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (MyGame.Example.Test?)(new MyGame.Example.Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
public int Test4Length { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } } public int Test4Length { get { int o = __p.__offset(22); return o != 0 ? __p.__vector_len(o) : 0; } }
@@ -174,10 +173,8 @@ public struct Monster : IFlatbufferObject
public ulong[] GetVectorOfNonOwningReferencesArray() { return __p.__vector_as_array<ulong>(88); } public ulong[] GetVectorOfNonOwningReferencesArray() { return __p.__vector_as_array<ulong>(88); }
public bool MutateVectorOfNonOwningReferences(int j, ulong vector_of_non_owning_references) { int o = __p.__offset(88); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } } public bool MutateVectorOfNonOwningReferences(int j, ulong vector_of_non_owning_references) { int o = __p.__offset(88); if (o != 0) { __p.bb.PutUlong(__p.__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
public MyGame.Example.AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (MyGame.Example.AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyUniqueAliases.NONE; } } public MyGame.Example.AnyUniqueAliases AnyUniqueType { get { int o = __p.__offset(90); return o != 0 ? (MyGame.Example.AnyUniqueAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyUniqueAliases.NONE; } }
public bool MutateAnyUniqueType(MyGame.Example.AnyUniqueAliases any_unique_type) { int o = __p.__offset(90); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_unique_type); return true; } else { return false; } }
public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; } public TTable? AnyUnique<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(92); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
public MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (MyGame.Example.AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyAmbiguousAliases.NONE; } } public MyGame.Example.AnyAmbiguousAliases AnyAmbiguousType { get { int o = __p.__offset(94); return o != 0 ? (MyGame.Example.AnyAmbiguousAliases)__p.bb.Get(o + __p.bb_pos) : MyGame.Example.AnyAmbiguousAliases.NONE; } }
public bool MutateAnyAmbiguousType(MyGame.Example.AnyAmbiguousAliases any_ambiguous_type) { int o = __p.__offset(94); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)any_ambiguous_type); return true; } else { return false; } }
public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; } public TTable? AnyAmbiguous<TTable>() where TTable : struct, IFlatbufferObject { int o = __p.__offset(96); return o != 0 ? (TTable?)__p.__union<TTable>(o + __p.bb_pos) : null; }
public MyGame.Example.Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(__p.__vector(o) + j * 1) : (MyGame.Example.Color)0; } public MyGame.Example.Color VectorOfEnums(int j) { int o = __p.__offset(98); return o != 0 ? (MyGame.Example.Color)__p.bb.Get(__p.__vector(o) + j * 1) : (MyGame.Example.Color)0; }
public int VectorOfEnumsLength { get { int o = __p.__offset(98); return o != 0 ? __p.__vector_len(o) : 0; } } public int VectorOfEnumsLength { get { int o = __p.__offset(98); return o != 0 ? __p.__vector_len(o) : 0; } }

View File

@@ -9,6 +9,428 @@ import (
) )
/// an example documentation comment: monster object /// an example documentation comment: monster object
type MonsterT struct {
Pos *Vec3T
Mana int16
Hp int16
Name string
Inventory []byte
Color Color
Test *AnyT
Test4 []*TestT
Testarrayofstring []string
Testarrayoftables []*MonsterT
Enemy *MonsterT
Testnestedflatbuffer []byte
Testempty *StatT
Testbool bool
Testhashs32Fnv1 int32
Testhashu32Fnv1 uint32
Testhashs64Fnv1 int64
Testhashu64Fnv1 uint64
Testhashs32Fnv1a int32
Testhashu32Fnv1a uint32
Testhashs64Fnv1a int64
Testhashu64Fnv1a uint64
Testarrayofbools []bool
Testf float32
Testf2 float32
Testf3 float32
Testarrayofstring2 []string
Testarrayofsortedstruct []*AbilityT
Flex []byte
Test5 []*TestT
VectorOfLongs []int64
VectorOfDoubles []float64
ParentNamespaceTest *MyGame.InParentNamespaceT
VectorOfReferrables []*ReferrableT
SingleWeakReference uint64
VectorOfWeakReferences []uint64
VectorOfStrongReferrables []*ReferrableT
CoOwningReference uint64
VectorOfCoOwningReferences []uint64
NonOwningReference uint64
VectorOfNonOwningReferences []uint64
AnyUnique *AnyUniqueAliasesT
AnyAmbiguous *AnyAmbiguousAliasesT
VectorOfEnums []Color
SignedEnum Race
}
func MonsterPack(builder *flatbuffers.Builder, t *MonsterT) flatbuffers.UOffsetT {
if t == nil { return 0 }
nameOffset := builder.CreateString(t.Name)
inventoryOffset := flatbuffers.UOffsetT(0)
if t.Inventory != nil {
inventoryOffset = builder.CreateByteString(t.Inventory)
}
testOffset := AnyPack(builder, t.Test)
test4Offset := flatbuffers.UOffsetT(0)
if t.Test4 != nil {
test4Length := len(t.Test4)
MonsterStartTest4Vector(builder, test4Length)
for j := test4Length - 1; j >= 0; j-- {
TestPack(builder, t.Test4[j])
}
test4Offset = builder.EndVector(test4Length)
}
testarrayofstringOffset := flatbuffers.UOffsetT(0)
if t.Testarrayofstring != nil {
testarrayofstringLength := len(t.Testarrayofstring)
testarrayofstringOffsets := make([]flatbuffers.UOffsetT, testarrayofstringLength)
for j := 0; j < testarrayofstringLength; j++ {
testarrayofstringOffsets[j] = builder.CreateString(t.Testarrayofstring[j])
}
MonsterStartTestarrayofstringVector(builder, testarrayofstringLength)
for j := testarrayofstringLength - 1; j >= 0; j-- {
builder.PrependUOffsetT(testarrayofstringOffsets[j])
}
testarrayofstringOffset = builder.EndVector(testarrayofstringLength)
}
testarrayoftablesOffset := flatbuffers.UOffsetT(0)
if t.Testarrayoftables != nil {
testarrayoftablesLength := len(t.Testarrayoftables)
testarrayoftablesOffsets := make([]flatbuffers.UOffsetT, testarrayoftablesLength)
for j := 0; j < testarrayoftablesLength; j++ {
testarrayoftablesOffsets[j] = MonsterPack(builder, t.Testarrayoftables[j])
}
MonsterStartTestarrayoftablesVector(builder, testarrayoftablesLength)
for j := testarrayoftablesLength - 1; j >= 0; j-- {
builder.PrependUOffsetT(testarrayoftablesOffsets[j])
}
testarrayoftablesOffset = builder.EndVector(testarrayoftablesLength)
}
enemyOffset := MonsterPack(builder, t.Enemy)
testnestedflatbufferOffset := flatbuffers.UOffsetT(0)
if t.Testnestedflatbuffer != nil {
testnestedflatbufferOffset = builder.CreateByteString(t.Testnestedflatbuffer)
}
testemptyOffset := StatPack(builder, t.Testempty)
testarrayofboolsOffset := flatbuffers.UOffsetT(0)
if t.Testarrayofbools != nil {
testarrayofboolsLength := len(t.Testarrayofbools)
MonsterStartTestarrayofboolsVector(builder, testarrayofboolsLength)
for j := testarrayofboolsLength - 1; j >= 0; j-- {
builder.PrependBool(t.Testarrayofbools[j])
}
testarrayofboolsOffset = builder.EndVector(testarrayofboolsLength)
}
testarrayofstring2Offset := flatbuffers.UOffsetT(0)
if t.Testarrayofstring2 != nil {
testarrayofstring2Length := len(t.Testarrayofstring2)
testarrayofstring2Offsets := make([]flatbuffers.UOffsetT, testarrayofstring2Length)
for j := 0; j < testarrayofstring2Length; j++ {
testarrayofstring2Offsets[j] = builder.CreateString(t.Testarrayofstring2[j])
}
MonsterStartTestarrayofstring2Vector(builder, testarrayofstring2Length)
for j := testarrayofstring2Length - 1; j >= 0; j-- {
builder.PrependUOffsetT(testarrayofstring2Offsets[j])
}
testarrayofstring2Offset = builder.EndVector(testarrayofstring2Length)
}
testarrayofsortedstructOffset := flatbuffers.UOffsetT(0)
if t.Testarrayofsortedstruct != nil {
testarrayofsortedstructLength := len(t.Testarrayofsortedstruct)
MonsterStartTestarrayofsortedstructVector(builder, testarrayofsortedstructLength)
for j := testarrayofsortedstructLength - 1; j >= 0; j-- {
AbilityPack(builder, t.Testarrayofsortedstruct[j])
}
testarrayofsortedstructOffset = builder.EndVector(testarrayofsortedstructLength)
}
flexOffset := flatbuffers.UOffsetT(0)
if t.Flex != nil {
flexOffset = builder.CreateByteString(t.Flex)
}
test5Offset := flatbuffers.UOffsetT(0)
if t.Test5 != nil {
test5Length := len(t.Test5)
MonsterStartTest5Vector(builder, test5Length)
for j := test5Length - 1; j >= 0; j-- {
TestPack(builder, t.Test5[j])
}
test5Offset = builder.EndVector(test5Length)
}
vectorOfLongsOffset := flatbuffers.UOffsetT(0)
if t.VectorOfLongs != nil {
vectorOfLongsLength := len(t.VectorOfLongs)
MonsterStartVectorOfLongsVector(builder, vectorOfLongsLength)
for j := vectorOfLongsLength - 1; j >= 0; j-- {
builder.PrependInt64(t.VectorOfLongs[j])
}
vectorOfLongsOffset = builder.EndVector(vectorOfLongsLength)
}
vectorOfDoublesOffset := flatbuffers.UOffsetT(0)
if t.VectorOfDoubles != nil {
vectorOfDoublesLength := len(t.VectorOfDoubles)
MonsterStartVectorOfDoublesVector(builder, vectorOfDoublesLength)
for j := vectorOfDoublesLength - 1; j >= 0; j-- {
builder.PrependFloat64(t.VectorOfDoubles[j])
}
vectorOfDoublesOffset = builder.EndVector(vectorOfDoublesLength)
}
parentNamespaceTestOffset := MyGame.InParentNamespacePack(builder, t.ParentNamespaceTest)
vectorOfReferrablesOffset := flatbuffers.UOffsetT(0)
if t.VectorOfReferrables != nil {
vectorOfReferrablesLength := len(t.VectorOfReferrables)
vectorOfReferrablesOffsets := make([]flatbuffers.UOffsetT, vectorOfReferrablesLength)
for j := 0; j < vectorOfReferrablesLength; j++ {
vectorOfReferrablesOffsets[j] = ReferrablePack(builder, t.VectorOfReferrables[j])
}
MonsterStartVectorOfReferrablesVector(builder, vectorOfReferrablesLength)
for j := vectorOfReferrablesLength - 1; j >= 0; j-- {
builder.PrependUOffsetT(vectorOfReferrablesOffsets[j])
}
vectorOfReferrablesOffset = builder.EndVector(vectorOfReferrablesLength)
}
vectorOfWeakReferencesOffset := flatbuffers.UOffsetT(0)
if t.VectorOfWeakReferences != nil {
vectorOfWeakReferencesLength := len(t.VectorOfWeakReferences)
MonsterStartVectorOfWeakReferencesVector(builder, vectorOfWeakReferencesLength)
for j := vectorOfWeakReferencesLength - 1; j >= 0; j-- {
builder.PrependUint64(t.VectorOfWeakReferences[j])
}
vectorOfWeakReferencesOffset = builder.EndVector(vectorOfWeakReferencesLength)
}
vectorOfStrongReferrablesOffset := flatbuffers.UOffsetT(0)
if t.VectorOfStrongReferrables != nil {
vectorOfStrongReferrablesLength := len(t.VectorOfStrongReferrables)
vectorOfStrongReferrablesOffsets := make([]flatbuffers.UOffsetT, vectorOfStrongReferrablesLength)
for j := 0; j < vectorOfStrongReferrablesLength; j++ {
vectorOfStrongReferrablesOffsets[j] = ReferrablePack(builder, t.VectorOfStrongReferrables[j])
}
MonsterStartVectorOfStrongReferrablesVector(builder, vectorOfStrongReferrablesLength)
for j := vectorOfStrongReferrablesLength - 1; j >= 0; j-- {
builder.PrependUOffsetT(vectorOfStrongReferrablesOffsets[j])
}
vectorOfStrongReferrablesOffset = builder.EndVector(vectorOfStrongReferrablesLength)
}
vectorOfCoOwningReferencesOffset := flatbuffers.UOffsetT(0)
if t.VectorOfCoOwningReferences != nil {
vectorOfCoOwningReferencesLength := len(t.VectorOfCoOwningReferences)
MonsterStartVectorOfCoOwningReferencesVector(builder, vectorOfCoOwningReferencesLength)
for j := vectorOfCoOwningReferencesLength - 1; j >= 0; j-- {
builder.PrependUint64(t.VectorOfCoOwningReferences[j])
}
vectorOfCoOwningReferencesOffset = builder.EndVector(vectorOfCoOwningReferencesLength)
}
vectorOfNonOwningReferencesOffset := flatbuffers.UOffsetT(0)
if t.VectorOfNonOwningReferences != nil {
vectorOfNonOwningReferencesLength := len(t.VectorOfNonOwningReferences)
MonsterStartVectorOfNonOwningReferencesVector(builder, vectorOfNonOwningReferencesLength)
for j := vectorOfNonOwningReferencesLength - 1; j >= 0; j-- {
builder.PrependUint64(t.VectorOfNonOwningReferences[j])
}
vectorOfNonOwningReferencesOffset = builder.EndVector(vectorOfNonOwningReferencesLength)
}
anyUniqueOffset := AnyUniqueAliasesPack(builder, t.AnyUnique)
anyAmbiguousOffset := AnyAmbiguousAliasesPack(builder, t.AnyAmbiguous)
vectorOfEnumsOffset := flatbuffers.UOffsetT(0)
if t.VectorOfEnums != nil {
vectorOfEnumsLength := len(t.VectorOfEnums)
MonsterStartVectorOfEnumsVector(builder, vectorOfEnumsLength)
for j := vectorOfEnumsLength - 1; j >= 0; j-- {
builder.PrependByte(byte(t.VectorOfEnums[j]))
}
vectorOfEnumsOffset = builder.EndVector(vectorOfEnumsLength)
}
MonsterStart(builder)
posOffset := Vec3Pack(builder, t.Pos)
MonsterAddPos(builder, posOffset)
MonsterAddMana(builder, t.Mana)
MonsterAddHp(builder, t.Hp)
MonsterAddName(builder, nameOffset)
MonsterAddInventory(builder, inventoryOffset)
MonsterAddColor(builder, t.Color)
if t.Test != nil {
MonsterAddTestType(builder, t.Test.Type)
}
MonsterAddTest(builder, testOffset)
MonsterAddTest4(builder, test4Offset)
MonsterAddTestarrayofstring(builder, testarrayofstringOffset)
MonsterAddTestarrayoftables(builder, testarrayoftablesOffset)
MonsterAddEnemy(builder, enemyOffset)
MonsterAddTestnestedflatbuffer(builder, testnestedflatbufferOffset)
MonsterAddTestempty(builder, testemptyOffset)
MonsterAddTestbool(builder, t.Testbool)
MonsterAddTesthashs32Fnv1(builder, t.Testhashs32Fnv1)
MonsterAddTesthashu32Fnv1(builder, t.Testhashu32Fnv1)
MonsterAddTesthashs64Fnv1(builder, t.Testhashs64Fnv1)
MonsterAddTesthashu64Fnv1(builder, t.Testhashu64Fnv1)
MonsterAddTesthashs32Fnv1a(builder, t.Testhashs32Fnv1a)
MonsterAddTesthashu32Fnv1a(builder, t.Testhashu32Fnv1a)
MonsterAddTesthashs64Fnv1a(builder, t.Testhashs64Fnv1a)
MonsterAddTesthashu64Fnv1a(builder, t.Testhashu64Fnv1a)
MonsterAddTestarrayofbools(builder, testarrayofboolsOffset)
MonsterAddTestf(builder, t.Testf)
MonsterAddTestf2(builder, t.Testf2)
MonsterAddTestf3(builder, t.Testf3)
MonsterAddTestarrayofstring2(builder, testarrayofstring2Offset)
MonsterAddTestarrayofsortedstruct(builder, testarrayofsortedstructOffset)
MonsterAddFlex(builder, flexOffset)
MonsterAddTest5(builder, test5Offset)
MonsterAddVectorOfLongs(builder, vectorOfLongsOffset)
MonsterAddVectorOfDoubles(builder, vectorOfDoublesOffset)
MonsterAddParentNamespaceTest(builder, parentNamespaceTestOffset)
MonsterAddVectorOfReferrables(builder, vectorOfReferrablesOffset)
MonsterAddSingleWeakReference(builder, t.SingleWeakReference)
MonsterAddVectorOfWeakReferences(builder, vectorOfWeakReferencesOffset)
MonsterAddVectorOfStrongReferrables(builder, vectorOfStrongReferrablesOffset)
MonsterAddCoOwningReference(builder, t.CoOwningReference)
MonsterAddVectorOfCoOwningReferences(builder, vectorOfCoOwningReferencesOffset)
MonsterAddNonOwningReference(builder, t.NonOwningReference)
MonsterAddVectorOfNonOwningReferences(builder, vectorOfNonOwningReferencesOffset)
if t.AnyUnique != nil {
MonsterAddAnyUniqueType(builder, t.AnyUnique.Type)
}
MonsterAddAnyUnique(builder, anyUniqueOffset)
if t.AnyAmbiguous != nil {
MonsterAddAnyAmbiguousType(builder, t.AnyAmbiguous.Type)
}
MonsterAddAnyAmbiguous(builder, anyAmbiguousOffset)
MonsterAddVectorOfEnums(builder, vectorOfEnumsOffset)
MonsterAddSignedEnum(builder, t.SignedEnum)
return MonsterEnd(builder)
}
func (rcv *Monster) UnPackTo(t *MonsterT) {
t.Pos = rcv.Pos(nil).UnPack()
t.Mana = rcv.Mana()
t.Hp = rcv.Hp()
t.Name = string(rcv.Name())
t.Inventory = rcv.InventoryBytes()
t.Color = rcv.Color()
testTable := flatbuffers.Table{}
if rcv.Test(&testTable) {
t.Test = AnyUnPack(rcv.TestType(), testTable)
}
test4Length := rcv.Test4Length()
t.Test4 = make([]*TestT, test4Length)
for j := 0; j < test4Length; j++ {
x := Test{}
rcv.Test4(&x, j)
t.Test4[j] = x.UnPack()
}
testarrayofstringLength := rcv.TestarrayofstringLength()
t.Testarrayofstring = make([]string, testarrayofstringLength)
for j := 0; j < testarrayofstringLength; j++ {
t.Testarrayofstring[j] = string(rcv.Testarrayofstring(j))
}
testarrayoftablesLength := rcv.TestarrayoftablesLength()
t.Testarrayoftables = make([]*MonsterT, testarrayoftablesLength)
for j := 0; j < testarrayoftablesLength; j++ {
x := Monster{}
rcv.Testarrayoftables(&x, j)
t.Testarrayoftables[j] = x.UnPack()
}
t.Enemy = rcv.Enemy(nil).UnPack()
t.Testnestedflatbuffer = rcv.TestnestedflatbufferBytes()
t.Testempty = rcv.Testempty(nil).UnPack()
t.Testbool = rcv.Testbool()
t.Testhashs32Fnv1 = rcv.Testhashs32Fnv1()
t.Testhashu32Fnv1 = rcv.Testhashu32Fnv1()
t.Testhashs64Fnv1 = rcv.Testhashs64Fnv1()
t.Testhashu64Fnv1 = rcv.Testhashu64Fnv1()
t.Testhashs32Fnv1a = rcv.Testhashs32Fnv1a()
t.Testhashu32Fnv1a = rcv.Testhashu32Fnv1a()
t.Testhashs64Fnv1a = rcv.Testhashs64Fnv1a()
t.Testhashu64Fnv1a = rcv.Testhashu64Fnv1a()
testarrayofboolsLength := rcv.TestarrayofboolsLength()
t.Testarrayofbools = make([]bool, testarrayofboolsLength)
for j := 0; j < testarrayofboolsLength; j++ {
t.Testarrayofbools[j] = rcv.Testarrayofbools(j)
}
t.Testf = rcv.Testf()
t.Testf2 = rcv.Testf2()
t.Testf3 = rcv.Testf3()
testarrayofstring2Length := rcv.Testarrayofstring2Length()
t.Testarrayofstring2 = make([]string, testarrayofstring2Length)
for j := 0; j < testarrayofstring2Length; j++ {
t.Testarrayofstring2[j] = string(rcv.Testarrayofstring2(j))
}
testarrayofsortedstructLength := rcv.TestarrayofsortedstructLength()
t.Testarrayofsortedstruct = make([]*AbilityT, testarrayofsortedstructLength)
for j := 0; j < testarrayofsortedstructLength; j++ {
x := Ability{}
rcv.Testarrayofsortedstruct(&x, j)
t.Testarrayofsortedstruct[j] = x.UnPack()
}
t.Flex = rcv.FlexBytes()
test5Length := rcv.Test5Length()
t.Test5 = make([]*TestT, test5Length)
for j := 0; j < test5Length; j++ {
x := Test{}
rcv.Test5(&x, j)
t.Test5[j] = x.UnPack()
}
vectorOfLongsLength := rcv.VectorOfLongsLength()
t.VectorOfLongs = make([]int64, vectorOfLongsLength)
for j := 0; j < vectorOfLongsLength; j++ {
t.VectorOfLongs[j] = rcv.VectorOfLongs(j)
}
vectorOfDoublesLength := rcv.VectorOfDoublesLength()
t.VectorOfDoubles = make([]float64, vectorOfDoublesLength)
for j := 0; j < vectorOfDoublesLength; j++ {
t.VectorOfDoubles[j] = rcv.VectorOfDoubles(j)
}
t.ParentNamespaceTest = rcv.ParentNamespaceTest(nil).UnPack()
vectorOfReferrablesLength := rcv.VectorOfReferrablesLength()
t.VectorOfReferrables = make([]*ReferrableT, vectorOfReferrablesLength)
for j := 0; j < vectorOfReferrablesLength; j++ {
x := Referrable{}
rcv.VectorOfReferrables(&x, j)
t.VectorOfReferrables[j] = x.UnPack()
}
t.SingleWeakReference = rcv.SingleWeakReference()
vectorOfWeakReferencesLength := rcv.VectorOfWeakReferencesLength()
t.VectorOfWeakReferences = make([]uint64, vectorOfWeakReferencesLength)
for j := 0; j < vectorOfWeakReferencesLength; j++ {
t.VectorOfWeakReferences[j] = rcv.VectorOfWeakReferences(j)
}
vectorOfStrongReferrablesLength := rcv.VectorOfStrongReferrablesLength()
t.VectorOfStrongReferrables = make([]*ReferrableT, vectorOfStrongReferrablesLength)
for j := 0; j < vectorOfStrongReferrablesLength; j++ {
x := Referrable{}
rcv.VectorOfStrongReferrables(&x, j)
t.VectorOfStrongReferrables[j] = x.UnPack()
}
t.CoOwningReference = rcv.CoOwningReference()
vectorOfCoOwningReferencesLength := rcv.VectorOfCoOwningReferencesLength()
t.VectorOfCoOwningReferences = make([]uint64, vectorOfCoOwningReferencesLength)
for j := 0; j < vectorOfCoOwningReferencesLength; j++ {
t.VectorOfCoOwningReferences[j] = rcv.VectorOfCoOwningReferences(j)
}
t.NonOwningReference = rcv.NonOwningReference()
vectorOfNonOwningReferencesLength := rcv.VectorOfNonOwningReferencesLength()
t.VectorOfNonOwningReferences = make([]uint64, vectorOfNonOwningReferencesLength)
for j := 0; j < vectorOfNonOwningReferencesLength; j++ {
t.VectorOfNonOwningReferences[j] = rcv.VectorOfNonOwningReferences(j)
}
anyUniqueTable := flatbuffers.Table{}
if rcv.AnyUnique(&anyUniqueTable) {
t.AnyUnique = AnyUniqueAliasesUnPack(rcv.AnyUniqueType(), anyUniqueTable)
}
anyAmbiguousTable := flatbuffers.Table{}
if rcv.AnyAmbiguous(&anyAmbiguousTable) {
t.AnyAmbiguous = AnyAmbiguousAliasesUnPack(rcv.AnyAmbiguousType(), anyAmbiguousTable)
}
vectorOfEnumsLength := rcv.VectorOfEnumsLength()
t.VectorOfEnums = make([]Color, vectorOfEnumsLength)
for j := 0; j < vectorOfEnumsLength; j++ {
t.VectorOfEnums[j] = rcv.VectorOfEnums(j)
}
t.SignedEnum = rcv.SignedEnum()
}
func (rcv *Monster) UnPack() *MonsterT {
if rcv == nil { return nil }
t := &MonsterT{}
rcv.UnPackTo(t)
return t
}
type Monster struct { type Monster struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -38,7 +38,6 @@ public final class Monster extends Table {
public int color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 8; } public int color() { int o = __offset(16); return o != 0 ? bb.get(o + bb_pos) & 0xFF : 8; }
public boolean mutateColor(int color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } } public boolean mutateColor(int color) { int o = __offset(16); if (o != 0) { bb.put(o + bb_pos, (byte)color); return true; } else { return false; } }
public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; } public byte testType() { int o = __offset(18); return o != 0 ? bb.get(o + bb_pos) : 0; }
public boolean mutateTestType(byte test_type) { int o = __offset(18); if (o != 0) { bb.put(o + bb_pos, test_type); return true; } else { return false; } }
public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o + bb_pos) : null; } public Table test(Table obj) { int o = __offset(20); return o != 0 ? __union(obj, o + bb_pos) : null; }
public MyGame.Example.Test test4(int j) { return test4(new MyGame.Example.Test(), j); } public MyGame.Example.Test test4(int j) { return test4(new MyGame.Example.Test(), j); }
public MyGame.Example.Test test4(MyGame.Example.Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; } public MyGame.Example.Test test4(MyGame.Example.Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
@@ -183,10 +182,8 @@ public final class Monster extends Table {
public ByteBuffer vectorOfNonOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 88, 8); } public ByteBuffer vectorOfNonOwningReferencesInByteBuffer(ByteBuffer _bb) { return __vector_in_bytebuffer(_bb, 88, 8); }
public boolean mutateVectorOfNonOwningReferences(int j, long vector_of_non_owning_references) { int o = __offset(88); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } } public boolean mutateVectorOfNonOwningReferences(int j, long vector_of_non_owning_references) { int o = __offset(88); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_non_owning_references); return true; } else { return false; } }
public byte anyUniqueType() { int o = __offset(90); return o != 0 ? bb.get(o + bb_pos) : 0; } public byte anyUniqueType() { int o = __offset(90); return o != 0 ? bb.get(o + bb_pos) : 0; }
public boolean mutateAnyUniqueType(byte any_unique_type) { int o = __offset(90); if (o != 0) { bb.put(o + bb_pos, any_unique_type); return true; } else { return false; } }
public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o + bb_pos) : null; } public Table anyUnique(Table obj) { int o = __offset(92); return o != 0 ? __union(obj, o + bb_pos) : null; }
public byte anyAmbiguousType() { int o = __offset(94); return o != 0 ? bb.get(o + bb_pos) : 0; } public byte anyAmbiguousType() { int o = __offset(94); return o != 0 ? bb.get(o + bb_pos) : 0; }
public boolean mutateAnyAmbiguousType(byte any_ambiguous_type) { int o = __offset(94); if (o != 0) { bb.put(o + bb_pos, any_ambiguous_type); return true; } else { return false; } }
public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o + bb_pos) : null; } public Table anyAmbiguous(Table obj) { int o = __offset(96); return o != 0 ? __union(obj, o + bb_pos) : null; }
public int vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; } public int vectorOfEnums(int j) { int o = __offset(98); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
public int vectorOfEnumsLength() { int o = __offset(98); return o != 0 ? __vector_len(o) : 0; } public int vectorOfEnumsLength() { int o = __offset(98); return o != 0 ? __vector_len(o) : 0; }

View File

@@ -116,7 +116,7 @@ class Monster : Table() {
} }
} }
fun test(obj: Table) : Table? { fun test(obj: Table) : Table? {
val o = __offset(20); return if (o != 0) __union(obj, o) else null val o = __offset(20); return if (o != 0) __union(obj, o + bb_pos) else null
} }
fun test4(j: Int) : MyGame.Example.Test? = test4(MyGame.Example.Test(), j) fun test4(j: Int) : MyGame.Example.Test? = test4(MyGame.Example.Test(), j)
fun test4(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? { fun test4(obj: MyGame.Example.Test, j: Int) : MyGame.Example.Test? {
@@ -717,7 +717,7 @@ class Monster : Table() {
} }
} }
fun anyUnique(obj: Table) : Table? { fun anyUnique(obj: Table) : Table? {
val o = __offset(92); return if (o != 0) __union(obj, o) else null val o = __offset(92); return if (o != 0) __union(obj, o + bb_pos) else null
} }
val anyAmbiguousType : UByte val anyAmbiguousType : UByte
get() { get() {
@@ -734,7 +734,7 @@ class Monster : Table() {
} }
} }
fun anyAmbiguous(obj: Table) : Table? { fun anyAmbiguous(obj: Table) : Table? {
val o = __offset(96); return if (o != 0) __union(obj, o) else null val o = __offset(96); return if (o != 0) __union(obj, o + bb_pos) else null
} }
fun vectorOfEnums(j: Int) : UByte { fun vectorOfEnums(j: Int) : UByte {
val o = __offset(98) val o = __offset(98)

View File

@@ -6,6 +6,28 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type ReferrableT struct {
Id uint64
}
func ReferrablePack(builder *flatbuffers.Builder, t *ReferrableT) flatbuffers.UOffsetT {
if t == nil { return 0 }
ReferrableStart(builder)
ReferrableAddId(builder, t.Id)
return ReferrableEnd(builder)
}
func (rcv *Referrable) UnPackTo(t *ReferrableT) {
t.Id = rcv.Id()
}
func (rcv *Referrable) UnPack() *ReferrableT {
if rcv == nil { return nil }
t := &ReferrableT{}
rcv.UnPackTo(t)
return t
}
type Referrable struct { type Referrable struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -6,6 +6,35 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type StatT struct {
Id string
Val int64
Count uint16
}
func StatPack(builder *flatbuffers.Builder, t *StatT) flatbuffers.UOffsetT {
if t == nil { return 0 }
idOffset := builder.CreateString(t.Id)
StatStart(builder)
StatAddId(builder, idOffset)
StatAddVal(builder, t.Val)
StatAddCount(builder, t.Count)
return StatEnd(builder)
}
func (rcv *Stat) UnPackTo(t *StatT) {
t.Id = string(rcv.Id())
t.Val = rcv.Val()
t.Count = rcv.Count()
}
func (rcv *Stat) UnPack() *StatT {
if rcv == nil { return nil }
t := &StatT{}
rcv.UnPackTo(t)
return t
}
type Stat struct { type Stat struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -6,6 +6,27 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type TestT struct {
A int16
B int8
}
func TestPack(builder *flatbuffers.Builder, t *TestT) flatbuffers.UOffsetT {
if t == nil { return 0 }
return CreateTest(builder, t.A, t.B)
}
func (rcv *Test) UnPackTo(t *TestT) {
t.A = rcv.A()
t.B = rcv.B()
}
func (rcv *Test) UnPack() *TestT {
if rcv == nil { return nil }
t := &TestT{}
rcv.UnPackTo(t)
return t
}
type Test struct { type Test struct {
_tab flatbuffers.Struct _tab flatbuffers.Struct
} }

View File

@@ -6,6 +6,28 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type TestSimpleTableWithEnumT struct {
Color Color
}
func TestSimpleTableWithEnumPack(builder *flatbuffers.Builder, t *TestSimpleTableWithEnumT) flatbuffers.UOffsetT {
if t == nil { return 0 }
TestSimpleTableWithEnumStart(builder)
TestSimpleTableWithEnumAddColor(builder, t.Color)
return TestSimpleTableWithEnumEnd(builder)
}
func (rcv *TestSimpleTableWithEnum) UnPackTo(t *TestSimpleTableWithEnumT) {
t.Color = rcv.Color()
}
func (rcv *TestSimpleTableWithEnum) UnPack() *TestSimpleTableWithEnumT {
if rcv == nil { return nil }
t := &TestSimpleTableWithEnumT{}
rcv.UnPackTo(t)
return t
}
type TestSimpleTableWithEnum struct { type TestSimpleTableWithEnum struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -6,6 +6,87 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type TypeAliasesT struct {
I8 int8
U8 byte
I16 int16
U16 uint16
I32 int32
U32 uint32
I64 int64
U64 uint64
F32 float32
F64 float64
V8 []int8
Vf64 []float64
}
func TypeAliasesPack(builder *flatbuffers.Builder, t *TypeAliasesT) flatbuffers.UOffsetT {
if t == nil { return 0 }
v8Offset := flatbuffers.UOffsetT(0)
if t.V8 != nil {
v8Length := len(t.V8)
TypeAliasesStartV8Vector(builder, v8Length)
for j := v8Length - 1; j >= 0; j-- {
builder.PrependInt8(t.V8[j])
}
v8Offset = builder.EndVector(v8Length)
}
vf64Offset := flatbuffers.UOffsetT(0)
if t.Vf64 != nil {
vf64Length := len(t.Vf64)
TypeAliasesStartVf64Vector(builder, vf64Length)
for j := vf64Length - 1; j >= 0; j-- {
builder.PrependFloat64(t.Vf64[j])
}
vf64Offset = builder.EndVector(vf64Length)
}
TypeAliasesStart(builder)
TypeAliasesAddI8(builder, t.I8)
TypeAliasesAddU8(builder, t.U8)
TypeAliasesAddI16(builder, t.I16)
TypeAliasesAddU16(builder, t.U16)
TypeAliasesAddI32(builder, t.I32)
TypeAliasesAddU32(builder, t.U32)
TypeAliasesAddI64(builder, t.I64)
TypeAliasesAddU64(builder, t.U64)
TypeAliasesAddF32(builder, t.F32)
TypeAliasesAddF64(builder, t.F64)
TypeAliasesAddV8(builder, v8Offset)
TypeAliasesAddVf64(builder, vf64Offset)
return TypeAliasesEnd(builder)
}
func (rcv *TypeAliases) UnPackTo(t *TypeAliasesT) {
t.I8 = rcv.I8()
t.U8 = rcv.U8()
t.I16 = rcv.I16()
t.U16 = rcv.U16()
t.I32 = rcv.I32()
t.U32 = rcv.U32()
t.I64 = rcv.I64()
t.U64 = rcv.U64()
t.F32 = rcv.F32()
t.F64 = rcv.F64()
v8Length := rcv.V8Length()
t.V8 = make([]int8, v8Length)
for j := 0; j < v8Length; j++ {
t.V8[j] = rcv.V8(j)
}
vf64Length := rcv.Vf64Length()
t.Vf64 = make([]float64, vf64Length)
for j := 0; j < vf64Length; j++ {
t.Vf64[j] = rcv.Vf64(j)
}
}
func (rcv *TypeAliases) UnPack() *TypeAliasesT {
if rcv == nil { return nil }
t := &TypeAliasesT{}
rcv.UnPackTo(t)
return t
}
type TypeAliases struct { type TypeAliases struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -6,6 +6,35 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type Vec3T struct {
X float32
Y float32
Z float32
Test1 float64
Test2 Color
Test3 *TestT
}
func Vec3Pack(builder *flatbuffers.Builder, t *Vec3T) flatbuffers.UOffsetT {
if t == nil { return 0 }
return CreateVec3(builder, t.X, t.Y, t.Z, t.Test1, t.Test2, t.Test3.A, t.Test3.B)
}
func (rcv *Vec3) UnPackTo(t *Vec3T) {
t.X = rcv.X()
t.Y = rcv.Y()
t.Z = rcv.Z()
t.Test1 = rcv.Test1()
t.Test2 = rcv.Test2()
t.Test3 = rcv.Test3(nil).UnPack()
}
func (rcv *Vec3) UnPack() *Vec3T {
if rcv == nil { return nil }
t := &Vec3T{}
rcv.UnPackTo(t)
return t
}
type Vec3 struct { type Vec3 struct {
_tab flatbuffers.Struct _tab flatbuffers.Struct
} }

View File

@@ -0,0 +1,241 @@
# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
import grpc
class MonsterStorageStub(object):
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Store = channel.unary_unary(
'/MyGame.Example.MonsterStorage/Store',
)
self.Retrieve = channel.unary_stream(
'/MyGame.Example.MonsterStorage/Retrieve',
)
self.GetMaxHitPoint = channel.stream_unary(
'/MyGame.Example.MonsterStorage/GetMaxHitPoint',
)
self.GetMinMaxHitPoints = channel.unary_unary(
'/MyGame.Example.MonsterStorage/GetMinMaxHitPoints',
)
class MonsterStorageServicer(object):
def Store(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Retrieve(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMaxHitPoint(self, request_iterator, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMinMaxHitPoints(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_MonsterStorageServicer_to_server(servicer, server):
rpc_method_handlers = {
'Store': grpc.unary_unary_rpc_method_handler(
servicer.Store,
),
'Retrieve': grpc.unary_stream_rpc_method_handler(
servicer.Retrieve,
),
'GetMaxHitPoint': grpc.stream_unary_rpc_method_handler(
servicer.GetMaxHitPoint,
),
'GetMinMaxHitPoints': grpc.unary_unary_rpc_method_handler(
servicer.GetMinMaxHitPoints,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'MyGame.Example.MonsterStorage', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
try:
# THESE ELEMENTS WILL BE DEPRECATED.
# Please use the generated *_pb2_grpc.py files instead.
import grpc
from grpc.beta import implementations as beta_implementations
from grpc.beta import interfaces as beta_interfaces
from grpc.framework.common import cardinality
from grpc.framework.interfaces.face import utilities as face_utilities
class MonsterStorageStub(object):
def __init__(self, channel):
"""Constructor.
Args:
channel: A grpc.Channel.
"""
self.Store = channel.unary_unary(
'/MyGame.Example.MonsterStorage/Store',
)
self.Retrieve = channel.unary_stream(
'/MyGame.Example.MonsterStorage/Retrieve',
)
self.GetMaxHitPoint = channel.stream_unary(
'/MyGame.Example.MonsterStorage/GetMaxHitPoint',
)
self.GetMinMaxHitPoints = channel.unary_unary(
'/MyGame.Example.MonsterStorage/GetMinMaxHitPoints',
)
class MonsterStorageServicer(object):
def Store(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def Retrieve(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMaxHitPoint(self, request_iterator, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def GetMinMaxHitPoints(self, request, context):
context.set_code(grpc.StatusCode.UNIMPLEMENTED)
context.set_details('Method not implemented!')
raise NotImplementedError('Method not implemented!')
def add_MonsterStorageServicer_to_server(servicer, server):
rpc_method_handlers = {
'Store': grpc.unary_unary_rpc_method_handler(
servicer.Store,
),
'Retrieve': grpc.unary_stream_rpc_method_handler(
servicer.Retrieve,
),
'GetMaxHitPoint': grpc.stream_unary_rpc_method_handler(
servicer.GetMaxHitPoint,
),
'GetMinMaxHitPoints': grpc.unary_unary_rpc_method_handler(
servicer.GetMinMaxHitPoints,
),
}
generic_handler = grpc.method_handlers_generic_handler(
'MyGame.Example.MonsterStorage', rpc_method_handlers)
server.add_generic_rpc_handlers((generic_handler,))
class BetaMonsterStorageServicer(object):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This class was generated
only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
def Store(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def Retrieve(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def GetMaxHitPoint(self, request_iterator, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
def GetMinMaxHitPoints(self, request, context):
context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)
class BetaMonsterStorageStub(object):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This class was generated
only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0."""
def Store(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
Store.future = None
def Retrieve(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
def GetMaxHitPoint(self, request_iterator, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
GetMaxHitPoint.future = None
def GetMinMaxHitPoints(self, request, timeout, metadata=None, with_call=False, protocol_options=None):
raise NotImplementedError()
GetMinMaxHitPoints.future = None
def beta_create_MonsterStorage_server(servicer, pool=None, pool_size=None, default_timeout=None, maximum_timeout=None):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This function was
generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
method_implementations = {
('MyGame.Example.MonsterStorage', 'GetMaxHitPoint'): face_utilities.stream_unary_inline(servicer.GetMaxHitPoint),
('MyGame.Example.MonsterStorage', 'GetMinMaxHitPoints'): face_utilities.unary_unary_inline(servicer.GetMinMaxHitPoints),
('MyGame.Example.MonsterStorage', 'Retrieve'): face_utilities.unary_stream_inline(servicer.Retrieve),
('MyGame.Example.MonsterStorage', 'Store'): face_utilities.unary_unary_inline(servicer.Store),
}
server_options = beta_implementations.server_options(thread_pool=pool, thread_pool_size=pool_size, default_timeout=default_timeout, maximum_timeout=maximum_timeout)
return beta_implementations.server(method_implementations, options=server_options)
def beta_create_MonsterStorage_stub(channel, host=None, metadata_transformer=None, pool=None, pool_size=None):
"""The Beta API is deprecated for 0.15.0 and later.
It is recommended to use the GA API (classes and functions in this
file not marked beta) for all further purposes. This function was
generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"""
cardinalities = {
'GetMaxHitPoint': cardinality.Cardinality.STREAM_UNARY,
'GetMinMaxHitPoints': cardinality.Cardinality.UNARY_UNARY,
'Retrieve': cardinality.Cardinality.UNARY_STREAM,
'Store': cardinality.Cardinality.UNARY_UNARY,
}
stub_options = beta_implementations.stub_options(host=host, metadata_transformer=metadata_transformer, thread_pool=pool, thread_pool_size=pool_size)
return beta_implementations.dynamic_stub(channel, 'MyGame.Example.MonsterStorage', cardinalities, options=stub_options)
except ImportError:
pass

View File

@@ -6,6 +6,25 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type MonsterT struct {
}
func MonsterPack(builder *flatbuffers.Builder, t *MonsterT) flatbuffers.UOffsetT {
if t == nil { return 0 }
MonsterStart(builder)
return MonsterEnd(builder)
}
func (rcv *Monster) UnPackTo(t *MonsterT) {
}
func (rcv *Monster) UnPack() *MonsterT {
if rcv == nil { return nil }
t := &MonsterT{}
rcv.UnPackTo(t)
return t
}
type Monster struct { type Monster struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -6,6 +6,25 @@ import (
flatbuffers "github.com/google/flatbuffers/go" flatbuffers "github.com/google/flatbuffers/go"
) )
type InParentNamespaceT struct {
}
func InParentNamespacePack(builder *flatbuffers.Builder, t *InParentNamespaceT) flatbuffers.UOffsetT {
if t == nil { return 0 }
InParentNamespaceStart(builder)
return InParentNamespaceEnd(builder)
}
func (rcv *InParentNamespace) UnPackTo(t *InParentNamespaceT) {
}
func (rcv *InParentNamespace) UnPack() *InParentNamespaceT {
if rcv == nil { return nil }
t := &InParentNamespaceT{}
rcv.UnPackTo(t)
return t
}
type InParentNamespace struct { type InParentNamespace struct {
_tab flatbuffers.Table _tab flatbuffers.Table
} }

View File

@@ -0,0 +1,10 @@
FROM debian:10.1-slim as base
RUN apt -qq update >/dev/null
RUN apt -qq install -y cmake make build-essential >/dev/null
RUN apt -qq install -y autoconf git libtool >/dev/null
RUN apt -qq install -y clang >/dev/null
FROM base
# Travis machines have 2 cores. Can be redefined with 'run --env PAR_JOBS=N'.
ENV JOBS=2
WORKDIR /flatbuffers
ADD . .

15
tests/docker/build_flatc.run.sh Executable file
View File

@@ -0,0 +1,15 @@
set -e
JOBS=${JOBS:-1}
config=$1
echo ""
echo "Build 'flatc' compiler for '$config'"
cmake . -DCMAKE_BUILD_TYPE=$config \
-DFLATBUFFERS_BUILD_FLATC=1 -DFLATBUFFERS_STATIC_FLATC=1 \
-DFLATBUFFERS_BUILD_TESTS=0 -DFLATBUFFERS_INSTALL=0
cmake --build . --target flatc --clean-first -- -j$JOBS
echo "Check generated code"
.travis/check-generate-code.sh
echo "Done"

20
tests/docker/cpp_test.run.sh Executable file
View File

@@ -0,0 +1,20 @@
set -e
JOBS=${JOBS:-1}
export UBSAN_OPTIONS=halt_on_error=1
export ASAN_OPTIONS=halt_on_error=1
export MAKEFLAGS="-j$JOBS"
config=$1
echo ""
echo "Build Flatbuffers project for '$config' with jobs=$JOBS"
cmake . -DCMAKE_BUILD_TYPE=$config \
-DFLATBUFFERS_BUILD_TESTS=ON -DFLATBUFFERS_CODE_SANITIZE=ON
cmake --build . --target all --clean-first -- -j$JOBS
ctest --extra-verbose --output-on-failure -j$JOBS
echo "Check generated code"
.travis/check-generate-code.sh
echo "C++ tests done"

View File

@@ -0,0 +1,39 @@
namespace Evolution.V1;
table TableA {
a:float;
b:int;
}
table TableB {
a:int;
}
enum Enum : byte {
King,
Queen
}
union Union {
TableA,
TableB
}
struct Struct {
a:int;
b:double;
}
table Root {
a:int;
b:bool;
c:Union;
d:Enum;
e:TableA;
f:Struct;
g:[int];
h:[TableB];
i:int = 1234;
}
root_type Root;

View File

@@ -0,0 +1,26 @@
{
"a": 42,
"b": true,
"c_type": "TableB",
"c": {
"a": 15
},
"d": "King",
"e": {
"a": 3.1452,
"b": 325
},
"f":{
"a": 16,
"b": 243.980943
},
"g": [ 7, 8, 9],
"h": [
{
"a": 212
},
{
"a": 459
}
]
}

View File

@@ -0,0 +1,453 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
#define FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_
#include "flatbuffers/flatbuffers.h"
namespace Evolution {
namespace V1 {
struct TableA;
struct TableB;
struct Struct;
struct Root;
enum class Enum : int8_t {
King = 0,
Queen = 1,
MIN = King,
MAX = Queen
};
inline const Enum (&EnumValuesEnum())[2] {
static const Enum values[] = {
Enum::King,
Enum::Queen
};
return values;
}
inline const char * const *EnumNamesEnum() {
static const char * const names[3] = {
"King",
"Queen",
nullptr
};
return names;
}
inline const char *EnumNameEnum(Enum e) {
if (e < Enum::King || e > Enum::Queen) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesEnum()[index];
}
enum class Union : uint8_t {
NONE = 0,
TableA = 1,
TableB = 2,
MIN = NONE,
MAX = TableB
};
inline const Union (&EnumValuesUnion())[3] {
static const Union values[] = {
Union::NONE,
Union::TableA,
Union::TableB
};
return values;
}
inline const char * const *EnumNamesUnion() {
static const char * const names[4] = {
"NONE",
"TableA",
"TableB",
nullptr
};
return names;
}
inline const char *EnumNameUnion(Union e) {
if (e < Union::NONE || e > Union::TableB) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesUnion()[index];
}
template<typename T> struct UnionTraits {
static const Union enum_value = Union::NONE;
};
template<> struct UnionTraits<Evolution::V1::TableA> {
static const Union enum_value = Union::TableA;
};
template<> struct UnionTraits<Evolution::V1::TableB> {
static const Union enum_value = Union::TableB;
};
bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type);
bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS {
private:
int32_t a_;
int32_t padding0__;
double b_;
public:
Struct() {
memset(static_cast<void *>(this), 0, sizeof(Struct));
}
Struct(int32_t _a, double _b)
: a_(flatbuffers::EndianScalar(_a)),
padding0__(0),
b_(flatbuffers::EndianScalar(_b)) {
(void)padding0__;
}
int32_t a() const {
return flatbuffers::EndianScalar(a_);
}
double b() const {
return flatbuffers::EndianScalar(b_);
}
};
FLATBUFFERS_STRUCT_END(Struct, 16);
struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_A = 4,
VT_B = 6
};
float a() const {
return GetField<float>(VT_A, 0.0f);
}
int32_t b() const {
return GetField<int32_t>(VT_B, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<float>(verifier, VT_A) &&
VerifyField<int32_t>(verifier, VT_B) &&
verifier.EndTable();
}
};
struct TableABuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_a(float a) {
fbb_.AddElement<float>(TableA::VT_A, a, 0.0f);
}
void add_b(int32_t b) {
fbb_.AddElement<int32_t>(TableA::VT_B, b, 0);
}
explicit TableABuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
TableABuilder &operator=(const TableABuilder &);
flatbuffers::Offset<TableA> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<TableA>(end);
return o;
}
};
inline flatbuffers::Offset<TableA> CreateTableA(
flatbuffers::FlatBufferBuilder &_fbb,
float a = 0.0f,
int32_t b = 0) {
TableABuilder builder_(_fbb);
builder_.add_b(b);
builder_.add_a(a);
return builder_.Finish();
}
struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_A = 4
};
int32_t a() const {
return GetField<int32_t>(VT_A, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_A) &&
verifier.EndTable();
}
};
struct TableBBuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_a(int32_t a) {
fbb_.AddElement<int32_t>(TableB::VT_A, a, 0);
}
explicit TableBBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
TableBBuilder &operator=(const TableBBuilder &);
flatbuffers::Offset<TableB> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<TableB>(end);
return o;
}
};
inline flatbuffers::Offset<TableB> CreateTableB(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t a = 0) {
TableBBuilder builder_(_fbb);
builder_.add_a(a);
return builder_.Finish();
}
struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_A = 4,
VT_B = 6,
VT_C_TYPE = 8,
VT_C = 10,
VT_D = 12,
VT_E = 14,
VT_F = 16,
VT_G = 18,
VT_H = 20,
VT_I = 22
};
int32_t a() const {
return GetField<int32_t>(VT_A, 0);
}
bool b() const {
return GetField<uint8_t>(VT_B, 0) != 0;
}
Evolution::V1::Union c_type() const {
return static_cast<Evolution::V1::Union>(GetField<uint8_t>(VT_C_TYPE, 0));
}
const void *c() const {
return GetPointer<const void *>(VT_C);
}
template<typename T> const T *c_as() const;
const Evolution::V1::TableA *c_as_TableA() const {
return c_type() == Evolution::V1::Union::TableA ? static_cast<const Evolution::V1::TableA *>(c()) : nullptr;
}
const Evolution::V1::TableB *c_as_TableB() const {
return c_type() == Evolution::V1::Union::TableB ? static_cast<const Evolution::V1::TableB *>(c()) : nullptr;
}
Evolution::V1::Enum d() const {
return static_cast<Evolution::V1::Enum>(GetField<int8_t>(VT_D, 0));
}
const Evolution::V1::TableA *e() const {
return GetPointer<const Evolution::V1::TableA *>(VT_E);
}
const Evolution::V1::Struct *f() const {
return GetStruct<const Evolution::V1::Struct *>(VT_F);
}
const flatbuffers::Vector<int32_t> *g() const {
return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_G);
}
const flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>> *h() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>> *>(VT_H);
}
int32_t i() const {
return GetField<int32_t>(VT_I, 1234);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_A) &&
VerifyField<uint8_t>(verifier, VT_B) &&
VerifyField<uint8_t>(verifier, VT_C_TYPE) &&
VerifyOffset(verifier, VT_C) &&
VerifyUnion(verifier, c(), c_type()) &&
VerifyField<int8_t>(verifier, VT_D) &&
VerifyOffset(verifier, VT_E) &&
verifier.VerifyTable(e()) &&
VerifyField<Evolution::V1::Struct>(verifier, VT_F) &&
VerifyOffset(verifier, VT_G) &&
verifier.VerifyVector(g()) &&
VerifyOffset(verifier, VT_H) &&
verifier.VerifyVector(h()) &&
verifier.VerifyVectorOfTables(h()) &&
VerifyField<int32_t>(verifier, VT_I) &&
verifier.EndTable();
}
};
template<> inline const Evolution::V1::TableA *Root::c_as<Evolution::V1::TableA>() const {
return c_as_TableA();
}
template<> inline const Evolution::V1::TableB *Root::c_as<Evolution::V1::TableB>() const {
return c_as_TableB();
}
struct RootBuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_a(int32_t a) {
fbb_.AddElement<int32_t>(Root::VT_A, a, 0);
}
void add_b(bool b) {
fbb_.AddElement<uint8_t>(Root::VT_B, static_cast<uint8_t>(b), 0);
}
void add_c_type(Evolution::V1::Union c_type) {
fbb_.AddElement<uint8_t>(Root::VT_C_TYPE, static_cast<uint8_t>(c_type), 0);
}
void add_c(flatbuffers::Offset<void> c) {
fbb_.AddOffset(Root::VT_C, c);
}
void add_d(Evolution::V1::Enum d) {
fbb_.AddElement<int8_t>(Root::VT_D, static_cast<int8_t>(d), 0);
}
void add_e(flatbuffers::Offset<Evolution::V1::TableA> e) {
fbb_.AddOffset(Root::VT_E, e);
}
void add_f(const Evolution::V1::Struct *f) {
fbb_.AddStruct(Root::VT_F, f);
}
void add_g(flatbuffers::Offset<flatbuffers::Vector<int32_t>> g) {
fbb_.AddOffset(Root::VT_G, g);
}
void add_h(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>>> h) {
fbb_.AddOffset(Root::VT_H, h);
}
void add_i(int32_t i) {
fbb_.AddElement<int32_t>(Root::VT_I, i, 1234);
}
explicit RootBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
RootBuilder &operator=(const RootBuilder &);
flatbuffers::Offset<Root> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<Root>(end);
return o;
}
};
inline flatbuffers::Offset<Root> CreateRoot(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t a = 0,
bool b = false,
Evolution::V1::Union c_type = Evolution::V1::Union::NONE,
flatbuffers::Offset<void> c = 0,
Evolution::V1::Enum d = Evolution::V1::Enum::King,
flatbuffers::Offset<Evolution::V1::TableA> e = 0,
const Evolution::V1::Struct *f = 0,
flatbuffers::Offset<flatbuffers::Vector<int32_t>> g = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V1::TableB>>> h = 0,
int32_t i = 1234) {
RootBuilder builder_(_fbb);
builder_.add_i(i);
builder_.add_h(h);
builder_.add_g(g);
builder_.add_f(f);
builder_.add_e(e);
builder_.add_c(c);
builder_.add_a(a);
builder_.add_d(d);
builder_.add_c_type(c_type);
builder_.add_b(b);
return builder_.Finish();
}
inline flatbuffers::Offset<Root> CreateRootDirect(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t a = 0,
bool b = false,
Evolution::V1::Union c_type = Evolution::V1::Union::NONE,
flatbuffers::Offset<void> c = 0,
Evolution::V1::Enum d = Evolution::V1::Enum::King,
flatbuffers::Offset<Evolution::V1::TableA> e = 0,
const Evolution::V1::Struct *f = 0,
const std::vector<int32_t> *g = nullptr,
const std::vector<flatbuffers::Offset<Evolution::V1::TableB>> *h = nullptr,
int32_t i = 1234) {
auto g__ = g ? _fbb.CreateVector<int32_t>(*g) : 0;
auto h__ = h ? _fbb.CreateVector<flatbuffers::Offset<Evolution::V1::TableB>>(*h) : 0;
return Evolution::V1::CreateRoot(
_fbb,
a,
b,
c_type,
c,
d,
e,
f,
g__,
h__,
i);
}
inline bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type) {
switch (type) {
case Union::NONE: {
return true;
}
case Union::TableA: {
auto ptr = reinterpret_cast<const Evolution::V1::TableA *>(obj);
return verifier.VerifyTable(ptr);
}
case Union::TableB: {
auto ptr = reinterpret_cast<const Evolution::V1::TableB *>(obj);
return verifier.VerifyTable(ptr);
}
default: return true;
}
}
inline bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
if (!values || !types) return !values && !types;
if (values->size() != types->size()) return false;
for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifyUnion(
verifier, values->Get(i), types->GetEnum<Union>(i))) {
return false;
}
}
return true;
}
inline const Evolution::V1::Root *GetRoot(const void *buf) {
return flatbuffers::GetRoot<Evolution::V1::Root>(buf);
}
inline const Evolution::V1::Root *GetSizePrefixedRoot(const void *buf) {
return flatbuffers::GetSizePrefixedRoot<Evolution::V1::Root>(buf);
}
inline bool VerifyRootBuffer(
flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Evolution::V1::Root>(nullptr);
}
inline bool VerifySizePrefixedRootBuffer(
flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Evolution::V1::Root>(nullptr);
}
inline void FinishRootBuffer(
flatbuffers::FlatBufferBuilder &fbb,
flatbuffers::Offset<Evolution::V1::Root> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedRootBuffer(
flatbuffers::FlatBufferBuilder &fbb,
flatbuffers::Offset<Evolution::V1::Root> root) {
fbb.FinishSizePrefixed(root);
}
} // namespace V1
} // namespace Evolution
#endif // FLATBUFFERS_GENERATED_EVOLUTIONV1_EVOLUTION_V1_H_

View File

@@ -0,0 +1,50 @@
namespace Evolution.V2;
table TableA {
b:int (id: 1); // swapped with 'a'
a:float (id: 0); // swapped with 'b'
c:string (id: 2); // new in v2
}
table TableB {
a:int;
}
table TableC { // new in v2
a:double;
b:string;
}
enum Enum : byte {
King,
Queen,
Rook, // new in v2
Bishop // new in v2
}
union Union {
TableA,
TableB,
TableC
}
struct Struct {
a:int;
b:double;
}
table Root {
a:int (deprecated); // deprecated in v2
b:bool;
c:Union;
d:Enum;
e:TableA;
ff:Struct; // renamed from 'f' in v1
g:[int];
h:[TableB];
i:uint = 1234;
j:TableC; // new in v2
k:uint8 = 56; // new in v2
}
root_type Root;

View File

@@ -0,0 +1,34 @@
{
"b": false,
"c_type": "TableC",
"c": {
"a": 984.2494
},
"d": "Bishop",
"e": {
"a": 3.1452,
"b": 435,
"c": "yummy yummy fig bar bar"
},
"ff":{
"a": 35,
"b": 243.980943
},
"g": [ 7, 8, 10],
"h": [
{
"a": 212
},
{
"a": 459
},
{
"a": 333
}
],
"i": 4321,
"j": {
"a": 9874.342,
"b": "more please"
}
}

View File

@@ -0,0 +1,578 @@
// automatically generated by the FlatBuffers compiler, do not modify
#ifndef FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
#define FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_
#include "flatbuffers/flatbuffers.h"
namespace Evolution {
namespace V2 {
struct TableA;
struct TableB;
struct TableC;
struct Struct;
struct Root;
enum class Enum : int8_t {
King = 0,
Queen = 1,
Rook = 2,
Bishop = 3,
MIN = King,
MAX = Bishop
};
inline const Enum (&EnumValuesEnum())[4] {
static const Enum values[] = {
Enum::King,
Enum::Queen,
Enum::Rook,
Enum::Bishop
};
return values;
}
inline const char * const *EnumNamesEnum() {
static const char * const names[5] = {
"King",
"Queen",
"Rook",
"Bishop",
nullptr
};
return names;
}
inline const char *EnumNameEnum(Enum e) {
if (e < Enum::King || e > Enum::Bishop) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesEnum()[index];
}
enum class Union : uint8_t {
NONE = 0,
TableA = 1,
TableB = 2,
TableC = 3,
MIN = NONE,
MAX = TableC
};
inline const Union (&EnumValuesUnion())[4] {
static const Union values[] = {
Union::NONE,
Union::TableA,
Union::TableB,
Union::TableC
};
return values;
}
inline const char * const *EnumNamesUnion() {
static const char * const names[5] = {
"NONE",
"TableA",
"TableB",
"TableC",
nullptr
};
return names;
}
inline const char *EnumNameUnion(Union e) {
if (e < Union::NONE || e > Union::TableC) return "";
const size_t index = static_cast<size_t>(e);
return EnumNamesUnion()[index];
}
template<typename T> struct UnionTraits {
static const Union enum_value = Union::NONE;
};
template<> struct UnionTraits<Evolution::V2::TableA> {
static const Union enum_value = Union::TableA;
};
template<> struct UnionTraits<Evolution::V2::TableB> {
static const Union enum_value = Union::TableB;
};
template<> struct UnionTraits<Evolution::V2::TableC> {
static const Union enum_value = Union::TableC;
};
bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type);
bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types);
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Struct FLATBUFFERS_FINAL_CLASS {
private:
int32_t a_;
int32_t padding0__;
double b_;
public:
Struct() {
memset(static_cast<void *>(this), 0, sizeof(Struct));
}
Struct(int32_t _a, double _b)
: a_(flatbuffers::EndianScalar(_a)),
padding0__(0),
b_(flatbuffers::EndianScalar(_b)) {
(void)padding0__;
}
int32_t a() const {
return flatbuffers::EndianScalar(a_);
}
double b() const {
return flatbuffers::EndianScalar(b_);
}
};
FLATBUFFERS_STRUCT_END(Struct, 16);
struct TableA FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_A = 4,
VT_B = 6,
VT_C = 8
};
float a() const {
return GetField<float>(VT_A, 0.0f);
}
int32_t b() const {
return GetField<int32_t>(VT_B, 0);
}
const flatbuffers::String *c() const {
return GetPointer<const flatbuffers::String *>(VT_C);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<float>(verifier, VT_A) &&
VerifyField<int32_t>(verifier, VT_B) &&
VerifyOffset(verifier, VT_C) &&
verifier.VerifyString(c()) &&
verifier.EndTable();
}
};
struct TableABuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_a(float a) {
fbb_.AddElement<float>(TableA::VT_A, a, 0.0f);
}
void add_b(int32_t b) {
fbb_.AddElement<int32_t>(TableA::VT_B, b, 0);
}
void add_c(flatbuffers::Offset<flatbuffers::String> c) {
fbb_.AddOffset(TableA::VT_C, c);
}
explicit TableABuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
TableABuilder &operator=(const TableABuilder &);
flatbuffers::Offset<TableA> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<TableA>(end);
return o;
}
};
inline flatbuffers::Offset<TableA> CreateTableA(
flatbuffers::FlatBufferBuilder &_fbb,
float a = 0.0f,
int32_t b = 0,
flatbuffers::Offset<flatbuffers::String> c = 0) {
TableABuilder builder_(_fbb);
builder_.add_c(c);
builder_.add_b(b);
builder_.add_a(a);
return builder_.Finish();
}
inline flatbuffers::Offset<TableA> CreateTableADirect(
flatbuffers::FlatBufferBuilder &_fbb,
float a = 0.0f,
int32_t b = 0,
const char *c = nullptr) {
auto c__ = c ? _fbb.CreateString(c) : 0;
return Evolution::V2::CreateTableA(
_fbb,
a,
b,
c__);
}
struct TableB FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_A = 4
};
int32_t a() const {
return GetField<int32_t>(VT_A, 0);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<int32_t>(verifier, VT_A) &&
verifier.EndTable();
}
};
struct TableBBuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_a(int32_t a) {
fbb_.AddElement<int32_t>(TableB::VT_A, a, 0);
}
explicit TableBBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
TableBBuilder &operator=(const TableBBuilder &);
flatbuffers::Offset<TableB> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<TableB>(end);
return o;
}
};
inline flatbuffers::Offset<TableB> CreateTableB(
flatbuffers::FlatBufferBuilder &_fbb,
int32_t a = 0) {
TableBBuilder builder_(_fbb);
builder_.add_a(a);
return builder_.Finish();
}
struct TableC FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_A = 4,
VT_B = 6
};
double a() const {
return GetField<double>(VT_A, 0.0);
}
const flatbuffers::String *b() const {
return GetPointer<const flatbuffers::String *>(VT_B);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<double>(verifier, VT_A) &&
VerifyOffset(verifier, VT_B) &&
verifier.VerifyString(b()) &&
verifier.EndTable();
}
};
struct TableCBuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_a(double a) {
fbb_.AddElement<double>(TableC::VT_A, a, 0.0);
}
void add_b(flatbuffers::Offset<flatbuffers::String> b) {
fbb_.AddOffset(TableC::VT_B, b);
}
explicit TableCBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
TableCBuilder &operator=(const TableCBuilder &);
flatbuffers::Offset<TableC> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<TableC>(end);
return o;
}
};
inline flatbuffers::Offset<TableC> CreateTableC(
flatbuffers::FlatBufferBuilder &_fbb,
double a = 0.0,
flatbuffers::Offset<flatbuffers::String> b = 0) {
TableCBuilder builder_(_fbb);
builder_.add_a(a);
builder_.add_b(b);
return builder_.Finish();
}
inline flatbuffers::Offset<TableC> CreateTableCDirect(
flatbuffers::FlatBufferBuilder &_fbb,
double a = 0.0,
const char *b = nullptr) {
auto b__ = b ? _fbb.CreateString(b) : 0;
return Evolution::V2::CreateTableC(
_fbb,
a,
b__);
}
struct Root FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
VT_B = 6,
VT_C_TYPE = 8,
VT_C = 10,
VT_D = 12,
VT_E = 14,
VT_FF = 16,
VT_G = 18,
VT_H = 20,
VT_I = 22,
VT_J = 24,
VT_K = 26
};
bool b() const {
return GetField<uint8_t>(VT_B, 0) != 0;
}
Evolution::V2::Union c_type() const {
return static_cast<Evolution::V2::Union>(GetField<uint8_t>(VT_C_TYPE, 0));
}
const void *c() const {
return GetPointer<const void *>(VT_C);
}
template<typename T> const T *c_as() const;
const Evolution::V2::TableA *c_as_TableA() const {
return c_type() == Evolution::V2::Union::TableA ? static_cast<const Evolution::V2::TableA *>(c()) : nullptr;
}
const Evolution::V2::TableB *c_as_TableB() const {
return c_type() == Evolution::V2::Union::TableB ? static_cast<const Evolution::V2::TableB *>(c()) : nullptr;
}
const Evolution::V2::TableC *c_as_TableC() const {
return c_type() == Evolution::V2::Union::TableC ? static_cast<const Evolution::V2::TableC *>(c()) : nullptr;
}
Evolution::V2::Enum d() const {
return static_cast<Evolution::V2::Enum>(GetField<int8_t>(VT_D, 0));
}
const Evolution::V2::TableA *e() const {
return GetPointer<const Evolution::V2::TableA *>(VT_E);
}
const Evolution::V2::Struct *ff() const {
return GetStruct<const Evolution::V2::Struct *>(VT_FF);
}
const flatbuffers::Vector<int32_t> *g() const {
return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_G);
}
const flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>> *h() const {
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>> *>(VT_H);
}
uint32_t i() const {
return GetField<uint32_t>(VT_I, 1234);
}
const Evolution::V2::TableC *j() const {
return GetPointer<const Evolution::V2::TableC *>(VT_J);
}
uint8_t k() const {
return GetField<uint8_t>(VT_K, 56);
}
bool Verify(flatbuffers::Verifier &verifier) const {
return VerifyTableStart(verifier) &&
VerifyField<uint8_t>(verifier, VT_B) &&
VerifyField<uint8_t>(verifier, VT_C_TYPE) &&
VerifyOffset(verifier, VT_C) &&
VerifyUnion(verifier, c(), c_type()) &&
VerifyField<int8_t>(verifier, VT_D) &&
VerifyOffset(verifier, VT_E) &&
verifier.VerifyTable(e()) &&
VerifyField<Evolution::V2::Struct>(verifier, VT_FF) &&
VerifyOffset(verifier, VT_G) &&
verifier.VerifyVector(g()) &&
VerifyOffset(verifier, VT_H) &&
verifier.VerifyVector(h()) &&
verifier.VerifyVectorOfTables(h()) &&
VerifyField<uint32_t>(verifier, VT_I) &&
VerifyOffset(verifier, VT_J) &&
verifier.VerifyTable(j()) &&
VerifyField<uint8_t>(verifier, VT_K) &&
verifier.EndTable();
}
};
template<> inline const Evolution::V2::TableA *Root::c_as<Evolution::V2::TableA>() const {
return c_as_TableA();
}
template<> inline const Evolution::V2::TableB *Root::c_as<Evolution::V2::TableB>() const {
return c_as_TableB();
}
template<> inline const Evolution::V2::TableC *Root::c_as<Evolution::V2::TableC>() const {
return c_as_TableC();
}
struct RootBuilder {
flatbuffers::FlatBufferBuilder &fbb_;
flatbuffers::uoffset_t start_;
void add_b(bool b) {
fbb_.AddElement<uint8_t>(Root::VT_B, static_cast<uint8_t>(b), 0);
}
void add_c_type(Evolution::V2::Union c_type) {
fbb_.AddElement<uint8_t>(Root::VT_C_TYPE, static_cast<uint8_t>(c_type), 0);
}
void add_c(flatbuffers::Offset<void> c) {
fbb_.AddOffset(Root::VT_C, c);
}
void add_d(Evolution::V2::Enum d) {
fbb_.AddElement<int8_t>(Root::VT_D, static_cast<int8_t>(d), 0);
}
void add_e(flatbuffers::Offset<Evolution::V2::TableA> e) {
fbb_.AddOffset(Root::VT_E, e);
}
void add_ff(const Evolution::V2::Struct *ff) {
fbb_.AddStruct(Root::VT_FF, ff);
}
void add_g(flatbuffers::Offset<flatbuffers::Vector<int32_t>> g) {
fbb_.AddOffset(Root::VT_G, g);
}
void add_h(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>>> h) {
fbb_.AddOffset(Root::VT_H, h);
}
void add_i(uint32_t i) {
fbb_.AddElement<uint32_t>(Root::VT_I, i, 1234);
}
void add_j(flatbuffers::Offset<Evolution::V2::TableC> j) {
fbb_.AddOffset(Root::VT_J, j);
}
void add_k(uint8_t k) {
fbb_.AddElement<uint8_t>(Root::VT_K, k, 56);
}
explicit RootBuilder(flatbuffers::FlatBufferBuilder &_fbb)
: fbb_(_fbb) {
start_ = fbb_.StartTable();
}
RootBuilder &operator=(const RootBuilder &);
flatbuffers::Offset<Root> Finish() {
const auto end = fbb_.EndTable(start_);
auto o = flatbuffers::Offset<Root>(end);
return o;
}
};
inline flatbuffers::Offset<Root> CreateRoot(
flatbuffers::FlatBufferBuilder &_fbb,
bool b = false,
Evolution::V2::Union c_type = Evolution::V2::Union::NONE,
flatbuffers::Offset<void> c = 0,
Evolution::V2::Enum d = Evolution::V2::Enum::King,
flatbuffers::Offset<Evolution::V2::TableA> e = 0,
const Evolution::V2::Struct *ff = 0,
flatbuffers::Offset<flatbuffers::Vector<int32_t>> g = 0,
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Evolution::V2::TableB>>> h = 0,
uint32_t i = 1234,
flatbuffers::Offset<Evolution::V2::TableC> j = 0,
uint8_t k = 56) {
RootBuilder builder_(_fbb);
builder_.add_j(j);
builder_.add_i(i);
builder_.add_h(h);
builder_.add_g(g);
builder_.add_ff(ff);
builder_.add_e(e);
builder_.add_c(c);
builder_.add_k(k);
builder_.add_d(d);
builder_.add_c_type(c_type);
builder_.add_b(b);
return builder_.Finish();
}
inline flatbuffers::Offset<Root> CreateRootDirect(
flatbuffers::FlatBufferBuilder &_fbb,
bool b = false,
Evolution::V2::Union c_type = Evolution::V2::Union::NONE,
flatbuffers::Offset<void> c = 0,
Evolution::V2::Enum d = Evolution::V2::Enum::King,
flatbuffers::Offset<Evolution::V2::TableA> e = 0,
const Evolution::V2::Struct *ff = 0,
const std::vector<int32_t> *g = nullptr,
const std::vector<flatbuffers::Offset<Evolution::V2::TableB>> *h = nullptr,
uint32_t i = 1234,
flatbuffers::Offset<Evolution::V2::TableC> j = 0,
uint8_t k = 56) {
auto g__ = g ? _fbb.CreateVector<int32_t>(*g) : 0;
auto h__ = h ? _fbb.CreateVector<flatbuffers::Offset<Evolution::V2::TableB>>(*h) : 0;
return Evolution::V2::CreateRoot(
_fbb,
b,
c_type,
c,
d,
e,
ff,
g__,
h__,
i,
j,
k);
}
inline bool VerifyUnion(flatbuffers::Verifier &verifier, const void *obj, Union type) {
switch (type) {
case Union::NONE: {
return true;
}
case Union::TableA: {
auto ptr = reinterpret_cast<const Evolution::V2::TableA *>(obj);
return verifier.VerifyTable(ptr);
}
case Union::TableB: {
auto ptr = reinterpret_cast<const Evolution::V2::TableB *>(obj);
return verifier.VerifyTable(ptr);
}
case Union::TableC: {
auto ptr = reinterpret_cast<const Evolution::V2::TableC *>(obj);
return verifier.VerifyTable(ptr);
}
default: return true;
}
}
inline bool VerifyUnionVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector<flatbuffers::Offset<void>> *values, const flatbuffers::Vector<uint8_t> *types) {
if (!values || !types) return !values && !types;
if (values->size() != types->size()) return false;
for (flatbuffers::uoffset_t i = 0; i < values->size(); ++i) {
if (!VerifyUnion(
verifier, values->Get(i), types->GetEnum<Union>(i))) {
return false;
}
}
return true;
}
inline const Evolution::V2::Root *GetRoot(const void *buf) {
return flatbuffers::GetRoot<Evolution::V2::Root>(buf);
}
inline const Evolution::V2::Root *GetSizePrefixedRoot(const void *buf) {
return flatbuffers::GetSizePrefixedRoot<Evolution::V2::Root>(buf);
}
inline bool VerifyRootBuffer(
flatbuffers::Verifier &verifier) {
return verifier.VerifyBuffer<Evolution::V2::Root>(nullptr);
}
inline bool VerifySizePrefixedRootBuffer(
flatbuffers::Verifier &verifier) {
return verifier.VerifySizePrefixedBuffer<Evolution::V2::Root>(nullptr);
}
inline void FinishRootBuffer(
flatbuffers::FlatBufferBuilder &fbb,
flatbuffers::Offset<Evolution::V2::Root> root) {
fbb.Finish(root);
}
inline void FinishSizePrefixedRootBuffer(
flatbuffers::FlatBufferBuilder &fbb,
flatbuffers::Offset<Evolution::V2::Root> root) {
fbb.FinishSizePrefixed(root);
}
} // namespace V2
} // namespace Evolution
#endif // FLATBUFFERS_GENERATED_EVOLUTIONV2_EVOLUTION_V2_H_

View File

@@ -18,6 +18,7 @@ if "%1"=="-b" set buildtype=%2
..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL ..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json || goto FAIL
..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL ..\%buildtype%\flatc.exe --cpp --java --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs || goto FAIL
..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs || goto FAIL ..\%buildtype%\flatc.exe --cpp --java --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs || goto FAIL
..\%buildtype%\flatc.exe --cpp --scoped-enums -o evolution_test ./evolution_test/evolution_v1.fbs ./evolution_test/evolution_v2.fbs|| goto FAIL
..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL ..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs || goto FAIL
..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL ..\%buildtype%\flatc.exe -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs || goto FAIL
..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL ..\%buildtype%\flatc.exe --jsonschema --schema -I include_test monster_test.fbs || goto FAIL
@@ -26,7 +27,7 @@ if "%1"=="-b" set buildtype=%2
IF NOT "%MONSTER_EXTRA%"=="skip" ( IF NOT "%MONSTER_EXTRA%"=="skip" (
@echo Generate MosterExtra @echo Generate MosterExtra
..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs monsterdata_extra.json || goto FAIL ..\%buildtype%\flatc.exe --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr monster_extra.fbs monsterdata_extra.json || goto FAIL
) else ( ) else (
@echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments) @echo monster_extra.fbs skipped (the strtod function from MSVC2013 or older doesn't support NaN/Inf arguments)
) )

View File

@@ -18,10 +18,11 @@ set -e
../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json ../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --grpc --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr --no-fb-import -I include_test monster_test.fbs monsterdata_test.json
../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs ../flatc --cpp --java --kotlin --csharp --dart --go --binary --lobster --lua --python --js --ts --php --rust --gen-mutable --reflect-names --no-fb-import --cpp-ptr-type flatbuffers::unique_ptr -o namespace_test namespace_test/namespace_test1.fbs namespace_test/namespace_test2.fbs
../flatc --cpp --java --kotlin --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs ../flatc --cpp --java --kotlin --csharp --js --ts --php --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr -o union_vector ./union_vector/union_vector.fbs
../flatc --cpp --scoped-enums -o evolution_test ./evolution_test/evolution_v*.fbs
../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs ../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test monster_test.fbs
../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs ../flatc -b --schema --bfbs-comments --bfbs-builtins -I include_test arrays_test.fbs
../flatc --jsonschema --schema -I include_test monster_test.fbs ../flatc --jsonschema --schema -I include_test monster_test.fbs
../flatc --cpp --java --kotlin --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes monster_extra.fbs monsterdata_extra.json ../flatc --cpp --java --kotlin --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --cpp-ptr-type flatbuffers::unique_ptr monster_extra.fbs monsterdata_extra.json
../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs ../flatc --cpp --java --csharp --python --gen-mutable --reflect-names --gen-object-api --gen-compare --no-includes --scoped-enums --jsonschema --cpp-ptr-type flatbuffers::unique_ptr arrays_test.fbs
cd ../samples cd ../samples
../flatc --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs ../flatc --cpp --lobster --gen-mutable --reflect-names --gen-object-api --gen-compare --cpp-ptr-type flatbuffers::unique_ptr monster.fbs

View File

@@ -90,6 +90,7 @@ func TestAll(t *testing.T) {
// generated Go code: // generated Go code:
CheckReadBuffer(generated, off, t.Fatalf) CheckReadBuffer(generated, off, t.Fatalf)
CheckMutateBuffer(generated, off, t.Fatalf) CheckMutateBuffer(generated, off, t.Fatalf)
CheckObjectAPI(generated, off, t.Fatalf)
// Verify that the buffer generated by C++ code is readable by the // Verify that the buffer generated by C++ code is readable by the
// generated Go code: // generated Go code:
@@ -99,6 +100,7 @@ func TestAll(t *testing.T) {
} }
CheckReadBuffer(monsterDataCpp, 0, t.Fatalf) CheckReadBuffer(monsterDataCpp, 0, t.Fatalf)
CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf) CheckMutateBuffer(monsterDataCpp, 0, t.Fatalf)
CheckObjectAPI(monsterDataCpp, 0, t.Fatalf)
// Verify that vtables are deduplicated when written: // Verify that vtables are deduplicated when written:
CheckVtableDeduplication(t.Fatalf) CheckVtableDeduplication(t.Fatalf)
@@ -448,6 +450,26 @@ func CheckMutateBuffer(org []byte, offset flatbuffers.UOffsetT, fail func(string
} }
} }
func CheckObjectAPI(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
monster := example.GetRootAsMonster(buf, offset).UnPack()
if got := monster.Hp; 80 != got {
fail(FailString("hp", 80, got))
}
// default
if got := monster.Mana; 150 != got {
fail(FailString("mana", 150, got))
}
builder := flatbuffers.NewBuilder(0)
builder.Finish(example.MonsterPack(builder, monster))
monster2 := example.GetRootAsMonster(builder.FinishedBytes(), 0).UnPack()
if !reflect.DeepEqual(monster, monster2) {
fail(FailString("Pack/Unpack()", monster, monster2))
}
}
// Low level stress/fuzz test: serialize/deserialize a variety of // Low level stress/fuzz test: serialize/deserialize a variety of
// different kinds of data in different combinations // different kinds of data in different combinations
func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) { func checkFuzz(fuzzFields, fuzzObjects int, fail func(string, ...interface{})) {

View File

@@ -81,8 +81,9 @@ local function checkReadBuffer(buf, offset, sizePrefix)
assert(mon:Testempty() == nil) assert(mon:Testempty() == nil)
end end
local function generateMonster(sizePrefix) local function generateMonster(sizePrefix, b)
local b = flatbuffers.Builder(0) if b then b:Clear() end
b = b or flatbuffers.Builder(0)
local str = b:CreateString("MyMonster") local str = b:CreateString("MyMonster")
local test1 = b:CreateString("test1") local test1 = b:CreateString("test1")
local test2 = b:CreateString("test2") local test2 = b:CreateString("test2")
@@ -156,6 +157,51 @@ local function sizePrefix(sizePrefix)
checkReadBuffer(buf, offset, sizePrefix) checkReadBuffer(buf, offset, sizePrefix)
end end
local function fbbClear()
-- Generate a builder that will be 'cleared' and reused to create two different objects.
local fbb = flatbuffers.Builder(0)
-- First use the builder to read the normal monster data and verify it works
local buf, offset = generateMonster(false, fbb)
checkReadBuffer(buf, offset, false)
-- Then clear the builder to be used again
fbb:Clear()
-- Storage for the built monsters
local monsters = {}
local lastBuf
-- Make another builder that will be use identically to the 'cleared' one so outputs can be compared. Build both the
-- Cleared builder and new builder in the exact same way, so we can compare their results
for i, builder in ipairs({fbb, flatbuffers.Builder(0)}) do
local strOffset = builder:CreateString("Hi there")
monster.Start(builder)
monster.AddPos(builder, vec3.CreateVec3(builder, 3.0, 2.0, 1.0, 17.0, 3, 100, 123))
monster.AddName(builder, strOffset)
monster.AddMana(builder, 123)
builder:Finish(monster.End(builder))
local buf = builder:Output(false)
if not lastBuf then
lastBuf = buf
else
-- the output, sized-buffer should be identical
assert(lastBuf == buf, "Monster output buffers are not identical")
end
monsters[i] = monster.GetRootAsMonster(flatbuffers.binaryArray.New(buf), 0)
end
-- Check that all the fields for the generated monsters are as we expect
for i, monster in ipairs(monsters) do
assert(monster:Name() == "Hi there", "Monster Name is not 'Hi There' for monster "..i)
-- HP is default to 100 in the schema, but we change it in generateMonster to 80, so this is a good test to
-- see if the cleared builder really clears the data.
assert(monster:Hp() == 100, "HP doesn't equal the default value for monster "..i)
assert(monster:Mana() == 123, "Monster Mana is not '123' for monster "..i)
assert(monster:Pos():X() == 3.0, "Monster vec3.X is not '3' for monster "..i)
end
end
local function testCanonicalData() local function testCanonicalData()
local f = assert(io.open('monsterdata_test.mon', 'rb')) local f = assert(io.open('monsterdata_test.mon', 'rb'))
local wireData = f:read("*a") local wireData = f:read("*a")
@@ -163,26 +209,16 @@ local function testCanonicalData()
checkReadBuffer(wireData) checkReadBuffer(wireData)
end end
local function benchmarkMakeMonster(count) local function benchmarkMakeMonster(count, reuseBuilder)
local length = #(generateMonster()) local fbb = reuseBuilder and flatbuffers.Builder(0)
local length = #(generateMonster(false, fbb))
--require("flatbuffers.profiler")
--profiler = newProfiler("call")
--profiler:start()
local s = os.clock() local s = os.clock()
for i=1,count do for i=1,count do
generateMonster() generateMonster(false, fbb)
end end
local e = os.clock() local e = os.clock()
--profiler:stop()
--local outfile = io.open( "profile.txt", "w+" )
--profiler:report( outfile, true)
--outfile:close()
local dur = (e - s) local dur = (e - s)
local rate = count / (dur * 1000) local rate = count / (dur * 1000)
local data = (length * count) / (1024 * 1024) local data = (length * count) / (1024 * 1024)
@@ -219,6 +255,10 @@ local tests =
d = "Test size prefix", d = "Test size prefix",
args = {{true}, {false}} args = {{true}, {false}}
}, },
{
f = fbbClear,
d = "FlatBufferBuilder Clear",
},
{ {
f = testCanonicalData, f = testCanonicalData,
d = "Tests Canonical flatbuffer file included in repo" d = "Tests Canonical flatbuffer file included in repo"
@@ -230,6 +270,7 @@ local tests =
{100}, {100},
{1000}, {1000},
{10000}, {10000},
{10000, true}
} }
}, },
{ {
@@ -241,7 +282,7 @@ local tests =
{10000}, {10000},
-- uncomment following to run 1 million to compare. -- uncomment following to run 1 million to compare.
-- Took ~141 seconds on my machine -- Took ~141 seconds on my machine
--{1000000}, --{1000000},
} }
}, },
} }

View File

@@ -389,16 +389,16 @@ inline void FinishSizePrefixedMonsterExtraBuffer(
fbb.FinishSizePrefixed(root, MonsterExtraIdentifier()); fbb.FinishSizePrefixed(root, MonsterExtraIdentifier());
} }
inline std::unique_ptr<MyGame::MonsterExtraT> UnPackMonsterExtra( inline flatbuffers::unique_ptr<MyGame::MonsterExtraT> UnPackMonsterExtra(
const void *buf, const void *buf,
const flatbuffers::resolver_function_t *res = nullptr) { const flatbuffers::resolver_function_t *res = nullptr) {
return std::unique_ptr<MyGame::MonsterExtraT>(GetMonsterExtra(buf)->UnPack(res)); return flatbuffers::unique_ptr<MyGame::MonsterExtraT>(GetMonsterExtra(buf)->UnPack(res));
} }
inline std::unique_ptr<MyGame::MonsterExtraT> UnPackSizePrefixedMonsterExtra( inline flatbuffers::unique_ptr<MyGame::MonsterExtraT> UnPackSizePrefixedMonsterExtra(
const void *buf, const void *buf,
const flatbuffers::resolver_function_t *res = nullptr) { const flatbuffers::resolver_function_t *res = nullptr) {
return std::unique_ptr<MyGame::MonsterExtraT>(GetSizePrefixedMonsterExtra(buf)->UnPack(res)); return flatbuffers::unique_ptr<MyGame::MonsterExtraT>(GetSizePrefixedMonsterExtra(buf)->UnPack(res));
} }
} // namespace MyGame } // namespace MyGame

View File

@@ -1353,9 +1353,6 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
MyGame::Example::Any test_type() const { MyGame::Example::Any test_type() const {
return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0)); return static_cast<MyGame::Example::Any>(GetField<uint8_t>(VT_TEST_TYPE, 0));
} }
bool mutate_test_type(MyGame::Example::Any _test_type) {
return SetField<uint8_t>(VT_TEST_TYPE, static_cast<uint8_t>(_test_type), 0);
}
const void *test() const { const void *test() const {
return GetPointer<const void *>(VT_TEST); return GetPointer<const void *>(VT_TEST);
} }
@@ -1587,9 +1584,6 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
MyGame::Example::AnyUniqueAliases any_unique_type() const { MyGame::Example::AnyUniqueAliases any_unique_type() const {
return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0)); return static_cast<MyGame::Example::AnyUniqueAliases>(GetField<uint8_t>(VT_ANY_UNIQUE_TYPE, 0));
} }
bool mutate_any_unique_type(MyGame::Example::AnyUniqueAliases _any_unique_type) {
return SetField<uint8_t>(VT_ANY_UNIQUE_TYPE, static_cast<uint8_t>(_any_unique_type), 0);
}
const void *any_unique() const { const void *any_unique() const {
return GetPointer<const void *>(VT_ANY_UNIQUE); return GetPointer<const void *>(VT_ANY_UNIQUE);
} }
@@ -1609,9 +1603,6 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const { MyGame::Example::AnyAmbiguousAliases any_ambiguous_type() const {
return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0)); return static_cast<MyGame::Example::AnyAmbiguousAliases>(GetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, 0));
} }
bool mutate_any_ambiguous_type(MyGame::Example::AnyAmbiguousAliases _any_ambiguous_type) {
return SetField<uint8_t>(VT_ANY_AMBIGUOUS_TYPE, static_cast<uint8_t>(_any_ambiguous_type), 0);
}
const void *any_ambiguous() const { const void *any_ambiguous() const {
return GetPointer<const void *>(VT_ANY_AMBIGUOUS); return GetPointer<const void *>(VT_ANY_AMBIGUOUS);
} }

View File

@@ -1153,21 +1153,6 @@ MyGame.Example.Monster.prototype.testType = function() {
return offset ? /** @type {MyGame.Example.Any} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE; return offset ? /** @type {MyGame.Example.Any} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
}; };
/**
* @param {MyGame.Example.Any} value
* @returns {boolean}
*/
MyGame.Example.Monster.prototype.mutate_test_type = function(value) {
var offset = this.bb.__offset(this.bb_pos, 18);
if (offset === 0) {
return false;
}
this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
/** /**
* @param {flatbuffers.Table} obj * @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table} * @returns {?flatbuffers.Table}
@@ -1872,21 +1857,6 @@ MyGame.Example.Monster.prototype.anyUniqueType = function() {
return offset ? /** @type {MyGame.Example.AnyUniqueAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE; return offset ? /** @type {MyGame.Example.AnyUniqueAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
}; };
/**
* @param {MyGame.Example.AnyUniqueAliases} value
* @returns {boolean}
*/
MyGame.Example.Monster.prototype.mutate_any_unique_type = function(value) {
var offset = this.bb.__offset(this.bb_pos, 90);
if (offset === 0) {
return false;
}
this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
/** /**
* @param {flatbuffers.Table} obj * @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table} * @returns {?flatbuffers.Table}
@@ -1904,21 +1874,6 @@ MyGame.Example.Monster.prototype.anyAmbiguousType = function() {
return offset ? /** @type {MyGame.Example.AnyAmbiguousAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE; return offset ? /** @type {MyGame.Example.AnyAmbiguousAliases} */ (this.bb.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
}; };
/**
* @param {MyGame.Example.AnyAmbiguousAliases} value
* @returns {boolean}
*/
MyGame.Example.Monster.prototype.mutate_any_ambiguous_type = function(value) {
var offset = this.bb.__offset(this.bb_pos, 94);
if (offset === 0) {
return false;
}
this.bb.writeUint8(this.bb_pos + offset, value);
return true;
};
/** /**
* @param {flatbuffers.Table} obj * @param {flatbuffers.Table} obj
* @returns {?flatbuffers.Table} * @returns {?flatbuffers.Table}

View File

@@ -1001,21 +1001,6 @@ testType():MyGame.Example.Any {
return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE; return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.Any.NONE;
}; };
/**
* @param MyGame.Example.Any value
* @returns boolean
*/
mutate_test_type(value:MyGame.Example.Any):boolean {
var offset = this.bb!.__offset(this.bb_pos, 18);
if (offset === 0) {
return false;
}
this.bb!.writeUint8(this.bb_pos + offset, value);
return true;
};
/** /**
* @param flatbuffers.Table obj * @param flatbuffers.Table obj
* @returns ?flatbuffers.Table * @returns ?flatbuffers.Table
@@ -1724,21 +1709,6 @@ anyUniqueType():MyGame.Example.AnyUniqueAliases {
return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE; return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyUniqueAliases.NONE;
}; };
/**
* @param MyGame.Example.AnyUniqueAliases value
* @returns boolean
*/
mutate_any_unique_type(value:MyGame.Example.AnyUniqueAliases):boolean {
var offset = this.bb!.__offset(this.bb_pos, 90);
if (offset === 0) {
return false;
}
this.bb!.writeUint8(this.bb_pos + offset, value);
return true;
};
/** /**
* @param flatbuffers.Table obj * @param flatbuffers.Table obj
* @returns ?flatbuffers.Table * @returns ?flatbuffers.Table
@@ -1756,21 +1726,6 @@ anyAmbiguousType():MyGame.Example.AnyAmbiguousAliases {
return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE; return offset ? /** */ (this.bb!.readUint8(this.bb_pos + offset)) : MyGame.Example.AnyAmbiguousAliases.NONE;
}; };
/**
* @param MyGame.Example.AnyAmbiguousAliases value
* @returns boolean
*/
mutate_any_ambiguous_type(value:MyGame.Example.AnyAmbiguousAliases):boolean {
var offset = this.bb!.__offset(this.bb_pos, 94);
if (offset === 0) {
return false;
}
this.bb!.writeUint8(this.bb_pos + offset, value);
return true;
};
/** /**
* @param flatbuffers.Table obj * @param flatbuffers.Table obj
* @returns ?flatbuffers.Table * @returns ?flatbuffers.Table

View File

@@ -1,13 +1,13 @@
#include "native_type_test_impl.h" #include "native_type_test_impl.h"
#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) {
return Native::Vector3D(obj.x(), obj.y(), obj.z());
}
} }
const Native::Vector3D UnPack(const Geometry::Vector3D &obj) {
return Native::Vector3D(obj.x(), obj.y(), obj.z());
}
} // namespace flatbuffers

View File

@@ -2,23 +2,31 @@
#define NATIVE_TYPE_TEST_IMPL_H #define NATIVE_TYPE_TEST_IMPL_H
namespace Native { namespace Native {
struct Vector3D { struct Vector3D {
float x; float x;
float y; float y;
float z; float z;
Vector3D() { x = 0; y = 0; z = 0; }; Vector3D() {
Vector3D(float _x, float _y, float _z) { this->x = _x; this->y = _y; this->z = _z; } x = 0;
y = 0;
z = 0;
}; };
} Vector3D(float _x, float _y, float _z) {
this->x = _x;
this->y = _y;
this->z = _z;
}
};
} // namespace Native
namespace Geometry { namespace Geometry {
struct Vector3D; struct Vector3D;
} }
namespace flatbuffers { namespace flatbuffers {
Geometry::Vector3D Pack(const Native::Vector3D &obj); Geometry::Vector3D Pack(const Native::Vector3D &obj);
const Native::Vector3D UnPack(const Geometry::Vector3D &obj); const Native::Vector3D UnPack(const Geometry::Vector3D &obj);
} } // namespace flatbuffers
#endif // VECTOR3D_PACK_H #endif // VECTOR3D_PACK_H

View File

@@ -14,6 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include <cmath> #include <cmath>
#include "flatbuffers/flatbuffers.h" #include "flatbuffers/flatbuffers.h"
#include "flatbuffers/idl.h" #include "flatbuffers/idl.h"
#include "flatbuffers/minireflect.h" #include "flatbuffers/minireflect.h"
@@ -35,7 +36,9 @@
#include "union_vector/union_vector_generated.h" #include "union_vector/union_vector_generated.h"
#include "monster_extra_generated.h" #include "monster_extra_generated.h"
#if !defined(_MSC_VER) || _MSC_VER >= 1700 #if !defined(_MSC_VER) || _MSC_VER >= 1700
#include "arrays_test_generated.h" # include "arrays_test_generated.h"
# include "evolution_test/evolution_v1_generated.h"
# include "evolution_test/evolution_v2_generated.h"
#endif #endif
#include "native_type_test_generated.h" #include "native_type_test_generated.h"
@@ -43,7 +46,6 @@
#include "flatbuffers/flexbuffers.h" #include "flatbuffers/flexbuffers.h"
// clang-format off // clang-format off
// Check that char* and uint8_t* are interoperable types. // Check that char* and uint8_t* are interoperable types.
// The reinterpret_cast<> between the pointers are used to simplify data loading. // The reinterpret_cast<> between the pointers are used to simplify data loading.
@@ -72,7 +74,8 @@ void FlatBufferBuilderTest();
// http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator // http://en.wikipedia.org/wiki/Park%E2%80%93Miller_random_number_generator
uint32_t lcg_seed = 48271; uint32_t lcg_seed = 48271;
uint32_t lcg_rand() { uint32_t lcg_rand() {
return lcg_seed = (static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL; return lcg_seed =
(static_cast<uint64_t>(lcg_seed) * 279470273UL) % 4294967291UL;
} }
void lcg_reset() { lcg_seed = 48271; } void lcg_reset() { lcg_seed = 48271; }
@@ -200,14 +203,13 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2); auto vecofcolors = builder.CreateVectorScalarCast<uint8_t, Color>(colors, 2);
// shortcut for creating monster with all fields set: // shortcut for creating monster with all fields set:
auto mloc = CreateMonster(builder, &vec, 150, 80, name, inventory, Color_Blue, auto mloc = CreateMonster(
Any_Monster, mlocs[1].Union(), // Store a union. builder, &vec, 150, 80, name, inventory, Color_Blue, Any_Monster,
testv, vecofstrings, vecoftables, 0, mlocs[1].Union(), // Store a union.
nested_flatbuffer_vector, 0, false, 0, 0, 0, 0, 0, testv, vecofstrings, vecoftables, 0, nested_flatbuffer_vector, 0, false,
0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3.14159f, 3.0f, 0.0f, vecofstrings2,
vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, vecofstructs, flex, testv2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, AnyUniqueAliases_NONE, 0, AnyUniqueAliases_NONE, 0, AnyAmbiguousAliases_NONE, 0, vecofcolors);
AnyAmbiguousAliases_NONE, 0, vecofcolors);
FinishMonsterBuffer(builder, mloc); FinishMonsterBuffer(builder, mloc);
@@ -567,8 +569,7 @@ void SizePrefixedTest() {
// Create size prefixed buffer. // Create size prefixed buffer.
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
FinishSizePrefixedMonsterBuffer( FinishSizePrefixedMonsterBuffer(
fbb, fbb, CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
CreateMonster(fbb, 0, 200, 300, fbb.CreateString("bob")));
// Verify it. // Verify it.
flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize()); flatbuffers::Verifier verifier(fbb.GetBufferPointer(), fbb.GetSize());
@@ -598,7 +599,8 @@ void JsonDefaultTest() {
// load FlatBuffer schema (.fbs) from disk // load FlatBuffer schema (.fbs) from disk
std::string schemafile; std::string schemafile;
TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(), TEST_EQ(flatbuffers::LoadFile((test_data_path + "monster_test.fbs").c_str(),
false, &schemafile), true); false, &schemafile),
true);
// 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;
auto include_test_path = auto include_test_path =
@@ -771,7 +773,7 @@ void ParseAndGenerateTextTest(bool binary) {
true); true);
auto include_test_path = auto include_test_path =
flatbuffers::ConCatPathFileName(test_data_path, "include_test"); flatbuffers::ConCatPathFileName(test_data_path, "include_test");
const char *include_directories[] = { test_data_path.c_str(), const char *include_directories[] = { test_data_path.c_str(),
include_test_path.c_str(), nullptr }; include_test_path.c_str(), nullptr };
@@ -782,8 +784,10 @@ void ParseAndGenerateTextTest(bool binary) {
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((const uint8_t *)schemafile.c_str(), schemafile.size()), true); TEST_EQ(parser.Deserialize((const uint8_t *)schemafile.c_str(),
schemafile.size()),
true);
} else { } else {
TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true); TEST_EQ(parser.Parse(schemafile.c_str(), include_directories), true);
} }
@@ -1029,7 +1033,8 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
} }
void MiniReflectFlatBuffersTest(uint8_t *flatbuf) { void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
auto s = flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable()); auto s =
flatbuffers::FlatBufferToString(flatbuf, Monster::MiniReflectTypeTable());
TEST_EQ_STR( TEST_EQ_STR(
s.c_str(), s.c_str(),
"{ " "{ "
@@ -1060,15 +1065,15 @@ void MiniReflectFlatBuffersTest(uint8_t *flatbuf) {
"}"); "}");
Test test(16, 32); Test test(16, 32);
Vec3 vec(1,2,3, 1.5, Color_Red, test); Vec3 vec(1, 2, 3, 1.5, Color_Red, test);
flatbuffers::FlatBufferBuilder vec_builder; flatbuffers::FlatBufferBuilder vec_builder;
vec_builder.Finish(vec_builder.CreateStruct(vec)); vec_builder.Finish(vec_builder.CreateStruct(vec));
auto vec_buffer = vec_builder.Release(); auto vec_buffer = vec_builder.Release();
auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(), auto vec_str = flatbuffers::FlatBufferToString(vec_buffer.data(),
Vec3::MiniReflectTypeTable()); Vec3::MiniReflectTypeTable());
TEST_EQ_STR( TEST_EQ_STR(vec_str.c_str(),
vec_str.c_str(), "{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: "
"{ x: 1.0, y: 2.0, z: 3.0, test1: 1.5, test2: Red, test3: { a: 16, b: 32 } }"); "16, b: 32 } }");
} }
// Parse a .proto schema, output as .fbs // Parse a .proto schema, output as .fbs
@@ -1085,11 +1090,10 @@ void ParseProtoTest() {
flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(), flatbuffers::LoadFile((test_data_path + "prototest/test.golden").c_str(),
false, &goldenfile), false, &goldenfile),
true); true);
TEST_EQ( TEST_EQ(flatbuffers::LoadFile(
flatbuffers::LoadFile((test_data_path + (test_data_path + "prototest/test_union.golden").c_str(), false,
"prototest/test_union.golden").c_str(), &goldenunionfile),
false, &goldenunionfile), true);
true);
flatbuffers::IDLOptions opts; flatbuffers::IDLOptions opts;
opts.include_dependence_headers = false; opts.include_dependence_headers = false;
@@ -1390,7 +1394,7 @@ void FuzzTest2() {
break; break;
} }
} }
TEST_NOTNULL(NULL); TEST_NOTNULL(nullptr);
} }
// clang-format off // clang-format off
@@ -1526,9 +1530,9 @@ bool FloatCompare(float a, float b) { return fabs(a - b) < 0.001; }
// Additional parser testing not covered elsewhere. // Additional parser testing not covered elsewhere.
void ValueTest() { void ValueTest() {
// Test scientific notation numbers. // Test scientific notation numbers.
TEST_EQ(FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), TEST_EQ(
3.14159f), FloatCompare(TestValue<float>("{ Y:0.0314159e+2 }", "float"), 3.14159f),
true); true);
// number in string // number in string
TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"), TEST_EQ(FloatCompare(TestValue<float>("{ Y:\"0.0314159e+2\" }", "float"),
3.14159f), 3.14159f),
@@ -1566,7 +1570,6 @@ void ValueTest() {
// check comments before and after json object // check comments before and after json object
TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1); TEST_EQ(TestValue<int>("/*before*/ { Y:1 } /*after*/", "int"), 1);
TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1); TEST_EQ(TestValue<int>("//before \n { Y:1 } //after", "int"), 1);
} }
void NestedListTest() { void NestedListTest() {
@@ -1608,8 +1611,8 @@ void EnumNamesTest() {
// For details see C++17 standard or explanation on the SO: // For details see C++17 standard or explanation on the SO:
// stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class // stackoverflow.com/questions/18195312/what-happens-if-you-static-cast-invalid-value-to-enum-class
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0))); TEST_EQ_STR("", EnumNameColor(static_cast<Color>(0)));
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY-1))); TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY - 1)));
TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY+1))); TEST_EQ_STR("", EnumNameColor(static_cast<Color>(Color_ANY + 1)));
} }
void EnumOutOfRangeTest() { void EnumOutOfRangeTest() {
@@ -1629,12 +1632,14 @@ void EnumOutOfRangeTest() {
TestError("enum X:uint { Y = -1 }", "enum value does not fit"); TestError("enum X:uint { Y = -1 }", "enum value does not fit");
TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit"); TestError("enum X:uint { Y = 4294967297 }", "enum value does not fit");
TestError("enum X:long { Y = 9223372036854775808 }", "does not fit"); TestError("enum X:long { Y = 9223372036854775808 }", "does not fit");
TestError("enum X:long { Y = 9223372036854775807, Z }", "enum value does not fit"); TestError("enum X:long { Y = 9223372036854775807, Z }",
"enum value does not fit");
TestError("enum X:ulong { Y = -1 }", "does not fit"); TestError("enum X:ulong { Y = -1 }", "does not fit");
TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out"); TestError("enum X:ubyte (bit_flags) { Y=8 }", "bit flag out");
TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128 TestError("enum X:byte (bit_flags) { Y=7 }", "must be unsigned"); // -128
// bit_flgs out of range // bit_flgs out of range
TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }", "out of range"); TestError("enum X:ubyte (bit_flags) { Y0,Y1,Y2,Y3,Y4,Y5,Y6,Y7,Y8 }",
"out of range");
} }
void EnumValueTest() { void EnumValueTest() {
@@ -1734,11 +1739,12 @@ void IntegerOutOfRangeTest() {
void IntegerBoundaryTest() { void IntegerBoundaryTest() {
// Check numerical compatibility with non-C++ languages. // Check numerical compatibility with non-C++ languages.
// By the C++ standard, std::numerical_limits<int64_t>::min() == -9223372036854775807 (-2^63+1) or less* // By the C++ standard, std::numerical_limits<int64_t>::min() ==
// The Flatbuffers grammar and most of the languages (C#, Java, Rust) expect // -9223372036854775807 (-2^63+1) or less* The Flatbuffers grammar and most of
// that minimum values are: -128, -32768,.., -9223372036854775808. // the languages (C#, Java, Rust) expect that minimum values are: -128,
// Since C++20, static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement cast. // -32768,.., -9223372036854775808. Since C++20,
// Therefore -9223372036854775808 should be valid negative value. // static_cast<int64>(0x8000000000000000ULL) is well-defined two's complement
// cast. Therefore -9223372036854775808 should be valid negative value.
TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128); TEST_EQ(flatbuffers::numeric_limits<int8_t>::min(), -128);
TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127); TEST_EQ(flatbuffers::numeric_limits<int8_t>::max(), 127);
TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768); TEST_EQ(flatbuffers::numeric_limits<int16_t>::min(), -32768);
@@ -1810,11 +1816,11 @@ void ValidFloatTest() {
TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f); TEST_EQ(TestValue<float>("{ Y:5 }", "float"), 5.0f);
TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f); TEST_EQ(TestValue<float>("{ Y:\"5\" }", "float"), 5.0f);
#if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0) #if defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
// Old MSVC versions may have problem with this check. // Old MSVC versions may have problem with this check.
// https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/ // https://www.exploringbinary.com/visual-c-plus-plus-strtod-still-broken/
TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"), TEST_EQ(TestValue<double>("{ Y:6.9294956446009195e15 }", "double"),
6929495644600920.0); 6929495644600920.0);
// check nan's // check nan's
TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true); TEST_EQ(std::isnan(TestValue<double>("{ Y:nan }", "double")), true);
TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true); TEST_EQ(std::isnan(TestValue<float>("{ Y:nan }", "float")), true);
@@ -1936,8 +1942,8 @@ void GenerateTableTextTest() {
TEST_EQ(ok, true); TEST_EQ(ok, true);
auto include_test_path = auto include_test_path =
flatbuffers::ConCatPathFileName(test_data_path, "include_test"); flatbuffers::ConCatPathFileName(test_data_path, "include_test");
const char *include_directories[] = {test_data_path.c_str(), const char *include_directories[] = { test_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);
@@ -2237,7 +2243,7 @@ void InvalidUTF8Test() {
// Check independence of identifier from locale. // Check independence of identifier from locale.
std::string locale_ident; std::string locale_ident;
locale_ident += "table T { F"; locale_ident += "table T { F";
locale_ident += static_cast<char>(-32); // unsigned 0xE0 locale_ident += static_cast<char>(-32); // unsigned 0xE0
locale_ident += " :string; }"; locale_ident += " :string; }";
locale_ident += "root_type T;"; locale_ident += "root_type T;";
locale_ident += "{}"; locale_ident += "{}";
@@ -2304,15 +2310,82 @@ void InvalidNestedFlatbufferTest() {
TEST_EQ(parser1.Parse("{ name: \"Bender\", testnestedflatbuffer: { name: " TEST_EQ(parser1.Parse("{ name: \"Bender\", testnestedflatbuffer: { name: "
"\"Leela\", color: \"nonexistent\"}}"), "\"Leela\", color: \"nonexistent\"}}"),
false); false);
// Check that Parser is destroyed correctly after parsing invalid json }
void EvolutionTest() {
// VS10 does not support typed enums, exclude from tests
#if !defined(_MSC_VER) || _MSC_VER >= 1700
const int NUM_VERSIONS = 2;
std::string schemas[NUM_VERSIONS];
std::string jsonfiles[NUM_VERSIONS];
std::vector<uint8_t> binaries[NUM_VERSIONS];
flatbuffers::IDLOptions idl_opts;
idl_opts.lang_to_generate |= flatbuffers::IDLOptions::kBinary;
flatbuffers::Parser parser(idl_opts);
// Load all the schema versions and their associated data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
std::string schema = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".fbs";
TEST_ASSERT(flatbuffers::LoadFile(schema.c_str(), false, &schemas[i]));
std::string json = test_data_path + "evolution_test/evolution_v" +
flatbuffers::NumToString(i + 1) + ".json";
TEST_ASSERT(flatbuffers::LoadFile(json.c_str(), false, &jsonfiles[i]));
TEST_ASSERT(parser.Parse(schemas[i].c_str()));
TEST_ASSERT(parser.Parse(jsonfiles[i].c_str()));
auto bufLen = parser.builder_.GetSize();
auto buf = parser.builder_.GetBufferPointer();
binaries[i].reserve(bufLen);
std::copy(buf, buf + bufLen, std::back_inserter(binaries[i]));
}
// Assert that all the verifiers for the different schema versions properly verify any version data.
for (int i = 0; i < NUM_VERSIONS; ++i) {
flatbuffers::Verifier verifier(&binaries[i].front(), binaries[i].size());
TEST_ASSERT(Evolution::V1::VerifyRootBuffer(verifier));
TEST_ASSERT(Evolution::V2::VerifyRootBuffer(verifier));
}
// Test backwards compatibility by reading old data with an evolved schema.
auto root_v1_viewed_from_v2 = Evolution::V2::GetRoot(&binaries[0].front());
// field 'j' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->j());
// field 'k' is new in version 2 with a default of 56.
TEST_EQ(root_v1_viewed_from_v2->k(), 56);
// field 'c' of 'TableA' is new in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->e()->c());
// 'TableC' was added to field 'c' union in version 2, so it should be null.
TEST_ASSERT(nullptr == root_v1_viewed_from_v2->c_as_TableC());
// The field 'c' union should be of type 'TableB' regardless of schema version
TEST_ASSERT(root_v1_viewed_from_v2->c_type() == Evolution::V2::Union::TableB);
// The field 'f' was renamed to 'ff' in version 2, it should still be readable.
TEST_EQ(root_v1_viewed_from_v2->ff()->a(), 16);
// Test forwards compatibility by reading new data with an old schema.
auto root_v2_viewed_from_v1 = Evolution::V1::GetRoot(&binaries[1].front());
// The field 'c' union in version 2 is a new table (index = 3) and should still be accessible,
// but not interpretable.
TEST_EQ(static_cast<uint8_t>(root_v2_viewed_from_v1->c_type()), 3);
TEST_NOTNULL(root_v2_viewed_from_v1->c());
// The field 'd' enum in verison 2 has new members and should still be accessible, but not interpretable.
TEST_EQ(static_cast<int8_t>(root_v2_viewed_from_v1->d()), 3);
// The field 'a' in version 2 is deprecated and should return the default value (0) instead of the value stored in
// the in the buffer (42).
TEST_EQ(root_v2_viewed_from_v1->a(), 0);
// The field 'ff' was originally named 'f' in version 1, it should still be readable.
TEST_EQ(root_v2_viewed_from_v1->f()->a(), 35);
#endif
} }
void UnionVectorTest() { void UnionVectorTest() {
// 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(
(test_data_path + "union_vector/union_vector.fbs").c_str(), (test_data_path + "union_vector/union_vector.fbs").c_str(), false,
false, &schemafile), &schemafile),
true); true);
TEST_EQ(flatbuffers::LoadFile( TEST_EQ(flatbuffers::LoadFile(
(test_data_path + "union_vector/union_vector.json").c_str(), (test_data_path + "union_vector/union_vector.json").c_str(),
@@ -2420,70 +2493,67 @@ void UnionVectorTest() {
"characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, " "characters: [ { books_read: 7 }, { sword_attack_damage: 5 }, "
"{ books_read: 2 }, \"Other\", \"Unused\" ] }"); "{ books_read: 2 }, \"Other\", \"Unused\" ] }");
flatbuffers::ToStringVisitor visitor("\n", true, " "); flatbuffers::ToStringVisitor visitor("\n", true, " ");
IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor); IterateFlatBuffer(fbb.GetBufferPointer(), MovieTypeTable(), &visitor);
TEST_EQ_STR( TEST_EQ_STR(visitor.s.c_str(),
visitor.s.c_str(), "{\n"
"{\n" " \"main_character_type\": \"Rapunzel\",\n"
" \"main_character_type\": \"Rapunzel\",\n" " \"main_character\": {\n"
" \"main_character\": {\n" " \"hair_length\": 6\n"
" \"hair_length\": 6\n" " },\n"
" },\n" " \"characters_type\": [\n"
" \"characters_type\": [\n" " \"Belle\",\n"
" \"Belle\",\n" " \"MuLan\",\n"
" \"MuLan\",\n" " \"BookFan\",\n"
" \"BookFan\",\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ],\n"
" ],\n" " \"characters\": [\n"
" \"characters\": [\n" " {\n"
" {\n" " \"books_read\": 7\n"
" \"books_read\": 7\n" " },\n"
" },\n" " {\n"
" {\n" " \"sword_attack_damage\": 5\n"
" \"sword_attack_damage\": 5\n" " },\n"
" },\n" " {\n"
" {\n" " \"books_read\": 2\n"
" \"books_read\": 2\n" " },\n"
" },\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ]\n"
" ]\n" "}");
"}");
// Generate text using parsed schema. // Generate text using parsed schema.
std::string jsongen; std::string jsongen;
auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen); auto result = GenerateText(parser, fbb.GetBufferPointer(), &jsongen);
TEST_EQ(result, true); TEST_EQ(result, true);
TEST_EQ_STR( TEST_EQ_STR(jsongen.c_str(),
jsongen.c_str(), "{\n"
"{\n" " main_character_type: \"Rapunzel\",\n"
" main_character_type: \"Rapunzel\",\n" " main_character: {\n"
" main_character: {\n" " hair_length: 6\n"
" hair_length: 6\n" " },\n"
" },\n" " characters_type: [\n"
" characters_type: [\n" " \"Belle\",\n"
" \"Belle\",\n" " \"MuLan\",\n"
" \"MuLan\",\n" " \"BookFan\",\n"
" \"BookFan\",\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ],\n"
" ],\n" " characters: [\n"
" characters: [\n" " {\n"
" {\n" " books_read: 7\n"
" books_read: 7\n" " },\n"
" },\n" " {\n"
" {\n" " sword_attack_damage: 5\n"
" sword_attack_damage: 5\n" " },\n"
" },\n" " {\n"
" {\n" " books_read: 2\n"
" books_read: 2\n" " },\n"
" },\n" " \"Other\",\n"
" \"Other\",\n" " \"Unused\"\n"
" \"Unused\"\n" " ]\n"
" ]\n" "}\n");
"}\n");
// Simple test with reflection. // Simple test with reflection.
parser.Serialize(); parser.Serialize();
@@ -2496,7 +2566,8 @@ void UnionVectorTest() {
TEST_EQ(parser2.Parse("struct Bool { b:bool; }" TEST_EQ(parser2.Parse("struct Bool { b:bool; }"
"union Any { Bool }" "union Any { Bool }"
"table Root { a:Any; }" "table Root { a:Any; }"
"root_type Root;"), true); "root_type Root;"),
true);
TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true); TEST_EQ(parser2.Parse("{a_type:Bool,a:{b:true}}"), true);
} }
@@ -2703,7 +2774,7 @@ void TypeAliasesTest() {
TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max()); TEST_EQ(ta->u64(), flatbuffers::numeric_limits<uint64_t>::max());
TEST_EQ(ta->f32(), 2.3f); TEST_EQ(ta->f32(), 2.3f);
TEST_EQ(ta->f64(), 2.3); TEST_EQ(ta->f64(), 2.3);
using namespace flatbuffers; // is_same using namespace flatbuffers; // is_same
static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type"); static_assert(is_same<decltype(ta->i8()), int8_t>::value, "invalid type");
static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type"); static_assert(is_same<decltype(ta->i16()), int16_t>::value, "invalid type");
static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type"); static_assert(is_same<decltype(ta->i32()), int32_t>::value, "invalid type");
@@ -2729,14 +2800,16 @@ void UninitializedVectorTest() {
flatbuffers::FlatBufferBuilder builder; flatbuffers::FlatBufferBuilder builder;
Test *buf = nullptr; Test *buf = nullptr;
auto vector_offset = builder.CreateUninitializedVectorOfStructs<Test>(2, &buf); auto vector_offset =
builder.CreateUninitializedVectorOfStructs<Test>(2, &buf);
TEST_NOTNULL(buf); TEST_NOTNULL(buf);
buf[0] = Test(10, 20); buf[0] = Test(10, 20);
buf[1] = Test(30, 40); buf[1] = Test(30, 40);
auto required_name = builder.CreateString("myMonster"); auto required_name = builder.CreateString("myMonster");
auto monster_builder = MonsterBuilder(builder); auto monster_builder = MonsterBuilder(builder);
monster_builder.add_name(required_name); // required field mandated for monster. monster_builder.add_name(
required_name); // required field mandated for monster.
monster_builder.add_test4(vector_offset); monster_builder.add_test4(vector_offset);
builder.Finish(monster_builder.Finish()); builder.Finish(monster_builder.Finish());
@@ -2781,11 +2854,11 @@ void EqualOperatorTest() {
// For testing any binaries, e.g. from fuzzing. // For testing any binaries, e.g. from fuzzing.
void LoadVerifyBinaryTest() { void LoadVerifyBinaryTest() {
std::string binary; std::string binary;
if (flatbuffers::LoadFile((test_data_path + if (flatbuffers::LoadFile(
"fuzzer/your-filename-here").c_str(), (test_data_path + "fuzzer/your-filename-here").c_str(), true,
true, &binary)) { &binary)) {
flatbuffers::Verifier verifier( flatbuffers::Verifier verifier(
reinterpret_cast<const uint8_t *>(binary.data()), binary.size()); reinterpret_cast<const uint8_t *>(binary.data()), binary.size());
TEST_EQ(VerifyMonsterBuffer(verifier), true); TEST_EQ(VerifyMonsterBuffer(verifier), true);
} }
} }
@@ -2801,24 +2874,28 @@ 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));
TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro TEST_EQ(null_b1.o != null_c.o, true); // Issue#5058 repro
TEST_EQ(null_b1.o, null_b2.o); TEST_EQ(null_b1.o, null_b2.o);
// Put the strings into an array for round trip verification. // Put the strings into an array for round trip verification.
const flatbuffers::Offset<flatbuffers::String> array[7] = { one1, two, one2, onetwo, null_b1, null_c, null_b2 }; const flatbuffers::Offset<flatbuffers::String> array[7] = {
const auto vector_offset = builder.CreateVector(array, flatbuffers::uoffset_t(7)); one1, two, one2, onetwo, null_b1, null_c, null_b2
};
const auto vector_offset =
builder.CreateVector(array, flatbuffers::uoffset_t(7));
MonsterBuilder monster_builder(builder); MonsterBuilder monster_builder(builder);
monster_builder.add_name(two); monster_builder.add_name(two);
monster_builder.add_testarrayofstring(vector_offset); monster_builder.add_testarrayofstring(vector_offset);
builder.Finish(monster_builder.Finish()); builder.Finish(monster_builder.Finish());
// Read the Monster back. // Read the Monster back.
const auto *monster = flatbuffers::GetRoot<Monster>(builder.GetBufferPointer()); const auto *monster =
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));
@@ -2831,7 +2908,8 @@ void CreateSharedStringTest() {
TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c)))); TEST_EQ(a[5]->str(), (std::string(chars_c, sizeof(chars_c))));
TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b)))); TEST_EQ(a[6]->str(), (std::string(chars_b, sizeof(chars_b))));
// Make sure String::operator< works, too, since it is related to StringOffsetCompare. // Make sure String::operator< works, too, since it is related to
// StringOffsetCompare.
TEST_EQ((*a[0]) < (*a[1]), true); TEST_EQ((*a[0]) < (*a[1]), true);
TEST_EQ((*a[1]) < (*a[0]), false); TEST_EQ((*a[1]) < (*a[0]), false);
TEST_EQ((*a[1]) < (*a[2]), false); TEST_EQ((*a[1]) < (*a[2]), false);
@@ -2907,32 +2985,28 @@ void FixedLengthArrayTest() {
TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1)); TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1));
TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a()); TEST_NOTNULL(mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a());
mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a()->Mutate(1, 5); mArStruct->mutable_d()->GetMutablePointer(1)->mutable_a()->Mutate(1, 5);
TEST_EQ(mArStruct->d()->Get(1)->a()->Get(1), 5); TEST_EQ(5, mArStruct->d()->Get(1)->a()->Get(1));
TEST_EQ(mArStruct->d()->Get(0)->b() == MyGame::Example::TestEnum::B, true); TEST_EQ(MyGame::Example::TestEnum::B, mArStruct->d()->Get(0)->b());
TEST_NOTNULL(mArStruct->d()->Get(0)->c()); TEST_NOTNULL(mArStruct->d()->Get(0)->c());
TEST_EQ(mArStruct->d()->Get(0)->c()->Get(0) == MyGame::Example::TestEnum::C, TEST_EQ(MyGame::Example::TestEnum::C, mArStruct->d()->Get(0)->c()->Get(0));
true); TEST_EQ(MyGame::Example::TestEnum::A, mArStruct->d()->Get(0)->c()->Get(1));
TEST_EQ(mArStruct->d()->Get(0)->c()->Get(1) == MyGame::Example::TestEnum::A, TEST_EQ(flatbuffers::numeric_limits<int64_t>::max(),
true); mArStruct->d()->Get(0)->d()->Get(0));
TEST_EQ(mArStruct->d()->Get(0)->d()->Get(0), TEST_EQ(flatbuffers::numeric_limits<int64_t>::min(),
flatbuffers::numeric_limits<int64_t>::max()); mArStruct->d()->Get(0)->d()->Get(1));
TEST_EQ(mArStruct->d()->Get(0)->d()->Get(1), TEST_EQ(MyGame::Example::TestEnum::C, mArStruct->d()->Get(1)->b());
flatbuffers::numeric_limits<int64_t>::min());
TEST_EQ(mArStruct->d()->Get(1)->b() == MyGame::Example::TestEnum::C, true);
TEST_NOTNULL(mArStruct->d()->Get(1)->c()); TEST_NOTNULL(mArStruct->d()->Get(1)->c());
TEST_EQ(mArStruct->d()->Get(1)->c()->Get(0) == MyGame::Example::TestEnum::C, TEST_EQ(MyGame::Example::TestEnum::C, mArStruct->d()->Get(1)->c()->Get(0));
true); TEST_EQ(MyGame::Example::TestEnum::A, mArStruct->d()->Get(1)->c()->Get(1));
TEST_EQ(mArStruct->d()->Get(1)->c()->Get(1) == MyGame::Example::TestEnum::A, TEST_EQ(flatbuffers::numeric_limits<int64_t>::min(),
true); mArStruct->d()->Get(1)->d()->Get(0));
TEST_EQ(mArStruct->d()->Get(1)->d()->Get(0), TEST_EQ(flatbuffers::numeric_limits<int64_t>::max(),
flatbuffers::numeric_limits<int64_t>::min()); mArStruct->d()->Get(1)->d()->Get(1));
TEST_EQ(mArStruct->d()->Get(1)->d()->Get(1),
flatbuffers::numeric_limits<int64_t>::max());
for (int i = 0; i < mArStruct->b()->size() - 1; i++) for (int i = 0; i < mArStruct->b()->size() - 1; i++)
TEST_EQ(mArStruct->b()->Get(i), i + 1); TEST_EQ(mArStruct->b()->Get(i), i + 1);
// Check alignment // Check alignment
TEST_EQ(reinterpret_cast<uintptr_t>(mArStruct->d()) % 8, 0); TEST_EQ(0, reinterpret_cast<uintptr_t>(mArStruct->d()) % 8);
TEST_EQ(reinterpret_cast<uintptr_t>(mArStruct->f()) % 8, 0); TEST_EQ(0, reinterpret_cast<uintptr_t>(mArStruct->f()) % 8);
#endif #endif
} }
@@ -2943,16 +3017,17 @@ void NativeTypeTest() {
src_data.vectors.reserve(N); src_data.vectors.reserve(N);
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
src_data.vectors.push_back (Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f)); src_data.vectors.push_back(
Native::Vector3D(10 * i + 0.1f, 10 * i + 0.2f, 10 * i + 0.3f));
} }
flatbuffers::FlatBufferBuilder fbb; flatbuffers::FlatBufferBuilder fbb;
fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data)); fbb.Finish(Geometry::ApplicationData::Pack(fbb, &src_data));
auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer()); auto dstDataT = Geometry::UnPackApplicationData(fbb.GetBufferPointer());
for (int i = 0; i < N; ++i) { for (int i = 0; i < N; ++i) {
Native::Vector3D& v = dstDataT->vectors[i]; 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);
@@ -3061,6 +3136,7 @@ int FlatBufferTests() {
FixedLengthArrayJsonTest(true); FixedLengthArrayJsonTest(true);
ReflectionTest(flatbuf.data(), flatbuf.size()); ReflectionTest(flatbuf.data(), flatbuf.size());
ParseProtoTest(); ParseProtoTest();
EvolutionTest();
UnionVectorTest(); UnionVectorTest();
LoadVerifyBinaryTest(); LoadVerifyBinaryTest();
GenerateTableTextTest(); GenerateTableTextTest();
@@ -3107,7 +3183,7 @@ int FlatBufferTests() {
return 0; return 0;
} }
int main(int /*argc*/, const char * /*argv*/ []) { int main(int /*argc*/, const char * /*argv*/[]) {
InitTestEngine(); InitTestEngine();
std::string req_locale; std::string req_locale;

Some files were not shown because too many files have changed in this diff Show More