forked from BigfootDev/flatbuffers
Compare commits
133 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b29ba4c70c | ||
|
|
fea6b525ee | ||
|
|
69dc71b5ed | ||
|
|
1a89682251 | ||
|
|
5fd0fefab6 | ||
|
|
f8a964d2b0 | ||
|
|
84033ae035 | ||
|
|
b9efbf6a3d | ||
|
|
13194ececa | ||
|
|
9ec9303abb | ||
|
|
03ee3db240 | ||
|
|
cf825b8819 | ||
|
|
377a8ba6b2 | ||
|
|
13cf6e66e3 | ||
|
|
81b6bacead | ||
|
|
e6fa14a08d | ||
|
|
c66683f27f | ||
|
|
6d6271db2f | ||
|
|
ab76c57ec8 | ||
|
|
d1e8899310 | ||
|
|
ccba2edb7c | ||
|
|
2a7a44be33 | ||
|
|
6301da75d1 | ||
|
|
059661b9ac | ||
|
|
dc5975ba7a | ||
|
|
0de4f3f75b | ||
|
|
b59aafc659 | ||
|
|
92a6ae93fa | ||
|
|
a31ddd2bb3 | ||
|
|
bc2ec7119b | ||
|
|
641b397f8b | ||
|
|
d342918790 | ||
|
|
c4377390a8 | ||
|
|
5608be0f96 | ||
|
|
dbecdf209d | ||
|
|
c05803bf96 | ||
|
|
d298adc4e6 | ||
|
|
c2050aa0e3 | ||
|
|
290e9f270b | ||
|
|
76ae10df42 | ||
|
|
cf0d7829a6 | ||
|
|
af21b9064d | ||
|
|
e31fbb0b23 | ||
|
|
43ba7c6369 | ||
|
|
dae513e0e7 | ||
|
|
d8944e45a2 | ||
|
|
5b5fcbfc00 | ||
|
|
6862b2ff08 | ||
|
|
22e87071dd | ||
|
|
606098cac8 | ||
|
|
b5c622762b | ||
|
|
2beb985fcc | ||
|
|
fd97404c51 | ||
|
|
d9fe4e2769 | ||
|
|
424fc0c3ac | ||
|
|
c81239f6ea | ||
|
|
b830dac266 | ||
|
|
dc38f93ca8 | ||
|
|
f9025eeb52 | ||
|
|
486c048a0d | ||
|
|
ab51b03093 | ||
|
|
dc2fa215b8 | ||
|
|
199157e8f4 | ||
|
|
520d68449f | ||
|
|
b075b8c49d | ||
|
|
f6c1a1ebcf | ||
|
|
c4aede2268 | ||
|
|
4a43c2bb2c | ||
|
|
b2e55c556e | ||
|
|
df0991b7de | ||
|
|
3368407aff | ||
|
|
25f3f358a0 | ||
|
|
00e8aa87b3 | ||
|
|
09ee46a83e | ||
|
|
02dfa64a89 | ||
|
|
f136570417 | ||
|
|
b6ba322a04 | ||
|
|
4b79ff5351 | ||
|
|
edd77ae2f3 | ||
|
|
985de211af | ||
|
|
8e3fa336eb | ||
|
|
582fd90c4a | ||
|
|
a15659e9f8 | ||
|
|
afd230af8d | ||
|
|
52ca75506a | ||
|
|
3bb9b839b8 | ||
|
|
5e7bfd0461 | ||
|
|
d05d114523 | ||
|
|
722b903f89 | ||
|
|
2ff6152204 | ||
|
|
98f9af8ecc | ||
|
|
481d332e72 | ||
|
|
1a18122e3f | ||
|
|
ee56418cef | ||
|
|
e1f8037cb5 | ||
|
|
ea9ee4c99e | ||
|
|
4026117ba1 | ||
|
|
49ee30a207 | ||
|
|
7c69c5dc3d | ||
|
|
223ebebbeb | ||
|
|
f96eb472b3 | ||
|
|
c1b0abe079 | ||
|
|
b04e21db16 | ||
|
|
756050b62c | ||
|
|
ef67a58410 | ||
|
|
2da0821286 | ||
|
|
928effd198 | ||
|
|
2e7806ede0 | ||
|
|
67967476b2 | ||
|
|
79d127c863 | ||
|
|
4f3e1c2831 | ||
|
|
199a49b5b3 | ||
|
|
96ab6ade5a | ||
|
|
9f16090f90 | ||
|
|
63b240ec7b | ||
|
|
c4ba502f57 | ||
|
|
94d5643f97 | ||
|
|
f0d91fa143 | ||
|
|
726a5f523e | ||
|
|
fa74ce6d16 | ||
|
|
8fdced4e11 | ||
|
|
9031597f49 | ||
|
|
dc7f5bc0d8 | ||
|
|
867dfc5957 | ||
|
|
52acb4b347 | ||
|
|
4c861daa3e | ||
|
|
b7a26d73ee | ||
|
|
1ba4d3c4c7 | ||
|
|
06c1ad5a73 | ||
|
|
38b3893211 | ||
|
|
36daedf35f | ||
|
|
247388a20c | ||
|
|
4802e8a285 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -64,3 +64,5 @@ target
|
||||
build/VS2010/FlatBuffers.sdf
|
||||
build/VS2010/FlatBuffers.opensdf
|
||||
build/VS2010/ipch/**/*.ipch
|
||||
*.so
|
||||
Testing/Temporary
|
||||
|
||||
57
CMake/PackageDebian.cmake
Normal file
57
CMake/PackageDebian.cmake
Normal file
@@ -0,0 +1,57 @@
|
||||
# ------------------- Debianization ---------------------
|
||||
if (UNIX)
|
||||
|
||||
# Set build environment
|
||||
SET(CPACK_GENERATOR "TGZ;DEB")
|
||||
SET(CPACK_SOURCE_TGZ "ON")
|
||||
|
||||
# Common package information
|
||||
SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY
|
||||
"FlatBuffers is an efficient cross platform serialization library for C++, with support for Java, C# and Go. It was created at Google specifically for game development and other performance-critical applications.")
|
||||
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
|
||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vitaly Isaev <vitalyisaev2@gmail.com>")
|
||||
|
||||
# Derive package version from git
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND date +%Y%m%d
|
||||
OUTPUT_VARIABLE DATE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
EXECUTE_PROCESS(
|
||||
COMMAND git describe
|
||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
||||
OUTPUT_VARIABLE GIT_DESCRIBE_DIRTY
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESCRIBE_DIRTY}")
|
||||
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_DESCRIBE_DIRTY}")
|
||||
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GIT_DESCRIBE_DIRTY}")
|
||||
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_DESCRIBE_DIRTY}")
|
||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||
SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
|
||||
SET(CPACK_PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_COMMIT}")
|
||||
SET(CPACK_DEBIAN_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}")
|
||||
|
||||
# Derive architecture
|
||||
IF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||
FIND_PROGRAM(DPKG_CMD dpkg)
|
||||
IF(NOT DPKG_CMD)
|
||||
MESSAGE(STATUS "Can not find dpkg in your path, default to i386.")
|
||||
SET(CPACK_DEBIAN_PACKAGE_ARCHITECTURE i386)
|
||||
ENDIF(NOT DPKG_CMD)
|
||||
EXECUTE_PROCESS(COMMAND "${DPKG_CMD}" --print-architecture
|
||||
OUTPUT_VARIABLE CPACK_DEBIAN_PACKAGE_ARCHITECTURE
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
ENDIF(NOT CPACK_DEBIAN_PACKAGE_ARCHITECTURE)
|
||||
|
||||
# Package name
|
||||
SET(CPACK_DEBIAN_PACKAGE_NAME "flatbuffers")
|
||||
SET(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_SOURCE_DIR}/LICENSE.txt)
|
||||
SET(CPACK_PACKAGE_FILE_NAME
|
||||
"${CPACK_DEBIAN_PACKAGE_NAME}_${CPACK_DEBIAN_PACKAGE_VERSION}_${CPACK_DEBIAN_PACKAGE_ARCHITECTURE}")
|
||||
|
||||
endif(UNIX)
|
||||
|
||||
INCLUDE(CPack)
|
||||
@@ -12,6 +12,9 @@ option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
|
||||
ON)
|
||||
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
||||
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
||||
option(FLATBUFFERS_BUILD_SHAREDLIB
|
||||
"Enable the build of the flatbuffers shared library"
|
||||
OFF)
|
||||
|
||||
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
||||
message(WARNING
|
||||
@@ -44,8 +47,11 @@ set(FlatBuffers_Compiler_SRCS
|
||||
src/idl_gen_fbs.cpp
|
||||
src/idl_gen_grpc.cpp
|
||||
src/flatc.cpp
|
||||
grpc/src/compiler/schema_interface.h
|
||||
grpc/src/compiler/cpp_generator.h
|
||||
grpc/src/compiler/cpp_generator.cc
|
||||
grpc/src/compiler/go_generator.h
|
||||
grpc/src/compiler/go_generator.cc
|
||||
)
|
||||
|
||||
set(FlatHash_SRCS
|
||||
@@ -95,7 +101,10 @@ set(FlatBuffers_GRPCTest_SRCS
|
||||
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
|
||||
# source_group(Tests FILES ${FlatBuffers_Tests_SRCS})
|
||||
|
||||
if(APPLE)
|
||||
if(EXISTS "${CMAKE_TOOLCHAIN_FILE}")
|
||||
# do not apply any global settings if the toolchain
|
||||
# is being configured externally
|
||||
elseif(APPLE)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -stdlib=libc++")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra")
|
||||
elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
@@ -110,7 +119,8 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
"${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Werror=shadow")
|
||||
if (GCC_VERSION VERSION_GREATER 4.4)
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result")
|
||||
"${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result \
|
||||
-Wunused-parameter -Werror=unused-parameter")
|
||||
endif()
|
||||
|
||||
# Certain platforms such as ARM do not use signed chars by default
|
||||
@@ -118,7 +128,7 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -fsigned-char")
|
||||
|
||||
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
|
||||
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||
set(CMAKE_CXX_FLAGS
|
||||
"${CMAKE_CXX_FLAGS} -std=c++0x -stdlib=libc++ -Wall -pedantic -Werror \
|
||||
-Wextra")
|
||||
@@ -163,6 +173,11 @@ if(FLATBUFFERS_BUILD_FLATHASH)
|
||||
add_executable(flathash ${FlatHash_SRCS})
|
||||
endif()
|
||||
|
||||
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||
add_library(flatbuffers_shared SHARED ${FlatBuffers_Library_SRCS})
|
||||
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers)
|
||||
endif()
|
||||
|
||||
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
|
||||
@@ -188,6 +203,9 @@ if(FLATBUFFERS_BUILD_TESTS)
|
||||
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
|
||||
add_executable(flattests ${FlatBuffers_Tests_SRCS})
|
||||
set_property(TARGET flattests
|
||||
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
|
||||
|
||||
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
|
||||
@@ -211,6 +229,9 @@ if(FLATBUFFERS_INSTALL)
|
||||
if(FLATBUFFERS_BUILD_FLATC)
|
||||
install(TARGETS flatc DESTINATION bin)
|
||||
endif()
|
||||
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||
install(TARGETS flatbuffers_shared DESTINATION lib)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(FLATBUFFERS_BUILD_TESTS)
|
||||
@@ -222,3 +243,7 @@ if(FLATBUFFERS_BUILD_TESTS)
|
||||
endif()
|
||||
|
||||
include(CMake/BuildFlatBuffers.cmake)
|
||||
|
||||
if(FLATBUFFERS_PACKAGE_DEBIAN)
|
||||
include(CMake/PackageDebian.cmake)
|
||||
endif()
|
||||
|
||||
12
ISSUE_TEMPLATE.md
Normal file
12
ISSUE_TEMPLATE.md
Normal file
@@ -0,0 +1,12 @@
|
||||
Thank you for submitting an issue!
|
||||
|
||||
Please make sure you include the names of the affected language(s), compiler version(s), operating system version(s), and FlatBuffers version(s) in your issue title.
|
||||
|
||||
This helps us get the correct maintainers to look at your issue. Here are examples of good titles:
|
||||
|
||||
- Crash when accessing FlatBuffer [C++, gcc 4.8, OS X, master]
|
||||
- Flatc converts a protobuf 'bytes' field to 'string' in fbs schema file [all languages, FlatBuffers 1.4]
|
||||
|
||||
Include other details as appropriate.
|
||||
|
||||
Thanks!
|
||||
30
appveyor.yml
30
appveyor.yml
@@ -14,13 +14,33 @@ configuration:
|
||||
|
||||
before_build:
|
||||
- cmake -G"Visual Studio 10 2010"
|
||||
# This cuts down on a lot of noise generated by xamarin warnings.
|
||||
- del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
|
||||
|
||||
build:
|
||||
project: ALL_BUILD.vcxproj
|
||||
verbosity: minimal
|
||||
|
||||
#test_script:
|
||||
# - Debug/flattests.exe
|
||||
test_script:
|
||||
- rem "---------------- C++ -----------------"
|
||||
- "%CONFIGURATION%\\flattests.exe"
|
||||
- rem "---------------- Java -----------------"
|
||||
- "cd tests"
|
||||
- "java -version"
|
||||
- "JavaTest.bat"
|
||||
- rem "---------------- JS -----------------"
|
||||
- "node --version"
|
||||
- "..\\%CONFIGURATION%\\flatc -b monster_test.fbs unicode_test.json"
|
||||
- "node JavaScriptTest"
|
||||
- rem "---------------- C# -----------------"
|
||||
# Have to compile this here rather than in "build" above because AppVeyor only
|
||||
# supports building one project??
|
||||
- "cd FlatBuffers.Test"
|
||||
- "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
|
||||
- "tempcs\\FlatBuffers.Test.exe"
|
||||
# TODO: add more languages.
|
||||
- "cd ..\\.."
|
||||
|
||||
#artifacts:
|
||||
# - path: Release/flatc.exe
|
||||
# name: flatc.exe
|
||||
artifacts:
|
||||
- path: $(CONFIGURATION)\\flatc.exe
|
||||
name: flatc.exe
|
||||
|
||||
@@ -99,13 +99,41 @@ construction, access and mutation.
|
||||
To use:
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||
auto monsterobj = GetMonster(buffer)->UnPack();
|
||||
auto monsterobj = UnpackMonster(buffer);
|
||||
cout << monsterobj->name; // This is now a std::string!
|
||||
monsterobj->name = "Bob"; // Change the name.
|
||||
FlatBufferBuilder fbb;
|
||||
CreateMonster(fbb, monsterobj.get()); // Serialize into new buffer.
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
# External references.
|
||||
|
||||
An additional feature of the object API is the ability to allow you to load
|
||||
multiple independent FlatBuffers, and have them refer to eachothers objects
|
||||
using hashes which are then represented as typed pointers in the object API.
|
||||
|
||||
To make this work have a field in the objects you want to referred to which is
|
||||
using the string hashing feature (see `hash` attribute in the
|
||||
[schema](@ref flatbuffers_guide_writing_schema) documentation). Then you have
|
||||
a similar hash in the field referring to it, along with a `cpp_type`
|
||||
attribute specifying the C++ type this will refer to (this can be any C++
|
||||
type, and will get a `*` added).
|
||||
|
||||
Then, in JSON or however you create these buffers, make sure they use the
|
||||
same string (or hash).
|
||||
|
||||
When you call `UnPack` (or `Create`), you'll need a function that maps from
|
||||
hash to the object (see `resolver_function_t` for details).
|
||||
|
||||
# Using different pointer types.
|
||||
|
||||
By default the object tree is built out of `std::unique_ptr`, but you can
|
||||
influence this either globally (using the `--cpp-ptr-type` argument to
|
||||
`flatc`) or per field (using the `cpp_ptr_type` attribute) to by any smart
|
||||
pointer type (`my_ptr<T>`), or by specifying `naked` as the type to get `T *`
|
||||
pointers. Unlike the smart pointers, naked pointers do not manage memory for
|
||||
you, so you'll have to manage their lifecycles manually.
|
||||
|
||||
## Reflection (& Resizing)
|
||||
|
||||
There is experimental support for reflection in FlatBuffers, allowing you to
|
||||
|
||||
@@ -131,6 +131,36 @@ object are prefixed with `Get`, e.g.:
|
||||
monster.GetPos(preconstructedPos);
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
## Storing dictionaries in a FlatBuffer
|
||||
|
||||
FlatBuffers doesn't support dictionaries natively, but there is support to
|
||||
emulate their behavior with vectors and binary search, which means you
|
||||
can have fast lookups directly from a FlatBuffer without having to unpack
|
||||
your data into a `Dictionary` or similar.
|
||||
|
||||
To use it:
|
||||
- Designate one of the fields in a table as they "key" field. You do this
|
||||
by setting the `key` attribute on this field, e.g.
|
||||
`name:string (key)`.
|
||||
You may only have one key field, and it must be of string or scalar type.
|
||||
- Write out tables of this type as usual, collect their offsets in an
|
||||
array.
|
||||
- Instead of calling standard generated method,
|
||||
e.g.: `Monster.createTestarrayoftablesVector`,
|
||||
call `CreateMySortedVectorOfTables` in C# or
|
||||
`createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
|
||||
which will first sort all offsets such that the tables they refer to
|
||||
are sorted by the key field, then serialize it.
|
||||
- Now when you're accessing the FlatBuffer, you can use `LookupByKey`
|
||||
to access elements of the vector, e.g.:
|
||||
`Monster.lookupByKey(tablesVectorOffset, "Frodo", dataBuffer)`,
|
||||
which returns an object of the corresponding table type,
|
||||
or `null` if not found.
|
||||
`LookupByKey` performs a binary search, so should have a similar speed to
|
||||
`Dictionary`, though may be faster because of better caching. `LookupByKey`
|
||||
only works if the vector has been sorted, it will likely not find elements
|
||||
if it hasn't been sorted.
|
||||
|
||||
## Text parsing
|
||||
|
||||
There currently is no support for parsing text (Schema's and JSON) directly
|
||||
|
||||
@@ -285,9 +285,6 @@ Current understood attributes:
|
||||
code may access it directly, without checking for NULL. If the constructing
|
||||
code does not initialize this field, they will get an assert, and also
|
||||
the verifier will fail on buffers that have missing required fields.
|
||||
- `original_order` (on a table): since elements in a table do not need
|
||||
to be stored in any particular order, they are often optimized for
|
||||
space by sorting them to size. This attribute stops that from happening.
|
||||
- `force_align: size` (on a struct): force the alignment of this struct
|
||||
to be something higher than what it is naturally aligned to. Causes
|
||||
these structs to be aligned to that amount inside a buffer, IF that
|
||||
@@ -304,6 +301,14 @@ Current understood attributes:
|
||||
- `key` (on a field): this field is meant to be used as a key when sorting
|
||||
a vector of the type of table it sits in. Can be used for in-place
|
||||
binary search.
|
||||
- `hash` (on a field). This is an (un)signed 32/64 bit integer field, whose
|
||||
value during JSON parsing is allowed to be a string, which will then be
|
||||
stored as its hash. The value of attribute is the hashing algorithm to
|
||||
use, one of `fnv1_32` `fnv1_64` `fnv1a_32` `fnv1a_64`.
|
||||
- `original_order` (on a table): since elements in a table do not need
|
||||
to be stored in any particular order, they are often optimized for
|
||||
space by sorting them to size. This attribute stops that from happening.
|
||||
There should generally not be any reason to use this flag.
|
||||
|
||||
## JSON Parsing
|
||||
|
||||
@@ -359,6 +364,66 @@ When parsing JSON, it recognizes the following escape codes in strings:
|
||||
It also generates these escape codes back again when generating JSON from a
|
||||
binary representation.
|
||||
|
||||
## Guidelines
|
||||
|
||||
### Efficiency
|
||||
|
||||
FlatBuffers is all about efficiency, but to realize that efficiency you
|
||||
require an efficient schema. There are usually multiple choices on
|
||||
how to represent data that have vastly different size characteristics.
|
||||
|
||||
It is very common nowadays to represent any kind of data as dictionaries
|
||||
(as in e.g. JSON), because of its flexibility and extensibility. While
|
||||
it is possible to emulate this in FlatBuffers (as a vector
|
||||
of tables with key and value(s)), this is a bad match for a strongly
|
||||
typed system like FlatBuffers, leading to relatively large binaries.
|
||||
FlatBuffer tables are more flexible than classes/structs in most systems,
|
||||
since having a large number of fields only few of which are actually
|
||||
used is still efficient. You should thus try to organize your data
|
||||
as much as possible such that you can use tables where you might be
|
||||
tempted to use a dictionary.
|
||||
|
||||
Similarly, strings as values should only be used when they are
|
||||
truely open-ended. If you can, always use an enum instead.
|
||||
|
||||
FlatBuffers doesn't have inheritance, so the way to represent a set
|
||||
of related data structures is a union. Unions do have a cost however,
|
||||
so an alternative to a union is to have a single table that has
|
||||
all the fields of all the data structures you are trying to
|
||||
represent, if they are relatively similar / share many fields.
|
||||
Again, this is efficient because optional fields are cheap.
|
||||
|
||||
FlatBuffers supports the full range of integer sizes, so try to pick
|
||||
the smallest size needed, rather than defaulting to int/long.
|
||||
|
||||
Remember that you can share data (refer to the same string/table
|
||||
within a buffer), so factoring out repeating data into its own
|
||||
data structure may be worth it.
|
||||
|
||||
### Style guide
|
||||
|
||||
Identifiers in a schema are meant to translate to many different programming
|
||||
languages, so using the style of your "main" language is generally a bad idea.
|
||||
|
||||
For this reason, below is a suggested style guide to adhere to, to keep schemas
|
||||
consistent for interoperation regardless of the target language.
|
||||
|
||||
Where possible, the code generators for specific languages will generate
|
||||
identifiers that adhere to the language style, based on the schema identifiers.
|
||||
|
||||
- Table, struct, enum and rpc names (types): UpperCamelCase.
|
||||
- Table and struct field names: snake_case. This is translated to lowerCamelCase
|
||||
automatically for some languages, e.g. Java.
|
||||
- Enum values: UpperCamelCase.
|
||||
- namespaces: UpperCamelCase.
|
||||
|
||||
Formatting (this is less important, but still worth adhering to):
|
||||
|
||||
- Opening brace: on the same line as the start of the declaration.
|
||||
- Spacing: Indent by 2 spaces. None around `:` for types, on both sides for `=`.
|
||||
|
||||
For an example, see the schema at the top of this file.
|
||||
|
||||
## Gotchas
|
||||
|
||||
### Schemas and version control
|
||||
|
||||
@@ -399,55 +399,56 @@ The first step is to import/include the library, generated files, etc.
|
||||
|
||||
Now we are ready to start building some buffers. In order to start, we need
|
||||
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
|
||||
as it grows:
|
||||
as it grows. You can pass an initial size of the buffer (here 1024 bytes),
|
||||
which will grow automatically if needed:
|
||||
|
||||
<div class="language-cpp">
|
||||
~~~{.cpp}
|
||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||
// monsters' FlatBuffers.
|
||||
flatbuffers::FlatBufferBuilder builder;
|
||||
flatbuffers::FlatBufferBuilder builder(1024);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-java">
|
||||
~~~{.java}
|
||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||
// monsters' FlatBuffers.
|
||||
FlatBufferBuilder builder = new FlatBufferBuilder(0);
|
||||
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-csharp">
|
||||
~~~{.cs}
|
||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||
// monsters' FlatBuffers.
|
||||
var builder = new FlatBufferBuilder(1);
|
||||
var builder = new FlatBufferBuilder(1024);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-go">
|
||||
~~~{.go}
|
||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||
// monsters' FlatBuffers.
|
||||
builder := flatbuffers.NewBuilder(0)
|
||||
builder := flatbuffers.NewBuilder(1024)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-python">
|
||||
~~~{.py}
|
||||
# Create a `FlatBufferBuilder`, which will be used to create our
|
||||
# monsters' FlatBuffers.
|
||||
builder = flatbuffers.Builder(0)
|
||||
builder = flatbuffers.Builder(1024)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-javascript">
|
||||
~~~{.js}
|
||||
// Create a `flatbuffer.Builder`, which will be used to create our
|
||||
// monsters' FlatBuffers.
|
||||
var builder = new flatbuffers.Builder(1);
|
||||
var builder = new flatbuffers.Builder(1024);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-php">
|
||||
~~~{.php}
|
||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||
// monsters' FlatBuffers.
|
||||
$builder = new Google\FlatBuffers\FlatbufferBuilder(0);
|
||||
$builder = new Google\FlatBuffers\FlatbufferBuilder(1024);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-c">
|
||||
@@ -798,58 +799,6 @@ elements by calling a lambda. For the common case of `std::vector<std::string>`
|
||||
there's also `CreateVectorOfStrings`.
|
||||
</div>
|
||||
|
||||
To create a `struct`, use the `Vec3` class/struct that was generated by
|
||||
the schema compiler:
|
||||
|
||||
<div class="language-cpp">
|
||||
~~~{.cpp}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
auto pos = Vec3(1.0f, 2.0f, 3.0f);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-java">
|
||||
~~~{.java}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
int pos = Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-csharp">
|
||||
~~~{.cs}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
var pos = Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-go">
|
||||
~~~{.go}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
pos := sample.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-python">
|
||||
~~~{.py}
|
||||
# Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
pos = MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-javascript">
|
||||
~~~{.js}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
var pos = MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-php">
|
||||
~~~{.js}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
$pos = \MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-c">
|
||||
~~~{.c}
|
||||
// Create a `Vec3`, representing the Orc's position in 3-D space.
|
||||
ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f };
|
||||
~~~
|
||||
</div>
|
||||
|
||||
We have now serialized the non-scalar components of the orc, so we
|
||||
can serialize the monster itself:
|
||||
|
||||
@@ -861,15 +810,16 @@ can serialize the monster itself:
|
||||
|
||||
// Finally, create the monster using the `CreateMonster` helper function
|
||||
// to set all fields.
|
||||
auto orc = CreateMonster(builder, &pos, mana, hp, name, inventory, Color_Red,
|
||||
weapons, Equipment_Weapon, axe.Union());
|
||||
auto orc = CreateMonster(builder, Vec3(1.0f, 2.0f, 3.0f), mana, hp, name,
|
||||
inventory, Color_Red, weapons, Equipment_Weapon,
|
||||
axe.Union());
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-java">
|
||||
~~~{.java}
|
||||
// Create our monster using `startMonster()` and `endMonster()`.
|
||||
Monster.startMonster(builder);
|
||||
Monster.addPos(builder, pos);
|
||||
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f));
|
||||
Monster.addName(builder, name);
|
||||
Monster.addColor(builder, Color.Red);
|
||||
Monster.addHp(builder, (short)300);
|
||||
@@ -884,7 +834,7 @@ can serialize the monster itself:
|
||||
~~~{.cs}
|
||||
// Create our monster using `StartMonster()` and `EndMonster()`.
|
||||
Monster.StartMonster(builder);
|
||||
Monster.AddPos(builder, pos);
|
||||
Monster.AddPos(builder, Vec3.CreateVec3(builder, 1.0f, 2.0f, 3.0f));
|
||||
Monster.AddHp(builder, (short)300);
|
||||
Monster.AddName(builder, name);
|
||||
Monster.AddInventory(builder, inv);
|
||||
@@ -899,7 +849,7 @@ can serialize the monster itself:
|
||||
~~~{.go}
|
||||
// Create our monster using `MonsterStart()` and `MonsterEnd()`.
|
||||
sample.MonsterStart(builder)
|
||||
sample.MonsterAddPos(builder, pos)
|
||||
sample.MonsterAddPos(builder, sample.CreateVec3(builder, 1.0, 2.0, 3.0))
|
||||
sample.MonsterAddHp(builder, 300)
|
||||
sample.MonsterAddName(builder, name)
|
||||
sample.MonsterAddInventory(builder, inv)
|
||||
@@ -914,7 +864,8 @@ can serialize the monster itself:
|
||||
~~~{.py}
|
||||
# Create our monster by using `MonsterStart()` and `MonsterEnd()`.
|
||||
MyGame.Sample.Monster.MonsterStart(builder)
|
||||
MyGame.Sample.Monster.MonsterAddPos(builder, pos)
|
||||
MyGame.Sample.Monster.MonsterAddPos(builder,
|
||||
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0))
|
||||
MyGame.Sample.Monster.MonsterAddHp(builder, 300)
|
||||
MyGame.Sample.Monster.MonsterAddName(builder, name)
|
||||
MyGame.Sample.Monster.MonsterAddInventory(builder, inv)
|
||||
@@ -931,7 +882,8 @@ can serialize the monster itself:
|
||||
~~~{.js}
|
||||
// Create our monster by using `startMonster()` and `endMonster()`.
|
||||
MyGame.Sample.Monster.startMonster(builder);
|
||||
MyGame.Sample.Monster.addPos(builder, pos);
|
||||
MyGame.Sample.Monster.addPos(builder,
|
||||
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0));
|
||||
MyGame.Sample.Monster.addHp(builder, 300);
|
||||
MyGame.Sample.Monster.addColor(builder, MyGame.Sample.Color.Red)
|
||||
MyGame.Sample.Monster.addName(builder, name);
|
||||
@@ -946,7 +898,8 @@ can serialize the monster itself:
|
||||
~~~{.php}
|
||||
// Create our monster by using `StartMonster()` and `EndMonster()`.
|
||||
\MyGame\Sample\Monster::StartMonster($builder);
|
||||
\MyGame\Sample\Monster::AddPos($builder, $pos);
|
||||
\MyGame\Sample\Monster::AddPos($builder,
|
||||
\MyGame\Sample\Vec3::CreateVec3($builder, 1.0, 2.0, 3.0));
|
||||
\MyGame\Sample\Monster::AddHp($builder, 300);
|
||||
\MyGame\Sample\Monster::AddName($builder, $name);
|
||||
\MyGame\Sample\Monster::AddInventory($builder, $inv);
|
||||
@@ -966,11 +919,21 @@ can serialize the monster itself:
|
||||
// Define an equipment union. `create` calls in C has a single
|
||||
// argument for unions where C++ has both a type and a data argument.
|
||||
ns(Equipment_union_ref_t) equipped = ns(Equipment_as_Weapon(axe));
|
||||
ns(Vec3_t) pos = { 1.0f, 2.0f, 3.0f };
|
||||
ns(Monster_create_as_root(B, &pos, mana, hp, name, inventory, ns(Color_Red),
|
||||
weapons, equipped));
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
|
||||
are simple combinations of scalars that are always stored inline, just like
|
||||
scalars themselves.
|
||||
|
||||
**Important**: you should not nest tables or any other objects, which is why
|
||||
we created all the strings/vectors/tables that this monster refers to before
|
||||
`start`. If you try to create any of them between `start` and `end`, you
|
||||
will get an assert/exception/panic depending on your language.
|
||||
|
||||
*Note: Since we are passing `150` as the `mana` field, which happens to be the
|
||||
default value, the field will not actually be written to the buffer, since the
|
||||
default value will be returned on query anyway. This is a nice space savings,
|
||||
@@ -1231,6 +1194,11 @@ like so:
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Now you can write the bytes to a file, send them over the network..
|
||||
**Make sure your file mode (or tranfer protocol) is set to BINARY, not text.**
|
||||
If you transfer a FlatBuffer in text mode, the buffer will be corrupted,
|
||||
which will lead to hard to find problems when you read the buffer.
|
||||
|
||||
#### Reading Orc FlatBuffers
|
||||
|
||||
Now that we have successfully created an `Orc` FlatBuffer, the monster data can
|
||||
@@ -1326,92 +1294,82 @@ before:
|
||||
~~~
|
||||
</div>
|
||||
|
||||
Then, assuming you have a variable containing to the bytes of data from disk,
|
||||
network, etc., you can create a monster from this data:
|
||||
Then, assuming you have a buffer of bytes received from disk,
|
||||
network, etc., you can create start accessing the buffer like so:
|
||||
|
||||
**Again, make sure you read the bytes in BINARY mode, otherwise the code below
|
||||
won't work**
|
||||
|
||||
<div class="language-cpp">
|
||||
~~~{.cpp}
|
||||
// We can access the buffer we just made directly. Pretend this came over a
|
||||
// network, was read off of disk, etc.
|
||||
auto buffer_pointer = builder.GetBufferPointer();
|
||||
uint8_t *buffer_pointer = /* the data you just read */;
|
||||
|
||||
// Deserialize the data from the buffer.
|
||||
// Get a pointer to the root object inside the buffer.
|
||||
auto monster = GetMonster(buffer_pointer);
|
||||
|
||||
// `monster` is of type`Monster *`, and points to somewhere inside the buffer.
|
||||
|
||||
// `monster` is of type `Monster *`.
|
||||
// Note: root object pointers are NOT the same as `buffer_pointer`.
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-java">
|
||||
~~~{.java}
|
||||
// We can access the buffer we just made directly. Pretend this came over a
|
||||
// network, was read off of disk, etc.
|
||||
java.nio.ByteBuffer buf = builder.dataBuffer();
|
||||
byte[] bytes = /* the data you just read */
|
||||
java.nio.ByteBuffer buf = java.nio.ByteBuffer.wrap(bytes);
|
||||
|
||||
// Deserialize the data from the buffer.
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
Monster monster = Monster.getRootAsMonster(buf);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-csharp">
|
||||
~~~{.cs}
|
||||
// We can access the buffer we just made directly. Pretend this came over a
|
||||
// network, was read off of disk, etc.
|
||||
var buf = builder.DataBuffer;
|
||||
byte[] bytes = /* the data you just read */
|
||||
var buf = new ByteBuffer(bytes);
|
||||
|
||||
// Deserialize the data from the buffer.
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
var monster = Monster.GetRootAsMonster(buf);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-go">
|
||||
~~~{.go}
|
||||
// We can access the buffer we just made directly. Pretend this came over a
|
||||
// network, was read off of disk, etc.
|
||||
buf := builder.FinishedBytes()
|
||||
var buf []byte = /* the data you just read */
|
||||
|
||||
// Deserialize the data from the buffer.
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
monster := sample.GetRootAsMonster(buf, 0)
|
||||
|
||||
// Note: We use `0` for the offset here, since we got the data using the
|
||||
// `builder.FinishedBytes()` method. This simulates the data you would
|
||||
// store/receive in your FlatBuffer. If you wanted to read from the
|
||||
// `builder.Bytes` directly, you would need to pass in the offset of
|
||||
// `builder.Head()`, as the builder actually constructs the buffer backwards.
|
||||
// Note: We use `0` for the offset here, which is typical for most buffers
|
||||
// you would read. If you wanted to read from `builder.Bytes` directly, you
|
||||
// would need to pass in the offset of `builder.Head()`, as the builder
|
||||
// constructs the buffer backwards, so may not start at offset 0.
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-python">
|
||||
~~~{.py}
|
||||
# We can access the buffer we just made directly. Pretend this came over a
|
||||
# network, was read off of disk, etc.
|
||||
buf = builder.Output()
|
||||
buf = /* the data you just read, in an object of type "bytearray" */
|
||||
|
||||
# Deserialize the data from the buffer.
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
monster = MyGame.Sample.Monster.Monster.GetRootAsMonster(buf, 0)
|
||||
|
||||
# Note: We use `0` for the offset here, since we got the data using the
|
||||
# `builder.Output()` method. This simulates the data you would store/receive
|
||||
# in your FlatBuffer. If you wanted to read from the `builder.Bytes` directly,
|
||||
# Note: We use `0` for the offset here, which is typical for most buffers
|
||||
# you would read. If you wanted to read from the `builder.Bytes` directly,
|
||||
# you would need to pass in the offset of `builder.Head()`, as the builder
|
||||
# actually constructs the buffer backwards.
|
||||
# constructs the buffer backwards, so may not start at offset 0.
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-javascript">
|
||||
~~~{.js}
|
||||
// We can access the buffer we just made directly. Pretend this came over a
|
||||
// network, was read off of disk, etc.
|
||||
var buf = builder.dataBuffer();
|
||||
var bytes = /* the data you just read, in an object of type "Uint8Array" */
|
||||
var buf = new flatbuffers.ByteBuffer(bytes);
|
||||
|
||||
// Deserialize the data from the buffer.
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
var monster = MyGame.Sample.Monster.getRootAsMonster(buf);
|
||||
~~~
|
||||
</div>
|
||||
<div class="language-php">
|
||||
~~~{.php}
|
||||
// We can access the buffer we just made directly. Pretend this came over a
|
||||
// network, was read off of disk, etc.
|
||||
$buf = $builder->dataBuffer();
|
||||
$bytes = /* the data you just read, in a string */
|
||||
$buf = Google\FlatBuffers\ByteBuffer::wrap($bytes);
|
||||
|
||||
// Deserialize the data from the buffer.
|
||||
// Get an accessor to the root object inside the buffer.
|
||||
$monster = \MyGame\Sample\Monster::GetRootAsMonster($buf);
|
||||
~~~
|
||||
</div>
|
||||
|
||||
23
go/grpc.go
Normal file
23
go/grpc.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package flatbuffers
|
||||
|
||||
// Codec implements gRPC-go Codec which is used to encode and decode messages.
|
||||
var Codec = "flatbuffers"
|
||||
|
||||
type FlatbuffersCodec struct{}
|
||||
|
||||
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
|
||||
return v.(*Builder).FinishedBytes(), nil
|
||||
}
|
||||
|
||||
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
|
||||
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
|
||||
return nil
|
||||
}
|
||||
|
||||
func (FlatbuffersCodec) String() string {
|
||||
return Codec
|
||||
}
|
||||
|
||||
type flatbuffersInit interface {
|
||||
Init(data []byte, i UOffsetT)
|
||||
}
|
||||
13
go/lib.go
Normal file
13
go/lib.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package flatbuffers
|
||||
|
||||
// FlatBuffer is the interface that represents a flatbuffer.
|
||||
type FlatBuffer interface {
|
||||
Table() Table
|
||||
Init(buf []byte, i UOffsetT)
|
||||
}
|
||||
|
||||
// GetRootAs is a generic helper to initialize a FlatBuffer with the provided buffer bytes and its data offset.
|
||||
func GetRootAs(buf []byte, offset UOffsetT, fb FlatBuffer) {
|
||||
n := GetUOffsetT(buf[offset:])
|
||||
fb.Init(buf, n+offset)
|
||||
}
|
||||
@@ -1,47 +1,52 @@
|
||||
package flatbuffers
|
||||
|
||||
import "unsafe"
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
const (
|
||||
// See http://golang.org/ref/spec#Numeric_types
|
||||
|
||||
// SizeUint8 is the byte size of a uint8.
|
||||
SizeUint8 = int(unsafe.Sizeof(uint8(0)))
|
||||
SizeUint8 = 1
|
||||
// SizeUint16 is the byte size of a uint16.
|
||||
SizeUint16 = int(unsafe.Sizeof(uint16(0)))
|
||||
SizeUint16 = 2
|
||||
// SizeUint32 is the byte size of a uint32.
|
||||
SizeUint32 = int(unsafe.Sizeof(uint32(0)))
|
||||
SizeUint32 = 4
|
||||
// SizeUint64 is the byte size of a uint64.
|
||||
SizeUint64 = int(unsafe.Sizeof(uint64(0)))
|
||||
SizeUint64 = 8
|
||||
|
||||
// SizeInt8 is the byte size of a int8.
|
||||
SizeInt8 = int(unsafe.Sizeof(int8(0)))
|
||||
// SizeInt8 is the byte size of a int8.
|
||||
SizeInt8 = 1
|
||||
// SizeInt16 is the byte size of a int16.
|
||||
SizeInt16 = int(unsafe.Sizeof(int16(0)))
|
||||
SizeInt16 = 2
|
||||
// SizeInt32 is the byte size of a int32.
|
||||
SizeInt32 = int(unsafe.Sizeof(int32(0)))
|
||||
SizeInt32 = 4
|
||||
// SizeInt64 is the byte size of a int64.
|
||||
SizeInt64 = int(unsafe.Sizeof(int64(0)))
|
||||
SizeInt64 = 8
|
||||
|
||||
// SizeFloat32 is the byte size of a float32.
|
||||
SizeFloat32 = int(unsafe.Sizeof(float32(0)))
|
||||
SizeFloat32 = 4
|
||||
// SizeFloat64 is the byte size of a float64.
|
||||
SizeFloat64 = int(unsafe.Sizeof(float64(0)))
|
||||
SizeFloat64 = 8
|
||||
|
||||
// SizeByte is the byte size of a byte.
|
||||
// The `byte` type is aliased (by Go definition) to uint8.
|
||||
SizeByte = SizeUint8
|
||||
SizeByte = 1
|
||||
|
||||
// SizeBool is the byte size of a bool.
|
||||
// The `bool` type is aliased (by flatbuffers convention) to uint8.
|
||||
SizeBool = SizeUint8
|
||||
SizeBool = 1
|
||||
|
||||
// SizeSOffsetT is the byte size of an SOffsetT.
|
||||
SizeSOffsetT = int(unsafe.Sizeof(SOffsetT(0)))
|
||||
// The `SOffsetT` type is aliased (by flatbuffers convention) to int32.
|
||||
SizeSOffsetT = 4
|
||||
// SizeUOffsetT is the byte size of an UOffsetT.
|
||||
SizeUOffsetT = int(unsafe.Sizeof(UOffsetT(0)))
|
||||
// The `UOffsetT` type is aliased (by flatbuffers convention) to uint32.
|
||||
SizeUOffsetT = 4
|
||||
// SizeVOffsetT is the byte size of an VOffsetT.
|
||||
SizeVOffsetT = int(unsafe.Sizeof(VOffsetT(0)))
|
||||
// The `VOffsetT` type is aliased (by flatbuffers convention) to uint16.
|
||||
SizeVOffsetT = 2
|
||||
)
|
||||
|
||||
// byteSliceToString converts a []byte to string without a heap allocation.
|
||||
@@ -67,7 +67,8 @@ grpc::string FilenameIdentifier(const grpc::string &filename) {
|
||||
template<class T, size_t N>
|
||||
T *array_end(T (&array)[N]) { return array + N; }
|
||||
|
||||
void PrintIncludes(Printer *printer, const std::vector<grpc::string>& headers, const Parameters ¶ms) {
|
||||
void PrintIncludes(grpc_generator::Printer *printer,
|
||||
const std::vector<grpc::string>& headers, const Parameters ¶ms) {
|
||||
std::map<grpc::string, grpc::string> vars;
|
||||
|
||||
vars["l"] = params.use_system_headers ? '<' : '"';
|
||||
@@ -86,7 +87,7 @@ void PrintIncludes(Printer *printer, const std::vector<grpc::string>& headers, c
|
||||
}
|
||||
}
|
||||
|
||||
grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
|
||||
grpc::string GetHeaderPrologue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||
grpc::string output;
|
||||
{
|
||||
// Scope the output stream so it closes and finalizes output to the string.
|
||||
@@ -106,12 +107,13 @@ grpc::string GetHeaderPrologue(File *file, const Parameters & /*params*/) {
|
||||
printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
|
||||
printer->Print(vars, "\n");
|
||||
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
|
||||
printer->Print(vars, file->additional_headers().c_str());
|
||||
printer->Print(vars, "\n");
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
grpc::string GetHeaderIncludes(File *file,
|
||||
grpc::string GetHeaderIncludes(grpc_generator::File *file,
|
||||
const Parameters ¶ms) {
|
||||
grpc::string output;
|
||||
{
|
||||
@@ -122,7 +124,6 @@ grpc::string GetHeaderIncludes(File *file,
|
||||
static const char *headers_strs[] = {
|
||||
"grpc++/impl/codegen/async_stream.h",
|
||||
"grpc++/impl/codegen/async_unary_call.h",
|
||||
"grpc++/impl/codegen/proto_utils.h",
|
||||
"grpc++/impl/codegen/rpc_method.h",
|
||||
"grpc++/impl/codegen/service_type.h",
|
||||
"grpc++/impl/codegen/status.h",
|
||||
@@ -154,7 +155,7 @@ grpc::string GetHeaderIncludes(File *file,
|
||||
}
|
||||
|
||||
void PrintHeaderClientMethodInterfaces(
|
||||
Printer *printer, const Method *method,
|
||||
grpc_generator::Printer *printer, const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars, bool is_public) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = method->input_type_name();
|
||||
@@ -303,8 +304,8 @@ void PrintHeaderClientMethodInterfaces(
|
||||
}
|
||||
}
|
||||
|
||||
void PrintHeaderClientMethod(Printer *printer,
|
||||
const Method *method,
|
||||
void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
||||
const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars,
|
||||
bool is_public) {
|
||||
(*vars)["Method"] = method->name();
|
||||
@@ -445,13 +446,13 @@ void PrintHeaderClientMethod(Printer *printer,
|
||||
}
|
||||
}
|
||||
|
||||
void PrintHeaderClientMethodData(Printer *printer, const Method *method,
|
||||
void PrintHeaderClientMethodData(grpc_generator::Printer *printer, const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Method"] = method->name();
|
||||
printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
|
||||
}
|
||||
|
||||
void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
|
||||
void PrintHeaderServerMethodSync(grpc_generator::Printer *printer, const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = method->input_type_name();
|
||||
@@ -483,8 +484,8 @@ void PrintHeaderServerMethodSync(Printer *printer, const Method *method,
|
||||
}
|
||||
|
||||
void PrintHeaderServerMethodAsync(
|
||||
Printer *printer,
|
||||
const Method *method,
|
||||
grpc_generator::Printer *printer,
|
||||
const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = method->input_type_name();
|
||||
@@ -599,8 +600,8 @@ void PrintHeaderServerMethodAsync(
|
||||
}
|
||||
|
||||
void PrintHeaderServerMethodGeneric(
|
||||
Printer *printer,
|
||||
const Method *method,
|
||||
grpc_generator::Printer *printer,
|
||||
const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = method->input_type_name();
|
||||
@@ -669,8 +670,8 @@ void PrintHeaderServerMethodGeneric(
|
||||
printer->Print(*vars, "};\n");
|
||||
}
|
||||
|
||||
void PrintHeaderService(Printer *printer,
|
||||
const Service *service,
|
||||
void PrintHeaderService(grpc_generator::Printer *printer,
|
||||
const grpc_generator::Service *service,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Service"] = service->name();
|
||||
|
||||
@@ -764,7 +765,7 @@ void PrintHeaderService(Printer *printer,
|
||||
printer->Print("};\n");
|
||||
}
|
||||
|
||||
grpc::string GetHeaderServices(File *file,
|
||||
grpc::string GetHeaderServices(grpc_generator::File *file,
|
||||
const Parameters ¶ms) {
|
||||
grpc::string output;
|
||||
{
|
||||
@@ -795,7 +796,7 @@ grpc::string GetHeaderServices(File *file,
|
||||
return output;
|
||||
}
|
||||
|
||||
grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
|
||||
grpc::string GetHeaderEpilogue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||
grpc::string output;
|
||||
{
|
||||
// Scope the output stream so it closes and finalizes output to the string.
|
||||
@@ -821,7 +822,7 @@ grpc::string GetHeaderEpilogue(File *file, const Parameters & /*params*/) {
|
||||
return output;
|
||||
}
|
||||
|
||||
grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
|
||||
grpc::string GetSourcePrologue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||
grpc::string output;
|
||||
{
|
||||
// Scope the output stream so it closes and finalizes output to the string.
|
||||
@@ -839,13 +840,12 @@ grpc::string GetSourcePrologue(File *file, const Parameters & /*params*/) {
|
||||
printer->Print(vars, "// source: $filename$\n\n");
|
||||
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
|
||||
printer->Print(vars, "#include \"$filename_base$$service_header_ext$\"\n");
|
||||
printer->Print(vars, file->additional_headers().c_str());
|
||||
printer->Print(vars, "\n");
|
||||
printer->Print("\n");
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
grpc::string GetSourceIncludes(File *file,
|
||||
grpc::string GetSourceIncludes(grpc_generator::File *file,
|
||||
const Parameters ¶ms) {
|
||||
grpc::string output;
|
||||
{
|
||||
@@ -867,6 +867,7 @@ grpc::string GetSourceIncludes(File *file,
|
||||
PrintIncludes(printer.get(), headers, params);
|
||||
|
||||
if (!file->package().empty()) {
|
||||
printer->Print("\n");
|
||||
std::vector<grpc::string> parts = file->package_parts();
|
||||
|
||||
for (auto part = parts.begin(); part != parts.end(); part++) {
|
||||
@@ -880,8 +881,8 @@ grpc::string GetSourceIncludes(File *file,
|
||||
return output;
|
||||
}
|
||||
|
||||
void PrintSourceClientMethod(Printer *printer,
|
||||
const Method *method,
|
||||
void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
||||
const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = method->input_type_name();
|
||||
@@ -981,8 +982,8 @@ void PrintSourceClientMethod(Printer *printer,
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSourceServerMethod(Printer *printer,
|
||||
const Method *method,
|
||||
void PrintSourceServerMethod(grpc_generator::Printer *printer,
|
||||
const grpc_generator::Method *method,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Method"] = method->name();
|
||||
(*vars)["Request"] = method->input_type_name();
|
||||
@@ -1040,8 +1041,8 @@ void PrintSourceServerMethod(Printer *printer,
|
||||
}
|
||||
}
|
||||
|
||||
void PrintSourceService(Printer *printer,
|
||||
const Service *service,
|
||||
void PrintSourceService(grpc_generator::Printer *printer,
|
||||
const grpc_generator::Service *service,
|
||||
std::map<grpc::string, grpc::string> *vars) {
|
||||
(*vars)["Service"] = service->name();
|
||||
|
||||
@@ -1153,7 +1154,7 @@ void PrintSourceService(Printer *printer,
|
||||
}
|
||||
}
|
||||
|
||||
grpc::string GetSourceServices(File *file,
|
||||
grpc::string GetSourceServices(grpc_generator::File *file,
|
||||
const Parameters ¶ms) {
|
||||
grpc::string output;
|
||||
{
|
||||
@@ -1182,7 +1183,7 @@ grpc::string GetSourceServices(File *file,
|
||||
return output;
|
||||
}
|
||||
|
||||
grpc::string GetSourceEpilogue(File *file, const Parameters & /*params*/) {
|
||||
grpc::string GetSourceEpilogue(grpc_generator::File *file, const Parameters & /*params*/) {
|
||||
grpc::string temp;
|
||||
|
||||
if (!file->package().empty()) {
|
||||
|
||||
@@ -41,16 +41,7 @@
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
#include <string>
|
||||
#define GRPC_CUSTOM_STRING std::string
|
||||
#endif
|
||||
|
||||
namespace grpc {
|
||||
|
||||
typedef GRPC_CUSTOM_STRING string;
|
||||
|
||||
} // namespace grpc
|
||||
#include "src/compiler/schema_interface.h"
|
||||
|
||||
namespace grpc_cpp_generator {
|
||||
|
||||
@@ -64,83 +55,29 @@ struct Parameters {
|
||||
grpc::string grpc_search_path;
|
||||
};
|
||||
|
||||
// An abstract interface representing a method.
|
||||
struct Method {
|
||||
virtual ~Method() {}
|
||||
|
||||
virtual grpc::string name() const = 0;
|
||||
|
||||
virtual grpc::string input_type_name() const = 0;
|
||||
virtual grpc::string output_type_name() const = 0;
|
||||
|
||||
virtual bool NoStreaming() const = 0;
|
||||
virtual bool ClientOnlyStreaming() const = 0;
|
||||
virtual bool ServerOnlyStreaming() const = 0;
|
||||
virtual bool BidiStreaming() const = 0;
|
||||
};
|
||||
|
||||
// An abstract interface representing a service.
|
||||
struct Service {
|
||||
virtual ~Service() {}
|
||||
|
||||
virtual grpc::string name() const = 0;
|
||||
|
||||
virtual int method_count() const = 0;
|
||||
virtual std::unique_ptr<const Method> method(int i) const = 0;
|
||||
};
|
||||
|
||||
struct Printer {
|
||||
virtual ~Printer() {}
|
||||
|
||||
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
||||
const char *template_string) = 0;
|
||||
virtual void Print(const char *string) = 0;
|
||||
virtual void Indent() = 0;
|
||||
virtual void Outdent() = 0;
|
||||
};
|
||||
|
||||
// An interface that allows the source generated to be output using various
|
||||
// libraries/idls/serializers.
|
||||
struct File {
|
||||
virtual ~File() {}
|
||||
|
||||
virtual grpc::string filename() const = 0;
|
||||
virtual grpc::string filename_without_ext() const = 0;
|
||||
virtual grpc::string message_header_ext() const = 0;
|
||||
virtual grpc::string service_header_ext() const = 0;
|
||||
virtual grpc::string package() const = 0;
|
||||
virtual std::vector<grpc::string> package_parts() const = 0;
|
||||
virtual grpc::string additional_headers() const = 0;
|
||||
|
||||
virtual int service_count() const = 0;
|
||||
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
||||
|
||||
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
|
||||
};
|
||||
|
||||
// Return the prologue of the generated header file.
|
||||
grpc::string GetHeaderPrologue(File *file, const Parameters ¶ms);
|
||||
grpc::string GetHeaderPrologue(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the includes needed for generated header file.
|
||||
grpc::string GetHeaderIncludes(File *file, const Parameters ¶ms);
|
||||
grpc::string GetHeaderIncludes(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the includes needed for generated source file.
|
||||
grpc::string GetSourceIncludes(File *file, const Parameters ¶ms);
|
||||
grpc::string GetSourceIncludes(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the epilogue of the generated header file.
|
||||
grpc::string GetHeaderEpilogue(File *file, const Parameters ¶ms);
|
||||
grpc::string GetHeaderEpilogue(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the prologue of the generated source file.
|
||||
grpc::string GetSourcePrologue(File *file, const Parameters ¶ms);
|
||||
grpc::string GetSourcePrologue(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the services for generated header file.
|
||||
grpc::string GetHeaderServices(File *file, const Parameters ¶ms);
|
||||
grpc::string GetHeaderServices(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the services for generated source file.
|
||||
grpc::string GetSourceServices(File *file, const Parameters ¶ms);
|
||||
grpc::string GetSourceServices(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
// Return the epilogue of the generated source file.
|
||||
grpc::string GetSourceEpilogue(File *file, const Parameters ¶ms);
|
||||
grpc::string GetSourceEpilogue(grpc_generator::File *file, const Parameters ¶ms);
|
||||
|
||||
} // namespace grpc_cpp_generator
|
||||
|
||||
|
||||
437
grpc/src/compiler/go_generator.cc
Normal file
437
grpc/src/compiler/go_generator.cc
Normal file
@@ -0,0 +1,437 @@
|
||||
/*
|
||||
*
|
||||
* 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 AN/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 <map>
|
||||
#include <cctype>
|
||||
#include <sstream>
|
||||
|
||||
#include "src/compiler/go_generator.h"
|
||||
|
||||
template <class T>
|
||||
grpc::string as_string(T x) {
|
||||
std::ostringstream out;
|
||||
out << x;
|
||||
return out.str();
|
||||
}
|
||||
|
||||
namespace grpc_go_generator {
|
||||
|
||||
// Returns string with first letter to lowerCase
|
||||
grpc::string unexportName(grpc::string s) {
|
||||
if (s.empty())
|
||||
return s;
|
||||
s[0] = std::tolower(s[0]);
|
||||
return s;
|
||||
}
|
||||
|
||||
// Returns string with first letter to uppercase
|
||||
grpc::string exportName(grpc::string s) {
|
||||
if (s.empty())
|
||||
return s;
|
||||
s[0] = std::toupper(s[0]);
|
||||
return s;
|
||||
}
|
||||
|
||||
// Generates imports for the service
|
||||
void GenerateImports(grpc_generator::File *file, grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["filename"] = file->filename();
|
||||
printer->Print("//Generated by gRPC Go plugin\n");
|
||||
printer->Print("//If you make any local changes, they will be lost\n");
|
||||
printer->Print(vars, "//source: $filename$\n\n");
|
||||
printer->Print(vars, "package $Package$\n\n");
|
||||
if (file->additional_imports() != "") {
|
||||
printer->Print(file->additional_imports().c_str());
|
||||
printer->Print("\n\n");
|
||||
}
|
||||
printer->Print("import (\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$context$ \"golang.org/x/net/context\"\n");
|
||||
printer->Print(vars, "$grpc$ \"google.golang.org/grpc\"\n");
|
||||
printer->Outdent();
|
||||
printer->Print(")\n\n");
|
||||
}
|
||||
|
||||
// Generates Server method signature source
|
||||
void GenerateServerMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = method->input_name();
|
||||
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->output_name() : vars["CustomMethodIO"];
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "$Method$($context$.Context, *$Request$) (*$Response$, error)");
|
||||
} else if (method->ServerOnlyStreaming()) {
|
||||
printer->Print(vars, "$Method$(*$Request$, $Service$_$Method$Server) error");
|
||||
} else {
|
||||
printer->Print(vars, "$Method$($Service$_$Method$Server) error");
|
||||
}
|
||||
}
|
||||
|
||||
void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = method->input_name();
|
||||
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->output_name() : vars["CustomMethodIO"];
|
||||
vars["FullMethodName"] = "/" + vars["Package"] + "." + vars["Service"] + "/" + vars["Method"];
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "in := new($Request$)\n");
|
||||
printer->Print("if err := dec(in); err != nil { return nil, err }\n");
|
||||
printer->Print(vars, "if interceptor == nil { return srv.($Service$Server).$Method$(ctx, in) }\n");
|
||||
printer->Print(vars, "info := &$grpc$.UnaryServerInfo{\n");
|
||||
printer->Indent();
|
||||
printer->Print("Server: srv,\n");
|
||||
printer->Print(vars, "FullMethod: \"$FullMethodName$\",\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
printer->Print(vars, "handler := func(ctx $context$.Context, req interface{}) (interface{}, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "return srv.($Service$Server).$Method$(ctx, req.(* $Request$))\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n");
|
||||
printer->Print("return interceptor(ctx, in, info, handler)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
return;
|
||||
}
|
||||
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Server";
|
||||
printer->Print(vars, "func $Handler$(srv interface{}, stream $grpc$.ServerStream) error {\n");
|
||||
printer->Indent();
|
||||
if (method->ServerOnlyStreaming()) {
|
||||
printer->Print(vars, "m := new($Request$)\n");
|
||||
printer->Print(vars, "if err := stream.RecvMsg(m); err != nil { return err }\n");
|
||||
printer->Print(vars, "return srv.($Service$Server).$Method$(m, &$StreamType${stream})\n");
|
||||
} else {
|
||||
printer->Print(vars, "return srv.($Service$Server).$Method$(&$StreamType${stream})\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
bool genSend = method->BidiStreaming() || method->ServerOnlyStreaming();
|
||||
bool genRecv = method->BidiStreaming() || method->ClientOnlyStreaming();
|
||||
bool genSendAndClose = method->ClientOnlyStreaming();
|
||||
|
||||
printer->Print(vars, "type $Service$_$Method$Server interface { \n");
|
||||
printer->Indent();
|
||||
if (genSend) {
|
||||
printer->Print(vars, "Send(* $Response$) error\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "Recv() (* $Request$, error)\n");
|
||||
}
|
||||
if (genSendAndClose) {
|
||||
printer->Print(vars, "SendAndClose(* $Response$) error\n");
|
||||
}
|
||||
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
printer->Print(vars, "type $StreamType$ struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$grpc$.ServerStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
if (genSend) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Send(m *$Response$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Request$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "m := new($Request$)\n");
|
||||
printer->Print("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }\n");
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
if (genSendAndClose) {
|
||||
printer->Print(vars, "func (x *$StreamType$) SendAndClose(m *$Response$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ServerStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Generates Client method signature source
|
||||
void GenerateClientMethodSignature(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = ", in *" + ((vars["CustomMethodIO"] == "") ? method->input_name() : vars["CustomMethodIO"]);
|
||||
if (method->ClientOnlyStreaming() || method->BidiStreaming()) {
|
||||
vars["Request"] = "";
|
||||
}
|
||||
vars["Response"] = "* " + method->output_name();
|
||||
if (method->ClientOnlyStreaming() || method->BidiStreaming() || method->ServerOnlyStreaming()) {
|
||||
vars["Response"] = vars["Service"] + "_" + vars["Method"] + "Client" ;
|
||||
}
|
||||
printer->Print(vars, "$Method$(ctx $context$.Context$Request$, \n\topts... $grpc$.CallOption) ($Response$, error)");
|
||||
}
|
||||
|
||||
// Generates Client method source
|
||||
void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::Printer *printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
printer->Print(vars, "func (c *$ServiceUnexported$Client) ");
|
||||
GenerateClientMethodSignature(method, printer, vars);
|
||||
printer->Print(" {\n");
|
||||
printer->Indent();
|
||||
vars["Method"] = exportName(method->name());
|
||||
vars["Request"] = (vars["CustomMethodIO"] == "") ? method->input_name() : vars["CustomMethodIO"];
|
||||
vars["Response"] = method->output_name();
|
||||
vars["FullMethodName"] = "/" + vars["Package"] + "." + vars["Service"] + "/" + vars["Method"];
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print(vars, "out := new($Response$)\n");
|
||||
printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
|
||||
printer->Print("if err != nil { return nil, err }\n");
|
||||
printer->Print("return out, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
return;
|
||||
}
|
||||
vars["StreamType"] = vars["ServiceUnexported"] + vars["Method"] + "Client";
|
||||
printer->Print(vars, "stream, err := $grpc$.NewClientStream(ctx, &$MethodDesc$, c.cc, \"$FullMethodName$\", opts...)\n");
|
||||
printer->Print("if err != nil { return nil, err }\n");
|
||||
|
||||
printer->Print(vars, "x := &$StreamType${stream}\n");
|
||||
if (method->ServerOnlyStreaming()) {
|
||||
printer->Print("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }\n");
|
||||
printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
|
||||
}
|
||||
printer->Print("return x,nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
bool genSend = method->BidiStreaming() || method->ClientOnlyStreaming();
|
||||
bool genRecv = method->BidiStreaming() || method->ServerOnlyStreaming();
|
||||
bool genCloseAndRecv = method->ClientOnlyStreaming();
|
||||
|
||||
//Stream interface
|
||||
printer->Print(vars, "type $Service$_$Method$Client interface {\n");
|
||||
printer->Indent();
|
||||
if (genSend) {
|
||||
printer->Print(vars, "Send(*$Request$) error\n");
|
||||
}
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "Recv() (*$Response$, error)\n");
|
||||
}
|
||||
if (genCloseAndRecv) {
|
||||
printer->Print(vars, "CloseAndRecv() (*$Response$, error)\n");
|
||||
}
|
||||
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
//Stream Client
|
||||
printer->Print(vars, "type $StreamType$ struct{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "$grpc$.ClientStream\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
if (genSend) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Send(m *$Request$) error {\n");
|
||||
printer->Indent();
|
||||
printer->Print("return x.ClientStream.SendMsg(m)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
if (genRecv) {
|
||||
printer->Print(vars, "func (x *$StreamType$) Recv() (*$Response$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "m := new($Response$)\n");
|
||||
printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
|
||||
if (genCloseAndRecv) {
|
||||
printer->Print(vars, "func (x *$StreamType$) CloseAndRecv() (*$Response$, error) {\n");
|
||||
printer->Indent();
|
||||
printer->Print("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }\n");
|
||||
printer->Print(vars, "m := new ($Response$)\n");
|
||||
printer->Print("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }\n");
|
||||
printer->Print("return m, nil\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
// Generates client API for the service
|
||||
void GenerateService(const grpc_generator::Service *service, grpc_generator::Printer* printer,
|
||||
std::map<grpc::string, grpc::string> vars) {
|
||||
vars["Service"] = exportName(service->name());
|
||||
// Client Interface
|
||||
printer->Print(vars, "// Client API for $Service$ service\n");
|
||||
printer->Print(vars, "type $Service$Client interface{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateClientMethodSignature(service->method(i).get(), printer, vars);
|
||||
printer->Print("\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
// Client structure
|
||||
vars["ServiceUnexported"] = unexportName(vars["Service"]);
|
||||
printer->Print(vars, "type $ServiceUnexported$Client struct {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "cc *$grpc$.ClientConn\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
// NewClient
|
||||
printer->Print(vars, "func New$Service$Client(cc *$grpc$.ClientConn) $Service$Client {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "return &$ServiceUnexported$Client{cc}");
|
||||
printer->Outdent();
|
||||
printer->Print("\n}\n\n");
|
||||
|
||||
int unary_methods = 0, streaming_methods = 0;
|
||||
vars["ServiceDesc"] = "_" + vars["Service"] + "_serviceDesc";
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
if (method->NoStreaming()) {
|
||||
vars["MethodDesc"] = vars["ServiceDesc"] + ".Method[" + as_string(unary_methods) + "]";
|
||||
unary_methods++;
|
||||
} else {
|
||||
vars["MethodDesc"] = vars["ServiceDesc"] + ".Streams[" + as_string(streaming_methods) + "]";
|
||||
streaming_methods++;
|
||||
}
|
||||
GenerateClientMethod(method.get(), printer, vars);
|
||||
}
|
||||
|
||||
//Server Interface
|
||||
printer->Print(vars, "// Server API for $Service$ service\n");
|
||||
printer->Print(vars, "type $Service$Server interface {\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateServerMethodSignature(service->method(i).get(), printer, vars);
|
||||
printer->Print("\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
// Server registration.
|
||||
printer->Print(vars, "func Register$Service$Server(s *$grpc$.Server, srv $Service$Server) {\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "s.RegisterService(&$ServiceDesc$, srv)\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
GenerateServerMethod(service->method(i).get(), printer, vars);
|
||||
printer->Print("\n");
|
||||
}
|
||||
|
||||
|
||||
//Service Descriptor
|
||||
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "ServiceName: \"$Package$.$Service$\",\n");
|
||||
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
|
||||
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
vars["Method"] = method->name();
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (method->NoStreaming()) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "MethodName: \"$Method$\",\n");
|
||||
printer->Print(vars, "Handler: $Handler$, \n");
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
printer->Print(vars, "Streams: []$grpc$.StreamDesc{\n");
|
||||
printer->Indent();
|
||||
for (int i = 0; i < service->method_count(); i++) {
|
||||
auto method = service->method(i);
|
||||
vars["Method"] = method->name();
|
||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||
if (!method->NoStreaming()) {
|
||||
printer->Print("{\n");
|
||||
printer->Indent();
|
||||
printer->Print(vars, "StreamName: \"$Method$\",\n");
|
||||
printer->Print(vars, "Handler: $Handler$, \n");
|
||||
if (method->ClientOnlyStreaming()) {
|
||||
printer->Print("ClientStreams: true,\n");
|
||||
} else if (method->ServerOnlyStreaming()) {
|
||||
printer->Print("ServerStreams: true,\n");
|
||||
} else {
|
||||
printer->Print("ServerStreams: true,\n");
|
||||
printer->Print("ClientStreams: true,\n");
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
}
|
||||
}
|
||||
printer->Outdent();
|
||||
printer->Print("},\n");
|
||||
printer->Outdent();
|
||||
printer->Print("}\n\n");
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Returns source for the service
|
||||
grpc::string GenerateServiceSource(grpc_generator::File *file,
|
||||
const grpc_generator::Service *service,
|
||||
grpc_go_generator::Parameters *parameters) {
|
||||
grpc::string out;
|
||||
auto p = file->CreatePrinter(&out);
|
||||
auto printer = p.get();
|
||||
std::map<grpc::string, grpc::string> vars;
|
||||
vars["Package"] = parameters->package_name;
|
||||
vars["grpc"] = "grpc";
|
||||
vars["context"] = "context";
|
||||
GenerateImports(file, printer, vars);
|
||||
if (parameters->custom_method_io_type != "") {
|
||||
vars["CustomMethodIO"] = parameters->custom_method_io_type;
|
||||
}
|
||||
GenerateService(service, printer, vars);
|
||||
return out;
|
||||
}
|
||||
}// Namespace grpc_go_generator
|
||||
61
grpc/src/compiler/go_generator.h
Normal file
61
grpc/src/compiler/go_generator.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
*
|
||||
* 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_GO_GENERATOR_H
|
||||
#define GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||
|
||||
//go generator is used to generate GRPC code for serialization system, such as flatbuffers
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#include "src/compiler/schema_interface.h"
|
||||
|
||||
namespace grpc_go_generator {
|
||||
|
||||
struct Parameters {
|
||||
//Defines the custom parameter types for methods
|
||||
//eg: flatbuffers uses flatbuffers.Builder as input for the client and output for the server
|
||||
grpc::string custom_method_io_type;
|
||||
|
||||
//Package name for the service
|
||||
grpc::string package_name;
|
||||
};
|
||||
|
||||
// Return the source of the generated service file.
|
||||
grpc::string GenerateServiceSource(grpc_generator::File *file,
|
||||
const grpc_generator::Service *service,
|
||||
grpc_go_generator::Parameters *parameters);
|
||||
|
||||
}
|
||||
|
||||
#endif // GRPC_INTERNAL_COMPILER_GO_GENERATOR_H
|
||||
112
grpc/src/compiler/schema_interface.h
Normal file
112
grpc/src/compiler/schema_interface.h
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
*
|
||||
* 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_SCHEMA_INTERFACE_H
|
||||
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
#ifndef GRPC_CUSTOM_STRING
|
||||
#include <string>
|
||||
#define GRPC_CUSTOM_STRING std::string
|
||||
#endif
|
||||
|
||||
namespace grpc {
|
||||
|
||||
typedef GRPC_CUSTOM_STRING string;
|
||||
|
||||
} // namespace grpc
|
||||
|
||||
namespace grpc_generator {
|
||||
|
||||
// An abstract interface representing a method.
|
||||
struct Method {
|
||||
virtual ~Method() {}
|
||||
|
||||
virtual grpc::string name() const = 0;
|
||||
|
||||
virtual grpc::string input_type_name() const = 0;
|
||||
virtual grpc::string output_type_name() const = 0;
|
||||
virtual grpc::string input_name() const = 0;
|
||||
virtual grpc::string output_name() const = 0;
|
||||
|
||||
virtual bool NoStreaming() const = 0;
|
||||
virtual bool ClientOnlyStreaming() const = 0;
|
||||
virtual bool ServerOnlyStreaming() const = 0;
|
||||
virtual bool BidiStreaming() const = 0;
|
||||
};
|
||||
|
||||
// An abstract interface representing a service.
|
||||
struct Service {
|
||||
virtual ~Service() {}
|
||||
|
||||
virtual grpc::string name() const = 0;
|
||||
|
||||
virtual int method_count() const = 0;
|
||||
virtual std::unique_ptr<const Method> method(int i) const = 0;
|
||||
};
|
||||
|
||||
struct Printer {
|
||||
virtual ~Printer() {}
|
||||
|
||||
virtual void Print(const std::map<grpc::string, grpc::string> &vars,
|
||||
const char *template_string) = 0;
|
||||
virtual void Print(const char *string) = 0;
|
||||
virtual void Indent() = 0;
|
||||
virtual void Outdent() = 0;
|
||||
};
|
||||
|
||||
// An interface that allows the source generated to be output using various
|
||||
// libraries/idls/serializers.
|
||||
struct File {
|
||||
virtual ~File() {}
|
||||
|
||||
virtual grpc::string filename() const = 0;
|
||||
virtual grpc::string filename_without_ext() const = 0;
|
||||
virtual grpc::string message_header_ext() const = 0;
|
||||
virtual grpc::string service_header_ext() const = 0;
|
||||
virtual grpc::string package() const = 0;
|
||||
virtual std::vector<grpc::string> package_parts() const = 0;
|
||||
virtual grpc::string additional_headers() const = 0;
|
||||
virtual grpc::string additional_imports() const = 0;
|
||||
|
||||
virtual int service_count() const = 0;
|
||||
virtual std::unique_ptr<const Service> service(int i) const = 0;
|
||||
|
||||
virtual std::unique_ptr<Printer> CreatePrinter(grpc::string *str) const = 0;
|
||||
};
|
||||
} // namespace grpc_generator
|
||||
|
||||
#endif // GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||
93
grpc/tests/go_test.go
Normal file
93
grpc/tests/go_test.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package testing
|
||||
|
||||
import (
|
||||
"../../tests/MyGame/Example"
|
||||
|
||||
"net"
|
||||
"testing"
|
||||
|
||||
"golang.org/x/net/context"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type server struct{}
|
||||
|
||||
// test used to send and receive in grpc methods
|
||||
var test = "Flatbuffers"
|
||||
var addr = "0.0.0.0:50051"
|
||||
|
||||
// gRPC server store method
|
||||
func (s *server) Store(context context.Context, in *Example.Monster) (*flatbuffers.Builder, error) {
|
||||
b := flatbuffers.NewBuilder(0)
|
||||
i := b.CreateString(test)
|
||||
Example.StatStart(b)
|
||||
Example.StatAddId(b, i)
|
||||
b.Finish(Example.StatEnd(b))
|
||||
return b, nil
|
||||
|
||||
}
|
||||
|
||||
// gRPC server retrieve method
|
||||
func (s *server) Retrieve(context context.Context, in *Example.Stat) (*flatbuffers.Builder, error) {
|
||||
b := flatbuffers.NewBuilder(0)
|
||||
i := b.CreateString(test)
|
||||
Example.MonsterStart(b)
|
||||
Example.MonsterAddName(b, i)
|
||||
b.Finish(Example.MonsterEnd(b))
|
||||
return b, nil
|
||||
}
|
||||
|
||||
func StoreClient(c Example.MonsterStorageClient, t *testing.T) {
|
||||
b := flatbuffers.NewBuilder(0)
|
||||
i := b.CreateString(test)
|
||||
Example.MonsterStart(b)
|
||||
Example.MonsterAddName(b, i)
|
||||
b.Finish(Example.MonsterEnd(b))
|
||||
out, err := c.Store(context.Background(), b)
|
||||
if err != nil {
|
||||
t.Fatalf("Store client failed: %v", err)
|
||||
}
|
||||
if string(out.Id()) != test {
|
||||
t.Errorf("StoreClient failed: expected=%s, got=%s\n", test, out.Id())
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func RetrieveClient(c Example.MonsterStorageClient, t *testing.T) {
|
||||
b := flatbuffers.NewBuilder(0)
|
||||
i := b.CreateString(test)
|
||||
Example.StatStart(b)
|
||||
Example.StatAddId(b, i)
|
||||
b.Finish(Example.StatEnd(b))
|
||||
out, err := c.Retrieve(context.Background(), b)
|
||||
if err != nil {
|
||||
t.Fatalf("Retrieve client failed: %v", err)
|
||||
}
|
||||
if string(out.Name()) != test {
|
||||
t.Errorf("RetrieveClient failed: expected=%s, got=%s\n", test, out.Name())
|
||||
t.Fail()
|
||||
}
|
||||
}
|
||||
|
||||
func TestGRPC(t *testing.T) {
|
||||
lis, err := net.Listen("tcp", addr)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to listen: %v", err)
|
||||
}
|
||||
ser := grpc.NewServer(grpc.CustomCodec(flatbuffers.FlatbuffersCodec{}))
|
||||
Example.RegisterMonsterStorageServer(ser, &server{})
|
||||
go func() {
|
||||
if err := ser.Serve(lis); err != nil {
|
||||
t.Fatalf("Failed to serve: %v", err)
|
||||
t.FailNow()
|
||||
}
|
||||
}()
|
||||
conn, err := grpc.Dial(addr, grpc.WithInsecure(), grpc.WithCodec(flatbuffers.FlatbuffersCodec{}))
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to connect: %v", err)
|
||||
}
|
||||
defer conn.Close()
|
||||
client := Example.NewMonsterStorageClient(conn)
|
||||
StoreClient(client, t)
|
||||
RetrieveClient(client, t)
|
||||
}
|
||||
@@ -44,7 +44,7 @@ class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
||||
}
|
||||
virtual ::grpc::Status Retrieve(::grpc::ServerContext *context,
|
||||
const flatbuffers::BufferRef<Stat> *request,
|
||||
flatbuffers::BufferRef<Monster> *response)
|
||||
::grpc::ServerWriter< flatbuffers::BufferRef<Monster>>* writer)
|
||||
override {
|
||||
assert(false); // We're not actually using this RPC.
|
||||
return grpc::Status::CANCELLED;
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||
|
||||
#define FLATBUFFERS_VERSION_MAJOR 1
|
||||
#define FLATBUFFERS_VERSION_MINOR 0
|
||||
#define FLATBUFFERS_VERSION_MINOR 5
|
||||
#define FLATBUFFERS_VERSION_REVISION 0
|
||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||
@@ -130,6 +130,9 @@ typedef uintmax_t largest_scalar_t;
|
||||
// In 32bits, this evaluates to 2GB - 1
|
||||
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
|
||||
|
||||
// We support aligning the contents of buffers up to this size.
|
||||
#define FLATBUFFERS_MAX_ALIGNMENT 16
|
||||
|
||||
#ifndef FLATBUFFERS_CPP98_STL
|
||||
// Pointer to relinquished memory.
|
||||
typedef std::unique_ptr<uint8_t, std::function<void(uint8_t * /* unused */)>>
|
||||
@@ -249,13 +252,13 @@ template<typename T> struct IndirectHelper<const T *> {
|
||||
// calling Get() for every element.
|
||||
template<typename T, typename IT>
|
||||
struct VectorIterator
|
||||
: public std::iterator<std::input_iterator_tag, IT, uoffset_t> {
|
||||
: public std::iterator<std::random_access_iterator_tag, IT, uoffset_t> {
|
||||
|
||||
typedef std::iterator<std::input_iterator_tag, IT, uoffset_t> super_type;
|
||||
typedef std::iterator<std::random_access_iterator_tag, IT, uoffset_t> super_type;
|
||||
|
||||
public:
|
||||
VectorIterator(const uint8_t *data, uoffset_t i) :
|
||||
data_(data + IndirectHelper<T>::element_stride * i) {};
|
||||
data_(data + IndirectHelper<T>::element_stride * i) {}
|
||||
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
||||
#ifndef FLATBUFFERS_CPP98_STL
|
||||
VectorIterator(VectorIterator &&other) : data_(std::move(other.data_)) {}
|
||||
@@ -271,15 +274,15 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const VectorIterator& other) const {
|
||||
bool operator==(const VectorIterator &other) const {
|
||||
return data_ == other.data_;
|
||||
}
|
||||
|
||||
bool operator!=(const VectorIterator& other) const {
|
||||
bool operator!=(const VectorIterator &other) const {
|
||||
return data_ != other.data_;
|
||||
}
|
||||
|
||||
ptrdiff_t operator-(const VectorIterator& other) const {
|
||||
ptrdiff_t operator-(const VectorIterator &other) const {
|
||||
return (data_ - other.data_) / IndirectHelper<T>::element_stride;
|
||||
}
|
||||
|
||||
@@ -297,11 +300,40 @@ public:
|
||||
}
|
||||
|
||||
VectorIterator operator++(int) {
|
||||
VectorIterator temp(data_,0);
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ += IndirectHelper<T>::element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator+(const uoffset_t &offset) {
|
||||
return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride, 0);
|
||||
}
|
||||
|
||||
VectorIterator& operator+=(const uoffset_t &offset) {
|
||||
data_ += offset * IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator &operator--() {
|
||||
data_ -= IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator--(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ -= IndirectHelper<T>::element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator-(const uoffset_t &offset) {
|
||||
return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride, 0);
|
||||
}
|
||||
|
||||
VectorIterator& operator-=(const uoffset_t &offset) {
|
||||
data_ -= offset * IndirectHelper<T>::element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
const uint8_t *data_;
|
||||
};
|
||||
@@ -580,6 +612,10 @@ inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
|
||||
template <typename T> const T* data(const std::vector<T> &v) {
|
||||
return v.empty() ? nullptr : &v.front();
|
||||
}
|
||||
template <typename T> T* data(std::vector<T> &v) {
|
||||
return v.empty() ? nullptr : &v.front();
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
/// @addtogroup flatbuffers_cpp_api
|
||||
@@ -658,6 +694,16 @@ FLATBUFFERS_FINAL_CLASS
|
||||
}
|
||||
#endif
|
||||
|
||||
/// @brief get the minimum alignment this buffer needs to be accessed
|
||||
/// properly. This is only known once all elements have been written (after
|
||||
/// you call Finish()). You can use this information if you need to embed
|
||||
/// a FlatBuffer in some other buffer, such that you can later read it
|
||||
/// without first having to copy it into its own buffer.
|
||||
size_t GetBufferMinAlignment() {
|
||||
Finished();
|
||||
return minalign_;
|
||||
}
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
void Finished() const {
|
||||
// If you get this assert, you're attempting to get access a buffer
|
||||
@@ -1110,7 +1156,7 @@ FLATBUFFERS_FINAL_CLASS
|
||||
/// where the vector is stored.
|
||||
template<typename T> Offset<Vector<Offset<T>>> CreateVectorOfSortedTables(
|
||||
std::vector<Offset<T>> *v) {
|
||||
return CreateVectorOfSortedTables(v->data(), v->size());
|
||||
return CreateVectorOfSortedTables(data(*v), v->size());
|
||||
}
|
||||
|
||||
/// @brief Specialized version of `CreateVector` for non-copying use cases.
|
||||
@@ -1153,17 +1199,20 @@ FLATBUFFERS_FINAL_CLASS
|
||||
/// will be prefixed with a standard FlatBuffers file header.
|
||||
template<typename T> void Finish(Offset<T> root,
|
||||
const char *file_identifier = nullptr) {
|
||||
NotNested();
|
||||
// This will cause the whole buffer to be aligned.
|
||||
PreAlign(sizeof(uoffset_t) + (file_identifier ? kFileIdentifierLength : 0),
|
||||
minalign_);
|
||||
if (file_identifier) {
|
||||
assert(strlen(file_identifier) == kFileIdentifierLength);
|
||||
buf_.push(reinterpret_cast<const uint8_t *>(file_identifier),
|
||||
kFileIdentifierLength);
|
||||
}
|
||||
PushElement(ReferTo(root.o)); // Location of root.
|
||||
finished = true;
|
||||
|
||||
Finish(root.o, file_identifier, false);
|
||||
}
|
||||
|
||||
/// @brief Finish a buffer with a 32 bit size field pre-fixed (size of the
|
||||
/// buffer following the size field). These buffers are NOT compatible
|
||||
/// with standard buffers created by Finish, i.e. you can't call GetRoot
|
||||
/// on them, you have to use GetSizePrefixedRoot instead.
|
||||
/// All >32 bit quantities in this buffer will be aligned when the whole
|
||||
/// size pre-fixed buffer is aligned.
|
||||
/// These kinds of buffers are useful for creating a stream of FlatBuffers.
|
||||
template<typename T> void FinishSizePrefixed(Offset<T> root,
|
||||
const char *file_identifier = nullptr) {
|
||||
Finish(root.o, file_identifier, true);
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -1171,6 +1220,25 @@ FLATBUFFERS_FINAL_CLASS
|
||||
FlatBufferBuilder(const FlatBufferBuilder &);
|
||||
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
|
||||
|
||||
void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
|
||||
NotNested();
|
||||
// This will cause the whole buffer to be aligned.
|
||||
PreAlign((size_prefix ? sizeof(uoffset_t) : 0) +
|
||||
sizeof(uoffset_t) +
|
||||
(file_identifier ? kFileIdentifierLength : 0),
|
||||
minalign_);
|
||||
if (file_identifier) {
|
||||
assert(strlen(file_identifier) == kFileIdentifierLength);
|
||||
buf_.push(reinterpret_cast<const uint8_t *>(file_identifier),
|
||||
kFileIdentifierLength);
|
||||
}
|
||||
PushElement(ReferTo(root)); // Location of root.
|
||||
if (size_prefix) {
|
||||
PushElement(GetSize());
|
||||
}
|
||||
finished = true;
|
||||
}
|
||||
|
||||
struct FieldLoc {
|
||||
uoffset_t off;
|
||||
voffset_t id;
|
||||
@@ -1224,7 +1292,11 @@ template<typename T> const T *GetRoot(const void *buf) {
|
||||
return GetMutableRoot<T>(const_cast<void *>(buf));
|
||||
}
|
||||
|
||||
/// Helpers to get a typed pointer to objects that are currently beeing built.
|
||||
template<typename T> const T *GetSizePrefixedRoot(const void *buf) {
|
||||
return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(uoffset_t));
|
||||
}
|
||||
|
||||
/// Helpers to get a typed pointer to objects that are currently being built.
|
||||
/// @warning Creating new objects will lead to reallocations and invalidates
|
||||
/// the pointer!
|
||||
template<typename T> T *GetMutableTemporaryPointer(FlatBufferBuilder &fbb,
|
||||
@@ -1252,7 +1324,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
: buf_(buf), end_(buf + buf_len), depth_(0), max_depth_(_max_depth),
|
||||
num_tables_(0), max_tables_(_max_tables)
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
, upper_bound_(buf)
|
||||
, upper_bound_(buf)
|
||||
#endif
|
||||
{}
|
||||
|
||||
@@ -1348,16 +1420,17 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Verify this whole buffer, starting with root type T.
|
||||
template<typename T> bool VerifyBuffer(const char *identifier) {
|
||||
if (identifier && (size_t(end_ - buf_) < 2 * sizeof(flatbuffers::uoffset_t) ||
|
||||
!BufferHasIdentifier(buf_, identifier))) {
|
||||
template<typename T> bool VerifyBufferFromStart(const char *identifier,
|
||||
const uint8_t *start) {
|
||||
if (identifier &&
|
||||
(size_t(end_ - start) < 2 * sizeof(flatbuffers::uoffset_t) ||
|
||||
!BufferHasIdentifier(start, identifier))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Call T::Verify, which must be in the generated code for this type.
|
||||
return Verify<uoffset_t>(buf_) &&
|
||||
reinterpret_cast<const T *>(buf_ + ReadScalar<uoffset_t>(buf_))->
|
||||
return Verify<uoffset_t>(start) &&
|
||||
reinterpret_cast<const T *>(start + ReadScalar<uoffset_t>(start))->
|
||||
Verify(*this)
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
&& GetComputedSize()
|
||||
@@ -1365,6 +1438,17 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
;
|
||||
}
|
||||
|
||||
// Verify this whole buffer, starting with root type T.
|
||||
template<typename T> bool VerifyBuffer(const char *identifier) {
|
||||
return VerifyBufferFromStart<T>(identifier, buf_);
|
||||
}
|
||||
|
||||
template<typename T> bool VerifySizePrefixedBuffer(const char *identifier) {
|
||||
return Verify<uoffset_t>(buf_) &&
|
||||
ReadScalar<uoffset_t>(buf_) == end_ - buf_ - sizeof(uoffset_t) &&
|
||||
VerifyBufferFromStart<T>(identifier, buf_ + sizeof(uoffset_t));
|
||||
}
|
||||
|
||||
// Called at the start of a table to increase counters measuring data
|
||||
// structure depth and amount, and possibly bails out with false if
|
||||
// limits set by the constructor have been hit. Needs to be balanced
|
||||
@@ -1398,9 +1482,9 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
size_t max_depth_;
|
||||
size_t num_tables_;
|
||||
size_t max_tables_;
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
mutable const uint8_t *upper_bound_;
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
// Convenient way to bundle a buffer and its length, to pass it around
|
||||
@@ -1418,7 +1502,7 @@ template<typename T> struct BufferRef : BufferRefBase {
|
||||
|
||||
bool Verify() {
|
||||
Verifier verifier(buf, len);
|
||||
return verifier.VerifyBuffer<T>();
|
||||
return verifier.VerifyBuffer<T>(nullptr);
|
||||
}
|
||||
|
||||
uint8_t *buf;
|
||||
@@ -1436,11 +1520,6 @@ class Struct FLATBUFFERS_FINAL_CLASS {
|
||||
return ReadScalar<T>(&data_[o]);
|
||||
}
|
||||
|
||||
template<typename T> T GetPointer(uoffset_t o) const {
|
||||
auto p = &data_[o];
|
||||
return reinterpret_cast<T>(p + ReadScalar<uoffset_t>(p));
|
||||
}
|
||||
|
||||
template<typename T> T GetStruct(uoffset_t o) const {
|
||||
return reinterpret_cast<T>(&data_[o]);
|
||||
}
|
||||
@@ -1456,11 +1535,15 @@ class Struct FLATBUFFERS_FINAL_CLASS {
|
||||
// omitted and added at will, but uses an extra indirection to read.
|
||||
class Table {
|
||||
public:
|
||||
const uint8_t *GetVTable() const {
|
||||
return data_ - ReadScalar<soffset_t>(data_);
|
||||
}
|
||||
|
||||
// This gets the field offset for any of the functions below it, or 0
|
||||
// if the field was not present.
|
||||
voffset_t GetOptionalFieldOffset(voffset_t field) const {
|
||||
// The vtable offset is always at the start.
|
||||
auto vtable = data_ - ReadScalar<soffset_t>(data_);
|
||||
auto vtable = GetVTable();
|
||||
// The first element is the size of the vtable (fields + type id + itself).
|
||||
auto vtsize = ReadScalar<voffset_t>(vtable);
|
||||
// If the field we're accessing is outside the vtable, we're reading older
|
||||
@@ -1513,8 +1596,6 @@ class Table {
|
||||
return const_cast<Table *>(this)->GetAddressOf(field);
|
||||
}
|
||||
|
||||
uint8_t *GetVTable() { return data_ - ReadScalar<soffset_t>(data_); }
|
||||
|
||||
bool CheckField(voffset_t field) const {
|
||||
return GetOptionalFieldOffset(field) != 0;
|
||||
}
|
||||
@@ -1524,7 +1605,7 @@ class Table {
|
||||
bool VerifyTableStart(Verifier &verifier) const {
|
||||
// Check the vtable offset.
|
||||
if (!verifier.Verify<soffset_t>(data_)) return false;
|
||||
auto vtable = data_ - ReadScalar<soffset_t>(data_);
|
||||
auto vtable = GetVTable();
|
||||
// Check the vtable size field, then check vtable fits in its entirety.
|
||||
return verifier.VerifyComplexity() &&
|
||||
verifier.Verify<voffset_t>(vtable) &&
|
||||
@@ -1559,12 +1640,68 @@ class Table {
|
||||
uint8_t data_[1];
|
||||
};
|
||||
|
||||
/// @brief This can compute the start of a FlatBuffer from a root pointer, i.e.
|
||||
/// it is the opposite transformation of GetRoot().
|
||||
/// This may be useful if you want to pass on a root and have the recipient
|
||||
/// delete the buffer afterwards.
|
||||
inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
||||
auto table = reinterpret_cast<const Table *>(root);
|
||||
auto vtable = table->GetVTable();
|
||||
// Either the vtable is before the root or after the root.
|
||||
auto start = std::min(vtable, reinterpret_cast<const uint8_t *>(root));
|
||||
// Align to at least sizeof(uoffset_t).
|
||||
start = reinterpret_cast<const uint8_t *>(
|
||||
reinterpret_cast<uintptr_t>(start) & ~(sizeof(uoffset_t) - 1));
|
||||
// Additionally, there may be a file_identifier in the buffer, and the root
|
||||
// offset. The buffer may have been aligned to any size between
|
||||
// sizeof(uoffset_t) and FLATBUFFERS_MAX_ALIGNMENT (see "force_align").
|
||||
// Sadly, the exact alignment is only known when constructing the buffer,
|
||||
// since it depends on the presence of values with said alignment properties.
|
||||
// So instead, we simply look at the next uoffset_t values (root,
|
||||
// file_identifier, and alignment padding) to see which points to the root.
|
||||
// None of the other values can "impersonate" the root since they will either
|
||||
// be 0 or four ASCII characters.
|
||||
static_assert(FlatBufferBuilder::kFileIdentifierLength == sizeof(uoffset_t),
|
||||
"file_identifier is assumed to be the same size as uoffset_t");
|
||||
for (auto possible_roots = FLATBUFFERS_MAX_ALIGNMENT / sizeof(uoffset_t) + 1;
|
||||
possible_roots;
|
||||
possible_roots--) {
|
||||
start -= sizeof(uoffset_t);
|
||||
if (ReadScalar<uoffset_t>(start) + start ==
|
||||
reinterpret_cast<const uint8_t *>(root)) return start;
|
||||
}
|
||||
// We didn't find the root, either the "root" passed isn't really a root,
|
||||
// or the buffer is corrupt.
|
||||
// Assert, because calling this function with bad data may cause reads
|
||||
// outside of buffer boundaries.
|
||||
assert(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Base class for native objects (FlatBuffer data de-serialized into native
|
||||
// C++ data structures).
|
||||
// Contains no functionality, purely documentative.
|
||||
struct NativeTable {
|
||||
};
|
||||
|
||||
/// @brief Function types to be used with resolving hashes into objects and
|
||||
/// back again. The resolver gets a pointer to a field inside an object API
|
||||
/// object that is of the type specified in the schema using the attribute
|
||||
/// `cpp_type` (it is thus important whatever you write to this address
|
||||
/// matches that type). The value of this field is initially null, so you
|
||||
/// may choose to implement a delayed binding lookup using this function
|
||||
/// if you wish. The resolver does the opposite lookup, for when the object
|
||||
/// is being serialized again.
|
||||
typedef uint64_t hash_value_t;
|
||||
#ifdef FLATBUFFERS_CPP98_STL
|
||||
typedef void (*resolver_function_t)(void **pointer_adr, hash_value_t hash);
|
||||
typedef hash_value_t (*rehasher_function_t)(void *pointer);
|
||||
#else
|
||||
typedef std::function<void (void **pointer_adr, hash_value_t hash)>
|
||||
resolver_function_t;
|
||||
typedef std::function<hash_value_t (void *pointer)> rehasher_function_t;
|
||||
#endif
|
||||
|
||||
// Helper function to test if a field is present, using any of the field
|
||||
// enums in the generated code.
|
||||
// `table` must be a generated table type. Since this is a template parameter,
|
||||
|
||||
@@ -102,6 +102,8 @@ inline bool IsInteger(BaseType t) { return t >= BASE_TYPE_UTYPE &&
|
||||
t <= BASE_TYPE_ULONG; }
|
||||
inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT ||
|
||||
t == BASE_TYPE_DOUBLE; }
|
||||
inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
||||
t == BASE_TYPE_ULONG; }
|
||||
|
||||
extern const char *const kTypeNames[];
|
||||
extern const char kTypeSizes[];
|
||||
@@ -234,6 +236,8 @@ struct FieldDef : public Definition {
|
||||
// written in new data nor accessed in new code.
|
||||
bool required; // Field must always be present.
|
||||
bool key; // Field functions as a key for creating sorted vectors.
|
||||
bool native_inline; // Field will be defined inline (instead of as a pointer)
|
||||
// for native tables if field is a struct.
|
||||
size_t padding; // Bytes to always pad after this field.
|
||||
};
|
||||
|
||||
@@ -347,6 +351,7 @@ struct IDLOptions {
|
||||
bool generate_name_strings;
|
||||
bool escape_proto_identifiers;
|
||||
bool generate_object_based_api;
|
||||
std::string cpp_object_api_pointer_type;
|
||||
bool union_value_namespacing;
|
||||
bool allow_non_utf8;
|
||||
|
||||
@@ -370,6 +375,7 @@ struct IDLOptions {
|
||||
generate_name_strings(false),
|
||||
escape_proto_identifiers(false),
|
||||
generate_object_based_api(false),
|
||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||
union_value_namespacing(true),
|
||||
allow_non_utf8(false),
|
||||
lang(IDLOptions::kJava) {}
|
||||
@@ -450,6 +456,9 @@ class Parser : public ParserState {
|
||||
known_attributes_["csharp_partial"] = true;
|
||||
known_attributes_["streaming"] = true;
|
||||
known_attributes_["idempotent"] = true;
|
||||
known_attributes_["cpp_type"] = true;
|
||||
known_attributes_["cpp_ptr_type"] = true;
|
||||
known_attributes_["native_inline"] = true;
|
||||
}
|
||||
|
||||
~Parser() {
|
||||
@@ -596,7 +605,9 @@ extern void GenComment(const std::vector<std::string> &dc,
|
||||
// if it is less than 0, no linefeeds will be generated either.
|
||||
// See idl_gen_text.cpp.
|
||||
// strict_json adds "quotes" around field names if true.
|
||||
extern void GenerateText(const Parser &parser,
|
||||
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
||||
// byte arrays in String values), returns false.
|
||||
extern bool GenerateText(const Parser &parser,
|
||||
const void *flatbuffer,
|
||||
std::string *text);
|
||||
extern bool GenerateTextFile(const Parser &parser,
|
||||
@@ -640,8 +651,8 @@ extern bool GenerateJava(const Parser &parser,
|
||||
// Generate Php code from the definitions in the Parser object.
|
||||
// See idl_gen_php.
|
||||
extern bool GeneratePhp(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Python files from the definitions in the Parser object.
|
||||
// See idl_gen_python.cpp.
|
||||
@@ -699,11 +710,17 @@ extern std::string BinaryMakeRule(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate GRPC interfaces.
|
||||
// Generate GRPC Cpp interfaces.
|
||||
// See idl_gen_grpc.cpp.
|
||||
bool GenerateGRPC(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
bool GenerateCppGRPC(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate GRPC Go interfaces.
|
||||
// See idl_gen_grpc.cpp.
|
||||
bool GenerateGoGRPC(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
|
||||
@@ -105,6 +105,22 @@ inline Table *GetFieldT(const Table &table,
|
||||
return table.GetPointer<Table *>(field.offset());
|
||||
}
|
||||
|
||||
// Get a field, if you know it's a struct.
|
||||
inline const Struct *GetFieldStruct(const Table &table,
|
||||
const reflection::Field &field) {
|
||||
// TODO: This does NOT check if the field is a table or struct, but we'd need
|
||||
// access to the schema to check the is_struct flag.
|
||||
assert(field.type()->base_type() == reflection::Obj);
|
||||
return table.GetStruct<const Struct *>(field.offset());
|
||||
}
|
||||
|
||||
// Get a structure's field, if you know it's a struct.
|
||||
inline const Struct *GetFieldStruct(const Struct &structure,
|
||||
const reflection::Field &field) {
|
||||
assert(field.type()->base_type() == reflection::Obj);
|
||||
return structure.GetStruct<const Struct *>(field.offset());
|
||||
}
|
||||
|
||||
// Raw helper functions used below: get any value in memory as a 64bit int, a
|
||||
// double or a string.
|
||||
// All scalars get static_cast to an int64_t, strings use strtoull, every other
|
||||
@@ -428,6 +444,15 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
||||
const Table &table,
|
||||
bool use_string_pooling = false);
|
||||
|
||||
// Verifies the provided flatbuffer using reflection.
|
||||
// root should point to the root type for this flatbuffer.
|
||||
// buf should point to the start of flatbuffer data.
|
||||
// length specifies the size of the flatbuffer data.
|
||||
bool Verify(const reflection::Schema &schema,
|
||||
const reflection::Object &root,
|
||||
const uint8_t *buf,
|
||||
size_t length);
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_REFLECTION_H_
|
||||
|
||||
@@ -38,7 +38,7 @@ enum BaseType {
|
||||
String = 13,
|
||||
Vector = 14,
|
||||
Obj = 15,
|
||||
Union = 16,
|
||||
Union = 16
|
||||
};
|
||||
|
||||
inline const char **EnumNamesBaseType() {
|
||||
@@ -529,17 +529,27 @@ inline flatbuffers::Offset<Schema> CreateSchemaDirect(flatbuffers::FlatBufferBui
|
||||
return CreateSchema(_fbb, objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0, enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0, file_ident ? _fbb.CreateString(file_ident) : 0, file_ext ? _fbb.CreateString(file_ext) : 0, root_table);
|
||||
}
|
||||
|
||||
inline const reflection::Schema *GetSchema(const void *buf) { return flatbuffers::GetRoot<reflection::Schema>(buf); }
|
||||
inline const reflection::Schema *GetSchema(const void *buf) {
|
||||
return flatbuffers::GetRoot<reflection::Schema>(buf);
|
||||
}
|
||||
|
||||
inline const char *SchemaIdentifier() { return "BFBS"; }
|
||||
inline const char *SchemaIdentifier() {
|
||||
return "BFBS";
|
||||
}
|
||||
|
||||
inline bool SchemaBufferHasIdentifier(const void *buf) { return flatbuffers::BufferHasIdentifier(buf, SchemaIdentifier()); }
|
||||
inline bool SchemaBufferHasIdentifier(const void *buf) {
|
||||
return flatbuffers::BufferHasIdentifier(buf, SchemaIdentifier());
|
||||
}
|
||||
|
||||
inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier()); }
|
||||
inline bool VerifySchemaBuffer(flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<reflection::Schema>(SchemaIdentifier());
|
||||
}
|
||||
|
||||
inline const char *SchemaExtension() { return "bfbs"; }
|
||||
|
||||
inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<reflection::Schema> root) { fbb.Finish(root, SchemaIdentifier()); }
|
||||
inline void FinishSchemaBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<reflection::Schema> root) {
|
||||
fbb.Finish(root, SchemaIdentifier());
|
||||
}
|
||||
|
||||
} // namespace reflection
|
||||
|
||||
|
||||
@@ -95,20 +95,20 @@ inline std::string IntToStringHex(int i, int xdigits) {
|
||||
}
|
||||
|
||||
// Portable implementation of strtoll().
|
||||
inline int64_t StringToInt(const char *str, int base = 10) {
|
||||
inline int64_t StringToInt(const char *str, char **endptr = nullptr, int base = 10) {
|
||||
#ifdef _MSC_VER
|
||||
return _strtoi64(str, nullptr, base);
|
||||
return _strtoi64(str, endptr, base);
|
||||
#else
|
||||
return strtoll(str, nullptr, base);
|
||||
return strtoll(str, endptr, base);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Portable implementation of strtoull().
|
||||
inline int64_t StringToUInt(const char *str, int base = 10) {
|
||||
inline int64_t StringToUInt(const char *str, char **endptr = nullptr, int base = 10) {
|
||||
#ifdef _MSC_VER
|
||||
return _strtoui64(str, nullptr, base);
|
||||
return _strtoui64(str, endptr, base);
|
||||
#else
|
||||
return strtoull(str, nullptr, base);
|
||||
return strtoull(str, endptr, base);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -367,6 +367,53 @@ public class FlatBufferBuilder {
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
/**
|
||||
* Create a new array/vector and return a ByteBuffer to be filled later.
|
||||
* Call {@link #endVector} after this method to get an offset to the beginning
|
||||
* of vector.
|
||||
*
|
||||
* @param elem_size the size of each element in bytes.
|
||||
* @param num_elems number of elements in the vector.
|
||||
* @param alignment byte alignment.
|
||||
* @return ByteBuffer with position and limit set to the space allocated for the array.
|
||||
*/
|
||||
public ByteBuffer createUnintializedVector(int elem_size, int num_elems, int alignment) {
|
||||
int length = elem_size * num_elems;
|
||||
startVector(elem_size, num_elems, alignment);
|
||||
|
||||
bb.position(space -= length);
|
||||
|
||||
// Slice and limit the copy vector to point to the 'array'
|
||||
ByteBuffer copy = bb.slice().order(ByteOrder.LITTLE_ENDIAN);
|
||||
copy.limit(length);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a vector of tables.
|
||||
*
|
||||
* @param offsets Offsets of the tables.
|
||||
* @return Returns offset of the vector.
|
||||
*/
|
||||
public int createVectorOfTables(int[] offsets) {
|
||||
notNested();
|
||||
startVector(Constants.SIZEOF_INT, offsets.length, Constants.SIZEOF_INT);
|
||||
for(int i = offsets.length - 1; i >= 0; i--) addOffset(offsets[i]);
|
||||
return endVector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a vector of sorted by the key tables.
|
||||
*
|
||||
* @param obj Instance of the table subclass.
|
||||
* @param offsets Offsets of the tables.
|
||||
* @return Returns offset of the sorted vector.
|
||||
*/
|
||||
public <T extends Table> int createSortedVectorOfTables(T obj, int[] offsets) {
|
||||
obj.sortTables(offsets, bb);
|
||||
return createVectorOfTables(offsets);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode the string `s` in the buffer using UTF-8. If {@code s} is
|
||||
* already a {@link CharBuffer}, this method is allocation free.
|
||||
@@ -413,6 +460,20 @@ public class FlatBufferBuilder {
|
||||
return endVector();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a byte array in the buffer.
|
||||
*
|
||||
* @param arr A source array with data
|
||||
* @return The offset in the buffer where the encoded array starts.
|
||||
*/
|
||||
public int createByteVector(byte[] arr) {
|
||||
int length = arr.length;
|
||||
startVector(1, length, 1);
|
||||
bb.position(space -= length);
|
||||
bb.put(arr);
|
||||
return endVector();
|
||||
}
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
/**
|
||||
* Should not be accessing the final buffer before it is finished.
|
||||
|
||||
@@ -37,6 +37,12 @@ public class Table {
|
||||
return Charset.forName("UTF-8").newDecoder();
|
||||
}
|
||||
};
|
||||
public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
|
||||
@Override
|
||||
protected Charset initialValue() {
|
||||
return Charset.forName("UTF-8");
|
||||
}
|
||||
};
|
||||
private final static ThreadLocal<CharBuffer> CHAR_BUFFER = new ThreadLocal<CharBuffer>();
|
||||
/** Used to hold the position of the `bb` buffer. */
|
||||
protected int bb_pos;
|
||||
@@ -61,6 +67,11 @@ public class Table {
|
||||
return vtable_offset < bb.getShort(vtable) ? bb.getShort(vtable + vtable_offset) : 0;
|
||||
}
|
||||
|
||||
protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) {
|
||||
int vtable = bb.array().length - offset;
|
||||
return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a relative offset.
|
||||
*
|
||||
@@ -71,6 +82,10 @@ public class Table {
|
||||
return offset + bb.getInt(offset);
|
||||
}
|
||||
|
||||
protected static int __indirect(int offset, ByteBuffer bb) {
|
||||
return offset + bb.getInt(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
|
||||
*
|
||||
@@ -188,6 +203,76 @@ public class Table {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort tables by the key.
|
||||
*
|
||||
* @param offsets An 'int' indexes of the tables into the bb.
|
||||
* @param bb A {@code ByteBuffer} to get the tables.
|
||||
*/
|
||||
protected void sortTables(int[] offsets, final ByteBuffer bb) {
|
||||
Integer[] off = new Integer[offsets.length];
|
||||
for (int i = 0; i < offsets.length; i++) off[i] = offsets[i];
|
||||
java.util.Arrays.sort(off, new java.util.Comparator<Integer>() {
|
||||
public int compare(Integer o1, Integer o2) {
|
||||
return keysCompare(o1, o2, bb);
|
||||
}
|
||||
});
|
||||
for (int i = 0; i < offsets.length; i++) offsets[i] = off[i];
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two tables by the key.
|
||||
*
|
||||
* @param o1 An 'Integer' index of the first key into the bb.
|
||||
* @param o2 An 'Integer' index of the second key into the bb.
|
||||
* @param bb A {@code ByteBuffer} to get the keys.
|
||||
*/
|
||||
protected int keysCompare(Integer o1, Integer o2, ByteBuffer bb) { return 0; }
|
||||
|
||||
/**
|
||||
* Compare two strings in the buffer.
|
||||
*
|
||||
* @param offset_1 An 'int' index of the first string into the bb.
|
||||
* @param offset_2 An 'int' index of the second string into the bb.
|
||||
* @param bb A {@code ByteBuffer} to get the strings.
|
||||
*/
|
||||
protected static int compareStrings(int offset_1, int offset_2, ByteBuffer bb) {
|
||||
offset_1 += bb.getInt(offset_1);
|
||||
offset_2 += bb.getInt(offset_2);
|
||||
int len_1 = bb.getInt(offset_1);
|
||||
int len_2 = bb.getInt(offset_2);
|
||||
int startPos_1 = offset_1 + SIZEOF_INT;
|
||||
int startPos_2 = offset_2 + SIZEOF_INT;
|
||||
int len = Math.min(len_1, len_2);
|
||||
byte[] bbArray = bb.array();
|
||||
for(int i = 0; i < len; i++) {
|
||||
if (bbArray[i + startPos_1] != bbArray[i + startPos_2])
|
||||
return bbArray[i + startPos_1] - bbArray[i + startPos_2];
|
||||
}
|
||||
return len_1 - len_2;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare string from the buffer with the 'String' object.
|
||||
*
|
||||
* @param offset_1 An 'int' index of the first string into the bb.
|
||||
* @param key Second string as a byte array.
|
||||
* @param bb A {@code ByteBuffer} to get the first string.
|
||||
*/
|
||||
protected static int compareStrings(int offset_1, byte[] key, ByteBuffer bb) {
|
||||
offset_1 += bb.getInt(offset_1);
|
||||
int len_1 = bb.getInt(offset_1);
|
||||
int len_2 = key.length;
|
||||
int startPos_1 = offset_1 + Constants.SIZEOF_INT;
|
||||
int len = Math.min(len_1, len_2);
|
||||
byte[] bbArray = bb.array();
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (bbArray[i + startPos_1] != key[i])
|
||||
return bbArray[i + startPos_1] - key[i];
|
||||
}
|
||||
return len_1 - len_2;
|
||||
}
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -75,8 +75,8 @@ flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] =
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @param {number} high
|
||||
* @param {number} low
|
||||
* @param {number} high
|
||||
*/
|
||||
flatbuffers.Long = function(low, high) {
|
||||
/**
|
||||
@@ -93,8 +93,8 @@ flatbuffers.Long = function(low, high) {
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} high
|
||||
* @param {number} low
|
||||
* @param {number} high
|
||||
* @returns {flatbuffers.Long}
|
||||
*/
|
||||
flatbuffers.Long.create = function(low, high) {
|
||||
@@ -129,11 +129,13 @@ flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
|
||||
* Create a FlatBufferBuilder.
|
||||
*
|
||||
* @constructor
|
||||
* @param {number=} initial_size
|
||||
* @param {number=} opt_initial_size
|
||||
*/
|
||||
flatbuffers.Builder = function(initial_size) {
|
||||
if (!initial_size) {
|
||||
initial_size = 1024;
|
||||
flatbuffers.Builder = function(opt_initial_size) {
|
||||
if (!opt_initial_size) {
|
||||
var initial_size = 1024;
|
||||
} else {
|
||||
var initial_size = opt_initial_size;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -642,10 +644,11 @@ outer_loop:
|
||||
* Finalize a buffer, poiting to the given `root_table`.
|
||||
*
|
||||
* @param {flatbuffers.Offset} root_table
|
||||
* @param {string=} file_identifier
|
||||
* @param {string=} opt_file_identifier
|
||||
*/
|
||||
flatbuffers.Builder.prototype.finish = function(root_table, file_identifier) {
|
||||
if (file_identifier) {
|
||||
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
|
||||
if (opt_file_identifier) {
|
||||
var file_identifier = opt_file_identifier;
|
||||
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
|
||||
flatbuffers.FILE_IDENTIFIER_LENGTH);
|
||||
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
|
||||
@@ -1018,10 +1021,10 @@ flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
|
||||
* FlatBuffer later on.
|
||||
*
|
||||
* @param {number} offset
|
||||
* @param {flatbuffers.Encoding=} optionalEncoding Defaults to UTF16_STRING
|
||||
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
|
||||
* @returns {string|Uint8Array}
|
||||
*/
|
||||
flatbuffers.ByteBuffer.prototype.__string = function(offset, optionalEncoding) {
|
||||
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
|
||||
offset += this.readInt32(offset);
|
||||
|
||||
var length = this.readInt32(offset);
|
||||
@@ -1030,7 +1033,7 @@ flatbuffers.ByteBuffer.prototype.__string = function(offset, optionalEncoding) {
|
||||
|
||||
offset += flatbuffers.SIZEOF_INT;
|
||||
|
||||
if (optionalEncoding === flatbuffers.Encoding.UTF8_BYTES) {
|
||||
if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
|
||||
return this.bytes_.subarray(offset, offset + length);
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,20 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
//#define UNSAFE_BYTEBUFFER // uncomment this line to use faster ByteBuffer
|
||||
// There are 2 #defines that have an impact on performance of this ByteBuffer implementation
|
||||
//
|
||||
// UNSAFE_BYTEBUFFER
|
||||
// This will use unsafe code to manipulate the underlying byte array. This
|
||||
// can yield a reasonable performance increase.
|
||||
//
|
||||
// BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
// This will disable the bounds check asserts to the byte array. This can
|
||||
// yield a small performance gain in normal code..
|
||||
//
|
||||
// Using UNSAFE_BYTEBUFFER and BYTEBUFFER_NO_BOUNDS_CHECK together can yield a
|
||||
// performance gain of ~15% for some operations, however doing so is potentially
|
||||
// dangerous. Do so at your own risk!
|
||||
//
|
||||
|
||||
using System;
|
||||
|
||||
@@ -22,9 +35,6 @@ namespace FlatBuffers
|
||||
{
|
||||
/// <summary>
|
||||
/// Class to mimic Java's ByteBuffer which is used heavily in Flatbuffers.
|
||||
/// If your execution environment allows unsafe code, you should enable
|
||||
/// unsafe code in your project and #define UNSAFE_BYTEBUFFER to use a
|
||||
/// MUCH faster version of ByteBuffer.
|
||||
/// </summary>
|
||||
public class ByteBuffer
|
||||
{
|
||||
@@ -126,11 +136,14 @@ namespace FlatBuffers
|
||||
}
|
||||
#endif // !UNSAFE_BYTEBUFFER
|
||||
|
||||
|
||||
private void AssertOffsetAndLength(int offset, int length)
|
||||
{
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
if (offset < 0 ||
|
||||
offset > _buffer.Length - length)
|
||||
throw new ArgumentOutOfRangeException();
|
||||
#endif
|
||||
}
|
||||
|
||||
public void PutSbyte(int offset, sbyte value)
|
||||
@@ -200,7 +213,6 @@ namespace FlatBuffers
|
||||
public unsafe void PutUlong(int offset, ulong value)
|
||||
{
|
||||
AssertOffsetAndLength(offset, sizeof(ulong));
|
||||
|
||||
fixed (byte* ptr = _buffer)
|
||||
{
|
||||
*(ulong*)(ptr + offset) = BitConverter.IsLittleEndian
|
||||
|
||||
@@ -296,6 +296,18 @@ namespace FlatBuffers
|
||||
return new VectorOffset(Offset);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a vector of tables.
|
||||
/// </summary>
|
||||
/// <param name="offsets">Offsets of the tables.</param>
|
||||
public VectorOffset CreateVectorOfTables<T>(Offset<T>[] offsets) where T : struct
|
||||
{
|
||||
NotNested();
|
||||
StartVector(sizeof(int), offsets.Length, sizeof(int));
|
||||
for (int i = offsets.Length - 1; i >= 0; i--) AddOffset(offsets[i].Value);
|
||||
return EndVector();
|
||||
}
|
||||
|
||||
/// @cond FLATBUFFERS_INTENRAL
|
||||
public void Nested(int obj)
|
||||
{
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
<Compile Include="ByteBuffer.cs" />
|
||||
<Compile Include="FlatBufferBuilder.cs" />
|
||||
<Compile Include="FlatBufferConstants.cs" />
|
||||
<Compile Include="IFlatbufferObject.cs" />
|
||||
<Compile Include="Offset.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Struct.cs" />
|
||||
|
||||
28
net/FlatBuffers/IFlatbufferObject.cs
Normal file
28
net/FlatBuffers/IFlatbufferObject.cs
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
namespace FlatBuffers
|
||||
{
|
||||
/// <summary>
|
||||
/// This is the base for both structs and tables.
|
||||
/// </summary>
|
||||
public interface IFlatbufferObject
|
||||
{
|
||||
void __init(int _i, ByteBuffer _bb);
|
||||
|
||||
ByteBuffer ByteBuffer { get; }
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ namespace FlatBuffers
|
||||
/// <summary>
|
||||
/// Offset class for typesafe assignments.
|
||||
/// </summary>
|
||||
public struct Offset<T> where T : class
|
||||
public struct Offset<T> where T : struct
|
||||
{
|
||||
public int Value;
|
||||
public Offset(int value)
|
||||
|
||||
@@ -19,9 +19,9 @@ namespace FlatBuffers
|
||||
/// <summary>
|
||||
/// All structs in the generated code derive from this class, and add their own accessors.
|
||||
/// </summary>
|
||||
public abstract class Struct
|
||||
public struct Struct
|
||||
{
|
||||
protected int bb_pos;
|
||||
protected ByteBuffer bb;
|
||||
public int bb_pos;
|
||||
public ByteBuffer bb;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,31 +20,42 @@ using System.Text;
|
||||
namespace FlatBuffers
|
||||
{
|
||||
/// <summary>
|
||||
/// All tables in the generated code derive from this class, and add their own accessors.
|
||||
/// All tables in the generated code derive from this struct, and add their own accessors.
|
||||
/// </summary>
|
||||
public abstract class Table
|
||||
public struct Table
|
||||
{
|
||||
protected int bb_pos;
|
||||
protected ByteBuffer bb;
|
||||
public int bb_pos;
|
||||
public ByteBuffer bb;
|
||||
|
||||
public ByteBuffer ByteBuffer { get { return bb; } }
|
||||
|
||||
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
|
||||
// present.
|
||||
protected int __offset(int vtableOffset)
|
||||
public int __offset(int vtableOffset)
|
||||
{
|
||||
int vtable = bb_pos - bb.GetInt(bb_pos);
|
||||
return vtableOffset < bb.GetShort(vtable) ? (int)bb.GetShort(vtable + vtableOffset) : 0;
|
||||
}
|
||||
|
||||
public static int __offset(int vtableOffset, int offset, ByteBuffer bb)
|
||||
{
|
||||
int vtable = bb.Length - offset;
|
||||
return (int)bb.GetShort(vtable + vtableOffset - bb.GetInt(vtable)) + vtable;
|
||||
}
|
||||
|
||||
// Retrieve the relative offset stored at "offset"
|
||||
protected int __indirect(int offset)
|
||||
public int __indirect(int offset)
|
||||
{
|
||||
return offset + bb.GetInt(offset);
|
||||
}
|
||||
|
||||
public static int __indirect(int offset, ByteBuffer bb)
|
||||
{
|
||||
return offset + bb.GetInt(offset);
|
||||
}
|
||||
|
||||
// Create a .NET String from UTF-8 data stored inside the flatbuffer.
|
||||
protected string __string(int offset)
|
||||
public string __string(int offset)
|
||||
{
|
||||
offset += bb.GetInt(offset);
|
||||
var len = bb.GetInt(offset);
|
||||
@@ -53,7 +64,7 @@ namespace FlatBuffers
|
||||
}
|
||||
|
||||
// Get the length of a vector whose offset is stored at "offset" in this object.
|
||||
protected int __vector_len(int offset)
|
||||
public int __vector_len(int offset)
|
||||
{
|
||||
offset += bb_pos;
|
||||
offset += bb.GetInt(offset);
|
||||
@@ -61,7 +72,7 @@ namespace FlatBuffers
|
||||
}
|
||||
|
||||
// Get the start of data of a vector whose offset is stored at "offset" in this object.
|
||||
protected int __vector(int offset)
|
||||
public int __vector(int offset)
|
||||
{
|
||||
offset += bb_pos;
|
||||
return offset + bb.GetInt(offset) + sizeof(int); // data starts after the length
|
||||
@@ -70,7 +81,8 @@ namespace FlatBuffers
|
||||
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
||||
// ArraySegment<byte>. If the vector is not present in the ByteBuffer,
|
||||
// then a null value will be returned.
|
||||
protected ArraySegment<byte>? __vector_as_arraysegment(int offset) {
|
||||
public ArraySegment<byte>? __vector_as_arraysegment(int offset)
|
||||
{
|
||||
var o = this.__offset(offset);
|
||||
if (0 == o)
|
||||
{
|
||||
@@ -83,15 +95,15 @@ namespace FlatBuffers
|
||||
}
|
||||
|
||||
// Initialize any Table-derived type to point to the union at the given offset.
|
||||
protected TTable __union<TTable>(TTable t, int offset) where TTable : Table
|
||||
public T __union<T>(int offset) where T : struct, IFlatbufferObject
|
||||
{
|
||||
offset += bb_pos;
|
||||
t.bb_pos = offset + bb.GetInt(offset);
|
||||
t.bb = bb;
|
||||
T t = new T();
|
||||
t.__init(offset + bb.GetInt(offset), bb);
|
||||
return t;
|
||||
}
|
||||
|
||||
protected static bool __has_identifier(ByteBuffer bb, string ident)
|
||||
public static bool __has_identifier(ByteBuffer bb, string ident)
|
||||
{
|
||||
if (ident.Length != FlatBufferConstants.FileIdentifierLength)
|
||||
throw new ArgumentException("FlatBuffers: file identifier must be length " + FlatBufferConstants.FileIdentifierLength, "ident");
|
||||
@@ -104,6 +116,38 @@ namespace FlatBuffers
|
||||
return true;
|
||||
}
|
||||
|
||||
// Compare strings in the ByteBuffer.
|
||||
public static int CompareStrings(int offset_1, int offset_2, ByteBuffer bb)
|
||||
{
|
||||
offset_1 += bb.GetInt(offset_1);
|
||||
offset_2 += bb.GetInt(offset_2);
|
||||
var len_1 = bb.GetInt(offset_1);
|
||||
var len_2 = bb.GetInt(offset_2);
|
||||
var startPos_1 = offset_1 + sizeof(int);
|
||||
var startPos_2 = offset_2 + sizeof(int);
|
||||
var len = Math.Min(len_1, len_2);
|
||||
byte[] bbArray = bb.Data;
|
||||
for(int i = 0; i < len; i++) {
|
||||
if (bbArray[i + startPos_1] != bbArray[i + startPos_2])
|
||||
return bbArray[i + startPos_1] - bbArray[i + startPos_2];
|
||||
}
|
||||
return len_1 - len_2;
|
||||
}
|
||||
|
||||
// Compare string from the ByteBuffer with the string object
|
||||
public static int CompareStrings(int offset_1, byte[] key, ByteBuffer bb)
|
||||
{
|
||||
offset_1 += bb.GetInt(offset_1);
|
||||
var len_1 = bb.GetInt(offset_1);
|
||||
var len_2 = key.Length;
|
||||
var startPos_1 = offset_1 + sizeof(int);
|
||||
var len = Math.Min(len_1, len_2);
|
||||
byte[] bbArray = bb.Data;
|
||||
for (int i = 0; i < len; i++) {
|
||||
if (bbArray[i + startPos_1] != key[i])
|
||||
return bbArray[i + startPos_1] - key[i];
|
||||
}
|
||||
return len_1 - len_2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,6 +593,10 @@ class FlatbufferBuilder
|
||||
|
||||
protected function is_utf8($bytes)
|
||||
{
|
||||
if (function_exists('mb_detect_encoding')) {
|
||||
return (bool) mb_detect_encoding($bytes, 'UTF-8', true);
|
||||
}
|
||||
|
||||
$len = strlen($bytes);
|
||||
if ($len < 1) {
|
||||
/* NOTE: always return 1 when passed string is null */
|
||||
|
||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.google.flatbuffers</groupId>
|
||||
<artifactId>flatbuffers-java</artifactId>
|
||||
<version>1.4.0-SNAPSHOT</version>
|
||||
<version>1.5.0-SNAPSHOT</version>
|
||||
<packaging>bundle</packaging>
|
||||
<name>FlatBuffers Java API</name>
|
||||
<description>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
 FlatBuffers
|
||||
===========
|
||||
|
||||
[](https://gitter.im/google/flatbuffers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/google/flatbuffers) [](https://ci.appveyor.com/project/gwvo/flatbuffers)
|
||||
|
||||
**FlatBuffers** is an efficient cross platform serialization library for games and
|
||||
|
||||
@@ -38,6 +38,21 @@ enum Equipment {
|
||||
Equipment_MAX = Equipment_Weapon
|
||||
};
|
||||
|
||||
inline const char **EnumNamesEquipment() {
|
||||
static const char *names[] = { "NONE", "Weapon", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameEquipment(Equipment e) { return EnumNamesEquipment()[static_cast<int>(e)]; }
|
||||
|
||||
template<typename T> struct EquipmentTraits {
|
||||
static const Equipment enum_value = Equipment_NONE;
|
||||
};
|
||||
|
||||
template<> struct EquipmentTraits<Weapon> {
|
||||
static const Equipment enum_value = Equipment_Weapon;
|
||||
};
|
||||
|
||||
struct EquipmentUnion {
|
||||
Equipment type;
|
||||
|
||||
@@ -45,21 +60,24 @@ struct EquipmentUnion {
|
||||
EquipmentUnion() : type(Equipment_NONE), table(nullptr) {}
|
||||
EquipmentUnion(const EquipmentUnion &);
|
||||
EquipmentUnion &operator=(const EquipmentUnion &);
|
||||
~EquipmentUnion();
|
||||
~EquipmentUnion() { Reset(); }
|
||||
void Reset();
|
||||
|
||||
static flatbuffers::NativeTable *UnPack(const void *union_obj, Equipment type);
|
||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb) const;
|
||||
template <typename T>
|
||||
void Set(T&& value) {
|
||||
Reset();
|
||||
type = EquipmentTraits<typename T::TableType>::enum_value;
|
||||
if (type != Equipment_NONE) {
|
||||
table = new T(std::forward<T>(value));
|
||||
}
|
||||
}
|
||||
|
||||
static flatbuffers::NativeTable *UnPack(const void *union_obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
|
||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *rehasher = nullptr) const;
|
||||
|
||||
WeaponT *AsWeapon() { return type == Equipment_Weapon ? reinterpret_cast<WeaponT *>(table) : nullptr; }
|
||||
};
|
||||
|
||||
inline const char **EnumNamesEquipment() {
|
||||
static const char *names[] = { "NONE", "Weapon", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameEquipment(Equipment e) { return EnumNamesEquipment()[static_cast<int>(e)]; }
|
||||
|
||||
inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_obj, Equipment type);
|
||||
|
||||
MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
|
||||
@@ -84,6 +102,7 @@ MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
|
||||
STRUCT_END(Vec3, 12);
|
||||
|
||||
struct MonsterT : public flatbuffers::NativeTable {
|
||||
typedef Monster TableType;
|
||||
std::unique_ptr<Vec3> pos;
|
||||
int16_t mana;
|
||||
int16_t hp;
|
||||
@@ -92,9 +111,14 @@ struct MonsterT : public flatbuffers::NativeTable {
|
||||
Color color;
|
||||
std::vector<std::unique_ptr<WeaponT>> weapons;
|
||||
EquipmentUnion equipped;
|
||||
MonsterT()
|
||||
: mana(150),
|
||||
hp(100),
|
||||
color(Color_Blue) {}
|
||||
};
|
||||
|
||||
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef MonsterT NativeTableType;
|
||||
enum {
|
||||
VT_POS = 4,
|
||||
VT_MANA = 6,
|
||||
@@ -142,7 +166,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyEquipment(verifier, equipped(), equipped_type()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
std::unique_ptr<MonsterT> UnPack() const;
|
||||
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct MonsterBuilder {
|
||||
@@ -201,14 +226,18 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(flatbuffers::FlatBufferB
|
||||
return CreateMonster(_fbb, pos, mana, hp, name ? _fbb.CreateString(name) : 0, inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0, color, weapons ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(*weapons) : 0, equipped_type, equipped);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o);
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
|
||||
struct WeaponT : public flatbuffers::NativeTable {
|
||||
typedef Weapon TableType;
|
||||
std::string name;
|
||||
int16_t damage;
|
||||
WeaponT()
|
||||
: damage(0) {}
|
||||
};
|
||||
|
||||
struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef WeaponT NativeTableType;
|
||||
enum {
|
||||
VT_NAME = 4,
|
||||
VT_DAMAGE = 6
|
||||
@@ -224,7 +253,8 @@ struct Weapon FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyField<int16_t>(verifier, VT_DAMAGE) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
std::unique_ptr<WeaponT> UnPack() const;
|
||||
WeaponT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Weapon> Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct WeaponBuilder {
|
||||
@@ -255,9 +285,10 @@ inline flatbuffers::Offset<Weapon> CreateWeaponDirect(flatbuffers::FlatBufferBui
|
||||
return CreateWeapon(_fbb, name ? _fbb.CreateString(name) : 0, damage);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o);
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
|
||||
inline std::unique_ptr<MonsterT> Monster::UnPack() const {
|
||||
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
auto _o = new MonsterT();
|
||||
{ auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); };
|
||||
{ auto _e = mana(); _o->mana = _e; };
|
||||
@@ -265,13 +296,18 @@ inline std::unique_ptr<MonsterT> Monster::UnPack() const {
|
||||
{ auto _e = name(); if (_e) _o->name = _e->str(); };
|
||||
{ auto _e = inventory(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } } };
|
||||
{ auto _e = color(); _o->color = _e; };
|
||||
{ auto _e = weapons(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(_e->Get(_i)->UnPack()); } } };
|
||||
{ auto _e = weapons(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons.push_back(std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(resolver))); } } };
|
||||
{ auto _e = equipped_type(); _o->equipped.type = _e; };
|
||||
{ auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type()); };
|
||||
return std::unique_ptr<MonsterT>(_o);
|
||||
{ auto _e = equipped(); if (_e) _o->equipped.table = EquipmentUnion::UnPack(_e, equipped_type(), resolver); };
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o) {
|
||||
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateMonster(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateMonster(_fbb,
|
||||
_o->pos ? _o->pos.get() : 0,
|
||||
_o->mana,
|
||||
@@ -279,19 +315,25 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
_o->name.size() ? _fbb.CreateString(_o->name) : 0,
|
||||
_o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0,
|
||||
_o->color,
|
||||
_o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get()); }) : 0,
|
||||
_o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get(), rehasher); }) : 0,
|
||||
_o->equipped.type,
|
||||
_o->equipped.Pack(_fbb));
|
||||
}
|
||||
|
||||
inline std::unique_ptr<WeaponT> Weapon::UnPack() const {
|
||||
inline WeaponT *Weapon::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
auto _o = new WeaponT();
|
||||
{ auto _e = name(); if (_e) _o->name = _e->str(); };
|
||||
{ auto _e = damage(); _o->damage = _e; };
|
||||
return std::unique_ptr<WeaponT>(_o);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o) {
|
||||
inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateWeapon(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateWeapon(_fbb,
|
||||
_o->name.size() ? _fbb.CreateString(_o->name) : 0,
|
||||
_o->damage);
|
||||
@@ -305,36 +347,50 @@ inline bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *union_o
|
||||
}
|
||||
}
|
||||
|
||||
inline flatbuffers::NativeTable *EquipmentUnion::UnPack(const void *union_obj, Equipment type) {
|
||||
inline flatbuffers::NativeTable *EquipmentUnion::UnPack(const void *union_obj, Equipment type, const flatbuffers::resolver_function_t *resolver) {
|
||||
switch (type) {
|
||||
case Equipment_NONE: return nullptr;
|
||||
case Equipment_Weapon: return reinterpret_cast<const Weapon *>(union_obj)->UnPack().release();
|
||||
case Equipment_Weapon: return reinterpret_cast<const Weapon *>(union_obj)->UnPack(resolver);
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb) const {
|
||||
inline flatbuffers::Offset<void> EquipmentUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *rehasher) const {
|
||||
switch (type) {
|
||||
case Equipment_NONE: return 0;
|
||||
case Equipment_Weapon: return CreateWeapon(_fbb, reinterpret_cast<const WeaponT *>(table)).Union();
|
||||
case Equipment_Weapon: return CreateWeapon(_fbb, reinterpret_cast<const WeaponT *>(table), rehasher).Union();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline EquipmentUnion::~EquipmentUnion() {
|
||||
inline void EquipmentUnion::Reset() {
|
||||
switch (type) {
|
||||
case Equipment_Weapon: delete reinterpret_cast<WeaponT *>(table); break;
|
||||
default:;
|
||||
default: break;
|
||||
}
|
||||
table = nullptr;
|
||||
type = Equipment_NONE;
|
||||
}
|
||||
|
||||
inline const MyGame::Sample::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf); }
|
||||
inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
|
||||
return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
|
||||
}
|
||||
|
||||
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
|
||||
inline Monster *GetMutableMonster(void *buf) {
|
||||
return flatbuffers::GetMutableRoot<Monster>(buf);
|
||||
}
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr); }
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<MyGame::Sample::Monster>(nullptr);
|
||||
}
|
||||
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) { fbb.Finish(root); }
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Sample::Monster> root) {
|
||||
fbb.Finish(root);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<MonsterT> UnPackMonster(const void *buf, const flatbuffers::resolver_function_t *resolver = nullptr) {
|
||||
return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(resolver));
|
||||
}
|
||||
|
||||
} // namespace Sample
|
||||
} // namespace MyGame
|
||||
|
||||
@@ -5,5 +5,21 @@
|
||||
z: 3
|
||||
},
|
||||
hp: 300,
|
||||
name: "Orc"
|
||||
name: "Orc",
|
||||
weapons:[
|
||||
{
|
||||
name: "axe",
|
||||
damage:100
|
||||
},
|
||||
{
|
||||
name: "bow",
|
||||
damage:90
|
||||
}
|
||||
],
|
||||
equipped_type: "Weapon",
|
||||
equipped:
|
||||
{
|
||||
name: "bow",
|
||||
damage:90
|
||||
}
|
||||
}
|
||||
|
||||
@@ -46,7 +46,10 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
||||
// to ensure it is correct, we now generate text back from the binary,
|
||||
// and compare the two:
|
||||
std::string jsongen;
|
||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen);
|
||||
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &jsongen)) {
|
||||
printf("Couldn't serialize parsed data to JSON!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (jsongen != jsonfile) {
|
||||
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "flatbuffers/util.h"
|
||||
#include <limits>
|
||||
|
||||
#define FLATC_VERSION "1.4.0 (" __DATE__ ")"
|
||||
#define FLATC_VERSION "1.5.0 (" __DATE__ ")"
|
||||
|
||||
static void Error(const std::string &err, bool usage = false,
|
||||
bool show_exe_name = true);
|
||||
@@ -33,6 +33,9 @@ struct Generator {
|
||||
const char *generator_opt_short;
|
||||
const char *generator_opt_long;
|
||||
const char *lang_name;
|
||||
bool (*generateGRPC)(const flatbuffers::Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
flatbuffers::IDLOptions::Language lang;
|
||||
const char *generator_help;
|
||||
|
||||
@@ -43,53 +46,63 @@ struct Generator {
|
||||
|
||||
const Generator generators[] = {
|
||||
{ flatbuffers::GenerateBinary, "-b", "--binary", "binary",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate wire format binaries for any data definitions",
|
||||
flatbuffers::BinaryMakeRule },
|
||||
{ flatbuffers::GenerateTextFile, "-t", "--json", "text",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate text output for any data definitions",
|
||||
flatbuffers::TextMakeRule },
|
||||
{ flatbuffers::GenerateCPP, "-c", "--cpp", "C++",
|
||||
flatbuffers::GenerateCppGRPC,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate C++ headers for tables/structs",
|
||||
flatbuffers::CPPMakeRule },
|
||||
{ flatbuffers::GenerateGo, "-g", "--go", "Go",
|
||||
flatbuffers::GenerateGoGRPC,
|
||||
flatbuffers::IDLOptions::kGo,
|
||||
"Generate Go files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateGeneral, "-j", "--java", "Java",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kJava,
|
||||
"Generate Java classes for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateJS, "-s", "--js", "JavaScript",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate JavaScript code for tables/structs",
|
||||
flatbuffers::JSMakeRule },
|
||||
{ flatbuffers::GenerateGeneral, "-n", "--csharp", "C#",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kCSharp,
|
||||
"Generate C# classes for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePython, "-p", "--python", "Python",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate Python files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GeneratePhp, nullptr, "--php", "PHP",
|
||||
nullptr,
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate PHP files for tables/structs",
|
||||
flatbuffers::GeneralMakeRule },
|
||||
{ flatbuffers::GenerateGRPC, nullptr, "--grpc", "GRPC",
|
||||
flatbuffers::IDLOptions::kMAX,
|
||||
"Generate GRPC interfaces",
|
||||
flatbuffers::CPPMakeRule },
|
||||
};
|
||||
|
||||
const char *g_program_name = nullptr;
|
||||
flatbuffers::Parser *g_parser = nullptr;
|
||||
|
||||
static void Warn(const std::string &warn, bool show_exe_name = true) {
|
||||
if (show_exe_name) printf("%s: ", g_program_name);
|
||||
printf("warning: %s\n", warn.c_str());
|
||||
}
|
||||
|
||||
static void Error(const std::string &err, bool usage, bool show_exe_name) {
|
||||
if (show_exe_name) printf("%s: ", g_program_name);
|
||||
printf("%s\n", err.c_str());
|
||||
printf("error: %s\n", err.c_str());
|
||||
if (usage) {
|
||||
printf("usage: %s [OPTION]... FILE... [-- FILE...]\n", g_program_name);
|
||||
for (size_t i = 0; i < sizeof(generators) / sizeof(generators[0]); ++i)
|
||||
@@ -126,13 +139,17 @@ static void Error(const std::string &err, bool usage, bool show_exe_name) {
|
||||
" --gen-onefile Generate single output file for C#.\n"
|
||||
" --gen-name-strings Generate type name functions for C++.\n"
|
||||
" --escape-proto-ids Disable appending '_' in namespaces names.\n"
|
||||
" --gen-object-api Generate an additional object-based API\n"
|
||||
" --gen-object-api Generate an additional object-based API.\n"
|
||||
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n"
|
||||
" --raw-binary Allow binaries without file_indentifier to be read.\n"
|
||||
" This may crash flatc given a mismatched schema.\n"
|
||||
" --proto Input is a .proto, translate to .fbs.\n"
|
||||
" --grpc Generate GRPC interfaces for the specified languages\n"
|
||||
" --schema Serialize schemas instead of JSON (use with -b)\n"
|
||||
" --conform FILE Specify a schema the following schemas should be\n"
|
||||
" an evolution of. Gives errors if not.\n"
|
||||
" --conform-includes Include path for the schema given with --conform\n"
|
||||
" PATH \n"
|
||||
"FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
|
||||
"FILEs after the -- must be binary flatbuffer format files.\n"
|
||||
"Output files are named using the base file name of the input,\n"
|
||||
@@ -167,8 +184,10 @@ int main(int argc, const char *argv[]) {
|
||||
bool print_make_rules = false;
|
||||
bool raw_binary = false;
|
||||
bool schema_binary = false;
|
||||
bool grpc_enabled = false;
|
||||
std::vector<std::string> filenames;
|
||||
std::vector<const char *> include_directories;
|
||||
std::vector<const char *> conform_include_directories;
|
||||
size_t binary_files_from = std::numeric_limits<size_t>::max();
|
||||
std::string conform_to_schema;
|
||||
for (int argi = 1; argi < argc; argi++) {
|
||||
@@ -185,6 +204,9 @@ int main(int argc, const char *argv[]) {
|
||||
} else if(arg == "--conform") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
conform_to_schema = argv[argi];
|
||||
} else if (arg == "--conform-includes") {
|
||||
if (++argi >= argc) Error("missing path following" + arg, true);
|
||||
conform_include_directories.push_back(argv[argi]);
|
||||
} else if(arg == "--strict-json") {
|
||||
opts.strict_json = true;
|
||||
} else if(arg == "--allow-non-utf8") {
|
||||
@@ -208,6 +230,9 @@ int main(int argc, const char *argv[]) {
|
||||
opts.generate_name_strings = true;
|
||||
} else if(arg == "--gen-object-api") {
|
||||
opts.generate_object_based_api = true;
|
||||
} else if (arg == "--cpp-ptr-type") {
|
||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||
opts.cpp_object_api_pointer_type = argv[argi];
|
||||
} else if(arg == "--gen-all") {
|
||||
opts.generate_all = true;
|
||||
opts.include_dependence_headers = false;
|
||||
@@ -233,6 +258,8 @@ int main(int argc, const char *argv[]) {
|
||||
} else if(arg == "--version") {
|
||||
printf("flatc version %s\n", FLATC_VERSION);
|
||||
exit(0);
|
||||
} else if(arg == "--grpc") {
|
||||
grpc_enabled = true;
|
||||
} else {
|
||||
for (size_t i = 0; i < num_generators; ++i) {
|
||||
if (arg == generators[i].generator_opt_long ||
|
||||
@@ -243,7 +270,7 @@ int main(int argc, const char *argv[]) {
|
||||
goto found;
|
||||
}
|
||||
}
|
||||
Error("unknown commandline argument" + arg, true);
|
||||
Error("unknown commandline argument: " + arg, true);
|
||||
found:;
|
||||
}
|
||||
} else {
|
||||
@@ -265,7 +292,8 @@ int main(int argc, const char *argv[]) {
|
||||
std::string contents;
|
||||
if (!flatbuffers::LoadFile(conform_to_schema.c_str(), true, &contents))
|
||||
Error("unable to load schema: " + conform_to_schema);
|
||||
ParseFile(conform_parser, conform_to_schema, contents, include_directories);
|
||||
ParseFile(conform_parser, conform_to_schema, contents,
|
||||
conform_include_directories);
|
||||
}
|
||||
|
||||
// Now process the files:
|
||||
@@ -349,6 +377,18 @@ int main(int argc, const char *argv[]) {
|
||||
printf("%s\n", flatbuffers::WordWrap(
|
||||
make_rule, 80, " ", " \\").c_str());
|
||||
}
|
||||
if (grpc_enabled) {
|
||||
if (generators[i].generateGRPC != nullptr) {
|
||||
if (!generators[i].generateGRPC(*g_parser, output_path,
|
||||
filebase)) {
|
||||
Error(std::string("Unable to generate GRPC interface for") +
|
||||
generators[i].lang_name);
|
||||
}
|
||||
} else {
|
||||
Warn(std::string("GRPC interface generator not implemented for ")
|
||||
+ generators[i].lang_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,40 +159,40 @@ class CppGenerator : public BaseGenerator {
|
||||
// The root datatype accessor:
|
||||
code += "inline const " + cpp_qualified_name + " *Get";
|
||||
code += name;
|
||||
code += "(const void *buf) { return flatbuffers::GetRoot<";
|
||||
code += cpp_qualified_name + ">(buf); }\n\n";
|
||||
code += "(const void *buf) {\n return flatbuffers::GetRoot<";
|
||||
code += cpp_qualified_name + ">(buf);\n}\n\n";
|
||||
if (parser_.opts.mutable_buffer) {
|
||||
code += "inline " + name + " *GetMutable";
|
||||
code += name;
|
||||
code += "(void *buf) { return flatbuffers::GetMutableRoot<";
|
||||
code += name + ">(buf); }\n\n";
|
||||
code += "(void *buf) {\n return flatbuffers::GetMutableRoot<";
|
||||
code += name + ">(buf);\n}\n\n";
|
||||
}
|
||||
|
||||
if (parser_.file_identifier_.length()) {
|
||||
// Return the identifier
|
||||
code += "inline const char *" + name;
|
||||
code += "Identifier() { return \"" + parser_.file_identifier_;
|
||||
code += "\"; }\n\n";
|
||||
code += "Identifier() {\n return \"" + parser_.file_identifier_;
|
||||
code += "\";\n}\n\n";
|
||||
|
||||
// Check if a buffer has the identifier.
|
||||
code += "inline bool " + name;
|
||||
code += "BufferHasIdentifier(const void *buf) { return flatbuffers::";
|
||||
code += "BufferHasIdentifier(const void *buf) {\n return flatbuffers::";
|
||||
code += "BufferHasIdentifier(buf, ";
|
||||
code += name + "Identifier()); }\n\n";
|
||||
code += name + "Identifier());\n}\n\n";
|
||||
}
|
||||
|
||||
// The root verifier:
|
||||
code += "inline bool Verify";
|
||||
code += name;
|
||||
code +=
|
||||
"Buffer(flatbuffers::Verifier &verifier) { "
|
||||
"return verifier.VerifyBuffer<";
|
||||
"Buffer(flatbuffers::Verifier &verifier) {\n"
|
||||
" return verifier.VerifyBuffer<";
|
||||
code += cpp_qualified_name + ">(";
|
||||
if (parser_.file_identifier_.length())
|
||||
code += name + "Identifier()";
|
||||
else
|
||||
code += "nullptr";
|
||||
code += "); }\n\n";
|
||||
code += ");\n}\n\n";
|
||||
|
||||
if (parser_.file_extension_.length()) {
|
||||
// Return the extension
|
||||
@@ -205,10 +205,22 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "inline void Finish" + name;
|
||||
code +=
|
||||
"Buffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<";
|
||||
code += cpp_qualified_name + "> root) { fbb.Finish(root";
|
||||
code += cpp_qualified_name + "> root) {\n fbb.Finish(root";
|
||||
if (parser_.file_identifier_.length())
|
||||
code += ", " + name + "Identifier()";
|
||||
code += "); }\n\n";
|
||||
code += ");\n}\n\n";
|
||||
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
// A convenient root unpack function.
|
||||
auto native_name =
|
||||
NativeName(WrapInNameSpace(*parser_.root_struct_def_));
|
||||
code += "inline " + GenTypeNativePtr(native_name, nullptr, false);
|
||||
code += " UnPack" + name;
|
||||
code += "(const void *buf, const flatbuffers::resolver_function_t *";
|
||||
code += "resolver = nullptr) {\n return ";
|
||||
code += GenTypeNativePtr(native_name, nullptr, true);
|
||||
code += "(Get" + name + "(buf)->UnPack(resolver));\n}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
assert(cur_name_space_);
|
||||
@@ -293,23 +305,42 @@ class CppGenerator : public BaseGenerator {
|
||||
// TODO(wvo): make this configurable.
|
||||
std::string NativeName(const std::string &name) { return name + "T"; }
|
||||
|
||||
std::string GenTypeNative(const Type &type, bool invector) {
|
||||
const std::string &PtrType(const FieldDef *field) {
|
||||
auto attr = field ? field->attributes.Lookup("cpp_ptr_type") : nullptr;
|
||||
return attr ? attr->constant : parser_.opts.cpp_object_api_pointer_type;
|
||||
}
|
||||
|
||||
std::string GenTypeNativePtr(const std::string &type, const FieldDef *field,
|
||||
bool is_constructor) {
|
||||
auto &ptr_type = PtrType(field);
|
||||
if (ptr_type == "naked") return is_constructor ? "" : type + " *";
|
||||
return ptr_type + "<" + type + ">";
|
||||
}
|
||||
|
||||
std::string GenPtrGet(const FieldDef &field) {
|
||||
auto &ptr_type = PtrType(&field);
|
||||
return ptr_type == "naked" ? "" : ".get()";
|
||||
}
|
||||
|
||||
std::string GenTypeNative(const Type &type, bool invector,
|
||||
const FieldDef &field) {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING:
|
||||
return "std::string";
|
||||
case BASE_TYPE_VECTOR:
|
||||
return "std::vector<" + GenTypeNative(type.VectorType(), true) + ">";
|
||||
return "std::vector<" + GenTypeNative(type.VectorType(), true, field) +
|
||||
">";
|
||||
case BASE_TYPE_STRUCT:
|
||||
if (IsStruct(type)) {
|
||||
if (invector) {
|
||||
if (invector || field.native_inline) {
|
||||
return WrapInNameSpace(*type.struct_def);
|
||||
} else {
|
||||
return "std::unique_ptr<" +
|
||||
WrapInNameSpace(*type.struct_def) + ">";
|
||||
return GenTypeNativePtr(WrapInNameSpace(*type.struct_def), &field,
|
||||
false);
|
||||
}
|
||||
} else {
|
||||
return "std::unique_ptr<" +
|
||||
NativeName(WrapInNameSpace(*type.struct_def)) + ">";
|
||||
return GenTypeNativePtr(NativeName(WrapInNameSpace(*type.struct_def)),
|
||||
&field, false);
|
||||
}
|
||||
case BASE_TYPE_UNION:
|
||||
return type.enum_def->name + "Union";
|
||||
@@ -333,15 +364,15 @@ class CppGenerator : public BaseGenerator {
|
||||
return (opts.scoped_enums ? "enum class " : "enum ") + enum_def.name;
|
||||
}
|
||||
|
||||
static std::string GenEnumVal(const EnumDef &enum_def,
|
||||
const std::string &enum_val,
|
||||
const IDLOptions &opts) {
|
||||
static std::string GenEnumValDecl(const EnumDef &enum_def,
|
||||
const std::string &enum_val,
|
||||
const IDLOptions &opts) {
|
||||
return opts.prefixed_enums ? enum_def.name + "_" + enum_val : enum_val;
|
||||
}
|
||||
|
||||
static std::string GetEnumVal(const EnumDef &enum_def,
|
||||
const EnumVal &enum_val,
|
||||
const IDLOptions &opts) {
|
||||
static std::string GetEnumValUse(const EnumDef &enum_def,
|
||||
const EnumVal &enum_val,
|
||||
const IDLOptions &opts) {
|
||||
if (opts.scoped_enums) {
|
||||
return enum_def.name + "::" + enum_val.name;
|
||||
} else if (opts.prefixed_enums) {
|
||||
@@ -361,25 +392,42 @@ class CppGenerator : public BaseGenerator {
|
||||
return (inclass ? "static " : "") +
|
||||
std::string("flatbuffers::NativeTable *") +
|
||||
(inclass ? "" : enum_def.name + "Union::") +
|
||||
"UnPack(const void *union_obj, " + enum_def.name + " type)";
|
||||
"UnPack(const void *union_obj, " + enum_def.name +
|
||||
" type, const flatbuffers::resolver_function_t *resolver)";
|
||||
}
|
||||
|
||||
std::string UnionPackSignature(EnumDef &enum_def, bool inclass) {
|
||||
return "flatbuffers::Offset<void> " +
|
||||
(inclass ? "" : enum_def.name + "Union::") +
|
||||
"Pack(flatbuffers::FlatBufferBuilder &_fbb) const";
|
||||
"Pack(flatbuffers::FlatBufferBuilder &_fbb, " +
|
||||
"const flatbuffers::rehasher_function_t *rehasher" +
|
||||
(inclass ? " = nullptr" : "") + ") const";
|
||||
}
|
||||
|
||||
std::string TableCreateSignature(StructDef &struct_def) {
|
||||
std::string TableCreateSignature(StructDef &struct_def, bool predecl) {
|
||||
return "inline flatbuffers::Offset<" + struct_def.name + "> Create" +
|
||||
struct_def.name +
|
||||
"(flatbuffers::FlatBufferBuilder &_fbb, const " +
|
||||
NativeName(struct_def.name) + " *_o)";
|
||||
NativeName(struct_def.name) +
|
||||
" *_o, const flatbuffers::rehasher_function_t *rehasher" +
|
||||
(predecl ? " = nullptr" : "") + ")";
|
||||
}
|
||||
|
||||
std::string TablePackSignature(StructDef &struct_def, bool inclass) {
|
||||
return std::string(inclass ? "static " : "") +
|
||||
"flatbuffers::Offset<" + struct_def.name + "> " +
|
||||
(inclass ? "" : struct_def.name + "::") +
|
||||
"Pack(flatbuffers::FlatBufferBuilder &_fbb, " +
|
||||
"const " + NativeName(struct_def.name) + "* _o, " +
|
||||
"const flatbuffers::rehasher_function_t *_rehasher" +
|
||||
(inclass ? " = nullptr" : "") + ")";
|
||||
}
|
||||
|
||||
std::string TableUnPackSignature(StructDef &struct_def, bool inclass) {
|
||||
return "std::unique_ptr<" + NativeName(struct_def.name) + "> " +
|
||||
(inclass ? "" : struct_def.name + "::") + "UnPack() const";
|
||||
return NativeName(struct_def.name) + " *" +
|
||||
(inclass ? "" : struct_def.name + "::") +
|
||||
"UnPack(const flatbuffers::resolver_function_t *resolver" +
|
||||
(inclass ? " = nullptr" : "") + ") const";
|
||||
}
|
||||
|
||||
// Generate an enum declaration and an enum string lookup table.
|
||||
@@ -396,8 +444,9 @@ class CppGenerator : public BaseGenerator {
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
GenComment(ev.doc_comment, code_ptr, nullptr, " ");
|
||||
code += " " + GenEnumVal(enum_def, ev.name, parser_.opts) + " = ";
|
||||
code += NumToString(ev.value) + ",\n";
|
||||
code += " " + GenEnumValDecl(enum_def, ev.name, parser_.opts) + " = ";
|
||||
code += NumToString(ev.value);
|
||||
if (it != enum_def.vals.vec.end() - 1) code += ",\n";
|
||||
minv = !minv || minv->value > ev.value ? &ev : minv;
|
||||
maxv = !maxv || maxv->value < ev.value ? &ev : maxv;
|
||||
anyv |= ev.value;
|
||||
@@ -406,53 +455,23 @@ class CppGenerator : public BaseGenerator {
|
||||
assert(minv && maxv);
|
||||
if (enum_def.attributes.Lookup("bit_flags")) {
|
||||
if (minv->value != 0) // If the user didn't defined NONE value
|
||||
code += " " + GenEnumVal(enum_def, "NONE", parser_.opts) + " = 0,\n";
|
||||
code += ",\n " + GenEnumValDecl(enum_def, "NONE", parser_.opts) + " = 0";
|
||||
if (maxv->value != anyv) // If the user didn't defined ANY value
|
||||
code += " " + GenEnumVal(enum_def, "ANY", parser_.opts) + " = " +
|
||||
NumToString(anyv) + "\n";
|
||||
code += ",\n " + GenEnumValDecl(enum_def, "ANY", parser_.opts) + " = " +
|
||||
NumToString(anyv);
|
||||
} else { // MIN & MAX are useless for bit_flags
|
||||
code += " " + GenEnumVal(enum_def, "MIN", parser_.opts) + " = ";
|
||||
code += GenEnumVal(enum_def, minv->name, parser_.opts) + ",\n";
|
||||
code += " " + GenEnumVal(enum_def, "MAX", parser_.opts) + " = ";
|
||||
code += GenEnumVal(enum_def, maxv->name, parser_.opts) + "\n";
|
||||
code += ",\n " + GenEnumValDecl(enum_def, "MIN", parser_.opts) + " = ";
|
||||
code += GenEnumValDecl(enum_def, minv->name, parser_.opts);
|
||||
code += ",\n " + GenEnumValDecl(enum_def, "MAX", parser_.opts) + " = ";
|
||||
code += GenEnumValDecl(enum_def, maxv->name, parser_.opts);
|
||||
}
|
||||
}
|
||||
code += "};\n";
|
||||
code += "\n};\n";
|
||||
if (parser_.opts.scoped_enums && enum_def.attributes.Lookup("bit_flags"))
|
||||
code += "DEFINE_BITMASK_OPERATORS(" + enum_def.name + ", " +
|
||||
GenTypeBasic(enum_def.underlying_type, false) + ")\n";
|
||||
code += "\n";
|
||||
|
||||
if (parser_.opts.generate_object_based_api && enum_def.is_union) {
|
||||
// Generate a union type
|
||||
code += "struct " + enum_def.name + "Union {\n";
|
||||
code += " " + enum_def.name + " type;\n\n";
|
||||
code += " flatbuffers::NativeTable *table;\n";
|
||||
code += " " + enum_def.name + "Union() : type(";
|
||||
code += GenEnumVal(enum_def, "NONE", parser_.opts);
|
||||
code += "), table(nullptr) {}\n";
|
||||
code += " " + enum_def.name + "Union(const ";
|
||||
code += enum_def.name + "Union &);\n";
|
||||
code += " " + enum_def.name + "Union &operator=(const ";
|
||||
code += enum_def.name + "Union &);\n";
|
||||
code += " ~" + enum_def.name + "Union();\n\n";
|
||||
code += " " + UnionUnPackSignature(enum_def, true) + ";\n";
|
||||
code += " " + UnionPackSignature(enum_def, true) + ";\n\n";
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
if (ev.value) {
|
||||
auto native_name = NativeName(WrapInNameSpace(*ev.struct_def));
|
||||
code += " " + native_name + " *As";
|
||||
code += ev.name + "() { return type == ";
|
||||
code += GetEnumVal(enum_def, ev, parser_.opts);
|
||||
code += " ? reinterpret_cast<" + native_name;
|
||||
code += " *>(table) : nullptr; }\n";
|
||||
}
|
||||
}
|
||||
code += "};\n\n";
|
||||
}
|
||||
|
||||
// Generate a generate string table for enum values.
|
||||
// Problem is, if values are very sparse that could generate really big
|
||||
// tables. Ideally in that case we generate a map lookup instead, but for
|
||||
@@ -478,12 +497,73 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "()[static_cast<int>(e)";
|
||||
if (enum_def.vals.vec.front()->value) {
|
||||
code += " - static_cast<int>(";
|
||||
code += GetEnumVal(enum_def, *enum_def.vals.vec.front(), parser_.opts) +
|
||||
code += GetEnumValUse(enum_def, *enum_def.vals.vec.front(), parser_.opts) +
|
||||
")";
|
||||
}
|
||||
code += "]; }\n\n";
|
||||
}
|
||||
|
||||
// Generate type traits for unions to map from a type to union enum value.
|
||||
if (enum_def.is_union) {
|
||||
for (auto it = enum_def.vals.vec.begin();
|
||||
it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
if (it == enum_def.vals.vec.begin()) {
|
||||
code += "template<typename T> struct " + enum_def.name + "Traits {\n";
|
||||
}
|
||||
else {
|
||||
code += "template<> struct " + enum_def.name + "Traits<" +
|
||||
WrapInNameSpace(*ev.struct_def) + "> {\n";
|
||||
}
|
||||
code += " static const " + enum_def.name + " enum_value = " +
|
||||
GetEnumValUse(enum_def, ev, parser_.opts) + ";\n";
|
||||
code += "};\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
if (parser_.opts.generate_object_based_api && enum_def.is_union) {
|
||||
// Generate a union type
|
||||
code += "struct " + enum_def.name + "Union {\n";
|
||||
code += " " + enum_def.name + " type;\n\n";
|
||||
code += " flatbuffers::NativeTable *table;\n";
|
||||
code += " " + enum_def.name + "Union() : type(";
|
||||
code += GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE"), parser_.opts);
|
||||
code += "), table(nullptr) {}\n";
|
||||
code += " " + enum_def.name + "Union(const ";
|
||||
code += enum_def.name + "Union &);\n";
|
||||
code += " " + enum_def.name + "Union &operator=(const ";
|
||||
code += enum_def.name + "Union &);\n";
|
||||
code += " ~" + enum_def.name + "Union() { Reset(); }\n";
|
||||
code += " void Reset();\n\n";
|
||||
code += " template <typename T>\n";
|
||||
code += " void Set(T&& value) {\n";
|
||||
code += " Reset();\n";
|
||||
code += " type = " + enum_def.name;
|
||||
code += "Traits<typename T::TableType>::enum_value;\n";
|
||||
code += " if (type != ";
|
||||
code += GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE"), parser_.opts);
|
||||
code += ") {\n";
|
||||
code += " table = new T(std::forward<T>(value));\n";
|
||||
code += " }\n";
|
||||
code += " }\n\n";
|
||||
code += " " + UnionUnPackSignature(enum_def, true) + ";\n";
|
||||
code += " " + UnionPackSignature(enum_def, true) + ";\n\n";
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
if (ev.value) {
|
||||
auto native_name = NativeName(WrapInNameSpace(*ev.struct_def));
|
||||
code += " " + native_name + " *As";
|
||||
code += ev.name + "() { return type == ";
|
||||
code += GetEnumValUse(enum_def, ev, parser_.opts);
|
||||
code += " ? reinterpret_cast<" + native_name;
|
||||
code += " *>(table) : nullptr; }\n";
|
||||
}
|
||||
}
|
||||
code += "};\n\n";
|
||||
}
|
||||
|
||||
if (enum_def.is_union) {
|
||||
code += UnionVerifySignature(enum_def) + ";\n\n";
|
||||
}
|
||||
@@ -500,7 +580,7 @@ class CppGenerator : public BaseGenerator {
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
code += " case " + GetEnumVal(enum_def, ev, parser_.opts);
|
||||
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||
if (!ev.value) {
|
||||
code += ": return true;\n"; // "NONE" enum value.
|
||||
} else {
|
||||
@@ -518,13 +598,13 @@ class CppGenerator : public BaseGenerator {
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
code += " case " + GetEnumVal(enum_def, ev, parser_.opts);
|
||||
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||
if (!ev.value) {
|
||||
code += ": return nullptr;\n"; // "NONE" enum value.
|
||||
} else {
|
||||
code += ": return reinterpret_cast<const ";
|
||||
code += WrapInNameSpace(*ev.struct_def);
|
||||
code += " *>(union_obj)->UnPack().release();\n";
|
||||
code += " *>(union_obj)->UnPack(resolver);\n";
|
||||
}
|
||||
}
|
||||
code += " default: return nullptr;\n }\n}\n\n";
|
||||
@@ -533,33 +613,38 @@ class CppGenerator : public BaseGenerator {
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
code += " case " + GetEnumVal(enum_def, ev, parser_.opts);
|
||||
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||
if (!ev.value) {
|
||||
code += ": return 0;\n"; // "NONE" enum value.
|
||||
} else {
|
||||
code += ": return Create" + ev.struct_def->name;
|
||||
code += "(_fbb, reinterpret_cast<const ";
|
||||
code += NativeName(WrapInNameSpace(*ev.struct_def));
|
||||
code += " *>(table)).Union();\n";
|
||||
code += " *>(table), rehasher).Union();\n";
|
||||
}
|
||||
}
|
||||
code += " default: return 0;\n }\n}\n\n";
|
||||
|
||||
// Generate a union destructor.
|
||||
code += "inline " + enum_def.name + "Union::~";
|
||||
code += enum_def.name + "Union() {\n";
|
||||
code += "inline void " + enum_def.name + "Union::Reset() {\n";
|
||||
code += " switch (type) {\n";
|
||||
for (auto it = enum_def.vals.vec.begin(); it != enum_def.vals.vec.end();
|
||||
++it) {
|
||||
auto &ev = **it;
|
||||
if (ev.value) {
|
||||
code += " case " + GenEnumVal(enum_def, ev.name, parser_.opts);
|
||||
code += " case " + GetEnumValUse(enum_def, ev, parser_.opts);
|
||||
code += ": delete reinterpret_cast<";
|
||||
code += NativeName(WrapInNameSpace(*ev.struct_def));
|
||||
code += " *>(table); break;\n";
|
||||
}
|
||||
}
|
||||
code += " default:;\n }\n}\n\n";
|
||||
code += " default: break;\n";
|
||||
code += " }\n";
|
||||
code += " table = nullptr;\n";
|
||||
code += " type = ";
|
||||
code += GetEnumValUse(enum_def, *enum_def.vals.Lookup("NONE"), parser_.opts);
|
||||
code += ";\n";
|
||||
code += "}\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -604,26 +689,72 @@ class CppGenerator : public BaseGenerator {
|
||||
: field.value.constant;
|
||||
}
|
||||
|
||||
void GenSimpleParam(std::string &code, FieldDef &field) {
|
||||
code += ",\n " + GenTypeWire(field.value.type, " ", true);
|
||||
code += field.name + " = ";
|
||||
std::string GetDefaultScalarValue(const FieldDef &field) {
|
||||
if (field.value.type.enum_def && IsScalar(field.value.type.base_type)) {
|
||||
auto ev = field.value.type.enum_def->ReverseLookup(
|
||||
static_cast<int>(StringToInt(field.value.constant.c_str())), false);
|
||||
if (ev) {
|
||||
code += WrapInNameSpace(
|
||||
return WrapInNameSpace(
|
||||
field.value.type.enum_def->defined_namespace,
|
||||
GetEnumVal(*field.value.type.enum_def, *ev, parser_.opts));
|
||||
GetEnumValUse(*field.value.type.enum_def, *ev, parser_.opts));
|
||||
} else {
|
||||
code += GenUnderlyingCast(field, true, field.value.constant);
|
||||
return GenUnderlyingCast(field, true, field.value.constant);
|
||||
}
|
||||
} else if (field.value.type.base_type == BASE_TYPE_BOOL) {
|
||||
code += field.value.constant == "0" ? "false" : "true";
|
||||
return field.value.constant == "0" ? "false" : "true";
|
||||
} else {
|
||||
code += GenDefaultConstant(field);
|
||||
return GenDefaultConstant(field);
|
||||
}
|
||||
}
|
||||
|
||||
void GenSimpleParam(std::string &code, FieldDef &field) {
|
||||
code += ",\n " + GenTypeWire(field.value.type, " ", true);
|
||||
code += field.name + " = " + GetDefaultScalarValue(field);
|
||||
}
|
||||
|
||||
// Generate a member, including a default value for scalars and raw pointers.
|
||||
void GenMember(std::string& code, const FieldDef &field) {
|
||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||
field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||
auto type = GenTypeNative(field.value.type, false, field);
|
||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
code += " " + (cpp_type ? cpp_type->constant + " *" : type+ " ") +
|
||||
field.name + ";\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the default constructor for this struct. Properly initialize all
|
||||
// scalar members with default values.
|
||||
void GenDefaultConstructor(std::string& code, const StructDef& struct_def) {
|
||||
code += " " + NativeName(struct_def.name) + "()";
|
||||
std::string initializer_list;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||
field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
// Scalar types get parsed defaults, raw pointers get nullptrs.
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
if (!initializer_list.empty()) {
|
||||
initializer_list += ",\n ";
|
||||
}
|
||||
initializer_list += field.name + "(" +GetDefaultScalarValue(field) +
|
||||
")";
|
||||
} else if (cpp_type) {
|
||||
if (!initializer_list.empty()) {
|
||||
code += ",\n ";
|
||||
}
|
||||
initializer_list += field.name + "(0)";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!initializer_list.empty()) {
|
||||
code += "\n : " + initializer_list;
|
||||
}
|
||||
code += " {}\n";
|
||||
}
|
||||
|
||||
// Generate an accessor struct, builder structs & function for a table.
|
||||
void GenTable(StructDef &struct_def, std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
@@ -633,15 +764,15 @@ class CppGenerator : public BaseGenerator {
|
||||
// table.
|
||||
code += "struct " + NativeName(struct_def.name);
|
||||
code += " : public flatbuffers::NativeTable {\n";
|
||||
code += " typedef " + struct_def.name + " TableType;\n";
|
||||
// Generate GetFullyQualifiedName
|
||||
GenFullyQualifiedNameGetter(NativeName(struct_def.name), code);
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (!field.deprecated && // Deprecated fields won't be accessible.
|
||||
field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||
code += " " + GenTypeNative(field.value.type, false) + " ";
|
||||
code += field.name + ";\n";
|
||||
}
|
||||
GenMember(code, field);
|
||||
}
|
||||
GenDefaultConstructor(code, struct_def);
|
||||
code += "};\n\n";
|
||||
}
|
||||
|
||||
@@ -651,6 +782,10 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "struct " + struct_def.name;
|
||||
code += " FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table";
|
||||
code += " {\n";
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
code += " typedef " + NativeName(struct_def.name) +
|
||||
" NativeTableType;\n";
|
||||
}
|
||||
// Generate GetFullyQualifiedName
|
||||
GenFullyQualifiedNameGetter(struct_def.name, code);
|
||||
// Generate field id constants.
|
||||
@@ -814,6 +949,7 @@ class CppGenerator : public BaseGenerator {
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
// Generate the UnPack() pre declaration.
|
||||
code += " " + TableUnPackSignature(struct_def, true) + ";\n";
|
||||
code += " " + TablePackSignature(struct_def, true) + ";\n";
|
||||
}
|
||||
|
||||
code += "};\n\n"; // End of table.
|
||||
@@ -945,10 +1081,36 @@ class CppGenerator : public BaseGenerator {
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
// Generate a pre-declaration for a CreateX method that works with an
|
||||
// unpacked C++ object.
|
||||
code += TableCreateSignature(struct_def) + ";\n\n";
|
||||
code += TableCreateSignature(struct_def, true) + ";\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
std::string GenUnpackVal(const Type &type, const std::string &val,
|
||||
bool invector, const FieldDef &afield) {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING:
|
||||
return val + "->str()";
|
||||
case BASE_TYPE_STRUCT:
|
||||
if (IsStruct(type)) {
|
||||
if (invector || afield.native_inline) {
|
||||
return "*" + val;
|
||||
} else {
|
||||
return GenTypeNativePtr(WrapInNameSpace(*type.struct_def),
|
||||
&afield, true) +
|
||||
"(new " +
|
||||
WrapInNameSpace(*type.struct_def) + "(*" + val + "))";
|
||||
}
|
||||
} else {
|
||||
return GenTypeNativePtr(NativeName(WrapInNameSpace(
|
||||
*type.struct_def)), &afield, true) +
|
||||
"(" + val + "->UnPack(resolver))";
|
||||
}
|
||||
default:
|
||||
return val;
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
// Generate code for tables that needs to come after the regular definition.
|
||||
void GenTablePost(StructDef &struct_def, std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
@@ -956,6 +1118,7 @@ class CppGenerator : public BaseGenerator {
|
||||
if (parser_.opts.generate_object_based_api) {
|
||||
// Generate the UnPack() method.
|
||||
code += "inline " + TableUnPackSignature(struct_def, false) + " {\n";
|
||||
code += " (void)resolver;\n";
|
||||
code += " auto _o = new " + NativeName(struct_def.name) + "();\n";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
@@ -966,40 +1129,21 @@ class CppGenerator : public BaseGenerator {
|
||||
auto deref = "_o->";
|
||||
auto dest = deref + field.name;
|
||||
auto assign = prefix + dest + " = ";
|
||||
auto gen_unpack_val = [&](const Type &type, const std::string &val,
|
||||
bool invector) -> std::string {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING:
|
||||
return val + "->str()";
|
||||
case BASE_TYPE_STRUCT:
|
||||
if (IsStruct(type)) {
|
||||
if (invector) {
|
||||
return "*" + val;
|
||||
} else {
|
||||
return "std::unique_ptr<" +
|
||||
WrapInNameSpace (*type.struct_def) +
|
||||
">(new " +
|
||||
WrapInNameSpace (*type.struct_def) + "(*" + val + "))";
|
||||
}
|
||||
} else {
|
||||
return val + "->UnPack()";
|
||||
}
|
||||
default:
|
||||
return val;
|
||||
break;
|
||||
}
|
||||
};
|
||||
switch (field.value.type.base_type) {
|
||||
case BASE_TYPE_VECTOR: {
|
||||
code += prefix;
|
||||
code += "{ for (flatbuffers::uoffset_t _i = 0;";
|
||||
code += " _i < _e->size(); _i++) { ";
|
||||
code += dest + ".push_back(";
|
||||
std::string indexing = "_e->Get(_i)";
|
||||
std::string indexing;
|
||||
if (field.value.type.enum_def) {
|
||||
indexing += "(" + field.value.type.enum_def->name + ")";
|
||||
}
|
||||
indexing += "_e->Get(_i)";
|
||||
if (field.value.type.element == BASE_TYPE_BOOL)
|
||||
indexing += "!=0";
|
||||
code += gen_unpack_val(field.value.type.VectorType(),
|
||||
indexing, true);
|
||||
code += GenUnpackVal(field.value.type.VectorType(),
|
||||
indexing, true, field);
|
||||
code += "); } }";
|
||||
break;
|
||||
}
|
||||
@@ -1009,25 +1153,43 @@ class CppGenerator : public BaseGenerator {
|
||||
code += prefix + deref + union_field.name + ".type = _e;";
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_UNION:
|
||||
case BASE_TYPE_UNION: {
|
||||
code += prefix + dest + ".table = ";
|
||||
code += field.value.type.enum_def->name;
|
||||
code += "Union::UnPack(_e, ";
|
||||
code += field.name + UnionTypeFieldSuffix() + "());";
|
||||
code += field.name + UnionTypeFieldSuffix() + "(), resolver);";
|
||||
break;
|
||||
default:
|
||||
code += assign + gen_unpack_val(field.value.type, "_e", false);
|
||||
}
|
||||
default: {
|
||||
auto cpp_type = field.attributes.Lookup("cpp_type");
|
||||
if (cpp_type) {
|
||||
code += prefix;
|
||||
code += "if (resolver) (*resolver)(reinterpret_cast<void **>(&";
|
||||
code += dest;
|
||||
code += "), static_cast<flatbuffers::hash_value_t>(_e)); else ";
|
||||
code += dest + " = nullptr";
|
||||
} else {
|
||||
code += assign;
|
||||
code += GenUnpackVal(field.value.type, "_e", false, field);
|
||||
}
|
||||
code += ";";
|
||||
break;
|
||||
}
|
||||
}
|
||||
code += " };\n";
|
||||
}
|
||||
}
|
||||
code += " return std::unique_ptr<" + NativeName(struct_def.name);
|
||||
code += ">(_o);\n}\n\n";
|
||||
code += " return _o;\n}\n\n";
|
||||
|
||||
// Generate the X::Pack member function that simply calls the global
|
||||
// CreateX function.
|
||||
code += "inline " + TablePackSignature(struct_def, false) + " {\n";
|
||||
code += " return Create" + struct_def.name + "(_fbb, _o, _rehasher);\n";
|
||||
code += "}\n\n";
|
||||
|
||||
// Generate a CreateX method that works with an unpacked C++ object.
|
||||
code += TableCreateSignature(struct_def) + " {\n";
|
||||
code += TableCreateSignature(struct_def, false) + " {\n";
|
||||
code += " (void)rehasher;\n";
|
||||
auto before_return_statement = code.size();
|
||||
code += " return Create";
|
||||
code += struct_def.name + "(_fbb";
|
||||
@@ -1044,6 +1206,10 @@ class CppGenerator : public BaseGenerator {
|
||||
field_name += ".type";
|
||||
}
|
||||
auto accessor = "_o->" + field_name;
|
||||
if (field.attributes.Lookup("cpp_type"))
|
||||
accessor = "rehasher ? static_cast<" +
|
||||
GenTypeBasic(field.value.type, false) +
|
||||
">((*rehasher)(" + accessor + ")) : 0";
|
||||
auto ptrprefix = accessor + " ? ";
|
||||
auto stlprefix = accessor + ".size() ? ";
|
||||
auto postfix = " : 0";
|
||||
@@ -1071,15 +1237,27 @@ class CppGenerator : public BaseGenerator {
|
||||
code += "_fbb.CreateVectorOfStructs(" + accessor + ")";
|
||||
} else {
|
||||
code += "_fbb.CreateVector<flatbuffers::Offset<";
|
||||
code += vector_type.struct_def->name + ">>(" + accessor;
|
||||
code += WrapInNameSpace(*vector_type.struct_def) + ">>(" +
|
||||
accessor;
|
||||
code += ".size(), [&](size_t i) { return Create";
|
||||
code += vector_type.struct_def->name + "(_fbb, " + accessor;
|
||||
code += "[i].get()); })";
|
||||
code += "[i]" + GenPtrGet(field) + ", rehasher); })";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
case BASE_TYPE_BOOL:
|
||||
code += "_fbb.CreateVector(" + accessor + ")";
|
||||
break;
|
||||
default: {
|
||||
std::string args = accessor;
|
||||
if (field.value.type.enum_def) {
|
||||
const std::string basetype = GenTypeBasic(
|
||||
field.value.type.enum_def->underlying_type, false);
|
||||
args = "(const " + basetype + "*)" + accessor +
|
||||
".data(), " + accessor + ".size()";
|
||||
}
|
||||
code += "_fbb.CreateVector(" + args + ")";
|
||||
break;
|
||||
}
|
||||
}
|
||||
code += postfix;
|
||||
break;
|
||||
@@ -1089,11 +1267,16 @@ class CppGenerator : public BaseGenerator {
|
||||
break;
|
||||
case BASE_TYPE_STRUCT:
|
||||
if (IsStruct(field.value.type)) {
|
||||
code += ptrprefix + accessor + ".get()" + postfix;
|
||||
if (field.native_inline) {
|
||||
code += "&" + accessor;
|
||||
} else {
|
||||
code += ptrprefix + accessor + GenPtrGet(field) + postfix;
|
||||
}
|
||||
} else {
|
||||
code += ptrprefix + "Create";
|
||||
code += field.value.type.struct_def->name;
|
||||
code += "(_fbb, " + accessor + ".get())" + postfix;
|
||||
code += "(_fbb, " + accessor + GenPtrGet(field) + ", rehasher)";
|
||||
code += postfix;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -1171,40 +1354,41 @@ class CppGenerator : public BaseGenerator {
|
||||
code += struct_def.name + ")); }\n";
|
||||
|
||||
// Generate a constructor that takes all fields as arguments.
|
||||
code += " " + struct_def.name + "(";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (it != struct_def.fields.vec.begin()) code += ", ";
|
||||
code += GenTypeGet(field.value.type, " ", "const ", " &", true);
|
||||
code += "_" + field.name;
|
||||
}
|
||||
code += ")\n : ";
|
||||
padding_id = 0;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (it != struct_def.fields.vec.begin()) code += ", ";
|
||||
code += field.name + "_(";
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
code += "flatbuffers::EndianScalar(";
|
||||
code += GenUnderlyingCast(field, false, "_" + field.name);
|
||||
code += "))";
|
||||
} else {
|
||||
code += "_" + field.name + ")";
|
||||
if (struct_def.fields.vec.size()) {
|
||||
code += " " + struct_def.name + "(";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (it != struct_def.fields.vec.begin()) code += ", ";
|
||||
code += GenTypeGet(field.value.type, " ", "const ", " &", true);
|
||||
code += "_" + field.name;
|
||||
}
|
||||
GenPadding(field, code, padding_id, PaddingInitializer);
|
||||
code += ")\n : ";
|
||||
padding_id = 0;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (it != struct_def.fields.vec.begin()) code += ", ";
|
||||
code += field.name + "_(";
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
code += "flatbuffers::EndianScalar(";
|
||||
code += GenUnderlyingCast(field, false, "_" + field.name);
|
||||
code += "))";
|
||||
} else {
|
||||
code += "_" + field.name + ")";
|
||||
}
|
||||
GenPadding(field, code, padding_id, PaddingInitializer);
|
||||
}
|
||||
code += " {";
|
||||
padding_id = 0;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
GenPadding(field, code, padding_id, PaddingDeclaration);
|
||||
}
|
||||
code += " }\n\n";
|
||||
}
|
||||
|
||||
code += " {";
|
||||
padding_id = 0;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
GenPadding(field, code, padding_id, PaddingDeclaration);
|
||||
}
|
||||
code += " }\n\n";
|
||||
|
||||
// Generate accessor methods of the form:
|
||||
// type name() const { return flatbuffers::EndianScalar(name_); }
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
|
||||
@@ -76,24 +76,28 @@ struct LanguageParameters {
|
||||
IDLOptions::Language language;
|
||||
// Whether function names in the language typically start with uppercase.
|
||||
bool first_camel_upper;
|
||||
const char *file_extension;
|
||||
const char *string_type;
|
||||
const char *bool_type;
|
||||
const char *open_curly;
|
||||
const char *const_decl;
|
||||
const char *unsubclassable_decl;
|
||||
const char *enum_decl;
|
||||
const char *enum_separator;
|
||||
const char *getter_prefix;
|
||||
const char *getter_suffix;
|
||||
const char *inheritance_marker;
|
||||
const char *namespace_ident;
|
||||
const char *namespace_begin;
|
||||
const char *namespace_end;
|
||||
const char *set_bb_byteorder;
|
||||
const char *get_bb_position;
|
||||
const char *get_fbb_offset;
|
||||
const char *includes;
|
||||
std::string file_extension;
|
||||
std::string string_type;
|
||||
std::string bool_type;
|
||||
std::string open_curly;
|
||||
std::string accessor_type;
|
||||
std::string const_decl;
|
||||
std::string unsubclassable_decl;
|
||||
std::string enum_decl;
|
||||
std::string enum_separator;
|
||||
std::string getter_prefix;
|
||||
std::string getter_suffix;
|
||||
std::string inheritance_marker;
|
||||
std::string namespace_ident;
|
||||
std::string namespace_begin;
|
||||
std::string namespace_end;
|
||||
std::string set_bb_byteorder;
|
||||
std::string get_bb_position;
|
||||
std::string get_fbb_offset;
|
||||
std::string accessor_prefix;
|
||||
std::string accessor_prefix_static;
|
||||
std::string optional_suffix;
|
||||
std::string includes;
|
||||
CommentConfig comment_config;
|
||||
};
|
||||
|
||||
@@ -105,6 +109,7 @@ LanguageParameters language_parameters[] = {
|
||||
"String",
|
||||
"boolean ",
|
||||
" {\n",
|
||||
"class ",
|
||||
" final ",
|
||||
"final ",
|
||||
"final class ",
|
||||
@@ -118,6 +123,9 @@ LanguageParameters language_parameters[] = {
|
||||
"_bb.order(ByteOrder.LITTLE_ENDIAN); ",
|
||||
"position()",
|
||||
"offset()",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
|
||||
"import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n",
|
||||
{
|
||||
@@ -133,8 +141,9 @@ LanguageParameters language_parameters[] = {
|
||||
"string",
|
||||
"bool ",
|
||||
"\n{\n",
|
||||
"struct ",
|
||||
" readonly ",
|
||||
"sealed ",
|
||||
"",
|
||||
"enum ",
|
||||
",\n",
|
||||
" { get",
|
||||
@@ -146,6 +155,9 @@ LanguageParameters language_parameters[] = {
|
||||
"",
|
||||
"Position",
|
||||
"Offset",
|
||||
"__p.",
|
||||
"Table.",
|
||||
"?",
|
||||
"using System;\nusing FlatBuffers;\n\n",
|
||||
{
|
||||
nullptr,
|
||||
@@ -162,6 +174,7 @@ LanguageParameters language_parameters[] = {
|
||||
"string",
|
||||
"bool ",
|
||||
"\n{\n",
|
||||
"class ",
|
||||
"const ",
|
||||
" ",
|
||||
"class ",
|
||||
@@ -175,6 +188,9 @@ LanguageParameters language_parameters[] = {
|
||||
"",
|
||||
"position()",
|
||||
"offset()",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"import (\n\tflatbuffers \"github.com/google/flatbuffers/go\"\n)",
|
||||
{
|
||||
nullptr,
|
||||
@@ -194,17 +210,21 @@ class GeneralGenerator : public BaseGenerator {
|
||||
GeneralGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name)
|
||||
: BaseGenerator(parser, path, file_name, "", "."),
|
||||
lang_(language_parameters[parser_.opts.lang]) {
|
||||
lang_(language_parameters[parser_.opts.lang]),
|
||||
cur_name_space_( nullptr ) {
|
||||
assert(parser_.opts.lang <= IDLOptions::kMAX);
|
||||
};
|
||||
GeneralGenerator &operator=(const GeneralGenerator &);
|
||||
bool generate() {
|
||||
std::string one_file_code;
|
||||
cur_name_space_ = parser_.namespaces_.back();
|
||||
|
||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||
++it) {
|
||||
std::string enumcode;
|
||||
auto &enum_def = **it;
|
||||
if (!parser_.opts.one_file)
|
||||
cur_name_space_ = enum_def.defined_namespace;
|
||||
GenEnum(enum_def, &enumcode);
|
||||
if (parser_.opts.one_file) {
|
||||
one_file_code += enumcode;
|
||||
@@ -218,6 +238,8 @@ class GeneralGenerator : public BaseGenerator {
|
||||
it != parser_.structs_.vec.end(); ++it) {
|
||||
std::string declcode;
|
||||
auto &struct_def = **it;
|
||||
if (!parser_.opts.one_file)
|
||||
cur_name_space_ = struct_def.defined_namespace;
|
||||
GenStruct(struct_def, &declcode);
|
||||
if (parser_.opts.one_file) {
|
||||
one_file_code += declcode;
|
||||
@@ -237,7 +259,7 @@ class GeneralGenerator : public BaseGenerator {
|
||||
// Save out the generated code for a single class while adding
|
||||
// declaration boilerplate.
|
||||
bool SaveType(const std::string &defname, const Namespace &ns,
|
||||
const std::string &classcode, bool needs_includes) {
|
||||
const std::string &classcode, bool needs_includes) {
|
||||
if (!classcode.length()) return true;
|
||||
|
||||
std::string code;
|
||||
@@ -254,7 +276,7 @@ class GeneralGenerator : public BaseGenerator {
|
||||
return SaveFile(filename.c_str(), code, false);
|
||||
}
|
||||
|
||||
const Namespace *CurrentNameSpace() { return parser_.namespaces_.back(); }
|
||||
const Namespace *CurrentNameSpace() { return cur_name_space_; }
|
||||
|
||||
std::string FunctionStart(char upper) {
|
||||
return std::string() + (lang_.language == IDLOptions::kJava
|
||||
@@ -343,7 +365,8 @@ std::string GenOffsetConstruct(const StructDef &struct_def,
|
||||
const std::string &variable_name)
|
||||
{
|
||||
if(lang_.language == IDLOptions::kCSharp) {
|
||||
return "new Offset<" + WrapInNameSpace(struct_def) + ">(" + variable_name + ")";
|
||||
return "new Offset<" + WrapInNameSpace(struct_def) + ">(" + variable_name +
|
||||
")";
|
||||
}
|
||||
return variable_name;
|
||||
}
|
||||
@@ -401,9 +424,11 @@ std::string DestinationCast(const Type &type) {
|
||||
}
|
||||
|
||||
// Cast statements for mutator method parameters.
|
||||
// In Java, parameters representing unsigned numbers need to be cast down to their respective type.
|
||||
// For example, a long holding an unsigned int value would be cast down to int before being put onto the buffer.
|
||||
// In C#, one cast directly cast an Enum to its underlying type, which is essential before putting it onto the buffer.
|
||||
// In Java, parameters representing unsigned numbers need to be cast down to
|
||||
// their respective type. For example, a long holding an unsigned int value
|
||||
// would be cast down to int before being put onto the buffer. In C#, one cast
|
||||
// directly cast an Enum to its underlying type, which is essential before
|
||||
// putting it onto the buffer.
|
||||
std::string SourceCast(const Type &type, bool castFromDest) {
|
||||
if (type.base_type == BASE_TYPE_VECTOR) {
|
||||
return SourceCast(type.VectorType(), castFromDest);
|
||||
@@ -465,9 +490,21 @@ std::string GenDefaultValue(const Value &value, bool enableLangOverrides) {
|
||||
return GenEnumDefaultValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
auto longSuffix = lang_.language == IDLOptions::kJava ? "L" : "";
|
||||
switch (value.type.base_type) {
|
||||
case BASE_TYPE_FLOAT: return value.constant + "f";
|
||||
case BASE_TYPE_BOOL: return value.constant == "0" ? "false" : "true";
|
||||
case BASE_TYPE_ULONG:
|
||||
{
|
||||
if (lang_.language != IDLOptions::kJava)
|
||||
return value.constant;
|
||||
// Converts the ulong into its bits signed equivalent
|
||||
uint64_t defaultValue = StringToUInt(value.constant.c_str());
|
||||
return NumToString(static_cast<int64_t>(defaultValue)) + longSuffix;
|
||||
}
|
||||
case BASE_TYPE_UINT:
|
||||
case BASE_TYPE_LONG: return value.constant + longSuffix;
|
||||
default: return value.constant;
|
||||
}
|
||||
}
|
||||
@@ -484,7 +521,8 @@ std::string GenDefaultValueBasic(const Value &value, bool enableLangOverrides) {
|
||||
case BASE_TYPE_STRING:
|
||||
return "default(StringOffset)";
|
||||
case BASE_TYPE_STRUCT:
|
||||
return "default(Offset<" + WrapInNameSpace(*value.type.struct_def) + ">)";
|
||||
return "default(Offset<" + WrapInNameSpace(*value.type.struct_def) +
|
||||
">)";
|
||||
case BASE_TYPE_VECTOR:
|
||||
return "default(VectorOffset)";
|
||||
default:
|
||||
@@ -513,7 +551,8 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr) {
|
||||
GenComment(enum_def.doc_comment, code_ptr, &lang_.comment_config);
|
||||
code += std::string("public ") + lang_.enum_decl + enum_def.name;
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
code += lang_.inheritance_marker + GenTypeBasic(enum_def.underlying_type, false);
|
||||
code += lang_.inheritance_marker +
|
||||
GenTypeBasic(enum_def.underlying_type, false);
|
||||
}
|
||||
code += lang_.open_curly;
|
||||
if (lang_.language == IDLOptions::kJava) {
|
||||
@@ -578,12 +617,13 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr) {
|
||||
// Returns the function name that is able to read a value of the given type.
|
||||
std::string GenGetter(const Type &type) {
|
||||
switch (type.base_type) {
|
||||
case BASE_TYPE_STRING: return "__string";
|
||||
case BASE_TYPE_STRUCT: return "__struct";
|
||||
case BASE_TYPE_UNION: return "__union";
|
||||
case BASE_TYPE_STRING: return lang_.accessor_prefix + "__string";
|
||||
case BASE_TYPE_STRUCT: return lang_.accessor_prefix + "__struct";
|
||||
case BASE_TYPE_UNION: return lang_.accessor_prefix + "__union";
|
||||
case BASE_TYPE_VECTOR: return GenGetter(type.VectorType());
|
||||
default: {
|
||||
std::string getter = "bb." + FunctionStart('G') + "et";
|
||||
std::string getter =
|
||||
lang_.accessor_prefix + "bb." + FunctionStart('G') + "et";
|
||||
if (type.base_type == BASE_TYPE_BOOL) {
|
||||
getter = "0!=" + getter;
|
||||
} else if (GenTypeBasic(type, false) != "byte") {
|
||||
@@ -598,7 +638,8 @@ std::string GenGetter(const Type &type) {
|
||||
// Hence a setter method will only be generated for such fields.
|
||||
std::string GenSetter(const Type &type) {
|
||||
if (IsScalar(type.base_type)) {
|
||||
std::string setter = "bb." + FunctionStart('P') + "ut";
|
||||
std::string setter =
|
||||
lang_.accessor_prefix + "bb." + FunctionStart('P') + "ut";
|
||||
if (GenTypeBasic(type, false) != "byte" &&
|
||||
type.base_type != BASE_TYPE_BOOL) {
|
||||
setter += MakeCamel(GenTypeBasic(type, false));
|
||||
@@ -618,7 +659,8 @@ std::string GenMethod(const Type &type) {
|
||||
|
||||
// Recursively generate arguments for a constructor, to deal with nested
|
||||
// structs.
|
||||
void GenStructArgs(const StructDef &struct_def, std::string *code_ptr, const char *nameprefix) {
|
||||
void GenStructArgs(const StructDef &struct_def, std::string *code_ptr,
|
||||
const char *nameprefix) {
|
||||
std::string &code = *code_ptr;
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end();
|
||||
@@ -643,7 +685,8 @@ void GenStructArgs(const StructDef &struct_def, std::string *code_ptr, const cha
|
||||
// Recusively generate struct construction statements of the form:
|
||||
// builder.putType(name);
|
||||
// and insert manual padding.
|
||||
void GenStructBody(const StructDef &struct_def, std::string *code_ptr, const char *nameprefix) {
|
||||
void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
|
||||
const char *nameprefix) {
|
||||
std::string &code = *code_ptr;
|
||||
code += " builder." + FunctionStart('P') + "rep(";
|
||||
code += NumToString(struct_def.minalign) + ", ";
|
||||
@@ -669,6 +712,90 @@ void GenStructBody(const StructDef &struct_def, std::string *code_ptr, const cha
|
||||
}
|
||||
}
|
||||
|
||||
std::string GenByteBufferLength(const char *bb_name) {
|
||||
std::string bb_len = bb_name;
|
||||
if (lang_.language == IDLOptions::kCSharp) bb_len += ".Length";
|
||||
else bb_len += ".array().length";
|
||||
return bb_len;
|
||||
}
|
||||
|
||||
std::string GenOffsetGetter(flatbuffers::FieldDef *key_field,
|
||||
const char *num = nullptr) {
|
||||
std::string key_offset = "";
|
||||
key_offset += lang_.accessor_prefix_static + "__offset(" +
|
||||
NumToString(key_field->value.offset) + ", ";
|
||||
if (num) {
|
||||
key_offset += num;
|
||||
key_offset += (lang_.language == IDLOptions::kCSharp ?
|
||||
".Value, builder.DataBuffer)" : ", _bb)");
|
||||
} else {
|
||||
key_offset += GenByteBufferLength("bb");
|
||||
key_offset += " - tableOffset, bb)";
|
||||
}
|
||||
return key_offset;
|
||||
}
|
||||
|
||||
std::string GenLookupKeyGetter(flatbuffers::FieldDef *key_field) {
|
||||
std::string key_getter = " ";
|
||||
key_getter += "int tableOffset = " + lang_.accessor_prefix_static;
|
||||
key_getter += "__indirect(vectorLocation + 4 * (start + middle)";
|
||||
key_getter += ", bb);\n ";
|
||||
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
||||
key_getter += "int comp = " + lang_.accessor_prefix_static;
|
||||
key_getter += FunctionStart('C') + "ompareStrings(";
|
||||
key_getter += GenOffsetGetter(key_field);
|
||||
key_getter += ", byteKey, bb);\n";
|
||||
} else {
|
||||
auto get_val = GenGetter(key_field->value.type) +
|
||||
"(" + GenOffsetGetter(key_field) + ")";
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
key_getter += "int comp = " + get_val + ".CompareTo(key);\n";
|
||||
} else {
|
||||
key_getter += GenTypeGet(key_field->value.type) + " val = ";
|
||||
key_getter += get_val + ";\n";
|
||||
key_getter += " int comp = val > key ? 1 : val < key ? -1 : 0;\n";
|
||||
}
|
||||
}
|
||||
return key_getter;
|
||||
}
|
||||
|
||||
|
||||
std::string GenKeyGetter(flatbuffers::FieldDef *key_field) {
|
||||
std::string key_getter = "";
|
||||
auto data_buffer = (lang_.language == IDLOptions::kCSharp) ?
|
||||
"builder.DataBuffer" : "_bb";
|
||||
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
||||
if (lang_.language == IDLOptions::kJava)
|
||||
key_getter += " return ";
|
||||
key_getter += lang_.accessor_prefix_static;
|
||||
key_getter += FunctionStart('C') + "ompareStrings(";
|
||||
key_getter += GenOffsetGetter(key_field, "o1") + ", ";
|
||||
key_getter += GenOffsetGetter(key_field, "o2") + ", " + data_buffer + ")";
|
||||
if (lang_.language == IDLOptions::kJava)
|
||||
key_getter += ";";
|
||||
}
|
||||
else {
|
||||
auto field_getter = data_buffer + GenGetter(key_field->value.type).substr(2) +
|
||||
"(" + GenOffsetGetter(key_field, "o1") + ")";
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
key_getter += field_getter;
|
||||
field_getter = data_buffer + GenGetter(key_field->value.type).substr(2) +
|
||||
"(" + GenOffsetGetter(key_field, "o2") + ")";
|
||||
key_getter += ".CompareTo(" + field_getter + ")";
|
||||
}
|
||||
else {
|
||||
key_getter += "\n " + GenTypeGet(key_field->value.type) + " val_1 = ";
|
||||
key_getter += field_getter + ";\n " + GenTypeGet(key_field->value.type);
|
||||
key_getter += " val_2 = ";
|
||||
field_getter = data_buffer + GenGetter(key_field->value.type).substr(2) +
|
||||
"(" + GenOffsetGetter(key_field, "o2") + ")";
|
||||
key_getter += field_getter + ";\n";
|
||||
key_getter += " return val_1 > val_2 ? 1 : val_1 < val_2 ? -1 : 0;\n ";
|
||||
}
|
||||
}
|
||||
return key_getter;
|
||||
}
|
||||
|
||||
void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
if (struct_def.generated) return;
|
||||
std::string &code = *code_ptr;
|
||||
@@ -685,18 +812,32 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
struct_def.attributes.Lookup("csharp_partial")) {
|
||||
// generate a partial class for this C# struct/table
|
||||
code += "partial ";
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
code += lang_.unsubclassable_decl;
|
||||
}
|
||||
code += "class " + struct_def.name + lang_.inheritance_marker;
|
||||
code += struct_def.fixed ? "Struct" : "Table";
|
||||
code += " {\n";
|
||||
code += lang_.accessor_type + struct_def.name;
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
code += " : IFlatbufferObject";
|
||||
code += lang_.open_curly;
|
||||
code += " private ";
|
||||
code += struct_def.fixed ? "Struct" : "Table";
|
||||
code += " __p;\n";
|
||||
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
code += " public ByteBuffer ByteBuffer { get { return __p.bb; } }\n";
|
||||
}
|
||||
|
||||
} else {
|
||||
code += lang_.inheritance_marker;
|
||||
code += struct_def.fixed ? "Struct" : "Table";
|
||||
code += lang_.open_curly;
|
||||
}
|
||||
if (!struct_def.fixed) {
|
||||
// Generate a special accessor for the table that when used as the root
|
||||
// of a FlatBuffer
|
||||
std::string method_name = FunctionStart('G') + "etRootAs" + struct_def.name;
|
||||
std::string method_signature = " public static " + struct_def.name + " " + method_name;
|
||||
std::string method_signature = " public static " + struct_def.name + " " +
|
||||
method_name;
|
||||
|
||||
// create convenience method that doesn't require an existing object
|
||||
code += method_signature + "(ByteBuffer _bb) ";
|
||||
@@ -705,8 +846,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
// create method that allows object reuse
|
||||
code += method_signature + "(ByteBuffer _bb, " + struct_def.name + " obj) { ";
|
||||
code += lang_.set_bb_byteorder;
|
||||
code += "return (obj.__init(_bb." + FunctionStart('G');
|
||||
code += "etInt(_bb.";
|
||||
code += "return (obj.__assign(_bb." + FunctionStart('G') + "etInt(_bb.";
|
||||
code += lang_.get_bb_position;
|
||||
code += ") + _bb.";
|
||||
code += lang_.get_bb_position;
|
||||
@@ -717,16 +857,19 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += " public static ";
|
||||
code += lang_.bool_type + struct_def.name;
|
||||
code += "BufferHasIdentifier(ByteBuffer _bb) { return ";
|
||||
code += "__has_identifier(_bb, \"" + parser_.file_identifier_;
|
||||
code += lang_.accessor_prefix_static + "__has_identifier(_bb, \"";
|
||||
code += parser_.file_identifier_;
|
||||
code += "\"); }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
// Generate the __init method that sets the field in a pre-existing
|
||||
// accessor object. This is to allow object reuse.
|
||||
code += " public " + struct_def.name;
|
||||
code += " __init(int _i, ByteBuffer _bb) ";
|
||||
code += "{ bb_pos = _i; bb = _bb; return this; }\n\n";
|
||||
code += " public void __init(int _i, ByteBuffer _bb) ";
|
||||
code += "{ " + lang_.accessor_prefix + "bb_pos = _i; ";
|
||||
code += lang_.accessor_prefix + "bb = _bb; }\n";
|
||||
code += " public " + struct_def.name + " __assign(int _i, ByteBuffer _bb) ";
|
||||
code += "{ __init(_i, _bb); return this; }\n\n";
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end();
|
||||
++it) {
|
||||
@@ -735,28 +878,35 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
GenComment(field.doc_comment, code_ptr, &lang_.comment_config, " ");
|
||||
std::string type_name = GenTypeGet(field.value.type);
|
||||
std::string type_name_dest = GenTypeNameDest(field.value.type);
|
||||
std::string conditional_cast = "";
|
||||
std::string optional = "";
|
||||
if (lang_.language == IDLOptions::kCSharp &&
|
||||
!struct_def.fixed &&
|
||||
(field.value.type.base_type == BASE_TYPE_STRUCT ||
|
||||
field.value.type.base_type == BASE_TYPE_UNION ||
|
||||
(field.value.type.base_type == BASE_TYPE_VECTOR &&
|
||||
field.value.type.element == BASE_TYPE_STRUCT))) {
|
||||
optional = lang_.optional_suffix;
|
||||
conditional_cast = "(" + type_name_dest + optional + ")";
|
||||
}
|
||||
std::string dest_mask = DestinationMask(field.value.type, true);
|
||||
std::string dest_cast = DestinationCast(field.value.type);
|
||||
std::string src_cast = SourceCast(field.value.type);
|
||||
std::string method_start = " public " + type_name_dest + " " +
|
||||
std::string method_start = " public " + type_name_dest + optional + " " +
|
||||
MakeCamel(field.name, lang_.first_camel_upper);
|
||||
std::string obj = lang_.language == IDLOptions::kCSharp
|
||||
? "(new " + type_name + "())"
|
||||
: "obj";
|
||||
|
||||
// Most field accessors need to retrieve and test the field offset first,
|
||||
// this is the prefix code for that:
|
||||
auto offset_prefix = " { int o = __offset(" +
|
||||
NumToString(field.value.offset) +
|
||||
"); return o != 0 ? ";
|
||||
auto offset_prefix = " { int o = " + lang_.accessor_prefix + "__offset(" +
|
||||
NumToString(field.value.offset) +
|
||||
"); return o != 0 ? ";
|
||||
// Generate the accessors that don't do object reuse.
|
||||
if (field.value.type.base_type == BASE_TYPE_STRUCT) {
|
||||
// Calls the accessor that takes an accessor object with a new object.
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
code += method_start + " { get { return Get";
|
||||
code += MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += "(new ";
|
||||
code += type_name + "()); } }\n";
|
||||
method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang_.first_camel_upper);
|
||||
}
|
||||
else {
|
||||
if (lang_.language != IDLOptions::kCSharp) {
|
||||
code += method_start + "() { return ";
|
||||
code += MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += "(new ";
|
||||
@@ -766,24 +916,16 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
field.value.type.element == BASE_TYPE_STRUCT) {
|
||||
// Accessors for vectors of structs also take accessor objects, this
|
||||
// generates a variant without that argument.
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += method_start + "(int j) { return Get";
|
||||
} else {
|
||||
if (lang_.language != IDLOptions::kCSharp) {
|
||||
code += method_start + "(int j) { return ";
|
||||
}
|
||||
code += MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += "(new ";
|
||||
code += type_name + "(), j); }\n";
|
||||
} else if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += "(new " + type_name + "(), j); }\n";
|
||||
}
|
||||
} else if (field.value.type.base_type == BASE_TYPE_UNION) {
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
// union types in C# use generic Table-derived type for better type safety
|
||||
method_start = " public " + type_name_dest + " Get" + MakeCamel(field.name, lang_.first_camel_upper) + "<TTable>";
|
||||
offset_prefix = " where TTable : Table" + offset_prefix;
|
||||
// Union types in C# use generic Table-derived type for better type
|
||||
// safety.
|
||||
method_start += "<TTable>";
|
||||
type_name = type_name_dest;
|
||||
}
|
||||
}
|
||||
@@ -793,64 +935,78 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
// only create default casts for c# scalars or vectors of scalars
|
||||
if (lang_.language == IDLOptions::kCSharp &&
|
||||
(IsScalar(field.value.type.base_type) ||
|
||||
(field.value.type.base_type == BASE_TYPE_VECTOR && IsScalar(field.value.type.element)))) {
|
||||
// For scalars, default value will be returned by GetDefaultValue(). If the scalar is an enum, GetDefaultValue()
|
||||
// returns an actual c# enum that doesn't need to be casted. However, default values for enum elements of
|
||||
// vectors are integer literals ("0") and are still casted for clarity.
|
||||
if (field.value.type.enum_def == nullptr || field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
(field.value.type.base_type == BASE_TYPE_VECTOR &&
|
||||
IsScalar(field.value.type.element)))) {
|
||||
// For scalars, default value will be returned by GetDefaultValue().
|
||||
// If the scalar is an enum, GetDefaultValue() returns an actual c# enum
|
||||
// that doesn't need to be casted. However, default values for enum
|
||||
// elements of vectors are integer literals ("0") and are still casted
|
||||
// for clarity.
|
||||
if (field.value.type.enum_def == nullptr ||
|
||||
field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
default_cast = "(" + type_name_dest + ")";
|
||||
}
|
||||
}
|
||||
std::string member_suffix = "";
|
||||
std::string member_suffix = "; ";
|
||||
if (IsScalar(field.value.type.base_type)) {
|
||||
code += lang_.getter_prefix;
|
||||
member_suffix = lang_.getter_suffix;
|
||||
member_suffix += lang_.getter_suffix;
|
||||
if (struct_def.fixed) {
|
||||
code += " { return " + getter;
|
||||
code += "(bb_pos + " + NumToString(field.value.offset) + ")";
|
||||
code += "(" + lang_.accessor_prefix + "bb_pos + ";
|
||||
code += NumToString(field.value.offset) + ")";
|
||||
code += dest_mask;
|
||||
} else {
|
||||
code += offset_prefix + getter;
|
||||
code += "(o + bb_pos)" + dest_mask + " : " + default_cast;
|
||||
code += "(o + " + lang_.accessor_prefix + "bb_pos)" + dest_mask;
|
||||
code += " : " + default_cast;
|
||||
code += GenDefaultValue(field.value);
|
||||
}
|
||||
} else {
|
||||
switch (field.value.type.base_type) {
|
||||
case BASE_TYPE_STRUCT:
|
||||
code += "(" + type_name + " obj";
|
||||
if (struct_def.fixed) {
|
||||
code += ") { return obj.__init(bb_pos + ";
|
||||
code += NumToString(field.value.offset) + ", bb)";
|
||||
if (lang_.language != IDLOptions::kCSharp) {
|
||||
code += "(" + type_name + " obj" + ")";
|
||||
} else {
|
||||
code += ")";
|
||||
code += offset_prefix;
|
||||
code += "obj.__init(";
|
||||
code += lang_.getter_prefix;
|
||||
member_suffix += lang_.getter_suffix;
|
||||
}
|
||||
if (struct_def.fixed) {
|
||||
code += " { return " + obj + ".__assign(" + lang_.accessor_prefix;
|
||||
code += "bb_pos + " + NumToString(field.value.offset) + ", ";
|
||||
code += lang_.accessor_prefix + "bb)";
|
||||
} else {
|
||||
code += offset_prefix + conditional_cast;
|
||||
code += obj + ".__assign(";
|
||||
code += field.value.type.struct_def->fixed
|
||||
? "o + bb_pos"
|
||||
: "__indirect(o + bb_pos)";
|
||||
code += ", bb) : null";
|
||||
? "o + " + lang_.accessor_prefix + "bb_pos"
|
||||
: lang_.accessor_prefix + "__indirect(o + " +
|
||||
lang_.accessor_prefix + "bb_pos)";
|
||||
code += ", " + lang_.accessor_prefix + "bb) : null";
|
||||
}
|
||||
break;
|
||||
case BASE_TYPE_STRING:
|
||||
code += lang_.getter_prefix;
|
||||
member_suffix = lang_.getter_suffix;
|
||||
code += offset_prefix + getter + "(o + bb_pos) : null";
|
||||
member_suffix += lang_.getter_suffix;
|
||||
code += offset_prefix + getter + "(o + " + lang_.accessor_prefix;
|
||||
code += "bb_pos) : null";
|
||||
break;
|
||||
case BASE_TYPE_VECTOR: {
|
||||
auto vectortype = field.value.type.VectorType();
|
||||
code += "(";
|
||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||
code += type_name + " obj, ";
|
||||
getter = "obj.__init";
|
||||
if (lang_.language != IDLOptions::kCSharp)
|
||||
code += type_name + " obj, ";
|
||||
getter = obj + ".__assign";
|
||||
}
|
||||
code += "int j)" + offset_prefix + getter +"(";
|
||||
auto index = "__vector(o) + j * " +
|
||||
code += "int j)" + offset_prefix + conditional_cast + getter +"(";
|
||||
auto index = lang_.accessor_prefix + "__vector(o) + j * " +
|
||||
NumToString(InlineSize(vectortype));
|
||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||
code += vectortype.struct_def->fixed
|
||||
? index
|
||||
: "__indirect(" + index + ")";
|
||||
code += ", bb";
|
||||
: lang_.accessor_prefix + "__indirect(" + index + ")";
|
||||
code += ", " + lang_.accessor_prefix + "bb";
|
||||
} else {
|
||||
code += index;
|
||||
}
|
||||
@@ -861,14 +1017,19 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_UNION:
|
||||
code += "(" + type_name + " obj)" + offset_prefix + getter;
|
||||
code += "(obj, o) : null";
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
code += "() where TTable : struct, IFlatbufferObject";
|
||||
code += offset_prefix + "(TTable?)" + getter;
|
||||
code += "<TTable>(o) : null";
|
||||
} else {
|
||||
code += "(" + type_name + " obj)" + offset_prefix + getter;
|
||||
code += "(obj, o) : null";
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
code += "; ";
|
||||
code += member_suffix;
|
||||
code += "}\n";
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
@@ -876,7 +1037,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += "Length";
|
||||
code += lang_.getter_prefix;
|
||||
code += offset_prefix;
|
||||
code += "__vector_len(o) : 0; ";
|
||||
code += lang_.accessor_prefix + "__vector_len(o) : 0; ";
|
||||
code += lang_.getter_suffix;
|
||||
code += "}\n";
|
||||
}
|
||||
@@ -888,16 +1049,19 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
case IDLOptions::kJava:
|
||||
code += " public ByteBuffer ";
|
||||
code += MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += "AsByteBuffer() { return __vector_as_bytebuffer(";
|
||||
code += "AsByteBuffer() { return ";
|
||||
code += lang_.accessor_prefix + "__vector_as_bytebuffer(";
|
||||
code += NumToString(field.value.offset) + ", ";
|
||||
code += NumToString(field.value.type.base_type == BASE_TYPE_STRING ? 1 :
|
||||
InlineSize(field.value.type.VectorType()));
|
||||
code += NumToString(field.value.type.base_type == BASE_TYPE_STRING
|
||||
? 1
|
||||
: InlineSize(field.value.type.VectorType()));
|
||||
code += "); }\n";
|
||||
break;
|
||||
case IDLOptions::kCSharp:
|
||||
code += " public ArraySegment<byte>? Get";
|
||||
code += MakeCamel(field.name, lang_.first_camel_upper);
|
||||
code += "Bytes() { return __vector_as_arraysegment(";
|
||||
code += "Bytes() { return ";
|
||||
code += lang_.accessor_prefix + "__vector_as_arraysegment(";
|
||||
code += NumToString(field.value.offset);
|
||||
code += "); }\n";
|
||||
break;
|
||||
@@ -917,30 +1081,49 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
auto getNestedMethodName = nestedMethodName;
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
getNestedMethodName = "Get" + nestedMethodName;
|
||||
conditional_cast = "(" + nested_type_name + lang_.optional_suffix + ")";
|
||||
}
|
||||
code += " public " + nested_type_name + " ";
|
||||
code += nestedMethodName + "() { return ";
|
||||
code += getNestedMethodName + "(new " + nested_type_name + "()); }\n";
|
||||
code += " public " + nested_type_name + " " + getNestedMethodName;
|
||||
code += "(" + nested_type_name + " obj) { ";
|
||||
code += "int o = __offset(" + NumToString(field.value.offset) +"); ";
|
||||
code += "return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }\n";
|
||||
if (lang_.language != IDLOptions::kCSharp) {
|
||||
code += " public " + nested_type_name + lang_.optional_suffix + " ";
|
||||
code += nestedMethodName + "() { return ";
|
||||
code += getNestedMethodName + "(new " + nested_type_name + "()); }\n";
|
||||
} else {
|
||||
obj = "(new " + nested_type_name + "())";
|
||||
}
|
||||
code += " public " + nested_type_name + lang_.optional_suffix + " ";
|
||||
code += getNestedMethodName + "(";
|
||||
if (lang_.language != IDLOptions::kCSharp)
|
||||
code += nested_type_name + " obj";
|
||||
code += ") { int o = " + lang_.accessor_prefix + "__offset(";
|
||||
code += NumToString(field.value.offset) +"); ";
|
||||
code += "return o != 0 ? " + conditional_cast + obj + ".__assign(";
|
||||
code += lang_.accessor_prefix;
|
||||
code += "__indirect(" + lang_.accessor_prefix + "__vector(o)), ";
|
||||
code += lang_.accessor_prefix + "bb) : null; }\n";
|
||||
}
|
||||
// generate mutators for scalar fields or vectors of scalars
|
||||
// Generate mutators for scalar fields or vectors of scalars.
|
||||
if (parser_.opts.mutable_buffer) {
|
||||
auto underlying_type = field.value.type.base_type == BASE_TYPE_VECTOR
|
||||
? field.value.type.VectorType()
|
||||
: field.value.type;
|
||||
// boolean parameters have to be explicitly converted to byte representation
|
||||
auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL ? "(byte)(" + field.name + " ? 1 : 0)" : field.name;
|
||||
// Boolean parameters have to be explicitly converted to byte
|
||||
// representation.
|
||||
auto setter_parameter = underlying_type.base_type == BASE_TYPE_BOOL
|
||||
? "(byte)(" + field.name + " ? 1 : 0)"
|
||||
: field.name;
|
||||
auto mutator_prefix = MakeCamel("mutate", lang_.first_camel_upper);
|
||||
//a vector mutator also needs the index of the vector element it should mutate
|
||||
auto mutator_params = (field.value.type.base_type == BASE_TYPE_VECTOR ? "(int j, " : "(") +
|
||||
GenTypeNameDest(underlying_type) + " " +
|
||||
field.name + ") { ";
|
||||
// A vector mutator also needs the index of the vector element it should
|
||||
// mutate.
|
||||
auto mutator_params = (field.value.type.base_type == BASE_TYPE_VECTOR
|
||||
? "(int j, "
|
||||
: "(") + GenTypeNameDest(underlying_type) + " " + field.name + ") { ";
|
||||
auto setter_index = field.value.type.base_type == BASE_TYPE_VECTOR
|
||||
? "__vector(o) + j * " + NumToString(InlineSize(underlying_type))
|
||||
: (struct_def.fixed ? "bb_pos + " + NumToString(field.value.offset) : "o + bb_pos");
|
||||
? lang_.accessor_prefix + "__vector(o) + j * " +
|
||||
NumToString(InlineSize(underlying_type))
|
||||
: (struct_def.fixed
|
||||
? lang_.accessor_prefix + "bb_pos + " +
|
||||
NumToString(field.value.offset)
|
||||
: "o + " + lang_.accessor_prefix + "bb_pos");
|
||||
if (IsScalar(field.value.type.base_type) ||
|
||||
(field.value.type.base_type == BASE_TYPE_VECTOR &&
|
||||
IsScalar(field.value.type.VectorType().base_type))) {
|
||||
@@ -952,14 +1135,17 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += GenSetter(underlying_type) + "(" + setter_index + ", ";
|
||||
code += src_cast + setter_parameter + "); }\n";
|
||||
} else {
|
||||
code += "int o = __offset(" + NumToString(field.value.offset) + ");";
|
||||
code += "int o = " + lang_.accessor_prefix + "__offset(";
|
||||
code += NumToString(field.value.offset) + ");";
|
||||
code += " if (o != 0) { " + GenSetter(underlying_type);
|
||||
code += "(" + setter_index + ", " + src_cast + setter_parameter + "); return true; } else { return false; } }\n";
|
||||
code += "(" + setter_index + ", " + src_cast + setter_parameter +
|
||||
"); return true; } else { return false; } }\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
code += "\n";
|
||||
flatbuffers::FieldDef *key_field = nullptr;
|
||||
if (struct_def.fixed) {
|
||||
// create a struct constructor function
|
||||
code += " public static " + GenOffsetType(struct_def) + " ";
|
||||
@@ -969,7 +1155,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += ") {\n";
|
||||
GenStructBody(struct_def, code_ptr, "");
|
||||
code += " return ";
|
||||
code += GenOffsetConstruct(struct_def, "builder." + std::string(lang_.get_fbb_offset));
|
||||
code += GenOffsetConstruct(struct_def,
|
||||
"builder." + std::string(lang_.get_fbb_offset));
|
||||
code += ";\n }\n";
|
||||
} else {
|
||||
// Generate a method that creates a table in one go. This is only possible
|
||||
@@ -1048,6 +1235,7 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
it != struct_def.fields.vec.end(); ++it) {
|
||||
auto &field = **it;
|
||||
if (field.deprecated) continue;
|
||||
if (field.key) key_field = &field;
|
||||
code += " public static void " + FunctionStart('A') + "dd";
|
||||
code += MakeCamel(field.name);
|
||||
code += "(FlatBufferBuilder builder, ";
|
||||
@@ -1059,10 +1247,15 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += NumToString(it - struct_def.fields.vec.begin()) + ", ";
|
||||
code += SourceCastBasic(field.value.type);
|
||||
code += argname;
|
||||
if(!IsScalar(field.value.type.base_type) && field.value.type.base_type != BASE_TYPE_UNION && lang_.language == IDLOptions::kCSharp) {
|
||||
if (!IsScalar(field.value.type.base_type) &&
|
||||
field.value.type.base_type != BASE_TYPE_UNION &&
|
||||
lang_.language == IDLOptions::kCSharp) {
|
||||
code += ".Value";
|
||||
}
|
||||
code += ", " + GenDefaultValue(field.value, false);
|
||||
code += ", ";
|
||||
if (lang_.language == IDLOptions::kJava)
|
||||
code += SourceCastBasic( field.value.type );
|
||||
code += GenDefaultValue(field.value, false);
|
||||
code += "); }\n";
|
||||
if (field.value.type.base_type == BASE_TYPE_VECTOR) {
|
||||
auto vector_type = field.value.type.VectorType();
|
||||
@@ -1070,7 +1263,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
auto elem_size = InlineSize(vector_type);
|
||||
if (!IsStruct(vector_type)) {
|
||||
// Generate a method to create a vector from a Java array.
|
||||
code += " public static " + GenVectorOffsetType() + " " + FunctionStart('C') + "reate";
|
||||
code += " public static " + GenVectorOffsetType() + " ";
|
||||
code += FunctionStart('C') + "reate";
|
||||
code += MakeCamel(field.name);
|
||||
code += "Vector(FlatBufferBuilder builder, ";
|
||||
code += GenTypeBasic(vector_type) + "[] data) ";
|
||||
@@ -1086,7 +1280,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += SourceCastBasic(vector_type, false);
|
||||
code += "data[i]";
|
||||
if (lang_.language == IDLOptions::kCSharp &&
|
||||
(vector_type.base_type == BASE_TYPE_STRUCT || vector_type.base_type == BASE_TYPE_STRING))
|
||||
(vector_type.base_type == BASE_TYPE_STRUCT ||
|
||||
vector_type.base_type == BASE_TYPE_STRING))
|
||||
code += ".Value";
|
||||
code += "); return ";
|
||||
code += "builder." + FunctionStart('E') + "ndVector(); }\n";
|
||||
@@ -1119,7 +1314,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
if (parser_.root_struct_def_ == &struct_def) {
|
||||
code += " public static void ";
|
||||
code += FunctionStart('F') + "inish" + struct_def.name;
|
||||
code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType(struct_def) + " offset) {";
|
||||
code += "Buffer(FlatBufferBuilder builder, " + GenOffsetType(struct_def);
|
||||
code += " offset) {";
|
||||
code += " builder." + FunctionStart('F') + "inish(offset";
|
||||
if (lang_.language == IDLOptions::kCSharp) {
|
||||
code += ".Value";
|
||||
@@ -1130,12 +1326,66 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
||||
code += "); }\n";
|
||||
}
|
||||
}
|
||||
if (struct_def.has_key) {
|
||||
if (lang_.language == IDLOptions::kJava) {
|
||||
code += "\n @Override\n protected int keysCompare(";
|
||||
code += "Integer o1, Integer o2, ByteBuffer _bb) {";
|
||||
code += GenKeyGetter(key_field);
|
||||
code += " }\n";
|
||||
}
|
||||
else {
|
||||
code += "\n public static VectorOffset ";
|
||||
code += "CreateMySortedVectorOfTables(FlatBufferBuilder builder, ";
|
||||
code += "Offset<" + struct_def.name + ">";
|
||||
code += "[] offsets) {\n";
|
||||
code += " Array.Sort(offsets, (Offset<" + struct_def.name +
|
||||
"> o1, Offset<" + struct_def.name + "> o2) => " + GenKeyGetter(key_field);
|
||||
code += ");\n";
|
||||
code += " return builder.CreateVectorOfTables(offsets);\n }\n";
|
||||
}
|
||||
|
||||
code += "\n public static " + struct_def.name + lang_.optional_suffix;
|
||||
code += " " + FunctionStart('L') + "ookupByKey(" + GenVectorOffsetType();
|
||||
code += " vectorOffset, " + GenTypeGet(key_field->value.type);
|
||||
code += " key, ByteBuffer bb) {\n";
|
||||
if (key_field->value.type.base_type == BASE_TYPE_STRING) {
|
||||
code += " byte[] byteKey = ";
|
||||
if (lang_.language == IDLOptions::kJava)
|
||||
code += "key.getBytes(Table.UTF8_CHARSET.get());\n";
|
||||
else
|
||||
code += "System.Text.Encoding.UTF8.GetBytes(key);\n";
|
||||
}
|
||||
code += " int vectorLocation = " + GenByteBufferLength("bb");
|
||||
code += " - vectorOffset";
|
||||
if (lang_.language == IDLOptions::kCSharp) code += ".Value";
|
||||
code += ";\n int span = ";
|
||||
code += "bb." + FunctionStart('G') + "etInt(vectorLocation);\n";
|
||||
code += " int start = 0;\n";
|
||||
code += " vectorLocation += 4;\n";
|
||||
code += " while (span != 0) {\n";
|
||||
code += " int middle = span / 2;\n";
|
||||
code += GenLookupKeyGetter(key_field);
|
||||
code += " if (comp > 0) {\n";
|
||||
code += " span = middle;\n";
|
||||
code += " } else if (comp < 0) {\n";
|
||||
code += " middle++;\n";
|
||||
code += " start += middle;\n";
|
||||
code += " span -= middle;\n";
|
||||
code += " } else {\n";
|
||||
code += " return new " + struct_def.name;
|
||||
code += "().__assign(tableOffset, bb);\n";
|
||||
code += " }\n }\n";
|
||||
code += " return null;\n";
|
||||
code += " }\n";
|
||||
}
|
||||
code += "}";
|
||||
// Java does not need the closing semi-colon on class definitions.
|
||||
code += (lang_.language != IDLOptions::kJava) ? ";" : "";
|
||||
code += "\n\n";
|
||||
}
|
||||
const LanguageParameters & lang_;
|
||||
// This tracks the current namespace used to determine if a type need to be prefixed by its namespace
|
||||
const Namespace *cur_name_space_;
|
||||
};
|
||||
} // namespace general
|
||||
|
||||
@@ -1157,8 +1407,7 @@ std::string GeneralMakeRule(const Parser &parser, const std::string &path,
|
||||
auto &enum_def = **it;
|
||||
if (make_rule != "") make_rule += " ";
|
||||
std::string directory =
|
||||
BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace) +
|
||||
kPathSeparator;
|
||||
BaseGenerator::NamespaceDir(parser, path, *enum_def.defined_namespace);
|
||||
make_rule += directory + enum_def.name + lang.file_extension;
|
||||
}
|
||||
|
||||
@@ -1167,8 +1416,8 @@ std::string GeneralMakeRule(const Parser &parser, const std::string &path,
|
||||
auto &struct_def = **it;
|
||||
if (make_rule != "") make_rule += " ";
|
||||
std::string directory =
|
||||
BaseGenerator::NamespaceDir(parser, path, *struct_def.defined_namespace) +
|
||||
kPathSeparator;
|
||||
BaseGenerator::NamespaceDir(parser, path,
|
||||
*struct_def.defined_namespace);
|
||||
make_rule += directory + struct_def.name + lang.file_extension;
|
||||
}
|
||||
|
||||
|
||||
@@ -144,6 +144,23 @@ static void InitializeExisting(const StructDef &struct_def,
|
||||
code += "}\n\n";
|
||||
}
|
||||
|
||||
// Implement the table accessor
|
||||
static void GenTableAccessor(const StructDef &struct_def,
|
||||
std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
|
||||
GenReceiver(struct_def, code_ptr);
|
||||
code += " Table() flatbuffers.Table ";
|
||||
code += "{\n";
|
||||
|
||||
if (struct_def.fixed) {
|
||||
code += "\treturn rcv._tab.Table\n";
|
||||
} else {
|
||||
code += "\treturn rcv._tab\n";
|
||||
}
|
||||
code += "}\n\n";
|
||||
}
|
||||
|
||||
// Get the length of a vector.
|
||||
static void GetVectorLen(const StructDef &struct_def,
|
||||
const FieldDef &field,
|
||||
@@ -288,9 +305,6 @@ static void GetMemberOfVectorOfStruct(const StructDef &struct_def,
|
||||
if (!(vectortype.struct_def->fixed)) {
|
||||
code += "\t\tx = rcv._tab.Indirect(x)\n";
|
||||
}
|
||||
code += "\t\tif obj == nil {\n";
|
||||
code += "\t\t\tobj = new(" + TypeName(field) + ")\n";
|
||||
code += "\t\t}\n";
|
||||
code += "\t\tobj.Init(rcv._tab.Bytes, x)\n";
|
||||
code += "\t\treturn true\n\t}\n";
|
||||
code += "\treturn false\n";
|
||||
@@ -594,6 +608,10 @@ static void GenStruct(const StructDef &struct_def,
|
||||
// Generate the Init method that sets the field in a pre-existing
|
||||
// accessor object. This is to allow object reuse.
|
||||
InitializeExisting(struct_def, code_ptr);
|
||||
// Generate _tab accessor
|
||||
GenTableAccessor(struct_def, code_ptr);
|
||||
|
||||
// Generate struct fields accessors
|
||||
for (auto it = struct_def.fields.vec.begin();
|
||||
it != struct_def.fields.vec.end();
|
||||
++it) {
|
||||
@@ -604,6 +622,7 @@ static void GenStruct(const StructDef &struct_def,
|
||||
GenStructMutator(struct_def, field, code_ptr);
|
||||
}
|
||||
|
||||
// Generate builders
|
||||
if (struct_def.fixed) {
|
||||
// create a struct constructor function
|
||||
GenStructBuilder(struct_def, code_ptr);
|
||||
|
||||
@@ -19,12 +19,14 @@
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "flatbuffers/idl.h"
|
||||
#include "flatbuffers/util.h"
|
||||
#include "flatbuffers/code_generators.h"
|
||||
|
||||
#include "src/compiler/cpp_generator.h"
|
||||
#include "src/compiler/go_generator.h"
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
class FlatBufMethod : public grpc_cpp_generator::Method {
|
||||
class FlatBufMethod : public grpc_generator::Method {
|
||||
public:
|
||||
enum Streaming { kNone, kClient, kServer, kBiDi };
|
||||
|
||||
@@ -52,6 +54,14 @@ class FlatBufMethod : public grpc_cpp_generator::Method {
|
||||
return GRPCType(*method_->response);
|
||||
}
|
||||
|
||||
std::string input_name() const {
|
||||
return (*method_->request).name;
|
||||
}
|
||||
|
||||
std::string output_name() const {
|
||||
return (*method_->response).name;
|
||||
}
|
||||
|
||||
bool NoStreaming() const { return streaming_ == kNone; }
|
||||
bool ClientOnlyStreaming() const { return streaming_ == kClient; }
|
||||
bool ServerOnlyStreaming() const { return streaming_ == kServer; }
|
||||
@@ -62,7 +72,7 @@ class FlatBufMethod : public grpc_cpp_generator::Method {
|
||||
Streaming streaming_;
|
||||
};
|
||||
|
||||
class FlatBufService : public grpc_cpp_generator::Service {
|
||||
class FlatBufService : public grpc_generator::Service {
|
||||
public:
|
||||
FlatBufService(const ServiceDef *service) : service_(service) {}
|
||||
|
||||
@@ -72,8 +82,8 @@ class FlatBufService : public grpc_cpp_generator::Service {
|
||||
return static_cast<int>(service_->calls.vec.size());
|
||||
};
|
||||
|
||||
std::unique_ptr<const grpc_cpp_generator::Method> method(int i) const {
|
||||
return std::unique_ptr<const grpc_cpp_generator::Method>(
|
||||
std::unique_ptr<const grpc_generator::Method> method(int i) const {
|
||||
return std::unique_ptr<const grpc_generator::Method>(
|
||||
new FlatBufMethod(service_->calls.vec[i]));
|
||||
};
|
||||
|
||||
@@ -81,7 +91,7 @@ class FlatBufService : public grpc_cpp_generator::Service {
|
||||
const ServiceDef *service_;
|
||||
};
|
||||
|
||||
class FlatBufPrinter : public grpc_cpp_generator::Printer {
|
||||
class FlatBufPrinter : public grpc_generator::Printer {
|
||||
public:
|
||||
FlatBufPrinter(std::string *str)
|
||||
: str_(str), escape_char_('$'), indent_(0) {}
|
||||
@@ -133,7 +143,7 @@ class FlatBufPrinter : public grpc_cpp_generator::Printer {
|
||||
int indent_;
|
||||
};
|
||||
|
||||
class FlatBufFile : public grpc_cpp_generator::File {
|
||||
class FlatBufFile : public grpc_generator::File {
|
||||
public:
|
||||
FlatBufFile(const Parser &parser, const std::string &file_name)
|
||||
: parser_(parser), file_name_(file_name) {}
|
||||
@@ -159,17 +169,21 @@ class FlatBufFile : public grpc_cpp_generator::File {
|
||||
return "#include \"flatbuffers/grpc.h\"\n";
|
||||
}
|
||||
|
||||
std::string additional_imports() const {
|
||||
return "import \"github.com/google/flatbuffers/go\"";
|
||||
}
|
||||
|
||||
int service_count() const {
|
||||
return static_cast<int>(parser_.services_.vec.size());
|
||||
};
|
||||
|
||||
std::unique_ptr<const grpc_cpp_generator::Service> service(int i) const {
|
||||
return std::unique_ptr<const grpc_cpp_generator::Service> (
|
||||
std::unique_ptr<const grpc_generator::Service> service(int i) const {
|
||||
return std::unique_ptr<const grpc_generator::Service> (
|
||||
new FlatBufService(parser_.services_.vec[i]));
|
||||
}
|
||||
|
||||
std::unique_ptr<grpc_cpp_generator::Printer> CreatePrinter(std::string *str) const {
|
||||
return std::unique_ptr<grpc_cpp_generator::Printer>(
|
||||
std::unique_ptr<grpc_generator::Printer> CreatePrinter(std::string *str) const {
|
||||
return std::unique_ptr<grpc_generator::Printer>(
|
||||
new FlatBufPrinter(str));
|
||||
}
|
||||
|
||||
@@ -178,7 +192,47 @@ class FlatBufFile : public grpc_cpp_generator::File {
|
||||
const std::string &file_name_;
|
||||
};
|
||||
|
||||
bool GenerateGRPC(const Parser &parser,
|
||||
class GoGRPCGenerator : public flatbuffers::BaseGenerator {
|
||||
public:
|
||||
GoGRPCGenerator(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name)
|
||||
: BaseGenerator(parser, path, file_name, "", "" /*Unused*/),
|
||||
parser_(parser), path_(path), file_name_(file_name) {}
|
||||
|
||||
bool generate() {
|
||||
FlatBufFile file(parser_, file_name_);
|
||||
grpc_go_generator::Parameters p;
|
||||
p.custom_method_io_type = "flatbuffers.Builder";
|
||||
for (int i = 0; i < file.service_count(); i++) {
|
||||
auto service = file.service(i);
|
||||
const Definition *def = parser_.services_.vec[i];
|
||||
p.package_name = LastNamespacePart(*(def->defined_namespace));
|
||||
std::string output = grpc_go_generator::GenerateServiceSource(&file, service.get(), &p);
|
||||
std::string filename = NamespaceDir(*def->defined_namespace) + def->name + "_grpc.go";
|
||||
if (!flatbuffers::SaveFile(filename.c_str(), output, false))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Parser &parser_;
|
||||
const std::string &path_, &file_name_;
|
||||
};
|
||||
|
||||
bool GenerateGoGRPC(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;
|
||||
return GoGRPCGenerator(parser, path, file_name).generate();
|
||||
}
|
||||
|
||||
bool GenerateCppGRPC(const Parser &parser,
|
||||
const std::string &/*path*/,
|
||||
const std::string &file_name) {
|
||||
|
||||
|
||||
@@ -557,13 +557,13 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
"@returns {boolean}");
|
||||
|
||||
code += object_name + ".prototype.mutate_" + field.name + " = function(value) {\n";
|
||||
code += " var offset = this.bb.__offset(this.bb_pos, " + NumToString(field.value.offset) + ")\n\n";
|
||||
code += " var offset = this.bb.__offset(this.bb_pos, " + NumToString(field.value.offset) + ");\n\n";
|
||||
code += " if (offset === 0) {\n";
|
||||
code += " return false;\n";
|
||||
code += " }\n\n";
|
||||
code += " this.bb.write" + MakeCamel(GenType(field.value.type)) + "(this.bb_pos + offset, value);\n";
|
||||
code += " return true;\n";
|
||||
code += "}\n\n";
|
||||
code += "};\n\n";
|
||||
}
|
||||
|
||||
// Emit vector helpers
|
||||
@@ -576,12 +576,12 @@ void GenStruct(const Parser &parser, StructDef &struct_def, std::string *code_pt
|
||||
|
||||
// For scalar types, emit a typed array helper
|
||||
auto vectorType = field.value.type.VectorType();
|
||||
if (IsScalar(vectorType.base_type)) {
|
||||
if (IsScalar(vectorType.base_type) && !IsLong(vectorType.base_type)) {
|
||||
GenDocComment(code_ptr, "@returns {" + GenType(vectorType) + "Array}");
|
||||
code += object_name + ".prototype." + MakeCamel(field.name, false);
|
||||
code += "Array = function() {\n" + offset_prefix;
|
||||
code += "new " + GenType(vectorType) + "Array(this.bb.bytes().buffer, "
|
||||
"this.bb.__vector(this.bb_pos + offset), "
|
||||
"this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), "
|
||||
"this.bb.__vector_len(this.bb_pos + offset)) : null;\n};\n\n";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,10 +89,10 @@ namespace php {
|
||||
code += classcode;
|
||||
|
||||
std::string filename = NamespaceDir(*def.defined_namespace) +
|
||||
kPathSeparator + def.name + ".php";
|
||||
def.name + ".php";
|
||||
return SaveFile(filename.c_str(), code, false);
|
||||
}
|
||||
|
||||
|
||||
// Begin a class declaration.
|
||||
static void BeginClass(const StructDef &struct_def, std::string *code_ptr) {
|
||||
std::string &code = *code_ptr;
|
||||
@@ -955,7 +955,7 @@ namespace php {
|
||||
code += Indent + Indent + "return $builder->offset();\n";
|
||||
code += Indent + "}\n";
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
} // namespace php
|
||||
|
||||
|
||||
@@ -655,7 +655,7 @@ class PythonGenerator : public BaseGenerator {
|
||||
BeginFile(LastNamespacePart(*def.defined_namespace), needs_imports, &code);
|
||||
code += classcode;
|
||||
std::string filename = NamespaceDir(*def.defined_namespace) +
|
||||
kPathSeparator + def.name + ".py";
|
||||
def.name + ".py";
|
||||
return SaveFile(filename.c_str(), code, false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
static void GenStruct(const StructDef &struct_def, const Table *table,
|
||||
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||
int indent, const IDLOptions &opts,
|
||||
std::string *_text);
|
||||
|
||||
@@ -48,7 +48,7 @@ void OutputIdentifier(const std::string &name, const IDLOptions &opts,
|
||||
// Print (and its template specialization below for pointers) generate text
|
||||
// for a single FlatBuffer value into JSON format.
|
||||
// The general case for scalars:
|
||||
template<typename T> void Print(T val, Type type, int /*indent*/,
|
||||
template<typename T> bool Print(T val, Type type, int /*indent*/,
|
||||
StructDef * /*union_sd*/,
|
||||
const IDLOptions &opts,
|
||||
std::string *_text) {
|
||||
@@ -57,7 +57,7 @@ template<typename T> void Print(T val, Type type, int /*indent*/,
|
||||
auto enum_val = type.enum_def->ReverseLookup(static_cast<int>(val));
|
||||
if (enum_val) {
|
||||
OutputIdentifier(enum_val->name, opts, _text);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,10 +66,12 @@ template<typename T> void Print(T val, Type type, int /*indent*/,
|
||||
} else {
|
||||
text += NumToString(val);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Print a vector a sequence of JSON values, comma separated, wrapped in "[]".
|
||||
template<typename T> void PrintVector(const Vector<T> &v, Type type,
|
||||
template<typename T> bool PrintVector(const Vector<T> &v, Type type,
|
||||
int indent, const IDLOptions &opts,
|
||||
std::string *_text) {
|
||||
std::string &text = *_text;
|
||||
@@ -81,19 +83,25 @@ template<typename T> void PrintVector(const Vector<T> &v, Type type,
|
||||
text += NewLine(opts);
|
||||
}
|
||||
text.append(indent + Indent(opts), ' ');
|
||||
if (IsStruct(type))
|
||||
Print(v.GetStructFromOffset(i * type.struct_def->bytesize), type,
|
||||
indent + Indent(opts), nullptr, opts, _text);
|
||||
else
|
||||
Print(v[i], type, indent + Indent(opts), nullptr,
|
||||
opts, _text);
|
||||
if (IsStruct(type)) {
|
||||
if (!Print(v.GetStructFromOffset(i * type.struct_def->bytesize), type,
|
||||
indent + Indent(opts), nullptr, opts, _text)) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!Print(v[i], type, indent + Indent(opts), nullptr,
|
||||
opts, _text)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
text += NewLine(opts);
|
||||
text.append(indent, ' ');
|
||||
text += "]";
|
||||
return true;
|
||||
}
|
||||
|
||||
static void EscapeString(const String &s, std::string *_text, const IDLOptions& opts) {
|
||||
static bool EscapeString(const String &s, std::string *_text, const IDLOptions& opts) {
|
||||
std::string &text = *_text;
|
||||
text += "\"";
|
||||
for (uoffset_t i = 0; i < s.size(); i++) {
|
||||
@@ -118,9 +126,19 @@ static void EscapeString(const String &s, std::string *_text, const IDLOptions&
|
||||
text += "\\x";
|
||||
text += IntToStringHex(static_cast<uint8_t>(c), 2);
|
||||
} else {
|
||||
// We previously checked for non-UTF-8 and returned a parse error,
|
||||
// so we shouldn't reach here.
|
||||
assert(0);
|
||||
// There are two cases here:
|
||||
//
|
||||
// 1) We reached here by parsing an IDL file. In that case,
|
||||
// we previously checked for non-UTF-8, so we shouldn't reach
|
||||
// here.
|
||||
//
|
||||
// 2) We reached here by someone calling GenerateText()
|
||||
// on a previously-serialized flatbuffer. The data might have
|
||||
// non-UTF-8 Strings, or might be corrupt.
|
||||
//
|
||||
// In both cases, we have to give up and inform the caller
|
||||
// they have no JSON.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (ucc <= 0xFFFF) {
|
||||
@@ -130,12 +148,12 @@ static void EscapeString(const String &s, std::string *_text, const IDLOptions&
|
||||
} else if (ucc <= 0x10FFFF) {
|
||||
// Encode Unicode SMP values to a surrogate pair using two \u escapes.
|
||||
uint32_t base = ucc - 0x10000;
|
||||
uint16_t highSurrogate = (base >> 10) + 0xD800;
|
||||
uint16_t lowSurrogate = (base & 0x03FF) + 0xDC00;
|
||||
auto high_surrogate = (base >> 10) + 0xD800;
|
||||
auto low_surrogate = (base & 0x03FF) + 0xDC00;
|
||||
text += "\\u";
|
||||
text += IntToStringHex(highSurrogate, 4);
|
||||
text += IntToStringHex(high_surrogate, 4);
|
||||
text += "\\u";
|
||||
text += IntToStringHex(lowSurrogate, 4);
|
||||
text += IntToStringHex(low_surrogate, 4);
|
||||
}
|
||||
// Skip past characters recognized.
|
||||
i = static_cast<uoffset_t>(utf8 - s.c_str() - 1);
|
||||
@@ -145,10 +163,11 @@ static void EscapeString(const String &s, std::string *_text, const IDLOptions&
|
||||
}
|
||||
}
|
||||
text += "\"";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Specialization of Print above for pointer types.
|
||||
template<> void Print<const void *>(const void *val,
|
||||
template<> bool Print<const void *>(const void *val,
|
||||
Type type, int indent,
|
||||
StructDef *union_sd,
|
||||
const IDLOptions &opts,
|
||||
@@ -158,21 +177,27 @@ template<> void Print<const void *>(const void *val,
|
||||
// If this assert hits, you have an corrupt buffer, a union type field
|
||||
// was not present or was out of range.
|
||||
assert(union_sd);
|
||||
GenStruct(*union_sd,
|
||||
reinterpret_cast<const Table *>(val),
|
||||
indent,
|
||||
opts,
|
||||
_text);
|
||||
if (!GenStruct(*union_sd,
|
||||
reinterpret_cast<const Table *>(val),
|
||||
indent,
|
||||
opts,
|
||||
_text)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case BASE_TYPE_STRUCT:
|
||||
GenStruct(*type.struct_def,
|
||||
reinterpret_cast<const Table *>(val),
|
||||
indent,
|
||||
opts,
|
||||
_text);
|
||||
if (!GenStruct(*type.struct_def,
|
||||
reinterpret_cast<const Table *>(val),
|
||||
indent,
|
||||
opts,
|
||||
_text)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case BASE_TYPE_STRING: {
|
||||
EscapeString(*reinterpret_cast<const String *>(val), _text, opts);
|
||||
if (!EscapeString(*reinterpret_cast<const String *>(val), _text, opts)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case BASE_TYPE_VECTOR:
|
||||
@@ -182,31 +207,35 @@ template<> void Print<const void *>(const void *val,
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
||||
PTYPE) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
PrintVector<CTYPE>( \
|
||||
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
||||
type, indent, opts, _text); break;
|
||||
if (!PrintVector<CTYPE>( \
|
||||
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
||||
type, indent, opts, _text)) { \
|
||||
return false; \
|
||||
} \
|
||||
break;
|
||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
}
|
||||
break;
|
||||
default: assert(0);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Generate text for a scalar field.
|
||||
template<typename T> static void GenField(const FieldDef &fd,
|
||||
template<typename T> static bool GenField(const FieldDef &fd,
|
||||
const Table *table, bool fixed,
|
||||
const IDLOptions &opts,
|
||||
int indent,
|
||||
std::string *_text) {
|
||||
Print(fixed ?
|
||||
return Print(fixed ?
|
||||
reinterpret_cast<const Struct *>(table)->GetField<T>(fd.value.offset) :
|
||||
table->GetField<T>(fd.value.offset, 0), fd.value.type, indent, nullptr,
|
||||
opts, _text);
|
||||
}
|
||||
|
||||
// Generate text for non-scalar field.
|
||||
static void GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||
static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||
int indent, StructDef *union_sd,
|
||||
const IDLOptions &opts, std::string *_text) {
|
||||
const void *val = nullptr;
|
||||
@@ -220,12 +249,12 @@ static void GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||
? table->GetStruct<const void *>(fd.value.offset)
|
||||
: table->GetPointer<const void *>(fd.value.offset);
|
||||
}
|
||||
Print(val, fd.value.type, indent, union_sd, opts, _text);
|
||||
return Print(val, fd.value.type, indent, union_sd, opts, _text);
|
||||
}
|
||||
|
||||
// Generate text for a struct or table, values separated by commas, indented,
|
||||
// and bracketed by "{}"
|
||||
static void GenStruct(const StructDef &struct_def, const Table *table,
|
||||
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||
int indent, const IDLOptions &opts,
|
||||
std::string *_text) {
|
||||
std::string &text = *_text;
|
||||
@@ -253,8 +282,10 @@ static void GenStruct(const StructDef &struct_def, const Table *table,
|
||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
||||
PTYPE) \
|
||||
case BASE_TYPE_ ## ENUM: \
|
||||
GenField<CTYPE>(fd, table, struct_def.fixed, \
|
||||
opts, indent + Indent(opts), _text); \
|
||||
if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
|
||||
opts, indent + Indent(opts), _text)) { \
|
||||
return false; \
|
||||
} \
|
||||
break;
|
||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
@@ -264,8 +295,10 @@ static void GenStruct(const StructDef &struct_def, const Table *table,
|
||||
case BASE_TYPE_ ## ENUM:
|
||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||
#undef FLATBUFFERS_TD
|
||||
GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
||||
union_sd, opts, _text);
|
||||
if (!GenFieldOffset(fd, table, struct_def.fixed, indent + Indent(opts),
|
||||
union_sd, opts, _text)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (fd.value.type.base_type == BASE_TYPE_UTYPE) {
|
||||
@@ -284,20 +317,24 @@ static void GenStruct(const StructDef &struct_def, const Table *table,
|
||||
text += NewLine(opts);
|
||||
text.append(indent, ' ');
|
||||
text += "}";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Generate a text representation of a flatbuffer in JSON format.
|
||||
void GenerateText(const Parser &parser, const void *flatbuffer,
|
||||
bool GenerateText(const Parser &parser, const void *flatbuffer,
|
||||
std::string *_text) {
|
||||
std::string &text = *_text;
|
||||
assert(parser.root_struct_def_); // call SetRootType()
|
||||
text.reserve(1024); // Reduce amount of inevitable reallocs.
|
||||
GenStruct(*parser.root_struct_def_,
|
||||
GetRoot<Table>(flatbuffer),
|
||||
0,
|
||||
parser.opts,
|
||||
_text);
|
||||
if (!GenStruct(*parser.root_struct_def_,
|
||||
GetRoot<Table>(flatbuffer),
|
||||
0,
|
||||
parser.opts,
|
||||
_text)) {
|
||||
return false;
|
||||
}
|
||||
text += NewLine(parser.opts);
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string TextFileName(const std::string &path,
|
||||
@@ -310,7 +347,9 @@ bool GenerateTextFile(const Parser &parser,
|
||||
const std::string &file_name) {
|
||||
if (!parser.builder_.GetSize() || !parser.root_struct_def_) return true;
|
||||
std::string text;
|
||||
GenerateText(parser, parser.builder_.GetBufferPointer(), &text);
|
||||
if (!GenerateText(parser, parser.builder_.GetBufferPointer(), &text)) {
|
||||
return false;
|
||||
}
|
||||
return flatbuffers::SaveFile(TextFileName(path, file_name).c_str(),
|
||||
text,
|
||||
false);
|
||||
|
||||
@@ -219,7 +219,7 @@ CheckedError Parser::ParseHexNum(int nibbles, int64_t *val) {
|
||||
return Error("escape code must be followed by " + NumToString(nibbles) +
|
||||
" hex digits");
|
||||
std::string target(cursor_, cursor_ + nibbles);
|
||||
*val = StringToUInt(target.c_str(), 16);
|
||||
*val = StringToUInt(target.c_str(), nullptr, 16);
|
||||
cursor_ += nibbles;
|
||||
return NoError();
|
||||
}
|
||||
@@ -352,6 +352,7 @@ CheckedError Parser::Next() {
|
||||
cursor_++;
|
||||
// TODO: make nested.
|
||||
while (*cursor_ != '*' || cursor_[1] != '/') {
|
||||
if (*cursor_ == '\n') line_++;
|
||||
if (!*cursor_) return Error("end of file in comment");
|
||||
cursor_++;
|
||||
}
|
||||
@@ -447,7 +448,7 @@ CheckedError Parser::Next() {
|
||||
cursor_++;
|
||||
while (isxdigit(static_cast<unsigned char>(*cursor_))) cursor_++;
|
||||
attribute_.append(start + 2, cursor_);
|
||||
attribute_ = NumToString(StringToUInt(attribute_.c_str(), 16));
|
||||
attribute_ = NumToString(StringToUInt(attribute_.c_str(), nullptr, 16));
|
||||
token_ = kTokenIntegerConstant;
|
||||
return NoError();
|
||||
}
|
||||
@@ -657,6 +658,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
"only int, uint, long and ulong data types support hashing.");
|
||||
}
|
||||
}
|
||||
auto cpp_type = field->attributes.Lookup("cpp_type");
|
||||
if (cpp_type) {
|
||||
if (!hash_name)
|
||||
return Error("cpp_type can only be used with a hashed field");
|
||||
}
|
||||
if (field->deprecated && struct_def.fixed)
|
||||
return Error("can't deprecate fields in a struct");
|
||||
field->required = field->attributes.Lookup("required") != nullptr;
|
||||
@@ -674,6 +680,11 @@ CheckedError Parser::ParseField(StructDef &struct_def) {
|
||||
return Error("'key' field must be string or scalar type");
|
||||
}
|
||||
}
|
||||
|
||||
field->native_inline = field->attributes.Lookup("native_inline") != nullptr;
|
||||
if (field->native_inline && !IsStruct(field->value.type))
|
||||
return Error("native_inline can only be defined on structs'");
|
||||
|
||||
auto nested = field->attributes.Lookup("nested_flatbuffer");
|
||||
if (nested) {
|
||||
if (nested->type.base_type != BASE_TYPE_STRING)
|
||||
@@ -1093,10 +1104,15 @@ CheckedError Parser::ParseSingleValue(Value &e) {
|
||||
NEXT();
|
||||
} else { // Numeric constant in string.
|
||||
if (IsInteger(e.type.base_type)) {
|
||||
// TODO(wvo): do we want to check for garbage after the number?
|
||||
e.constant = NumToString(StringToInt(attribute_.c_str()));
|
||||
char *end;
|
||||
e.constant = NumToString(StringToInt(attribute_.c_str(), &end));
|
||||
if (*end)
|
||||
return Error("invalid integer: " + attribute_);
|
||||
} else if (IsFloat(e.type.base_type)) {
|
||||
e.constant = NumToString(strtod(attribute_.c_str(), nullptr));
|
||||
char *end;
|
||||
e.constant = NumToString(strtod(attribute_.c_str(), &end));
|
||||
if (*end)
|
||||
return Error("invalid float: " + attribute_);
|
||||
} else {
|
||||
assert(0); // Shouldn't happen, we covered all types.
|
||||
e.constant = "0";
|
||||
@@ -1341,10 +1357,11 @@ CheckedError Parser::ParseDecl() {
|
||||
auto align = static_cast<size_t>(atoi(force_align->constant.c_str()));
|
||||
if (force_align->type.base_type != BASE_TYPE_INT ||
|
||||
align < struct_def->minalign ||
|
||||
align > 16 ||
|
||||
align > FLATBUFFERS_MAX_ALIGNMENT ||
|
||||
align & (align - 1))
|
||||
return Error("force_align must be a power of two integer ranging from the"
|
||||
"struct\'s natural alignment to 16");
|
||||
"struct\'s natural alignment to " +
|
||||
NumToString(FLATBUFFERS_MAX_ALIGNMENT));
|
||||
struct_def->minalign = align;
|
||||
}
|
||||
struct_def->PadLastField(struct_def->minalign);
|
||||
@@ -1819,6 +1836,7 @@ CheckedError Parser::DoParse(const char *source, const char **include_paths,
|
||||
source_ = cursor_ = source;
|
||||
line_ = 1;
|
||||
error_.clear();
|
||||
field_stack_.clear();
|
||||
builder_.Clear();
|
||||
// Start with a blank namespace just in case this file doesn't have one.
|
||||
namespaces_.push_back(new Namespace());
|
||||
@@ -1977,7 +1995,8 @@ std::set<std::string> Parser::GetIncludedFilesRecursive(
|
||||
// Schema serialization functionality:
|
||||
|
||||
template<typename T> bool compareName(const T* a, const T* b) {
|
||||
return a->name < b->name;
|
||||
return a->defined_namespace->GetFullyQualifiedName(a->name)
|
||||
< b->defined_namespace->GetFullyQualifiedName(b->name);
|
||||
}
|
||||
|
||||
template<typename T> void AssignIndices(const std::vector<T *> &defvec) {
|
||||
@@ -2023,8 +2042,9 @@ Offset<reflection::Object> StructDef::Serialize(FlatBufferBuilder *builder,
|
||||
(*it)->Serialize(builder,
|
||||
static_cast<uint16_t>(it - fields.vec.begin()), parser));
|
||||
}
|
||||
auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
|
||||
return reflection::CreateObject(*builder,
|
||||
builder->CreateString(name),
|
||||
builder->CreateString(qualified_name),
|
||||
builder->CreateVectorOfSortedTables(
|
||||
&field_offsets),
|
||||
fixed,
|
||||
@@ -2061,8 +2081,9 @@ Offset<reflection::Enum> EnumDef::Serialize(FlatBufferBuilder *builder,
|
||||
for (auto it = vals.vec.begin(); it != vals.vec.end(); ++it) {
|
||||
enumval_offsets.push_back((*it)->Serialize(builder));
|
||||
}
|
||||
auto qualified_name = defined_namespace->GetFullyQualifiedName(name);
|
||||
return reflection::CreateEnum(*builder,
|
||||
builder->CreateString(name),
|
||||
builder->CreateString(qualified_name),
|
||||
builder->CreateVector(enumval_offsets),
|
||||
is_union,
|
||||
underlying_type.Serialize(builder),
|
||||
|
||||
@@ -180,7 +180,8 @@ class ResizeContext {
|
||||
// Check if the range between first (lower address) and second straddles
|
||||
// the insertion point. If it does, change the offset at offsetloc (of
|
||||
// type T, with direction D).
|
||||
template<typename T, int D> void Straddle(void *first, void *second,
|
||||
template<typename T, int D> void Straddle(const void *first,
|
||||
const void *second,
|
||||
void *offsetloc) {
|
||||
if (first <= startptr_ && second >= startptr_) {
|
||||
WriteScalar<T>(offsetloc, ReadScalar<T>(offsetloc) + delta_ * D);
|
||||
@@ -194,9 +195,9 @@ class ResizeContext {
|
||||
// resize actually happens.
|
||||
// This must be checked for every offset, since we can't know which offsets
|
||||
// will straddle and which won't.
|
||||
uint8_t &DagCheck(void *offsetloc) {
|
||||
auto dag_idx = reinterpret_cast<uoffset_t *>(offsetloc) -
|
||||
reinterpret_cast<uoffset_t *>(buf_.data());
|
||||
uint8_t &DagCheck(const void *offsetloc) {
|
||||
auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) -
|
||||
reinterpret_cast<const uoffset_t *>(buf_.data());
|
||||
return dag_check_[dag_idx];
|
||||
}
|
||||
|
||||
@@ -480,4 +481,230 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
||||
}
|
||||
}
|
||||
|
||||
bool VerifyStruct(flatbuffers::Verifier &v,
|
||||
const flatbuffers::Table &parent_table,
|
||||
voffset_t field_offset,
|
||||
const reflection::Object &obj,
|
||||
bool required) {
|
||||
auto offset = parent_table.GetOptionalFieldOffset(field_offset);
|
||||
if (required && !offset) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !offset || v.Verify(reinterpret_cast<const uint8_t*>(&parent_table)
|
||||
+ offset, obj.bytesize());
|
||||
}
|
||||
|
||||
bool VerifyVectorOfStructs(flatbuffers::Verifier &v,
|
||||
const flatbuffers::Table &parent_table,
|
||||
voffset_t field_offset,
|
||||
const reflection::Object &obj,
|
||||
bool required) {
|
||||
auto p = parent_table.GetPointer<const uint8_t*>(field_offset);
|
||||
const uint8_t* end;
|
||||
if (required && !p) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !p || v.VerifyVector(p, obj.bytesize(), &end);
|
||||
}
|
||||
|
||||
// forward declare to resolve cyclic deps between VerifyObject and VerifyVector
|
||||
bool VerifyObject(flatbuffers::Verifier &v,
|
||||
const reflection::Schema &schema,
|
||||
const reflection::Object &obj,
|
||||
const flatbuffers::Table *table,
|
||||
bool isRequired);
|
||||
|
||||
bool VerifyVector(flatbuffers::Verifier &v,
|
||||
const reflection::Schema &schema,
|
||||
const flatbuffers::Table &table,
|
||||
const reflection::Field &vec_field) {
|
||||
assert(vec_field.type()->base_type() == reflection::Vector);
|
||||
if (!table.VerifyField<uoffset_t>(v, vec_field.offset()))
|
||||
return false;
|
||||
|
||||
switch (vec_field.type()->element()) {
|
||||
case reflection::None:
|
||||
assert(false);
|
||||
break;
|
||||
case reflection::UType:
|
||||
return v.Verify(flatbuffers::GetFieldV<uint8_t>(table, vec_field));
|
||||
case reflection::Bool:
|
||||
case reflection::Byte:
|
||||
case reflection::UByte:
|
||||
return v.Verify(flatbuffers::GetFieldV<int8_t>(table, vec_field));
|
||||
case reflection::Short:
|
||||
case reflection::UShort:
|
||||
return v.Verify(flatbuffers::GetFieldV<int16_t>(table, vec_field));
|
||||
case reflection::Int:
|
||||
case reflection::UInt:
|
||||
return v.Verify(flatbuffers::GetFieldV<int32_t>(table, vec_field));
|
||||
case reflection::Long:
|
||||
case reflection::ULong:
|
||||
return v.Verify(flatbuffers::GetFieldV<int64_t>(table, vec_field));
|
||||
case reflection::Float:
|
||||
return v.Verify(flatbuffers::GetFieldV<float>(table, vec_field));
|
||||
case reflection::Double:
|
||||
return v.Verify(flatbuffers::GetFieldV<double>(table, vec_field));
|
||||
case reflection::String: {
|
||||
auto vecString =
|
||||
flatbuffers::GetFieldV<flatbuffers::
|
||||
Offset<flatbuffers::String>>(table, vec_field);
|
||||
if (v.Verify(vecString) && v.VerifyVectorOfStrings(vecString)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
case reflection::Vector:
|
||||
assert(false);
|
||||
break;
|
||||
case reflection::Obj: {
|
||||
auto obj = schema.objects()->Get(vec_field.type()->index());
|
||||
if (obj->is_struct()) {
|
||||
if (!VerifyVectorOfStructs(v, table, vec_field.offset(), *obj,
|
||||
vec_field.required())) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
auto vec =
|
||||
flatbuffers::GetFieldV<flatbuffers::
|
||||
Offset<flatbuffers::Table>>(table, vec_field);
|
||||
if (!v.Verify(vec))
|
||||
return false;
|
||||
if (vec) {
|
||||
for (uoffset_t j = 0; j < vec->size(); j++) {
|
||||
if (!VerifyObject(v, schema, *obj, vec->Get(j), true)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
case reflection::Union:
|
||||
assert(false);
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyObject(flatbuffers::Verifier &v,
|
||||
const reflection::Schema &schema,
|
||||
const reflection::Object &obj,
|
||||
const flatbuffers::Table *table,
|
||||
bool required) {
|
||||
if (!table) {
|
||||
if (!required)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!table->VerifyTableStart(v))
|
||||
return false;
|
||||
|
||||
for (uoffset_t i = 0; i < obj.fields()->size(); i++) {
|
||||
auto field_def = obj.fields()->Get(i);
|
||||
switch (field_def->type()->base_type()) {
|
||||
case reflection::None:
|
||||
assert(false);
|
||||
break;
|
||||
case reflection::UType:
|
||||
if (!table->VerifyField<uint8_t>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Bool:
|
||||
case reflection::Byte:
|
||||
case reflection::UByte:
|
||||
if (!table->VerifyField<int8_t>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Short:
|
||||
case reflection::UShort:
|
||||
if (!table->VerifyField<int16_t>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Int:
|
||||
case reflection::UInt:
|
||||
if (!table->VerifyField<int32_t>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Long:
|
||||
case reflection::ULong:
|
||||
if (!table->VerifyField<int64_t>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Float:
|
||||
if (!table->VerifyField<float>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Double:
|
||||
if (!table->VerifyField<double>(v, field_def->offset()))
|
||||
return false;
|
||||
break;
|
||||
case reflection::String:
|
||||
if (!table->VerifyField<uoffset_t>(v, field_def->offset()) ||
|
||||
!v.Verify(flatbuffers::GetFieldS(*table, *field_def))) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case reflection::Vector:
|
||||
if (!VerifyVector(v, schema, *table, *field_def))
|
||||
return false;
|
||||
break;
|
||||
case reflection::Obj: {
|
||||
auto child_obj = schema.objects()->Get(field_def->type()->index());
|
||||
if (child_obj->is_struct()) {
|
||||
if (!VerifyStruct(v, *table, field_def->offset(), *child_obj,
|
||||
field_def->required())) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (!VerifyObject(v, schema, *child_obj,
|
||||
flatbuffers::GetFieldT(*table, *field_def),
|
||||
field_def->required())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case reflection::Union: {
|
||||
// get union type from the prev field
|
||||
voffset_t utype_offset = field_def->offset() - sizeof(voffset_t);
|
||||
auto utype = table->GetField<uint8_t>(utype_offset, 0);
|
||||
if (utype != 0) {
|
||||
// Means we have this union field present
|
||||
auto fb_enum = schema.enums()->Get(field_def->type()->index());
|
||||
auto child_obj = fb_enum->values()->Get(utype)->object();
|
||||
if (!VerifyObject(v, schema, *child_obj,
|
||||
flatbuffers::GetFieldT(*table, *field_def),
|
||||
field_def->required())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Verify(const reflection::Schema &schema,
|
||||
const reflection::Object &root,
|
||||
const uint8_t *buf,
|
||||
size_t length) {
|
||||
Verifier v(buf, length);
|
||||
return VerifyObject(v, schema, root, flatbuffers::GetAnyRoot(buf), true);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual((byte)99, buffer[0]);
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutByteCannotPutAtOffsetPastLength()
|
||||
{
|
||||
@@ -47,6 +48,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutByte(1, 99));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutShortPopulatesBufferCorrectly()
|
||||
@@ -60,6 +62,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual((byte)0, buffer[1]);
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutShortCannotPutAtOffsetPastLength()
|
||||
{
|
||||
@@ -67,7 +70,9 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(2, 99));
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutShortChecksLength()
|
||||
{
|
||||
@@ -83,6 +88,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutShort(1, 99));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutIntPopulatesBufferCorrectly()
|
||||
@@ -98,6 +104,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(0x0A, buffer[3]);
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutIntCannotPutAtOffsetPastLength()
|
||||
{
|
||||
@@ -121,6 +128,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutInt(2, 0x0A0B0C0D));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutLongPopulatesBufferCorrectly()
|
||||
@@ -140,6 +148,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(0x01, buffer[7]);
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_PutLongCannotPutAtOffsetPastLength()
|
||||
{
|
||||
@@ -163,6 +172,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.PutLong(2, 0x010203040A0B0C0D));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetByteReturnsCorrectData()
|
||||
@@ -173,6 +183,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual((byte)99, uut.Get(0));
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetByteChecksOffset()
|
||||
{
|
||||
@@ -180,6 +191,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(()=>uut.Get(1));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetShortReturnsCorrectData()
|
||||
@@ -191,6 +203,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(1, uut.GetShort(0));
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetShortChecksOffset()
|
||||
{
|
||||
@@ -206,6 +219,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetShort(1));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetIntReturnsCorrectData()
|
||||
@@ -219,6 +233,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(0x0A0B0C0D, uut.GetInt(0));
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetIntChecksOffset()
|
||||
{
|
||||
@@ -234,6 +249,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetInt(0));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetLongReturnsCorrectData()
|
||||
@@ -251,6 +267,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(0x010203040A0B0C0D, uut.GetLong(0));
|
||||
}
|
||||
|
||||
#if !BYTEBUFFER_NO_BOUNDS_CHECK
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_GetLongChecksOffset()
|
||||
{
|
||||
@@ -266,6 +283,7 @@ namespace FlatBuffers.Test
|
||||
var uut = new ByteBuffer(buffer);
|
||||
Assert.Throws<ArgumentOutOfRangeException>(() => uut.GetLong(0));
|
||||
}
|
||||
#endif
|
||||
|
||||
[FlatBuffersTestMethod]
|
||||
public void ByteBuffer_ReverseBytesUshort()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -41,6 +41,9 @@
|
||||
<Compile Include="..\..\net\FlatBuffers\ByteBuffer.cs">
|
||||
<Link>FlatBuffers\ByteBuffer.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\net\FlatBuffers\IFlatbufferObject.cs">
|
||||
<Link>FlatBuffers\IFlatbufferObject.cs</Link>
|
||||
</Compile>
|
||||
<Compile Include="..\..\net\FlatBuffers\Offset.cs">
|
||||
<Link>FlatBuffers\Offset.cs</Link>
|
||||
</Compile>
|
||||
@@ -116,4 +119,4 @@
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -39,6 +39,19 @@ namespace FlatBuffers.Test
|
||||
// better for performance.
|
||||
var fbb = new FlatBufferBuilder(1);
|
||||
|
||||
StringOffset[] names = { fbb.CreateString("Frodo"), fbb.CreateString("Barney"), fbb.CreateString("Wilma") };
|
||||
Offset<Monster>[] off = new Offset<Monster>[3];
|
||||
Monster.StartMonster(fbb);
|
||||
Monster.AddName(fbb, names[0]);
|
||||
off[0] = Monster.EndMonster(fbb);
|
||||
Monster.StartMonster(fbb);
|
||||
Monster.AddName(fbb, names[1]);
|
||||
off[1] = Monster.EndMonster(fbb);
|
||||
Monster.StartMonster(fbb);
|
||||
Monster.AddName(fbb, names[2]);
|
||||
off[2] = Monster.EndMonster(fbb);
|
||||
var sortMons = Monster.CreateMySortedVectorOfTables(fbb, off);
|
||||
|
||||
// We set up the same values as monsterdata.json:
|
||||
|
||||
var str = fbb.CreateString("MyMonster");
|
||||
@@ -79,6 +92,7 @@ namespace FlatBuffers.Test
|
||||
Monster.AddTest4(fbb, test4);
|
||||
Monster.AddTestarrayofstring(fbb, testArrayOfString);
|
||||
Monster.AddTestbool(fbb, false);
|
||||
Monster.AddTestarrayoftables(fbb, sortMons);
|
||||
var mon = Monster.EndMonster(fbb);
|
||||
|
||||
Monster.FinishMonsterBuffer(fbb, mon);
|
||||
@@ -103,6 +117,16 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(monster.MutateMana((short)10), false);
|
||||
Assert.AreEqual(monster.Mana, (short)150);
|
||||
|
||||
// Accessing a vector of sorted by the key tables
|
||||
Assert.AreEqual(monster.Testarrayoftables(0).Value.Name, "Barney");
|
||||
Assert.AreEqual(monster.Testarrayoftables(1).Value.Name, "Frodo");
|
||||
Assert.AreEqual(monster.Testarrayoftables(2).Value.Name, "Wilma");
|
||||
|
||||
// Example of searching for a table by the key
|
||||
Assert.IsTrue(Monster.LookupByKey(sortMons, "Frodo", fbb.DataBuffer) != null);
|
||||
Assert.IsTrue(Monster.LookupByKey(sortMons, "Barney", fbb.DataBuffer) != null);
|
||||
Assert.IsTrue(Monster.LookupByKey(sortMons, "Wilma", fbb.DataBuffer)!= null);
|
||||
|
||||
// testType is an existing field and mutating it should succeed
|
||||
Assert.AreEqual(monster.TestType, Any.Monster);
|
||||
Assert.AreEqual(monster.MutateTestType(Any.NONE), true);
|
||||
@@ -119,7 +143,7 @@ namespace FlatBuffers.Test
|
||||
|
||||
for (int i = 0; i < monster.InventoryLength; i++)
|
||||
{
|
||||
Assert.AreEqual(monster.GetInventory(i), i + 1);
|
||||
Assert.AreEqual(monster.Inventory(i), i + 1);
|
||||
}
|
||||
|
||||
//reverse mutation
|
||||
@@ -130,7 +154,7 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(monster.MutateInventory(4, 4), true);
|
||||
|
||||
// get a struct field and edit one of its fields
|
||||
Vec3 pos = monster.Pos;
|
||||
Vec3 pos = (Vec3)monster.Pos;
|
||||
Assert.AreEqual(pos.X, 1.0f);
|
||||
pos.MutateX(55.0f);
|
||||
Assert.AreEqual(pos.X, 55.0f);
|
||||
@@ -148,21 +172,20 @@ namespace FlatBuffers.Test
|
||||
Assert.AreEqual(150, monster.Mana);
|
||||
Assert.AreEqual("MyMonster", monster.Name);
|
||||
|
||||
var pos = monster.Pos;
|
||||
var pos = monster.Pos.Value;
|
||||
Assert.AreEqual(1.0f, pos.X);
|
||||
Assert.AreEqual(2.0f, pos.Y);
|
||||
Assert.AreEqual(3.0f, pos.Z);
|
||||
|
||||
Assert.AreEqual(3.0f, pos.Test1);
|
||||
Assert.AreEqual(Color.Green, pos.Test2);
|
||||
var t = pos.Test3;
|
||||
var t = (MyGame.Example.Test)pos.Test3;
|
||||
Assert.AreEqual((short)5, t.A);
|
||||
Assert.AreEqual((sbyte)6, t.B);
|
||||
|
||||
Assert.AreEqual(Any.Monster, monster.TestType);
|
||||
|
||||
var monster2 = new Monster();
|
||||
Assert.IsTrue(monster.GetTest(monster2) != null);
|
||||
var monster2 = monster.Test<Monster>().Value;
|
||||
Assert.AreEqual("Fred", monster2.Name);
|
||||
|
||||
|
||||
@@ -170,19 +193,19 @@ namespace FlatBuffers.Test
|
||||
var invsum = 0;
|
||||
for (var i = 0; i < monster.InventoryLength; i++)
|
||||
{
|
||||
invsum += monster.GetInventory(i);
|
||||
invsum += monster.Inventory(i);
|
||||
}
|
||||
Assert.AreEqual(10, invsum);
|
||||
|
||||
var test0 = monster.GetTest4(0);
|
||||
var test1 = monster.GetTest4(1);
|
||||
var test0 = monster.Test4(0).Value;
|
||||
var test1 = monster.Test4(1).Value;
|
||||
Assert.AreEqual(2, monster.Test4Length);
|
||||
|
||||
Assert.AreEqual(100, test0.A + test0.B + test1.A + test1.B);
|
||||
|
||||
Assert.AreEqual(2, monster.TestarrayofstringLength);
|
||||
Assert.AreEqual("test1", monster.GetTestarrayofstring(0));
|
||||
Assert.AreEqual("test2", monster.GetTestarrayofstring(1));
|
||||
Assert.AreEqual("test1", monster.Testarrayofstring(0));
|
||||
Assert.AreEqual("test2", monster.Testarrayofstring(1));
|
||||
|
||||
Assert.AreEqual(false, monster.Testbool);
|
||||
|
||||
@@ -245,10 +268,10 @@ namespace FlatBuffers.Test
|
||||
Monster.AddTestnestedflatbuffer(fbb2, nestedBuffer);
|
||||
var monster = Monster.EndMonster(fbb2);
|
||||
Monster.FinishMonsterBuffer(fbb2, monster);
|
||||
|
||||
|
||||
// Now test the data extracted from the nested buffer
|
||||
var mons = Monster.GetRootAsMonster(fbb2.DataBuffer);
|
||||
var nestedMonster = mons.TestnestedflatbufferAsMonster();
|
||||
var nestedMonster = mons.GetTestnestedflatbufferAsMonster().Value;
|
||||
|
||||
Assert.AreEqual(nestedMonsterMana, nestedMonster.Mana);
|
||||
Assert.AreEqual(nestedMonsterHp, nestedMonster.Hp);
|
||||
|
||||
@@ -19,133 +19,135 @@ namespace FlatBuffers.Test
|
||||
/// <summary>
|
||||
/// A test Table object that gives easy access to the slot data
|
||||
/// </summary>
|
||||
internal class TestTable : Table
|
||||
internal struct TestTable
|
||||
{
|
||||
Table t;
|
||||
|
||||
public TestTable(ByteBuffer bb, int pos)
|
||||
{
|
||||
base.bb = bb;
|
||||
base.bb_pos = pos;
|
||||
t.bb = bb;
|
||||
t.bb_pos = pos;
|
||||
}
|
||||
|
||||
public bool GetSlot(int slot, bool def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetSbyte(bb_pos + off) != 0;
|
||||
return t.bb.GetSbyte(t.bb_pos + off) != 0;
|
||||
}
|
||||
|
||||
public sbyte GetSlot(int slot, sbyte def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetSbyte(bb_pos + off);
|
||||
return t.bb.GetSbyte(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public byte GetSlot(int slot, byte def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.Get(bb_pos + off);
|
||||
return t.bb.Get(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public short GetSlot(int slot, short def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetShort(bb_pos + off);
|
||||
return t.bb.GetShort(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public ushort GetSlot(int slot, ushort def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetUshort(bb_pos + off);
|
||||
return t.bb.GetUshort(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public int GetSlot(int slot, int def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetInt(bb_pos + off);
|
||||
return t.bb.GetInt(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public uint GetSlot(int slot, uint def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetUint(bb_pos + off);
|
||||
return t.bb.GetUint(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public long GetSlot(int slot, long def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetLong(bb_pos + off);
|
||||
return t.bb.GetLong(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public ulong GetSlot(int slot, ulong def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetUlong(bb_pos + off);
|
||||
return t.bb.GetUlong(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public float GetSlot(int slot, float def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetFloat(bb_pos + off);
|
||||
return t.bb.GetFloat(t.bb_pos + off);
|
||||
}
|
||||
|
||||
public double GetSlot(int slot, double def)
|
||||
{
|
||||
var off = base.__offset(slot);
|
||||
var off = t.__offset(slot);
|
||||
|
||||
if (off == 0)
|
||||
{
|
||||
return def;
|
||||
}
|
||||
return bb.GetDouble(bb_pos + off);
|
||||
return t.bb.GetDouble(t.bb_pos + off);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,19 @@ class JavaTest {
|
||||
// better for performance.
|
||||
FlatBufferBuilder fbb = new FlatBufferBuilder(1);
|
||||
|
||||
int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
|
||||
int[] off = new int[3];
|
||||
Monster.startMonster(fbb);
|
||||
Monster.addName(fbb, names[0]);
|
||||
off[0] = Monster.endMonster(fbb);
|
||||
Monster.startMonster(fbb);
|
||||
Monster.addName(fbb, names[1]);
|
||||
off[1] = Monster.endMonster(fbb);
|
||||
Monster.startMonster(fbb);
|
||||
Monster.addName(fbb, names[2]);
|
||||
off[2] = Monster.endMonster(fbb);
|
||||
int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);
|
||||
|
||||
// We set up the same values as monsterdata.json:
|
||||
|
||||
int str = fbb.createString("MyMonster");
|
||||
@@ -84,6 +97,7 @@ class JavaTest {
|
||||
Monster.addTestarrayofstring(fbb, testArrayOfString);
|
||||
Monster.addTestbool(fbb, false);
|
||||
Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
|
||||
Monster.addTestarrayoftables(fbb, sortMons);
|
||||
int mon = Monster.endMonster(fbb);
|
||||
|
||||
Monster.finishMonsterBuffer(fbb, mon);
|
||||
@@ -121,6 +135,16 @@ class JavaTest {
|
||||
// the mana field should retain its default value
|
||||
TestEq(monster.mutateMana((short)10), false);
|
||||
TestEq(monster.mana(), (short)150);
|
||||
|
||||
// Accessing a vector of sorted by the key tables
|
||||
TestEq(monster.testarrayoftables(0).name(), "Barney");
|
||||
TestEq(monster.testarrayoftables(1).name(), "Frodo");
|
||||
TestEq(monster.testarrayoftables(2).name(), "Wilma");
|
||||
|
||||
// Example of searching for a table by the key
|
||||
TestEq(Monster.lookupByKey(sortMons, "Frodo", fbb.dataBuffer()).name(), "Frodo");
|
||||
TestEq(Monster.lookupByKey(sortMons, "Barney", fbb.dataBuffer()).name(), "Barney");
|
||||
TestEq(Monster.lookupByKey(sortMons, "Wilma", fbb.dataBuffer()).name(), "Wilma");
|
||||
|
||||
// testType is an existing field and mutating it should succeed
|
||||
TestEq(monster.testType(), (byte)Any.Monster);
|
||||
@@ -161,6 +185,10 @@ class JavaTest {
|
||||
|
||||
TestNestedFlatBuffer();
|
||||
|
||||
TestCreateByteVector();
|
||||
|
||||
TestCreateUninitializedVector();
|
||||
|
||||
System.out.println("FlatBuffers test: completed successfully");
|
||||
}
|
||||
|
||||
@@ -281,6 +309,44 @@ class JavaTest {
|
||||
TestEq(nestedMonsterName, nestedMonster.name());
|
||||
}
|
||||
|
||||
static void TestCreateByteVector() {
|
||||
FlatBufferBuilder fbb = new FlatBufferBuilder(16);
|
||||
int str = fbb.createString("MyMonster");
|
||||
byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
|
||||
int vec = fbb.createByteVector(inventory);
|
||||
Monster.startMonster(fbb);
|
||||
Monster.addInventory(fbb, vec);
|
||||
Monster.addName(fbb, str);
|
||||
int monster1 = Monster.endMonster(fbb);
|
||||
Monster.finishMonsterBuffer(fbb, monster1);
|
||||
Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
|
||||
|
||||
TestEq(monsterObject.inventory(1), (int)inventory[1]);
|
||||
TestEq(monsterObject.inventoryLength(), inventory.length);
|
||||
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
|
||||
}
|
||||
|
||||
static void TestCreateUninitializedVector() {
|
||||
FlatBufferBuilder fbb = new FlatBufferBuilder(16);
|
||||
int str = fbb.createString("MyMonster");
|
||||
byte[] inventory = new byte[] { 0, 1, 2, 3, 4 };
|
||||
ByteBuffer bb = fbb.createUnintializedVector(1, inventory.length, 1);
|
||||
for (byte i:inventory) {
|
||||
bb.put(i);
|
||||
}
|
||||
int vec = fbb.endVector();
|
||||
Monster.startMonster(fbb);
|
||||
Monster.addInventory(fbb, vec);
|
||||
Monster.addName(fbb, str);
|
||||
int monster1 = Monster.endMonster(fbb);
|
||||
Monster.finishMonsterBuffer(fbb, monster1);
|
||||
Monster monsterObject = Monster.getRootAsMonster(fbb.dataBuffer());
|
||||
|
||||
TestEq(monsterObject.inventory(1), (int)inventory[1]);
|
||||
TestEq(monsterObject.inventoryLength(), inventory.length);
|
||||
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
|
||||
}
|
||||
|
||||
static <T> void TestEq(T a, T b) {
|
||||
if (!a.equals(b)) {
|
||||
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2014 Google Inc. All rights reserved.
|
||||
#
|
||||
@@ -16,14 +16,29 @@
|
||||
|
||||
echo Compile then run the Java test.
|
||||
|
||||
java -version
|
||||
|
||||
testdir=$(readlink -fn `dirname $0`)
|
||||
thisdir=$(readlink -fn `pwd`)
|
||||
|
||||
targetdir=${testdir}/target
|
||||
|
||||
if [[ "$testdir" != "$thisdir" ]]; then
|
||||
echo error: must be run from inside the ${testdir} directory
|
||||
echo you ran it from ${thisdir}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
javac -classpath ${testdir}/../java:${testdir}:${testdir}/namespace_test JavaTest.java
|
||||
java -classpath ${testdir}/../java:${testdir}:${testdir}/namespace_test JavaTest
|
||||
find .. -type f -name "*.class" -exec rm {} \;
|
||||
|
||||
if [[ -e "${targetdir}" ]]; then
|
||||
echo "clean target"
|
||||
rm -rf ${targetdir}
|
||||
fi
|
||||
|
||||
mkdir ${targetdir}
|
||||
|
||||
javac -d ${targetdir} -classpath ${testdir}/../java:${testdir}:${testdir}/namespace_test JavaTest.java
|
||||
java -classpath ${targetdir} JavaTest
|
||||
|
||||
rm -rf ${targetdir}
|
||||
|
||||
@@ -7,79 +7,77 @@ using System;
|
||||
using FlatBuffers;
|
||||
|
||||
/// an example documentation comment: monster object
|
||||
public sealed class Monster : Table {
|
||||
public struct Monster : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
|
||||
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
|
||||
public Monster __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public static bool MonsterBufferHasIdentifier(ByteBuffer _bb) { return Table.__has_identifier(_bb, "MONS"); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public Vec3 Pos { get { return GetPos(new Vec3()); } }
|
||||
public Vec3 GetPos(Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
||||
public short Mana { get { int o = __offset(6); return o != 0 ? bb.GetShort(o + bb_pos) : (short)150; } }
|
||||
public bool MutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.PutShort(o + bb_pos, mana); return true; } else { return false; } }
|
||||
public short Hp { get { int o = __offset(8); return o != 0 ? bb.GetShort(o + bb_pos) : (short)100; } }
|
||||
public bool MutateHp(short hp) { int o = __offset(8); if (o != 0) { bb.PutShort(o + bb_pos, hp); return true; } else { return false; } }
|
||||
public string Name { get { int o = __offset(10); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public ArraySegment<byte>? GetNameBytes() { return __vector_as_arraysegment(10); }
|
||||
public byte GetInventory(int j) { int o = __offset(14); return o != 0 ? bb.Get(__vector(o) + j * 1) : (byte)0; }
|
||||
public int InventoryLength { get { int o = __offset(14); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetInventoryBytes() { return __vector_as_arraysegment(14); }
|
||||
public bool MutateInventory(int j, byte inventory) { int o = __offset(14); if (o != 0) { bb.Put(__vector(o) + j * 1, inventory); return true; } else { return false; } }
|
||||
public Color Color { get { int o = __offset(16); return o != 0 ? (Color)bb.GetSbyte(o + bb_pos) : Color.Blue; } }
|
||||
public bool MutateColor(Color color) { int o = __offset(16); if (o != 0) { bb.PutSbyte(o + bb_pos, (sbyte)color); return true; } else { return false; } }
|
||||
public Any TestType { get { int o = __offset(18); return o != 0 ? (Any)bb.Get(o + bb_pos) : Any.NONE; } }
|
||||
public bool MutateTestType(Any test_type) { int o = __offset(18); if (o != 0) { bb.Put(o + bb_pos, (byte)test_type); return true; } else { return false; } }
|
||||
public TTable GetTest<TTable>(TTable obj) where TTable : Table { int o = __offset(20); return o != 0 ? __union(obj, o) : null; }
|
||||
public Test GetTest4(int j) { return GetTest4(new Test(), j); }
|
||||
public Test GetTest4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__init(__vector(o) + j * 4, bb) : null; }
|
||||
public int Test4Length { get { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public string GetTestarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
|
||||
public int TestarrayofstringLength { get { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public Vec3? Pos { get { int o = __p.__offset(4); return o != 0 ? (Vec3?)(new Vec3()).__assign(o + __p.bb_pos, __p.bb) : null; } }
|
||||
public short Mana { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)150; } }
|
||||
public bool MutateMana(short mana) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, mana); return true; } else { return false; } }
|
||||
public short Hp { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetShort(o + __p.bb_pos) : (short)100; } }
|
||||
public bool MutateHp(short hp) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutShort(o + __p.bb_pos, hp); return true; } else { return false; } }
|
||||
public string Name { get { int o = __p.__offset(10); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
|
||||
public ArraySegment<byte>? GetNameBytes() { return __p.__vector_as_arraysegment(10); }
|
||||
public byte Inventory(int j) { int o = __p.__offset(14); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
|
||||
public int InventoryLength { get { int o = __p.__offset(14); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetInventoryBytes() { return __p.__vector_as_arraysegment(14); }
|
||||
public bool MutateInventory(int j, byte inventory) { int o = __p.__offset(14); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, inventory); return true; } else { return false; } }
|
||||
public Color Color { get { int o = __p.__offset(16); return o != 0 ? (Color)__p.bb.GetSbyte(o + __p.bb_pos) : Color.Blue; } }
|
||||
public bool MutateColor(Color color) { int o = __p.__offset(16); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)color); return true; } else { return false; } }
|
||||
public Any TestType { get { int o = __p.__offset(18); return o != 0 ? (Any)__p.bb.Get(o + __p.bb_pos) : Any.NONE; } }
|
||||
public bool MutateTestType(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) : null; }
|
||||
public Test? Test4(int j) { int o = __p.__offset(22); return o != 0 ? (Test?)(new 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 string Testarrayofstring(int j) { int o = __p.__offset(24); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
|
||||
public int TestarrayofstringLength { get { int o = __p.__offset(24); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
/// an example documentation comment: this will end up in the generated code
|
||||
/// multiline too
|
||||
public Monster GetTestarrayoftables(int j) { return GetTestarrayoftables(new Monster(), j); }
|
||||
public Monster GetTestarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public int TestarrayoftablesLength { get { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public Monster Enemy { get { return GetEnemy(new Monster()); } }
|
||||
public Monster GetEnemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public byte GetTestnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.Get(__vector(o) + j * 1) : (byte)0; }
|
||||
public int TestnestedflatbufferLength { get { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __vector_as_arraysegment(30); }
|
||||
public Monster TestnestedflatbufferAsMonster() { return GetTestnestedflatbufferAsMonster(new Monster()); }
|
||||
public Monster GetTestnestedflatbufferAsMonster(Monster obj) { int o = __offset(30); return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }
|
||||
public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.Put(__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
|
||||
public Stat Testempty { get { return GetTestempty(new Stat()); } }
|
||||
public Stat GetTestempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public bool Testbool { get { int o = __offset(34); return o != 0 ? 0!=bb.Get(o + bb_pos) : (bool)false; } }
|
||||
public bool MutateTestbool(bool testbool) { int o = __offset(34); if (o != 0) { bb.Put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
|
||||
public int Testhashs32Fnv1 { get { int o = __offset(36); return o != 0 ? bb.GetInt(o + bb_pos) : (int)0; } }
|
||||
public bool MutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __offset(36); if (o != 0) { bb.PutInt(o + bb_pos, testhashs32_fnv1); return true; } else { return false; } }
|
||||
public uint Testhashu32Fnv1 { get { int o = __offset(38); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public bool MutateTesthashu32Fnv1(uint testhashu32_fnv1) { int o = __offset(38); if (o != 0) { bb.PutUint(o + bb_pos, testhashu32_fnv1); return true; } else { return false; } }
|
||||
public long Testhashs64Fnv1 { get { int o = __offset(40); return o != 0 ? bb.GetLong(o + bb_pos) : (long)0; } }
|
||||
public bool MutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __offset(40); if (o != 0) { bb.PutLong(o + bb_pos, testhashs64_fnv1); return true; } else { return false; } }
|
||||
public ulong Testhashu64Fnv1 { get { int o = __offset(42); return o != 0 ? bb.GetUlong(o + bb_pos) : (ulong)0; } }
|
||||
public bool MutateTesthashu64Fnv1(ulong testhashu64_fnv1) { int o = __offset(42); if (o != 0) { bb.PutUlong(o + bb_pos, testhashu64_fnv1); return true; } else { return false; } }
|
||||
public int Testhashs32Fnv1a { get { int o = __offset(44); return o != 0 ? bb.GetInt(o + bb_pos) : (int)0; } }
|
||||
public bool MutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __offset(44); if (o != 0) { bb.PutInt(o + bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
|
||||
public uint Testhashu32Fnv1a { get { int o = __offset(46); return o != 0 ? bb.GetUint(o + bb_pos) : (uint)0; } }
|
||||
public bool MutateTesthashu32Fnv1a(uint testhashu32_fnv1a) { int o = __offset(46); if (o != 0) { bb.PutUint(o + bb_pos, testhashu32_fnv1a); return true; } else { return false; } }
|
||||
public long Testhashs64Fnv1a { get { int o = __offset(48); return o != 0 ? bb.GetLong(o + bb_pos) : (long)0; } }
|
||||
public bool MutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __offset(48); if (o != 0) { bb.PutLong(o + bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
|
||||
public ulong Testhashu64Fnv1a { get { int o = __offset(50); return o != 0 ? bb.GetUlong(o + bb_pos) : (ulong)0; } }
|
||||
public bool MutateTesthashu64Fnv1a(ulong testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.PutUlong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
|
||||
public bool GetTestarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.Get(__vector(o) + j * 1) : false; }
|
||||
public int TestarrayofboolsLength { get { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __vector_as_arraysegment(52); }
|
||||
public bool MutateTestarrayofbools(int j, bool testarrayofbools) { int o = __offset(52); if (o != 0) { bb.Put(__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
|
||||
public float Testf { get { int o = __offset(54); return o != 0 ? bb.GetFloat(o + bb_pos) : (float)3.14159f; } }
|
||||
public bool MutateTestf(float testf) { int o = __offset(54); if (o != 0) { bb.PutFloat(o + bb_pos, testf); return true; } else { return false; } }
|
||||
public float Testf2 { get { int o = __offset(56); return o != 0 ? bb.GetFloat(o + bb_pos) : (float)3.0f; } }
|
||||
public bool MutateTestf2(float testf2) { int o = __offset(56); if (o != 0) { bb.PutFloat(o + bb_pos, testf2); return true; } else { return false; } }
|
||||
public float Testf3 { get { int o = __offset(58); return o != 0 ? bb.GetFloat(o + bb_pos) : (float)0.0f; } }
|
||||
public bool MutateTestf3(float testf3) { int o = __offset(58); if (o != 0) { bb.PutFloat(o + bb_pos, testf3); return true; } else { return false; } }
|
||||
public string GetTestarrayofstring2(int j) { int o = __offset(60); return o != 0 ? __string(__vector(o) + j * 4) : null; }
|
||||
public int Testarrayofstring2Length { get { int o = __offset(60); return o != 0 ? __vector_len(o) : 0; } }
|
||||
public Monster? Testarrayoftables(int j) { int o = __p.__offset(26); return o != 0 ? (Monster?)(new Monster()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
|
||||
public int TestarrayoftablesLength { get { int o = __p.__offset(26); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public Monster? Enemy { get { int o = __p.__offset(28); return o != 0 ? (Monster?)(new Monster()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||
public byte Testnestedflatbuffer(int j) { int o = __p.__offset(30); return o != 0 ? __p.bb.Get(__p.__vector(o) + j * 1) : (byte)0; }
|
||||
public int TestnestedflatbufferLength { get { int o = __p.__offset(30); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetTestnestedflatbufferBytes() { return __p.__vector_as_arraysegment(30); }
|
||||
public Monster? GetTestnestedflatbufferAsMonster() { int o = __p.__offset(30); return o != 0 ? (Monster?)(new Monster()).__assign(__p.__indirect(__p.__vector(o)), __p.bb) : null; }
|
||||
public bool MutateTestnestedflatbuffer(int j, byte testnestedflatbuffer) { int o = __p.__offset(30); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, testnestedflatbuffer); return true; } else { return false; } }
|
||||
public Stat? Testempty { get { int o = __p.__offset(32); return o != 0 ? (Stat?)(new Stat()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||
public bool Testbool { get { int o = __p.__offset(34); return o != 0 ? 0!=__p.bb.Get(o + __p.bb_pos) : (bool)false; } }
|
||||
public bool MutateTestbool(bool testbool) { int o = __p.__offset(34); if (o != 0) { __p.bb.Put(o + __p.bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
|
||||
public int Testhashs32Fnv1 { get { int o = __p.__offset(36); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
|
||||
public bool MutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __p.__offset(36); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1); return true; } else { return false; } }
|
||||
public uint Testhashu32Fnv1 { get { int o = __p.__offset(38); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
|
||||
public bool MutateTesthashu32Fnv1(uint testhashu32_fnv1) { int o = __p.__offset(38); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1); return true; } else { return false; } }
|
||||
public long Testhashs64Fnv1 { get { int o = __p.__offset(40); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
|
||||
public bool MutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __p.__offset(40); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1); return true; } else { return false; } }
|
||||
public ulong Testhashu64Fnv1 { get { int o = __p.__offset(42); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
|
||||
public bool MutateTesthashu64Fnv1(ulong testhashu64_fnv1) { int o = __p.__offset(42); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1); return true; } else { return false; } }
|
||||
public int Testhashs32Fnv1a { get { int o = __p.__offset(44); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
|
||||
public bool MutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __p.__offset(44); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
|
||||
public uint Testhashu32Fnv1a { get { int o = __p.__offset(46); return o != 0 ? __p.bb.GetUint(o + __p.bb_pos) : (uint)0; } }
|
||||
public bool MutateTesthashu32Fnv1a(uint testhashu32_fnv1a) { int o = __p.__offset(46); if (o != 0) { __p.bb.PutUint(o + __p.bb_pos, testhashu32_fnv1a); return true; } else { return false; } }
|
||||
public long Testhashs64Fnv1a { get { int o = __p.__offset(48); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
|
||||
public bool MutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __p.__offset(48); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
|
||||
public ulong Testhashu64Fnv1a { get { int o = __p.__offset(50); return o != 0 ? __p.bb.GetUlong(o + __p.bb_pos) : (ulong)0; } }
|
||||
public bool MutateTesthashu64Fnv1a(ulong testhashu64_fnv1a) { int o = __p.__offset(50); if (o != 0) { __p.bb.PutUlong(o + __p.bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
|
||||
public bool Testarrayofbools(int j) { int o = __p.__offset(52); return o != 0 ? 0!=__p.bb.Get(__p.__vector(o) + j * 1) : false; }
|
||||
public int TestarrayofboolsLength { get { int o = __p.__offset(52); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
public ArraySegment<byte>? GetTestarrayofboolsBytes() { return __p.__vector_as_arraysegment(52); }
|
||||
public bool MutateTestarrayofbools(int j, bool testarrayofbools) { int o = __p.__offset(52); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, (byte)(testarrayofbools ? 1 : 0)); return true; } else { return false; } }
|
||||
public float Testf { get { int o = __p.__offset(54); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.14159f; } }
|
||||
public bool MutateTestf(float testf) { int o = __p.__offset(54); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf); return true; } else { return false; } }
|
||||
public float Testf2 { get { int o = __p.__offset(56); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)3.0f; } }
|
||||
public bool MutateTestf2(float testf2) { int o = __p.__offset(56); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf2); return true; } else { return false; } }
|
||||
public float Testf3 { get { int o = __p.__offset(58); return o != 0 ? __p.bb.GetFloat(o + __p.bb_pos) : (float)0.0f; } }
|
||||
public bool MutateTestf3(float testf3) { int o = __p.__offset(58); if (o != 0) { __p.bb.PutFloat(o + __p.bb_pos, testf3); return true; } else { return false; } }
|
||||
public string Testarrayofstring2(int j) { int o = __p.__offset(60); return o != 0 ? __p.__string(__p.__vector(o) + j * 4) : null; }
|
||||
public int Testarrayofstring2Length { get { int o = __p.__offset(60); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
|
||||
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(29); }
|
||||
public static void AddPos(FlatBufferBuilder builder, Offset<Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
|
||||
@@ -129,6 +127,34 @@ public sealed class Monster : Table {
|
||||
return new Offset<Monster>(o);
|
||||
}
|
||||
public static void FinishMonsterBuffer(FlatBufferBuilder builder, Offset<Monster> offset) { builder.Finish(offset.Value, "MONS"); }
|
||||
|
||||
public static VectorOffset CreateMySortedVectorOfTables(FlatBufferBuilder builder, Offset<Monster>[] offsets) {
|
||||
Array.Sort(offsets, (Offset<Monster> o1, Offset<Monster> o2) => Table.CompareStrings(Table.__offset(10, o1.Value, builder.DataBuffer), Table.__offset(10, o2.Value, builder.DataBuffer), builder.DataBuffer));
|
||||
return builder.CreateVectorOfTables(offsets);
|
||||
}
|
||||
|
||||
public static Monster? LookupByKey(VectorOffset vectorOffset, string key, ByteBuffer bb) {
|
||||
byte[] byteKey = System.Text.Encoding.UTF8.GetBytes(key);
|
||||
int vectorLocation = bb.Length - vectorOffset.Value;
|
||||
int span = bb.GetInt(vectorLocation);
|
||||
int start = 0;
|
||||
vectorLocation += 4;
|
||||
while (span != 0) {
|
||||
int middle = span / 2;
|
||||
int tableOffset = Table.__indirect(vectorLocation + 4 * (start + middle), bb);
|
||||
int comp = Table.CompareStrings(Table.__offset(10, bb.Length - tableOffset, bb), byteKey, bb);
|
||||
if (comp > 0) {
|
||||
span = middle;
|
||||
} else if (comp < 0) {
|
||||
middle++;
|
||||
start += middle;
|
||||
span -= middle;
|
||||
} else {
|
||||
return new Monster().__assign(tableOffset, bb);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,10 @@ func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Monster) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *Monster) Pos(obj *Vec3) *Vec3 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
@@ -131,9 +135,6 @@ func (rcv *Monster) Test4(obj *Test, j int) bool {
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
if obj == nil {
|
||||
obj = new(Test)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
@@ -173,9 +174,6 @@ func (rcv *Monster) Testarrayoftables(obj *Monster, j int) bool {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
if obj == nil {
|
||||
obj = new(Monster)
|
||||
}
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -13,12 +13,13 @@ import com.google.flatbuffers.*;
|
||||
*/
|
||||
public final class Monster extends Table {
|
||||
public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
|
||||
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public static boolean MonsterBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "MONS"); }
|
||||
public Monster __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public Vec3 pos() { return pos(new Vec3()); }
|
||||
public Vec3 pos(Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
||||
public Vec3 pos(Vec3 obj) { int o = __offset(4); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
|
||||
public short mana() { int o = __offset(6); return o != 0 ? bb.getShort(o + bb_pos) : 150; }
|
||||
public boolean mutateMana(short mana) { int o = __offset(6); if (o != 0) { bb.putShort(o + bb_pos, mana); return true; } else { return false; } }
|
||||
public short hp() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) : 100; }
|
||||
@@ -35,7 +36,7 @@ public final class Monster extends Table {
|
||||
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) : null; }
|
||||
public Test test4(int j) { return test4(new Test(), j); }
|
||||
public Test test4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__init(__vector(o) + j * 4, bb) : null; }
|
||||
public Test test4(Test obj, int j) { int o = __offset(22); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
|
||||
public int test4Length() { int o = __offset(22); return o != 0 ? __vector_len(o) : 0; }
|
||||
public String testarrayofstring(int j) { int o = __offset(24); return o != 0 ? __string(__vector(o) + j * 4) : null; }
|
||||
public int testarrayofstringLength() { int o = __offset(24); return o != 0 ? __vector_len(o) : 0; }
|
||||
@@ -44,35 +45,35 @@ public final class Monster extends Table {
|
||||
* multiline too
|
||||
*/
|
||||
public Monster testarrayoftables(int j) { return testarrayoftables(new Monster(), j); }
|
||||
public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__init(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public Monster testarrayoftables(Monster obj, int j) { int o = __offset(26); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public int testarrayoftablesLength() { int o = __offset(26); return o != 0 ? __vector_len(o) : 0; }
|
||||
public Monster enemy() { return enemy(new Monster()); }
|
||||
public Monster enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public Monster enemy(Monster obj) { int o = __offset(28); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||
public int testnestedflatbuffer(int j) { int o = __offset(30); return o != 0 ? bb.get(__vector(o) + j * 1) & 0xFF : 0; }
|
||||
public int testnestedflatbufferLength() { int o = __offset(30); return o != 0 ? __vector_len(o) : 0; }
|
||||
public ByteBuffer testnestedflatbufferAsByteBuffer() { return __vector_as_bytebuffer(30, 1); }
|
||||
public Monster testnestedflatbufferAsMonster() { return testnestedflatbufferAsMonster(new Monster()); }
|
||||
public Monster testnestedflatbufferAsMonster(Monster obj) { int o = __offset(30); return o != 0 ? obj.__init(__indirect(__vector(o)), bb) : null; }
|
||||
public Monster testnestedflatbufferAsMonster(Monster obj) { int o = __offset(30); return o != 0 ? obj.__assign(__indirect(__vector(o)), bb) : null; }
|
||||
public boolean mutateTestnestedflatbuffer(int j, int testnestedflatbuffer) { int o = __offset(30); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)testnestedflatbuffer); return true; } else { return false; } }
|
||||
public Stat testempty() { return testempty(new Stat()); }
|
||||
public Stat testempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public Stat testempty(Stat obj) { int o = __offset(32); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||
public boolean testbool() { int o = __offset(34); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
|
||||
public boolean mutateTestbool(boolean testbool) { int o = __offset(34); if (o != 0) { bb.put(o + bb_pos, (byte)(testbool ? 1 : 0)); return true; } else { return false; } }
|
||||
public int testhashs32Fnv1() { int o = __offset(36); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||
public boolean mutateTesthashs32Fnv1(int testhashs32_fnv1) { int o = __offset(36); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1); return true; } else { return false; } }
|
||||
public long testhashu32Fnv1() { int o = __offset(38); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0; }
|
||||
public long testhashu32Fnv1() { int o = __offset(38); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
|
||||
public boolean mutateTesthashu32Fnv1(long testhashu32_fnv1) { int o = __offset(38); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1); return true; } else { return false; } }
|
||||
public long testhashs64Fnv1() { int o = __offset(40); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
|
||||
public long testhashs64Fnv1() { int o = __offset(40); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
|
||||
public boolean mutateTesthashs64Fnv1(long testhashs64_fnv1) { int o = __offset(40); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1); return true; } else { return false; } }
|
||||
public long testhashu64Fnv1() { int o = __offset(42); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
|
||||
public long testhashu64Fnv1() { int o = __offset(42); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
|
||||
public boolean mutateTesthashu64Fnv1(long testhashu64_fnv1) { int o = __offset(42); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1); return true; } else { return false; } }
|
||||
public int testhashs32Fnv1a() { int o = __offset(44); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||
public boolean mutateTesthashs32Fnv1a(int testhashs32_fnv1a) { int o = __offset(44); if (o != 0) { bb.putInt(o + bb_pos, testhashs32_fnv1a); return true; } else { return false; } }
|
||||
public long testhashu32Fnv1a() { int o = __offset(46); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0; }
|
||||
public long testhashu32Fnv1a() { int o = __offset(46); return o != 0 ? (long)bb.getInt(o + bb_pos) & 0xFFFFFFFFL : 0L; }
|
||||
public boolean mutateTesthashu32Fnv1a(long testhashu32_fnv1a) { int o = __offset(46); if (o != 0) { bb.putInt(o + bb_pos, (int)testhashu32_fnv1a); return true; } else { return false; } }
|
||||
public long testhashs64Fnv1a() { int o = __offset(48); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
|
||||
public long testhashs64Fnv1a() { int o = __offset(48); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
|
||||
public boolean mutateTesthashs64Fnv1a(long testhashs64_fnv1a) { int o = __offset(48); if (o != 0) { bb.putLong(o + bb_pos, testhashs64_fnv1a); return true; } else { return false; } }
|
||||
public long testhashu64Fnv1a() { int o = __offset(50); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
|
||||
public long testhashu64Fnv1a() { int o = __offset(50); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
|
||||
public boolean mutateTesthashu64Fnv1a(long testhashu64_fnv1a) { int o = __offset(50); if (o != 0) { bb.putLong(o + bb_pos, testhashu64_fnv1a); return true; } else { return false; } }
|
||||
public boolean testarrayofbools(int j) { int o = __offset(52); return o != 0 ? 0!=bb.get(__vector(o) + j * 1) : false; }
|
||||
public int testarrayofboolsLength() { int o = __offset(52); return o != 0 ? __vector_len(o) : 0; }
|
||||
@@ -113,13 +114,13 @@ public final class Monster extends Table {
|
||||
public static void addTestempty(FlatBufferBuilder builder, int testemptyOffset) { builder.addOffset(14, testemptyOffset, 0); }
|
||||
public static void addTestbool(FlatBufferBuilder builder, boolean testbool) { builder.addBoolean(15, testbool, false); }
|
||||
public static void addTesthashs32Fnv1(FlatBufferBuilder builder, int testhashs32Fnv1) { builder.addInt(16, testhashs32Fnv1, 0); }
|
||||
public static void addTesthashu32Fnv1(FlatBufferBuilder builder, long testhashu32Fnv1) { builder.addInt(17, (int)testhashu32Fnv1, 0); }
|
||||
public static void addTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.addLong(18, testhashs64Fnv1, 0); }
|
||||
public static void addTesthashu64Fnv1(FlatBufferBuilder builder, long testhashu64Fnv1) { builder.addLong(19, testhashu64Fnv1, 0); }
|
||||
public static void addTesthashu32Fnv1(FlatBufferBuilder builder, long testhashu32Fnv1) { builder.addInt(17, (int)testhashu32Fnv1, (int)0L); }
|
||||
public static void addTesthashs64Fnv1(FlatBufferBuilder builder, long testhashs64Fnv1) { builder.addLong(18, testhashs64Fnv1, 0L); }
|
||||
public static void addTesthashu64Fnv1(FlatBufferBuilder builder, long testhashu64Fnv1) { builder.addLong(19, testhashu64Fnv1, 0L); }
|
||||
public static void addTesthashs32Fnv1a(FlatBufferBuilder builder, int testhashs32Fnv1a) { builder.addInt(20, testhashs32Fnv1a, 0); }
|
||||
public static void addTesthashu32Fnv1a(FlatBufferBuilder builder, long testhashu32Fnv1a) { builder.addInt(21, (int)testhashu32Fnv1a, 0); }
|
||||
public static void addTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.addLong(22, testhashs64Fnv1a, 0); }
|
||||
public static void addTesthashu64Fnv1a(FlatBufferBuilder builder, long testhashu64Fnv1a) { builder.addLong(23, testhashu64Fnv1a, 0); }
|
||||
public static void addTesthashu32Fnv1a(FlatBufferBuilder builder, long testhashu32Fnv1a) { builder.addInt(21, (int)testhashu32Fnv1a, (int)0L); }
|
||||
public static void addTesthashs64Fnv1a(FlatBufferBuilder builder, long testhashs64Fnv1a) { builder.addLong(22, testhashs64Fnv1a, 0L); }
|
||||
public static void addTesthashu64Fnv1a(FlatBufferBuilder builder, long testhashu64Fnv1a) { builder.addLong(23, testhashu64Fnv1a, 0L); }
|
||||
public static void addTestarrayofbools(FlatBufferBuilder builder, int testarrayofboolsOffset) { builder.addOffset(24, testarrayofboolsOffset, 0); }
|
||||
public static int createTestarrayofboolsVector(FlatBufferBuilder builder, boolean[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addBoolean(data[i]); return builder.endVector(); }
|
||||
public static void startTestarrayofboolsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
|
||||
@@ -135,5 +136,31 @@ public final class Monster extends Table {
|
||||
return o;
|
||||
}
|
||||
public static void finishMonsterBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset, "MONS"); }
|
||||
|
||||
@Override
|
||||
protected int keysCompare(Integer o1, Integer o2, ByteBuffer _bb) { return compareStrings(__offset(10, o1, _bb), __offset(10, o2, _bb), _bb); }
|
||||
|
||||
public static Monster lookupByKey(int vectorOffset, String key, ByteBuffer bb) {
|
||||
byte[] byteKey = key.getBytes(Table.UTF8_CHARSET.get());
|
||||
int vectorLocation = bb.array().length - vectorOffset;
|
||||
int span = bb.getInt(vectorLocation);
|
||||
int start = 0;
|
||||
vectorLocation += 4;
|
||||
while (span != 0) {
|
||||
int middle = span / 2;
|
||||
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
||||
int comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb);
|
||||
if (comp > 0) {
|
||||
span = middle;
|
||||
} else if (comp < 0) {
|
||||
middle++;
|
||||
start += middle;
|
||||
span -= middle;
|
||||
} else {
|
||||
return new Monster().__assign(tableOffset, bb);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
106
tests/MyGame/Example/MonsterStorage_grpc.go
Normal file
106
tests/MyGame/Example/MonsterStorage_grpc.go
Normal file
@@ -0,0 +1,106 @@
|
||||
//Generated by gRPC Go plugin
|
||||
//If you make any local changes, they will be lost
|
||||
//source: monster_test
|
||||
|
||||
package Example
|
||||
|
||||
import "github.com/google/flatbuffers/go"
|
||||
|
||||
import (
|
||||
context "golang.org/x/net/context"
|
||||
grpc "google.golang.org/grpc"
|
||||
)
|
||||
|
||||
// Client API for MonsterStorage service
|
||||
type MonsterStorageClient interface{
|
||||
Store(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Stat, error)
|
||||
Retrieve(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Monster, error)
|
||||
}
|
||||
|
||||
type monsterStorageClient struct {
|
||||
cc *grpc.ClientConn
|
||||
}
|
||||
|
||||
func NewMonsterStorageClient(cc *grpc.ClientConn) MonsterStorageClient {
|
||||
return &monsterStorageClient{cc}
|
||||
}
|
||||
|
||||
func (c *monsterStorageClient) Store(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Stat, error) {
|
||||
out := new(Stat)
|
||||
err := grpc.Invoke(ctx, "/Example.MonsterStorage/Store", in, out, c.cc, opts...)
|
||||
if err != nil { return nil, err }
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *monsterStorageClient) Retrieve(ctx context.Context, in *flatbuffers.Builder,
|
||||
opts... grpc.CallOption) (* Monster, error) {
|
||||
out := new(Monster)
|
||||
err := grpc.Invoke(ctx, "/Example.MonsterStorage/Retrieve", in, out, c.cc, opts...)
|
||||
if err != nil { return nil, err }
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for MonsterStorage service
|
||||
type MonsterStorageServer interface {
|
||||
Store(context.Context, *Monster) (*flatbuffers.Builder, error)
|
||||
Retrieve(context.Context, *Stat) (*flatbuffers.Builder, error)
|
||||
}
|
||||
|
||||
func RegisterMonsterStorageServer(s *grpc.Server, srv MonsterStorageServer) {
|
||||
s.RegisterService(&_MonsterStorage_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _MonsterStorage_Store_Handler(srv interface{}, ctx context.Context,
|
||||
dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Monster)
|
||||
if err := dec(in); err != nil { return nil, err }
|
||||
if interceptor == nil { return srv.(MonsterStorageServer).Store(ctx, in) }
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/Example.MonsterStorage/Store",
|
||||
}
|
||||
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MonsterStorageServer).Store(ctx, req.(* Monster))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
|
||||
func _MonsterStorage_Retrieve_Handler(srv interface{}, ctx context.Context,
|
||||
dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Stat)
|
||||
if err := dec(in); err != nil { return nil, err }
|
||||
if interceptor == nil { return srv.(MonsterStorageServer).Retrieve(ctx, in) }
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/Example.MonsterStorage/Retrieve",
|
||||
}
|
||||
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(MonsterStorageServer).Retrieve(ctx, req.(* Stat))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
|
||||
var _MonsterStorage_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "Example.MonsterStorage",
|
||||
HandlerType: (*MonsterStorageServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "Store",
|
||||
Handler: _MonsterStorage_Store_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Retrieve",
|
||||
Handler: _MonsterStorage_Retrieve_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{
|
||||
},
|
||||
}
|
||||
|
||||
@@ -6,17 +6,21 @@ namespace MyGame.Example
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class Stat : Table {
|
||||
public struct Stat : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static Stat GetRootAsStat(ByteBuffer _bb) { return GetRootAsStat(_bb, new Stat()); }
|
||||
public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public Stat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static Stat GetRootAsStat(ByteBuffer _bb, Stat obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public string Id { get { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; } }
|
||||
public ArraySegment<byte>? GetIdBytes() { return __vector_as_arraysegment(4); }
|
||||
public long Val { get { int o = __offset(6); return o != 0 ? bb.GetLong(o + bb_pos) : (long)0; } }
|
||||
public bool MutateVal(long val) { int o = __offset(6); if (o != 0) { bb.PutLong(o + bb_pos, val); return true; } else { return false; } }
|
||||
public ushort Count { get { int o = __offset(8); return o != 0 ? bb.GetUshort(o + bb_pos) : (ushort)0; } }
|
||||
public bool MutateCount(ushort count) { int o = __offset(8); if (o != 0) { bb.PutUshort(o + bb_pos, count); return true; } else { return false; } }
|
||||
public string Id { get { int o = __p.__offset(4); return o != 0 ? __p.__string(o + __p.bb_pos) : null; } }
|
||||
public ArraySegment<byte>? GetIdBytes() { return __p.__vector_as_arraysegment(4); }
|
||||
public long Val { get { int o = __p.__offset(6); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
|
||||
public bool MutateVal(long val) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutLong(o + __p.bb_pos, val); return true; } else { return false; } }
|
||||
public ushort Count { get { int o = __p.__offset(8); return o != 0 ? __p.bb.GetUshort(o + __p.bb_pos) : (ushort)0; } }
|
||||
public bool MutateCount(ushort count) { int o = __p.__offset(8); if (o != 0) { __p.bb.PutUshort(o + __p.bb_pos, count); return true; } else { return false; } }
|
||||
|
||||
public static Offset<Stat> CreateStat(FlatBufferBuilder builder,
|
||||
StringOffset idOffset = default(StringOffset),
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *Stat) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Stat) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *Stat) Id() []byte {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
|
||||
@@ -10,12 +10,13 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class Stat extends Table {
|
||||
public static Stat getRootAsStat(ByteBuffer _bb) { return getRootAsStat(_bb, new Stat()); }
|
||||
public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public Stat __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static Stat getRootAsStat(ByteBuffer _bb, Stat obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public Stat __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public String id() { int o = __offset(4); return o != 0 ? __string(o + bb_pos) : null; }
|
||||
public ByteBuffer idAsByteBuffer() { return __vector_as_bytebuffer(4, 1); }
|
||||
public long val() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0; }
|
||||
public long val() { int o = __offset(6); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
|
||||
public boolean mutateVal(long val) { int o = __offset(6); if (o != 0) { bb.putLong(o + bb_pos, val); return true; } else { return false; } }
|
||||
public int count() { int o = __offset(8); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
|
||||
public boolean mutateCount(int count) { int o = __offset(8); if (o != 0) { bb.putShort(o + bb_pos, (short)count); return true; } else { return false; } }
|
||||
@@ -33,8 +34,8 @@ public final class Stat extends Table {
|
||||
|
||||
public static void startStat(FlatBufferBuilder builder) { builder.startObject(3); }
|
||||
public static void addId(FlatBufferBuilder builder, int idOffset) { builder.addOffset(0, idOffset, 0); }
|
||||
public static void addVal(FlatBufferBuilder builder, long val) { builder.addLong(1, val, 0); }
|
||||
public static void addCount(FlatBufferBuilder builder, int count) { builder.addShort(2, (short)count, 0); }
|
||||
public static void addVal(FlatBufferBuilder builder, long val) { builder.addLong(1, val, 0L); }
|
||||
public static void addCount(FlatBufferBuilder builder, int count) { builder.addShort(2, (short)count, (short)0); }
|
||||
public static int endStat(FlatBufferBuilder builder) {
|
||||
int o = builder.endObject();
|
||||
return o;
|
||||
|
||||
@@ -6,13 +6,17 @@ namespace MyGame.Example
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class Test : Struct {
|
||||
public Test __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public struct Test : IFlatbufferObject
|
||||
{
|
||||
private Struct __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public short A { get { return bb.GetShort(bb_pos + 0); } }
|
||||
public void MutateA(short a) { bb.PutShort(bb_pos + 0, a); }
|
||||
public sbyte B { get { return bb.GetSbyte(bb_pos + 2); } }
|
||||
public void MutateB(sbyte b) { bb.PutSbyte(bb_pos + 2, b); }
|
||||
public short A { get { return __p.bb.GetShort(__p.bb_pos + 0); } }
|
||||
public void MutateA(short a) { __p.bb.PutShort(__p.bb_pos + 0, a); }
|
||||
public sbyte B { get { return __p.bb.GetSbyte(__p.bb_pos + 2); } }
|
||||
public void MutateB(sbyte b) { __p.bb.PutSbyte(__p.bb_pos + 2, b); }
|
||||
|
||||
public static Offset<Test> CreateTest(FlatBufferBuilder builder, short A, sbyte B) {
|
||||
builder.Prep(2, 4);
|
||||
|
||||
@@ -15,6 +15,10 @@ func (rcv *Test) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Test) Table() flatbuffers.Table {
|
||||
return rcv._tab.Table
|
||||
}
|
||||
|
||||
func (rcv *Test) A() int16 {
|
||||
return rcv._tab.GetInt16(rcv._tab.Pos + flatbuffers.UOffsetT(0))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import com.google.flatbuffers.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Test extends Struct {
|
||||
public Test __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public Test __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public short a() { return bb.getShort(bb_pos + 0); }
|
||||
public void mutateA(short a) { bb.putShort(bb_pos + 0, a); }
|
||||
|
||||
@@ -6,13 +6,17 @@ namespace MyGame.Example
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public partial class TestSimpleTableWithEnum : Table {
|
||||
public partial struct TestSimpleTableWithEnum : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return GetRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
|
||||
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public TestSimpleTableWithEnum __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TestSimpleTableWithEnum GetRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public Color Color { get { int o = __offset(4); return o != 0 ? (Color)bb.GetSbyte(o + bb_pos) : Color.Green; } }
|
||||
public bool MutateColor(Color color) { int o = __offset(4); if (o != 0) { bb.PutSbyte(o + bb_pos, (sbyte)color); return true; } else { return false; } }
|
||||
public Color Color { get { int o = __p.__offset(4); return o != 0 ? (Color)__p.bb.GetSbyte(o + __p.bb_pos) : Color.Green; } }
|
||||
public bool MutateColor(Color color) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)color); return true; } else { return false; } }
|
||||
|
||||
public static Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(FlatBufferBuilder builder,
|
||||
Color color = Color.Green) {
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *TestSimpleTableWithEnum) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *TestSimpleTableWithEnum) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TestSimpleTableWithEnum) Color() int8 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
|
||||
@@ -10,8 +10,9 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class TestSimpleTableWithEnum extends Table {
|
||||
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb) { return getRootAsTestSimpleTableWithEnum(_bb, new TestSimpleTableWithEnum()); }
|
||||
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public TestSimpleTableWithEnum __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TestSimpleTableWithEnum getRootAsTestSimpleTableWithEnum(ByteBuffer _bb, TestSimpleTableWithEnum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public TestSimpleTableWithEnum __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public byte color() { int o = __offset(4); return o != 0 ? bb.get(o + bb_pos) : 2; }
|
||||
public boolean mutateColor(byte color) { int o = __offset(4); if (o != 0) { bb.put(o + bb_pos, color); return true; } else { return false; } }
|
||||
|
||||
@@ -6,21 +6,24 @@ namespace MyGame.Example
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class Vec3 : Struct {
|
||||
public Vec3 __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public struct Vec3 : IFlatbufferObject
|
||||
{
|
||||
private Struct __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public float X { get { return bb.GetFloat(bb_pos + 0); } }
|
||||
public void MutateX(float x) { bb.PutFloat(bb_pos + 0, x); }
|
||||
public float Y { get { return bb.GetFloat(bb_pos + 4); } }
|
||||
public void MutateY(float y) { bb.PutFloat(bb_pos + 4, y); }
|
||||
public float Z { get { return bb.GetFloat(bb_pos + 8); } }
|
||||
public void MutateZ(float z) { bb.PutFloat(bb_pos + 8, z); }
|
||||
public double Test1 { get { return bb.GetDouble(bb_pos + 16); } }
|
||||
public void MutateTest1(double test1) { bb.PutDouble(bb_pos + 16, test1); }
|
||||
public Color Test2 { get { return (Color)bb.GetSbyte(bb_pos + 24); } }
|
||||
public void MutateTest2(Color test2) { bb.PutSbyte(bb_pos + 24, (sbyte)test2); }
|
||||
public Test Test3 { get { return GetTest3(new Test()); } }
|
||||
public Test GetTest3(Test obj) { return obj.__init(bb_pos + 26, bb); }
|
||||
public float X { get { return __p.bb.GetFloat(__p.bb_pos + 0); } }
|
||||
public void MutateX(float x) { __p.bb.PutFloat(__p.bb_pos + 0, x); }
|
||||
public float Y { get { return __p.bb.GetFloat(__p.bb_pos + 4); } }
|
||||
public void MutateY(float y) { __p.bb.PutFloat(__p.bb_pos + 4, y); }
|
||||
public float Z { get { return __p.bb.GetFloat(__p.bb_pos + 8); } }
|
||||
public void MutateZ(float z) { __p.bb.PutFloat(__p.bb_pos + 8, z); }
|
||||
public double Test1 { get { return __p.bb.GetDouble(__p.bb_pos + 16); } }
|
||||
public void MutateTest1(double test1) { __p.bb.PutDouble(__p.bb_pos + 16, test1); }
|
||||
public Color Test2 { get { return (Color)__p.bb.GetSbyte(__p.bb_pos + 24); } }
|
||||
public void MutateTest2(Color test2) { __p.bb.PutSbyte(__p.bb_pos + 24, (sbyte)test2); }
|
||||
public Test Test3 { get { return (new Test()).__assign(__p.bb_pos + 26, __p.bb); } }
|
||||
|
||||
public static Offset<Vec3> CreateVec3(FlatBufferBuilder builder, float X, float Y, float Z, double Test1, Color Test2, short test3_A, sbyte test3_B) {
|
||||
builder.Prep(16, 32);
|
||||
|
||||
@@ -15,6 +15,10 @@ func (rcv *Vec3) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Vec3) Table() flatbuffers.Table {
|
||||
return rcv._tab.Table
|
||||
}
|
||||
|
||||
func (rcv *Vec3) X() float32 {
|
||||
return rcv._tab.GetFloat32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import com.google.flatbuffers.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Vec3 extends Struct {
|
||||
public Vec3 __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public Vec3 __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public float x() { return bb.getFloat(bb_pos + 0); }
|
||||
public void mutateX(float x) { bb.putFloat(bb_pos + 0, x); }
|
||||
@@ -22,7 +23,7 @@ public final class Vec3 extends Struct {
|
||||
public byte test2() { return bb.get(bb_pos + 24); }
|
||||
public void mutateTest2(byte test2) { bb.put(bb_pos + 24, test2); }
|
||||
public Test test3() { return test3(new Test()); }
|
||||
public Test test3(Test obj) { return obj.__init(bb_pos + 26, bb); }
|
||||
public Test test3(Test obj) { return obj.__assign(bb_pos + 26, bb); }
|
||||
|
||||
public static int createVec3(FlatBufferBuilder builder, float x, float y, float z, double test1, byte test2, short test3_a, byte test3_b) {
|
||||
builder.prep(16, 32);
|
||||
|
||||
@@ -6,16 +6,20 @@ namespace MyGame.Example2
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class Monster : Table {
|
||||
public struct Monster : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static Monster GetRootAsMonster(ByteBuffer _bb) { return GetRootAsMonster(_bb, new Monster()); }
|
||||
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public Monster __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static Monster GetRootAsMonster(ByteBuffer _bb, Monster obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
|
||||
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(0); }
|
||||
public static Offset<MyGame.Example2.Monster> EndMonster(FlatBufferBuilder builder) {
|
||||
public static Offset<Monster> EndMonster(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return new Offset<MyGame.Example2.Monster>(o);
|
||||
return new Offset<Monster>(o);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *Monster) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Monster) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func MonsterStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(0)
|
||||
}
|
||||
|
||||
@@ -10,8 +10,9 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class Monster extends Table {
|
||||
public static Monster getRootAsMonster(ByteBuffer _bb) { return getRootAsMonster(_bb, new Monster()); }
|
||||
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public Monster __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static Monster getRootAsMonster(ByteBuffer _bb, Monster obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public Monster __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
|
||||
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(0); }
|
||||
|
||||
@@ -12,6 +12,9 @@
|
||||
:: See the License for the specific language governing permissions and
|
||||
:: limitations under the License.
|
||||
|
||||
..\flatc.exe --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
|
||||
..\flatc.exe --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test\namespace_test1.fbs namespace_test\namespace_test2.fbs
|
||||
..\flatc.exe --binary --schema monster_test.fbs
|
||||
set buildtype=Release
|
||||
if "%1"=="-b" set buildtype=%2
|
||||
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --php --grpc --gen-mutable --gen-object-api --no-includes monster_test.fbs monsterdata_test.json
|
||||
..\%buildtype%\flatc.exe --cpp --java --csharp --go --binary --python --js --php --gen-mutable -o namespace_test namespace_test\namespace_test1.fbs namespace_test\namespace_test2.fbs
|
||||
..\%buildtype%\flatc.exe --binary --schema monster_test.fbs
|
||||
|
||||
0
tests/generate_code.sh
Normal file → Executable file
0
tests/generate_code.sh
Normal file → Executable file
317
tests/go_test.go
317
tests/go_test.go
@@ -78,6 +78,7 @@ func TestAll(t *testing.T) {
|
||||
|
||||
// Verify that GetRootAs works for non-root tables
|
||||
CheckGetRootAsForNonRootTable(t.Fatalf)
|
||||
CheckTableAccessors(t.Fatalf)
|
||||
|
||||
// Verify that using the generated Go code builds a buffer without
|
||||
// returning errors:
|
||||
@@ -137,155 +138,159 @@ func TestAll(t *testing.T) {
|
||||
// CheckReadBuffer checks that the given buffer is evaluated correctly
|
||||
// as the example Monster.
|
||||
func CheckReadBuffer(buf []byte, offset flatbuffers.UOffsetT, fail func(string, ...interface{})) {
|
||||
monster := example.GetRootAsMonster(buf, offset)
|
||||
|
||||
if got := monster.Hp(); 80 != got {
|
||||
fail(FailString("hp", 80, got))
|
||||
}
|
||||
|
||||
// default
|
||||
if got := monster.Mana(); 150 != got {
|
||||
fail(FailString("mana", 150, got))
|
||||
}
|
||||
|
||||
if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
|
||||
fail(FailString("name", "MyMonster", got))
|
||||
}
|
||||
|
||||
// initialize a Vec3 from Pos()
|
||||
vec := new(example.Vec3)
|
||||
vec = monster.Pos(vec)
|
||||
if vec == nil {
|
||||
fail("vec3 initialization failed")
|
||||
}
|
||||
|
||||
// check that new allocs equal given ones:
|
||||
vec2 := monster.Pos(nil)
|
||||
if !reflect.DeepEqual(vec, vec2) {
|
||||
fail("fresh allocation failed")
|
||||
}
|
||||
|
||||
// verify the properties of the Vec3
|
||||
if got := vec.X(); float32(1.0) != got {
|
||||
fail(FailString("Pos.X", float32(1.0), got))
|
||||
}
|
||||
|
||||
if got := vec.Y(); float32(2.0) != got {
|
||||
fail(FailString("Pos.Y", float32(2.0), got))
|
||||
}
|
||||
|
||||
if got := vec.Z(); float32(3.0) != got {
|
||||
fail(FailString("Pos.Z", float32(3.0), got))
|
||||
}
|
||||
|
||||
if got := vec.Test1(); float64(3.0) != got {
|
||||
fail(FailString("Pos.Test1", float64(3.0), got))
|
||||
}
|
||||
|
||||
if got := vec.Test2(); int8(2) != got {
|
||||
fail(FailString("Pos.Test2", int8(2), got))
|
||||
}
|
||||
|
||||
// initialize a Test from Test3(...)
|
||||
t := new(example.Test)
|
||||
t = vec.Test3(t)
|
||||
if t == nil {
|
||||
fail("vec.Test3(&t) failed")
|
||||
}
|
||||
|
||||
// check that new allocs equal given ones:
|
||||
t2 := vec.Test3(nil)
|
||||
if !reflect.DeepEqual(t, t2) {
|
||||
fail("fresh allocation failed")
|
||||
}
|
||||
|
||||
// verify the properties of the Test
|
||||
if got := t.A(); int16(5) != got {
|
||||
fail(FailString("t.A()", int16(5), got))
|
||||
}
|
||||
|
||||
if got := t.B(); int8(6) != got {
|
||||
fail(FailString("t.B()", int8(6), got))
|
||||
}
|
||||
|
||||
if got := monster.TestType(); example.AnyMonster != got {
|
||||
fail(FailString("monster.TestType()", example.AnyMonster, got))
|
||||
}
|
||||
|
||||
// initialize a Table from a union field Test(...)
|
||||
var table2 flatbuffers.Table
|
||||
if ok := monster.Test(&table2); !ok {
|
||||
fail("monster.Test(&monster2) failed")
|
||||
}
|
||||
|
||||
// initialize a Monster from the Table from the union
|
||||
var monster2 example.Monster
|
||||
monster2.Init(table2.Bytes, table2.Pos)
|
||||
|
||||
if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
|
||||
fail(FailString("monster2.Name()", "Fred", got))
|
||||
}
|
||||
|
||||
inventorySlice := monster.InventoryBytes()
|
||||
if len(inventorySlice) != monster.InventoryLength() {
|
||||
fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
|
||||
}
|
||||
|
||||
if got := monster.InventoryLength(); 5 != got {
|
||||
fail(FailString("monster.InventoryLength", 5, got))
|
||||
}
|
||||
|
||||
invsum := 0
|
||||
l := monster.InventoryLength()
|
||||
for i := 0; i < l; i++ {
|
||||
v := monster.Inventory(i)
|
||||
if v != inventorySlice[i] {
|
||||
fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
|
||||
// try the two ways of generating a monster
|
||||
monster1 := example.GetRootAsMonster(buf, offset)
|
||||
monster2 := &example.Monster{}
|
||||
flatbuffers.GetRootAs(buf, offset, monster2)
|
||||
for _, monster := range []*example.Monster{monster1, monster2} {
|
||||
if got := monster.Hp(); 80 != got {
|
||||
fail(FailString("hp", 80, got))
|
||||
}
|
||||
invsum += int(v)
|
||||
}
|
||||
if invsum != 10 {
|
||||
fail(FailString("monster inventory sum", 10, invsum))
|
||||
}
|
||||
|
||||
if got := monster.Test4Length(); 2 != got {
|
||||
fail(FailString("monster.Test4Length()", 2, got))
|
||||
}
|
||||
// default
|
||||
if got := monster.Mana(); 150 != got {
|
||||
fail(FailString("mana", 150, got))
|
||||
}
|
||||
|
||||
var test0 example.Test
|
||||
ok := monster.Test4(&test0, 0)
|
||||
if !ok {
|
||||
fail(FailString("monster.Test4(&test0, 0)", true, ok))
|
||||
}
|
||||
if got := monster.Name(); !bytes.Equal([]byte("MyMonster"), got) {
|
||||
fail(FailString("name", "MyMonster", got))
|
||||
}
|
||||
|
||||
var test1 example.Test
|
||||
ok = monster.Test4(&test1, 1)
|
||||
if !ok {
|
||||
fail(FailString("monster.Test4(&test1, 1)", true, ok))
|
||||
}
|
||||
// initialize a Vec3 from Pos()
|
||||
vec := new(example.Vec3)
|
||||
vec = monster.Pos(vec)
|
||||
if vec == nil {
|
||||
fail("vec3 initialization failed")
|
||||
}
|
||||
|
||||
// the position of test0 and test1 are swapped in monsterdata_java_wire
|
||||
// and monsterdata_test_wire, so ignore ordering
|
||||
v0 := test0.A()
|
||||
v1 := test0.B()
|
||||
v2 := test1.A()
|
||||
v3 := test1.B()
|
||||
sum := int(v0) + int(v1) + int(v2) + int(v3)
|
||||
// check that new allocs equal given ones:
|
||||
vec2 := monster.Pos(nil)
|
||||
if !reflect.DeepEqual(vec, vec2) {
|
||||
fail("fresh allocation failed")
|
||||
}
|
||||
|
||||
if 100 != sum {
|
||||
fail(FailString("test0 and test1 sum", 100, sum))
|
||||
}
|
||||
// verify the properties of the Vec3
|
||||
if got := vec.X(); float32(1.0) != got {
|
||||
fail(FailString("Pos.X", float32(1.0), got))
|
||||
}
|
||||
|
||||
if got := monster.TestarrayofstringLength(); 2 != got {
|
||||
fail(FailString("Testarrayofstring length", 2, got))
|
||||
}
|
||||
if got := vec.Y(); float32(2.0) != got {
|
||||
fail(FailString("Pos.Y", float32(2.0), got))
|
||||
}
|
||||
|
||||
if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
|
||||
fail(FailString("Testarrayofstring(0)", "test1", got))
|
||||
}
|
||||
if got := vec.Z(); float32(3.0) != got {
|
||||
fail(FailString("Pos.Z", float32(3.0), got))
|
||||
}
|
||||
|
||||
if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
|
||||
fail(FailString("Testarrayofstring(1)", "test2", got))
|
||||
if got := vec.Test1(); float64(3.0) != got {
|
||||
fail(FailString("Pos.Test1", float64(3.0), got))
|
||||
}
|
||||
|
||||
if got := vec.Test2(); int8(2) != got {
|
||||
fail(FailString("Pos.Test2", int8(2), got))
|
||||
}
|
||||
|
||||
// initialize a Test from Test3(...)
|
||||
t := new(example.Test)
|
||||
t = vec.Test3(t)
|
||||
if t == nil {
|
||||
fail("vec.Test3(&t) failed")
|
||||
}
|
||||
|
||||
// check that new allocs equal given ones:
|
||||
t2 := vec.Test3(nil)
|
||||
if !reflect.DeepEqual(t, t2) {
|
||||
fail("fresh allocation failed")
|
||||
}
|
||||
|
||||
// verify the properties of the Test
|
||||
if got := t.A(); int16(5) != got {
|
||||
fail(FailString("t.A()", int16(5), got))
|
||||
}
|
||||
|
||||
if got := t.B(); int8(6) != got {
|
||||
fail(FailString("t.B()", int8(6), got))
|
||||
}
|
||||
|
||||
if got := monster.TestType(); example.AnyMonster != got {
|
||||
fail(FailString("monster.TestType()", example.AnyMonster, got))
|
||||
}
|
||||
|
||||
// initialize a Table from a union field Test(...)
|
||||
var table2 flatbuffers.Table
|
||||
if ok := monster.Test(&table2); !ok {
|
||||
fail("monster.Test(&monster2) failed")
|
||||
}
|
||||
|
||||
// initialize a Monster from the Table from the union
|
||||
var monster2 example.Monster
|
||||
monster2.Init(table2.Bytes, table2.Pos)
|
||||
|
||||
if got := monster2.Name(); !bytes.Equal([]byte("Fred"), got) {
|
||||
fail(FailString("monster2.Name()", "Fred", got))
|
||||
}
|
||||
|
||||
inventorySlice := monster.InventoryBytes()
|
||||
if len(inventorySlice) != monster.InventoryLength() {
|
||||
fail(FailString("len(monster.InventoryBytes) != monster.InventoryLength", len(inventorySlice), monster.InventoryLength()))
|
||||
}
|
||||
|
||||
if got := monster.InventoryLength(); 5 != got {
|
||||
fail(FailString("monster.InventoryLength", 5, got))
|
||||
}
|
||||
|
||||
invsum := 0
|
||||
l := monster.InventoryLength()
|
||||
for i := 0; i < l; i++ {
|
||||
v := monster.Inventory(i)
|
||||
if v != inventorySlice[i] {
|
||||
fail(FailString("monster inventory slice[i] != Inventory(i)", v, inventorySlice[i]))
|
||||
}
|
||||
invsum += int(v)
|
||||
}
|
||||
if invsum != 10 {
|
||||
fail(FailString("monster inventory sum", 10, invsum))
|
||||
}
|
||||
|
||||
if got := monster.Test4Length(); 2 != got {
|
||||
fail(FailString("monster.Test4Length()", 2, got))
|
||||
}
|
||||
|
||||
var test0 example.Test
|
||||
ok := monster.Test4(&test0, 0)
|
||||
if !ok {
|
||||
fail(FailString("monster.Test4(&test0, 0)", true, ok))
|
||||
}
|
||||
|
||||
var test1 example.Test
|
||||
ok = monster.Test4(&test1, 1)
|
||||
if !ok {
|
||||
fail(FailString("monster.Test4(&test1, 1)", true, ok))
|
||||
}
|
||||
|
||||
// the position of test0 and test1 are swapped in monsterdata_java_wire
|
||||
// and monsterdata_test_wire, so ignore ordering
|
||||
v0 := test0.A()
|
||||
v1 := test0.B()
|
||||
v2 := test1.A()
|
||||
v3 := test1.B()
|
||||
sum := int(v0) + int(v1) + int(v2) + int(v3)
|
||||
|
||||
if 100 != sum {
|
||||
fail(FailString("test0 and test1 sum", 100, sum))
|
||||
}
|
||||
|
||||
if got := monster.TestarrayofstringLength(); 2 != got {
|
||||
fail(FailString("Testarrayofstring length", 2, got))
|
||||
}
|
||||
|
||||
if got := monster.Testarrayofstring(0); !bytes.Equal([]byte("test1"), got) {
|
||||
fail(FailString("Testarrayofstring(0)", "test1", got))
|
||||
}
|
||||
|
||||
if got := monster.Testarrayofstring(1); !bytes.Equal([]byte("test2"), got) {
|
||||
fail(FailString("Testarrayofstring(1)", "test2", got))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1161,6 +1166,38 @@ func CheckGeneratedBuild(fail func(string, ...interface{})) ([]byte, flatbuffers
|
||||
return b.Bytes, b.Head()
|
||||
}
|
||||
|
||||
// CheckTableAccessors checks that the table accessors work as expected.
|
||||
func CheckTableAccessors(fail func(string, ...interface{})) {
|
||||
// test struct accessor
|
||||
b := flatbuffers.NewBuilder(0)
|
||||
pos := example.CreateVec3(b, 1.0, 2.0, 3.0, 3.0, 4, 5, 6)
|
||||
b.Finish(pos)
|
||||
vec3Bytes := b.FinishedBytes()
|
||||
vec3 := &example.Vec3{}
|
||||
flatbuffers.GetRootAs(vec3Bytes, 0, vec3)
|
||||
|
||||
if bytes.Compare(vec3Bytes, vec3.Table().Bytes) != 0 {
|
||||
fail("invalid vec3 table")
|
||||
}
|
||||
|
||||
// test table accessor
|
||||
b = flatbuffers.NewBuilder(0)
|
||||
str := b.CreateString("MyStat")
|
||||
example.StatStart(b)
|
||||
example.StatAddId(b, str)
|
||||
example.StatAddVal(b, 12345678)
|
||||
example.StatAddCount(b, 12345)
|
||||
pos = example.StatEnd(b)
|
||||
b.Finish(pos)
|
||||
statBytes := b.FinishedBytes()
|
||||
stat := &example.Stat{}
|
||||
flatbuffers.GetRootAs(statBytes, 0, stat)
|
||||
|
||||
if bytes.Compare(statBytes, stat.Table().Bytes) != 0 {
|
||||
fail("invalid stat table")
|
||||
}
|
||||
}
|
||||
|
||||
// CheckVtableDeduplication verifies that vtables are deduplicated.
|
||||
func CheckVtableDeduplication(fail func(string, ...interface{})) {
|
||||
b := flatbuffers.NewBuilder(0)
|
||||
|
||||
Binary file not shown.
@@ -61,7 +61,7 @@ table Monster {
|
||||
testhashs64_fnv1:long (id:18, hash:"fnv1_64");
|
||||
testhashu64_fnv1:ulong (id:19, hash:"fnv1_64");
|
||||
testhashs32_fnv1a:int (id:20, hash:"fnv1a_32");
|
||||
testhashu32_fnv1a:uint (id:21, hash:"fnv1a_32");
|
||||
testhashu32_fnv1a:uint (id:21, hash:"fnv1a_32", cpp_type:"Stat");
|
||||
testhashs64_fnv1a:long (id:22, hash:"fnv1a_64");
|
||||
testhashu64_fnv1a:ulong (id:23, hash:"fnv1a_64");
|
||||
testf:float = 3.14159 (id:25);
|
||||
@@ -71,7 +71,7 @@ table Monster {
|
||||
|
||||
rpc_service MonsterStorage {
|
||||
Store(Monster):Stat (streaming: "none");
|
||||
Retrieve(Stat):Monster (idempotent);
|
||||
Retrieve(Stat):Monster (streaming: "server", idempotent);
|
||||
}
|
||||
|
||||
root_type Monster;
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
#include "monster_test.grpc.fb.h"
|
||||
#include "flatbuffers/grpc.h"
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/channel_interface.h>
|
||||
@@ -29,7 +27,7 @@ std::unique_ptr< MonsterStorage::Stub> MonsterStorage::NewStub(const std::shared
|
||||
|
||||
MonsterStorage::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel)
|
||||
: channel_(channel) , rpcmethod_Store_(MonsterStorage_method_names[0], ::grpc::RpcMethod::NORMAL_RPC, channel)
|
||||
, rpcmethod_Retrieve_(MonsterStorage_method_names[1], ::grpc::RpcMethod::NORMAL_RPC, channel)
|
||||
, rpcmethod_Retrieve_(MonsterStorage_method_names[1], ::grpc::RpcMethod::SERVER_STREAMING, channel)
|
||||
{}
|
||||
|
||||
::grpc::Status MonsterStorage::Stub::Store(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, flatbuffers::BufferRef<Stat>* response) {
|
||||
@@ -40,12 +38,12 @@ MonsterStorage::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& cha
|
||||
return new ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>(channel_.get(), cq, rpcmethod_Store_, context, request);
|
||||
}
|
||||
|
||||
::grpc::Status MonsterStorage::Stub::Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, flatbuffers::BufferRef<Monster>* response) {
|
||||
return ::grpc::BlockingUnaryCall(channel_.get(), rpcmethod_Retrieve_, context, request, response);
|
||||
::grpc::ClientReader< flatbuffers::BufferRef<Monster>>* MonsterStorage::Stub::RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request) {
|
||||
return new ::grpc::ClientReader< flatbuffers::BufferRef<Monster>>(channel_.get(), rpcmethod_Retrieve_, context, request);
|
||||
}
|
||||
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>* MonsterStorage::Stub::AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) {
|
||||
return new ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>(channel_.get(), cq, rpcmethod_Retrieve_, context, request);
|
||||
::grpc::ClientAsyncReader< flatbuffers::BufferRef<Monster>>* MonsterStorage::Stub::AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
|
||||
return new ::grpc::ClientAsyncReader< flatbuffers::BufferRef<Monster>>(channel_.get(), cq, rpcmethod_Retrieve_, context, request, tag);
|
||||
}
|
||||
|
||||
MonsterStorage::Service::Service() {
|
||||
@@ -57,8 +55,8 @@ MonsterStorage::Service::Service() {
|
||||
std::mem_fn(&MonsterStorage::Service::Store), this)));
|
||||
AddMethod(new ::grpc::RpcServiceMethod(
|
||||
MonsterStorage_method_names[1],
|
||||
::grpc::RpcMethod::NORMAL_RPC,
|
||||
new ::grpc::RpcMethodHandler< MonsterStorage::Service, flatbuffers::BufferRef<Stat>, flatbuffers::BufferRef<Monster>>(
|
||||
::grpc::RpcMethod::SERVER_STREAMING,
|
||||
new ::grpc::ServerStreamingHandler< MonsterStorage::Service, flatbuffers::BufferRef<Stat>, flatbuffers::BufferRef<Monster>>(
|
||||
std::mem_fn(&MonsterStorage::Service::Retrieve), this)));
|
||||
}
|
||||
|
||||
@@ -72,10 +70,10 @@ MonsterStorage::Service::~Service() {
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
::grpc::Status MonsterStorage::Service::Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response) {
|
||||
::grpc::Status MonsterStorage::Service::Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, ::grpc::ServerWriter< flatbuffers::BufferRef<Monster>>* writer) {
|
||||
(void) context;
|
||||
(void) request;
|
||||
(void) response;
|
||||
(void) writer;
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
|
||||
@@ -5,10 +5,11 @@
|
||||
#define GRPC_monster_5ftest__INCLUDED
|
||||
|
||||
#include "monster_test_generated.h"
|
||||
#include "flatbuffers/grpc.h"
|
||||
|
||||
|
||||
#include <grpc++/impl/codegen/async_stream.h>
|
||||
#include <grpc++/impl/codegen/async_unary_call.h>
|
||||
#include <grpc++/impl/codegen/proto_utils.h>
|
||||
#include <grpc++/impl/codegen/rpc_method.h>
|
||||
#include <grpc++/impl/codegen/service_type.h>
|
||||
#include <grpc++/impl/codegen/status.h>
|
||||
@@ -35,13 +36,16 @@ class MonsterStorage GRPC_FINAL {
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Stat>>>(AsyncStoreRaw(context, request, cq));
|
||||
}
|
||||
virtual ::grpc::Status Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, flatbuffers::BufferRef<Monster>* response) = 0;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Monster>>>(AsyncRetrieveRaw(context, request, cq));
|
||||
std::unique_ptr< ::grpc::ClientReaderInterface< flatbuffers::BufferRef<Monster>>> Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request) {
|
||||
return std::unique_ptr< ::grpc::ClientReaderInterface< flatbuffers::BufferRef<Monster>>>(RetrieveRaw(context, request));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::BufferRef<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncReaderInterface< flatbuffers::BufferRef<Monster>>>(AsyncRetrieveRaw(context, request, cq, tag));
|
||||
}
|
||||
private:
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientAsyncResponseReaderInterface< flatbuffers::BufferRef<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) = 0;
|
||||
virtual ::grpc::ClientReaderInterface< flatbuffers::BufferRef<Monster>>* RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request) = 0;
|
||||
virtual ::grpc::ClientAsyncReaderInterface< flatbuffers::BufferRef<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) = 0;
|
||||
};
|
||||
class Stub GRPC_FINAL : public StubInterface {
|
||||
public:
|
||||
@@ -50,15 +54,18 @@ class MonsterStorage GRPC_FINAL {
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>> AsyncStore(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>>(AsyncStoreRaw(context, request, cq));
|
||||
}
|
||||
::grpc::Status Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, flatbuffers::BufferRef<Monster>* response) GRPC_OVERRIDE;
|
||||
std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>>(AsyncRetrieveRaw(context, request, cq));
|
||||
std::unique_ptr< ::grpc::ClientReader< flatbuffers::BufferRef<Monster>>> Retrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request) {
|
||||
return std::unique_ptr< ::grpc::ClientReader< flatbuffers::BufferRef<Monster>>>(RetrieveRaw(context, request));
|
||||
}
|
||||
std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::BufferRef<Monster>>> AsyncRetrieve(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) {
|
||||
return std::unique_ptr< ::grpc::ClientAsyncReader< flatbuffers::BufferRef<Monster>>>(AsyncRetrieveRaw(context, request, cq, tag));
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr< ::grpc::ChannelInterface> channel_;
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Stat>>* AsyncStoreRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Monster>& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
|
||||
::grpc::ClientAsyncResponseReader< flatbuffers::BufferRef<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq) GRPC_OVERRIDE;
|
||||
::grpc::ClientReader< flatbuffers::BufferRef<Monster>>* RetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request) GRPC_OVERRIDE;
|
||||
::grpc::ClientAsyncReader< flatbuffers::BufferRef<Monster>>* AsyncRetrieveRaw(::grpc::ClientContext* context, const flatbuffers::BufferRef<Stat>& request, ::grpc::CompletionQueue* cq, void* tag) GRPC_OVERRIDE;
|
||||
const ::grpc::RpcMethod rpcmethod_Store_;
|
||||
const ::grpc::RpcMethod rpcmethod_Retrieve_;
|
||||
};
|
||||
@@ -69,7 +76,7 @@ class MonsterStorage GRPC_FINAL {
|
||||
Service();
|
||||
virtual ~Service();
|
||||
virtual ::grpc::Status Store(::grpc::ServerContext* context, const flatbuffers::BufferRef<Monster>* request, flatbuffers::BufferRef<Stat>* response);
|
||||
virtual ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response);
|
||||
virtual ::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, ::grpc::ServerWriter< flatbuffers::BufferRef<Monster>>* writer);
|
||||
};
|
||||
template <class BaseClass>
|
||||
class WithAsyncMethod_Store : public BaseClass {
|
||||
@@ -103,12 +110,12 @@ class MonsterStorage GRPC_FINAL {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, ::grpc::ServerWriter< flatbuffers::BufferRef<Monster>>* writer) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
void RequestRetrieve(::grpc::ServerContext* context, flatbuffers::BufferRef<Stat>* request, ::grpc::ServerAsyncResponseWriter< flatbuffers::BufferRef<Monster>>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
|
||||
::grpc::Service::RequestAsyncUnary(1, context, request, response, new_call_cq, notification_cq, tag);
|
||||
void RequestRetrieve(::grpc::ServerContext* context, flatbuffers::BufferRef<Stat>* request, ::grpc::ServerAsyncWriter< flatbuffers::BufferRef<Monster>>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
|
||||
::grpc::Service::RequestAsyncServerStreaming(1, context, request, writer, new_call_cq, notification_cq, tag);
|
||||
}
|
||||
};
|
||||
typedef WithAsyncMethod_Store< WithAsyncMethod_Retrieve< Service > > AsyncService;
|
||||
@@ -141,7 +148,7 @@ class MonsterStorage GRPC_FINAL {
|
||||
BaseClassMustBeDerivedFromService(this);
|
||||
}
|
||||
// disable synchronous version of this method
|
||||
::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, flatbuffers::BufferRef<Monster>* response) GRPC_FINAL GRPC_OVERRIDE {
|
||||
::grpc::Status Retrieve(::grpc::ServerContext* context, const flatbuffers::BufferRef<Stat>* request, ::grpc::ServerWriter< flatbuffers::BufferRef<Monster>>* writer) GRPC_FINAL GRPC_OVERRIDE {
|
||||
abort();
|
||||
return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
|
||||
}
|
||||
|
||||
@@ -52,6 +52,29 @@ enum Any {
|
||||
Any_MAX = Any_MyGame_Example2_Monster
|
||||
};
|
||||
|
||||
inline const char **EnumNamesAny() {
|
||||
static const char *names[] = { "NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameAny(Any e) { return EnumNamesAny()[static_cast<int>(e)]; }
|
||||
|
||||
template<typename T> struct AnyTraits {
|
||||
static const Any enum_value = Any_NONE;
|
||||
};
|
||||
|
||||
template<> struct AnyTraits<Monster> {
|
||||
static const Any enum_value = Any_Monster;
|
||||
};
|
||||
|
||||
template<> struct AnyTraits<TestSimpleTableWithEnum> {
|
||||
static const Any enum_value = Any_TestSimpleTableWithEnum;
|
||||
};
|
||||
|
||||
template<> struct AnyTraits<MyGame::Example2::Monster> {
|
||||
static const Any enum_value = Any_MyGame_Example2_Monster;
|
||||
};
|
||||
|
||||
struct AnyUnion {
|
||||
Any type;
|
||||
|
||||
@@ -59,23 +82,26 @@ struct AnyUnion {
|
||||
AnyUnion() : type(Any_NONE), table(nullptr) {}
|
||||
AnyUnion(const AnyUnion &);
|
||||
AnyUnion &operator=(const AnyUnion &);
|
||||
~AnyUnion();
|
||||
~AnyUnion() { Reset(); }
|
||||
void Reset();
|
||||
|
||||
static flatbuffers::NativeTable *UnPack(const void *union_obj, Any type);
|
||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb) const;
|
||||
template <typename T>
|
||||
void Set(T&& value) {
|
||||
Reset();
|
||||
type = AnyTraits<typename T::TableType>::enum_value;
|
||||
if (type != Any_NONE) {
|
||||
table = new T(std::forward<T>(value));
|
||||
}
|
||||
}
|
||||
|
||||
static flatbuffers::NativeTable *UnPack(const void *union_obj, Any type, const flatbuffers::resolver_function_t *resolver);
|
||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *rehasher = nullptr) const;
|
||||
|
||||
MonsterT *AsMonster() { return type == Any_Monster ? reinterpret_cast<MonsterT *>(table) : nullptr; }
|
||||
TestSimpleTableWithEnumT *AsTestSimpleTableWithEnum() { return type == Any_TestSimpleTableWithEnum ? reinterpret_cast<TestSimpleTableWithEnumT *>(table) : nullptr; }
|
||||
MyGame::Example2::MonsterT *AsMyGame_Example2_Monster() { return type == Any_MyGame_Example2_Monster ? reinterpret_cast<MyGame::Example2::MonsterT *>(table) : nullptr; }
|
||||
};
|
||||
|
||||
inline const char **EnumNamesAny() {
|
||||
static const char *names[] = { "NONE", "Monster", "TestSimpleTableWithEnum", "MyGame_Example2_Monster", nullptr };
|
||||
return names;
|
||||
}
|
||||
|
||||
inline const char *EnumNameAny(Any e) { return EnumNamesAny()[static_cast<int>(e)]; }
|
||||
|
||||
inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, Any type);
|
||||
|
||||
MANUALLY_ALIGNED_STRUCT(2) Test FLATBUFFERS_FINAL_CLASS {
|
||||
@@ -135,14 +161,18 @@ STRUCT_END(Vec3, 32);
|
||||
namespace Example2 {
|
||||
|
||||
struct MonsterT : public flatbuffers::NativeTable {
|
||||
typedef Monster TableType;
|
||||
MonsterT() {}
|
||||
};
|
||||
|
||||
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef MonsterT NativeTableType;
|
||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
std::unique_ptr<MonsterT> UnPack() const;
|
||||
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct MonsterBuilder {
|
||||
@@ -161,17 +191,21 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o);
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
|
||||
} // namespace Example2
|
||||
|
||||
namespace Example {
|
||||
|
||||
struct TestSimpleTableWithEnumT : public flatbuffers::NativeTable {
|
||||
typedef TestSimpleTableWithEnum TableType;
|
||||
Color color;
|
||||
TestSimpleTableWithEnumT()
|
||||
: color(Color_Green) {}
|
||||
};
|
||||
|
||||
struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef TestSimpleTableWithEnumT NativeTableType;
|
||||
enum {
|
||||
VT_COLOR = 4
|
||||
};
|
||||
@@ -182,7 +216,8 @@ struct TestSimpleTableWithEnum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Ta
|
||||
VerifyField<int8_t>(verifier, VT_COLOR) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
std::unique_ptr<TestSimpleTableWithEnumT> UnPack() const;
|
||||
TestSimpleTableWithEnumT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
static flatbuffers::Offset<TestSimpleTableWithEnum> Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct TestSimpleTableWithEnumBuilder {
|
||||
@@ -204,15 +239,20 @@ inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnu
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o);
|
||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
|
||||
struct StatT : public flatbuffers::NativeTable {
|
||||
typedef Stat TableType;
|
||||
std::string id;
|
||||
int64_t val;
|
||||
uint16_t count;
|
||||
StatT()
|
||||
: val(0),
|
||||
count(0) {}
|
||||
};
|
||||
|
||||
struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef StatT NativeTableType;
|
||||
enum {
|
||||
VT_ID = 4,
|
||||
VT_VAL = 6,
|
||||
@@ -232,7 +272,8 @@ struct Stat FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
VerifyField<uint16_t>(verifier, VT_COUNT) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
std::unique_ptr<StatT> UnPack() const;
|
||||
StatT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Stat> Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct StatBuilder {
|
||||
@@ -267,9 +308,10 @@ inline flatbuffers::Offset<Stat> CreateStatDirect(flatbuffers::FlatBufferBuilder
|
||||
return CreateStat(_fbb, id ? _fbb.CreateString(id) : 0, val, count);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o);
|
||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
|
||||
struct MonsterT : public flatbuffers::NativeTable {
|
||||
typedef Monster TableType;
|
||||
std::unique_ptr<Vec3> pos;
|
||||
int16_t mana;
|
||||
int16_t hp;
|
||||
@@ -289,7 +331,7 @@ struct MonsterT : public flatbuffers::NativeTable {
|
||||
int64_t testhashs64_fnv1;
|
||||
uint64_t testhashu64_fnv1;
|
||||
int32_t testhashs32_fnv1a;
|
||||
uint32_t testhashu32_fnv1a;
|
||||
Stat *testhashu32_fnv1a;
|
||||
int64_t testhashs64_fnv1a;
|
||||
uint64_t testhashu64_fnv1a;
|
||||
std::vector<bool> testarrayofbools;
|
||||
@@ -297,10 +339,27 @@ struct MonsterT : public flatbuffers::NativeTable {
|
||||
float testf2;
|
||||
float testf3;
|
||||
std::vector<std::string> testarrayofstring2;
|
||||
MonsterT()
|
||||
: mana(150),
|
||||
hp(100),
|
||||
color(Color_Blue),
|
||||
testbool(false),
|
||||
testhashs32_fnv1(0),
|
||||
testhashu32_fnv1(0),
|
||||
testhashs64_fnv1(0),
|
||||
testhashu64_fnv1(0),
|
||||
testhashs32_fnv1a(0),
|
||||
testhashu32_fnv1a(0),
|
||||
testhashs64_fnv1a(0),
|
||||
testhashu64_fnv1a(0),
|
||||
testf(3.14159f),
|
||||
testf2(3.0f),
|
||||
testf3(0.0f) {}
|
||||
};
|
||||
|
||||
/// an example documentation comment: monster object
|
||||
struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
typedef MonsterT NativeTableType;
|
||||
enum {
|
||||
VT_POS = 4,
|
||||
VT_MANA = 6,
|
||||
@@ -438,7 +497,8 @@ struct Monster FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||
verifier.VerifyVectorOfStrings(testarrayofstring2()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
std::unique_ptr<MonsterT> UnPack() const;
|
||||
MonsterT *UnPack(const flatbuffers::resolver_function_t *resolver = nullptr) const;
|
||||
static flatbuffers::Offset<Monster> Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr);
|
||||
};
|
||||
|
||||
struct MonsterBuilder {
|
||||
@@ -574,18 +634,24 @@ inline flatbuffers::Offset<Monster> CreateMonsterDirect(flatbuffers::FlatBufferB
|
||||
return CreateMonster(_fbb, pos, mana, hp, name ? _fbb.CreateString(name) : 0, inventory ? _fbb.CreateVector<uint8_t>(*inventory) : 0, color, test_type, test, test4 ? _fbb.CreateVector<const Test *>(*test4) : 0, testarrayofstring ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring) : 0, testarrayoftables ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(*testarrayoftables) : 0, enemy, testnestedflatbuffer ? _fbb.CreateVector<uint8_t>(*testnestedflatbuffer) : 0, testempty, testbool, testhashs32_fnv1, testhashu32_fnv1, testhashs64_fnv1, testhashu64_fnv1, testhashs32_fnv1a, testhashu32_fnv1a, testhashs64_fnv1a, testhashu64_fnv1a, testarrayofbools ? _fbb.CreateVector<uint8_t>(*testarrayofbools) : 0, testf, testf2, testf3, testarrayofstring2 ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*testarrayofstring2) : 0);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o);
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher = nullptr);
|
||||
|
||||
} // namespace Example
|
||||
|
||||
namespace Example2 {
|
||||
|
||||
inline std::unique_ptr<MonsterT> Monster::UnPack() const {
|
||||
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
auto _o = new MonsterT();
|
||||
return std::unique_ptr<MonsterT>(_o);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o) {
|
||||
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateMonster(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
(void)_o;
|
||||
return CreateMonster(_fbb);
|
||||
}
|
||||
@@ -594,33 +660,46 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
|
||||
namespace Example {
|
||||
|
||||
inline std::unique_ptr<TestSimpleTableWithEnumT> TestSimpleTableWithEnum::UnPack() const {
|
||||
inline TestSimpleTableWithEnumT *TestSimpleTableWithEnum::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
auto _o = new TestSimpleTableWithEnumT();
|
||||
{ auto _e = color(); _o->color = _e; };
|
||||
return std::unique_ptr<TestSimpleTableWithEnumT>(_o);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o) {
|
||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pack(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateTestSimpleTableWithEnum(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateTestSimpleTableWithEnum(_fbb,
|
||||
_o->color);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<StatT> Stat::UnPack() const {
|
||||
inline StatT *Stat::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
auto _o = new StatT();
|
||||
{ auto _e = id(); if (_e) _o->id = _e->str(); };
|
||||
{ auto _e = val(); _o->val = _e; };
|
||||
{ auto _e = count(); _o->count = _e; };
|
||||
return std::unique_ptr<StatT>(_o);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o) {
|
||||
inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb, const StatT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateStat(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateStat(_fbb,
|
||||
_o->id.size() ? _fbb.CreateString(_o->id) : 0,
|
||||
_o->val,
|
||||
_o->count);
|
||||
}
|
||||
|
||||
inline std::unique_ptr<MonsterT> Monster::UnPack() const {
|
||||
inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *resolver) const {
|
||||
(void)resolver;
|
||||
auto _o = new MonsterT();
|
||||
{ auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); };
|
||||
{ auto _e = mana(); _o->mana = _e; };
|
||||
@@ -629,20 +708,20 @@ inline std::unique_ptr<MonsterT> Monster::UnPack() const {
|
||||
{ auto _e = inventory(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory.push_back(_e->Get(_i)); } } };
|
||||
{ auto _e = color(); _o->color = _e; };
|
||||
{ auto _e = test_type(); _o->test.type = _e; };
|
||||
{ auto _e = test(); if (_e) _o->test.table = AnyUnion::UnPack(_e, test_type()); };
|
||||
{ auto _e = test(); if (_e) _o->test.table = AnyUnion::UnPack(_e, test_type(), resolver); };
|
||||
{ auto _e = test4(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4.push_back(*_e->Get(_i)); } } };
|
||||
{ auto _e = testarrayofstring(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring.push_back(_e->Get(_i)->str()); } } };
|
||||
{ auto _e = testarrayoftables(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables.push_back(_e->Get(_i)->UnPack()); } } };
|
||||
{ auto _e = enemy(); if (_e) _o->enemy = _e->UnPack(); };
|
||||
{ auto _e = testarrayoftables(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables.push_back(std::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(resolver))); } } };
|
||||
{ auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MonsterT>(_e->UnPack(resolver)); };
|
||||
{ auto _e = testnestedflatbuffer(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer.push_back(_e->Get(_i)); } } };
|
||||
{ auto _e = testempty(); if (_e) _o->testempty = _e->UnPack(); };
|
||||
{ auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<StatT>(_e->UnPack(resolver)); };
|
||||
{ auto _e = testbool(); _o->testbool = _e; };
|
||||
{ auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
|
||||
{ auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
|
||||
{ auto _e = testhashs64_fnv1(); _o->testhashs64_fnv1 = _e; };
|
||||
{ auto _e = testhashu64_fnv1(); _o->testhashu64_fnv1 = _e; };
|
||||
{ auto _e = testhashs32_fnv1a(); _o->testhashs32_fnv1a = _e; };
|
||||
{ auto _e = testhashu32_fnv1a(); _o->testhashu32_fnv1a = _e; };
|
||||
{ auto _e = testhashu32_fnv1a(); if (resolver) (*resolver)(reinterpret_cast<void **>(&_o->testhashu32_fnv1a), static_cast<flatbuffers::hash_value_t>(_e)); else _o->testhashu32_fnv1a = nullptr; };
|
||||
{ auto _e = testhashs64_fnv1a(); _o->testhashs64_fnv1a = _e; };
|
||||
{ auto _e = testhashu64_fnv1a(); _o->testhashu64_fnv1a = _e; };
|
||||
{ auto _e = testarrayofbools(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofbools.push_back(_e->Get(_i)!=0); } } };
|
||||
@@ -650,10 +729,15 @@ inline std::unique_ptr<MonsterT> Monster::UnPack() const {
|
||||
{ auto _e = testf2(); _o->testf2 = _e; };
|
||||
{ auto _e = testf3(); _o->testf3 = _e; };
|
||||
{ auto _e = testarrayofstring2(); if (_e) { for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring2.push_back(_e->Get(_i)->str()); } } };
|
||||
return std::unique_ptr<MonsterT>(_o);
|
||||
return _o;
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o) {
|
||||
inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT* _o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||
return CreateMonster(_fbb, _o, _rehasher);
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *rehasher) {
|
||||
(void)rehasher;
|
||||
return CreateMonster(_fbb,
|
||||
_o->pos ? _o->pos.get() : 0,
|
||||
_o->mana,
|
||||
@@ -665,17 +749,17 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
||||
_o->test.Pack(_fbb),
|
||||
_o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0,
|
||||
_o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0,
|
||||
_o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(_o->testarrayoftables.size(), [&](size_t i) { return CreateMonster(_fbb, _o->testarrayoftables[i].get()); }) : 0,
|
||||
_o->enemy ? CreateMonster(_fbb, _o->enemy.get()) : 0,
|
||||
_o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(_o->testarrayoftables.size(), [&](size_t i) { return CreateMonster(_fbb, _o->testarrayoftables[i].get(), rehasher); }) : 0,
|
||||
_o->enemy ? CreateMonster(_fbb, _o->enemy.get(), rehasher) : 0,
|
||||
_o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0,
|
||||
_o->testempty ? CreateStat(_fbb, _o->testempty.get()) : 0,
|
||||
_o->testempty ? CreateStat(_fbb, _o->testempty.get(), rehasher) : 0,
|
||||
_o->testbool,
|
||||
_o->testhashs32_fnv1,
|
||||
_o->testhashu32_fnv1,
|
||||
_o->testhashs64_fnv1,
|
||||
_o->testhashu64_fnv1,
|
||||
_o->testhashs32_fnv1a,
|
||||
_o->testhashu32_fnv1a,
|
||||
rehasher ? static_cast<uint32_t>((*rehasher)(_o->testhashu32_fnv1a)) : 0,
|
||||
_o->testhashs64_fnv1a,
|
||||
_o->testhashu64_fnv1a,
|
||||
_o->testarrayofbools.size() ? _fbb.CreateVector(_o->testarrayofbools) : 0,
|
||||
@@ -695,48 +779,66 @@ inline bool VerifyAny(flatbuffers::Verifier &verifier, const void *union_obj, An
|
||||
}
|
||||
}
|
||||
|
||||
inline flatbuffers::NativeTable *AnyUnion::UnPack(const void *union_obj, Any type) {
|
||||
inline flatbuffers::NativeTable *AnyUnion::UnPack(const void *union_obj, Any type, const flatbuffers::resolver_function_t *resolver) {
|
||||
switch (type) {
|
||||
case Any_NONE: return nullptr;
|
||||
case Any_Monster: return reinterpret_cast<const Monster *>(union_obj)->UnPack().release();
|
||||
case Any_TestSimpleTableWithEnum: return reinterpret_cast<const TestSimpleTableWithEnum *>(union_obj)->UnPack().release();
|
||||
case Any_MyGame_Example2_Monster: return reinterpret_cast<const MyGame::Example2::Monster *>(union_obj)->UnPack().release();
|
||||
case Any_Monster: return reinterpret_cast<const Monster *>(union_obj)->UnPack(resolver);
|
||||
case Any_TestSimpleTableWithEnum: return reinterpret_cast<const TestSimpleTableWithEnum *>(union_obj)->UnPack(resolver);
|
||||
case Any_MyGame_Example2_Monster: return reinterpret_cast<const MyGame::Example2::Monster *>(union_obj)->UnPack(resolver);
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb) const {
|
||||
inline flatbuffers::Offset<void> AnyUnion::Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *rehasher) const {
|
||||
switch (type) {
|
||||
case Any_NONE: return 0;
|
||||
case Any_Monster: return CreateMonster(_fbb, reinterpret_cast<const MonsterT *>(table)).Union();
|
||||
case Any_TestSimpleTableWithEnum: return CreateTestSimpleTableWithEnum(_fbb, reinterpret_cast<const TestSimpleTableWithEnumT *>(table)).Union();
|
||||
case Any_MyGame_Example2_Monster: return CreateMonster(_fbb, reinterpret_cast<const MyGame::Example2::MonsterT *>(table)).Union();
|
||||
case Any_Monster: return CreateMonster(_fbb, reinterpret_cast<const MonsterT *>(table), rehasher).Union();
|
||||
case Any_TestSimpleTableWithEnum: return CreateTestSimpleTableWithEnum(_fbb, reinterpret_cast<const TestSimpleTableWithEnumT *>(table), rehasher).Union();
|
||||
case Any_MyGame_Example2_Monster: return CreateMonster(_fbb, reinterpret_cast<const MyGame::Example2::MonsterT *>(table), rehasher).Union();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline AnyUnion::~AnyUnion() {
|
||||
inline void AnyUnion::Reset() {
|
||||
switch (type) {
|
||||
case Any_Monster: delete reinterpret_cast<MonsterT *>(table); break;
|
||||
case Any_TestSimpleTableWithEnum: delete reinterpret_cast<TestSimpleTableWithEnumT *>(table); break;
|
||||
case Any_MyGame_Example2_Monster: delete reinterpret_cast<MyGame::Example2::MonsterT *>(table); break;
|
||||
default:;
|
||||
default: break;
|
||||
}
|
||||
table = nullptr;
|
||||
type = Any_NONE;
|
||||
}
|
||||
|
||||
inline const MyGame::Example::Monster *GetMonster(const void *buf) { return flatbuffers::GetRoot<MyGame::Example::Monster>(buf); }
|
||||
inline const MyGame::Example::Monster *GetMonster(const void *buf) {
|
||||
return flatbuffers::GetRoot<MyGame::Example::Monster>(buf);
|
||||
}
|
||||
|
||||
inline Monster *GetMutableMonster(void *buf) { return flatbuffers::GetMutableRoot<Monster>(buf); }
|
||||
inline Monster *GetMutableMonster(void *buf) {
|
||||
return flatbuffers::GetMutableRoot<Monster>(buf);
|
||||
}
|
||||
|
||||
inline const char *MonsterIdentifier() { return "MONS"; }
|
||||
inline const char *MonsterIdentifier() {
|
||||
return "MONS";
|
||||
}
|
||||
|
||||
inline bool MonsterBufferHasIdentifier(const void *buf) { return flatbuffers::BufferHasIdentifier(buf, MonsterIdentifier()); }
|
||||
inline bool MonsterBufferHasIdentifier(const void *buf) {
|
||||
return flatbuffers::BufferHasIdentifier(buf, MonsterIdentifier());
|
||||
}
|
||||
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) { return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier()); }
|
||||
inline bool VerifyMonsterBuffer(flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<MyGame::Example::Monster>(MonsterIdentifier());
|
||||
}
|
||||
|
||||
inline const char *MonsterExtension() { return "mon"; }
|
||||
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Example::Monster> root) { fbb.Finish(root, MonsterIdentifier()); }
|
||||
inline void FinishMonsterBuffer(flatbuffers::FlatBufferBuilder &fbb, flatbuffers::Offset<MyGame::Example::Monster> root) {
|
||||
fbb.Finish(root, MonsterIdentifier());
|
||||
}
|
||||
|
||||
inline std::unique_ptr<MonsterT> UnPackMonster(const void *buf, const flatbuffers::resolver_function_t *resolver = nullptr) {
|
||||
return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(resolver));
|
||||
}
|
||||
|
||||
} // namespace Example
|
||||
} // namespace MyGame
|
||||
|
||||
@@ -132,7 +132,7 @@ MyGame.Example.Test.prototype.a = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Test.prototype.mutate_a = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 0)
|
||||
var offset = this.bb.__offset(this.bb_pos, 0);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -140,7 +140,7 @@ MyGame.Example.Test.prototype.mutate_a = function(value) {
|
||||
|
||||
this.bb.writeInt16(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -154,7 +154,7 @@ MyGame.Example.Test.prototype.b = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Test.prototype.mutate_b = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 2)
|
||||
var offset = this.bb.__offset(this.bb_pos, 2);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -162,7 +162,7 @@ MyGame.Example.Test.prototype.mutate_b = function(value) {
|
||||
|
||||
this.bb.writeInt8(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
@@ -226,7 +226,7 @@ MyGame.Example.TestSimpleTableWithEnum.prototype.color = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.TestSimpleTableWithEnum.prototype.mutate_color = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 4)
|
||||
var offset = this.bb.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -234,7 +234,7 @@ MyGame.Example.TestSimpleTableWithEnum.prototype.mutate_color = function(value)
|
||||
|
||||
this.bb.writeInt8(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
@@ -298,7 +298,7 @@ MyGame.Example.Vec3.prototype.x = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Vec3.prototype.mutate_x = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 0)
|
||||
var offset = this.bb.__offset(this.bb_pos, 0);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -306,7 +306,7 @@ MyGame.Example.Vec3.prototype.mutate_x = function(value) {
|
||||
|
||||
this.bb.writeFloat32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -320,7 +320,7 @@ MyGame.Example.Vec3.prototype.y = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Vec3.prototype.mutate_y = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 4)
|
||||
var offset = this.bb.__offset(this.bb_pos, 4);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -328,7 +328,7 @@ MyGame.Example.Vec3.prototype.mutate_y = function(value) {
|
||||
|
||||
this.bb.writeFloat32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -342,7 +342,7 @@ MyGame.Example.Vec3.prototype.z = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Vec3.prototype.mutate_z = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 8)
|
||||
var offset = this.bb.__offset(this.bb_pos, 8);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -350,7 +350,7 @@ MyGame.Example.Vec3.prototype.mutate_z = function(value) {
|
||||
|
||||
this.bb.writeFloat32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -364,7 +364,7 @@ MyGame.Example.Vec3.prototype.test1 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Vec3.prototype.mutate_test1 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 16)
|
||||
var offset = this.bb.__offset(this.bb_pos, 16);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -372,7 +372,7 @@ MyGame.Example.Vec3.prototype.mutate_test1 = function(value) {
|
||||
|
||||
this.bb.writeFloat64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {MyGame.Example.Color}
|
||||
@@ -386,7 +386,7 @@ MyGame.Example.Vec3.prototype.test2 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Vec3.prototype.mutate_test2 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 24)
|
||||
var offset = this.bb.__offset(this.bb_pos, 24);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -394,7 +394,7 @@ MyGame.Example.Vec3.prototype.mutate_test2 = function(value) {
|
||||
|
||||
this.bb.writeInt8(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {MyGame.Example.Test=} obj
|
||||
@@ -489,7 +489,7 @@ MyGame.Example.Stat.prototype.val = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Stat.prototype.mutate_val = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 6)
|
||||
var offset = this.bb.__offset(this.bb_pos, 6);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -497,7 +497,7 @@ MyGame.Example.Stat.prototype.mutate_val = function(value) {
|
||||
|
||||
this.bb.writeInt64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -512,7 +512,7 @@ MyGame.Example.Stat.prototype.count = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Stat.prototype.mutate_count = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 8)
|
||||
var offset = this.bb.__offset(this.bb_pos, 8);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -520,7 +520,7 @@ MyGame.Example.Stat.prototype.mutate_count = function(value) {
|
||||
|
||||
this.bb.writeUint16(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Builder} builder
|
||||
@@ -629,7 +629,7 @@ MyGame.Example.Monster.prototype.mana = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_mana = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 6)
|
||||
var offset = this.bb.__offset(this.bb_pos, 6);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -637,7 +637,7 @@ MyGame.Example.Monster.prototype.mutate_mana = function(value) {
|
||||
|
||||
this.bb.writeInt16(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -652,7 +652,7 @@ MyGame.Example.Monster.prototype.hp = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_hp = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 8)
|
||||
var offset = this.bb.__offset(this.bb_pos, 8);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -660,7 +660,7 @@ MyGame.Example.Monster.prototype.mutate_hp = function(value) {
|
||||
|
||||
this.bb.writeInt16(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Encoding=} optionalEncoding
|
||||
@@ -693,7 +693,7 @@ MyGame.Example.Monster.prototype.inventoryLength = function() {
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.inventoryArray = function() {
|
||||
var offset = this.bb.__offset(this.bb_pos, 14);
|
||||
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -709,7 +709,7 @@ MyGame.Example.Monster.prototype.color = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_color = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 16)
|
||||
var offset = this.bb.__offset(this.bb_pos, 16);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -717,7 +717,7 @@ MyGame.Example.Monster.prototype.mutate_color = function(value) {
|
||||
|
||||
this.bb.writeInt8(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {MyGame.Example.Any}
|
||||
@@ -732,7 +732,7 @@ MyGame.Example.Monster.prototype.testType = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_test_type = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 18)
|
||||
var offset = this.bb.__offset(this.bb_pos, 18);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -740,7 +740,7 @@ MyGame.Example.Monster.prototype.mutate_test_type = function(value) {
|
||||
|
||||
this.bb.writeUint8(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {flatbuffers.Table} obj
|
||||
@@ -839,7 +839,7 @@ MyGame.Example.Monster.prototype.testnestedflatbufferLength = function() {
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.testnestedflatbufferArray = function() {
|
||||
var offset = this.bb.__offset(this.bb_pos, 30);
|
||||
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
return offset ? new Uint8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -864,7 +864,7 @@ MyGame.Example.Monster.prototype.testbool = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testbool = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 34)
|
||||
var offset = this.bb.__offset(this.bb_pos, 34);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -872,7 +872,7 @@ MyGame.Example.Monster.prototype.mutate_testbool = function(value) {
|
||||
|
||||
this.bb.writeInt8(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -887,7 +887,7 @@ MyGame.Example.Monster.prototype.testhashs32Fnv1 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 36)
|
||||
var offset = this.bb.__offset(this.bb_pos, 36);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -895,7 +895,7 @@ MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1 = function(value) {
|
||||
|
||||
this.bb.writeInt32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -910,7 +910,7 @@ MyGame.Example.Monster.prototype.testhashu32Fnv1 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 38)
|
||||
var offset = this.bb.__offset(this.bb_pos, 38);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -918,7 +918,7 @@ MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1 = function(value) {
|
||||
|
||||
this.bb.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {flatbuffers.Long}
|
||||
@@ -933,7 +933,7 @@ MyGame.Example.Monster.prototype.testhashs64Fnv1 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 40)
|
||||
var offset = this.bb.__offset(this.bb_pos, 40);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -941,7 +941,7 @@ MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1 = function(value) {
|
||||
|
||||
this.bb.writeInt64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {flatbuffers.Long}
|
||||
@@ -956,7 +956,7 @@ MyGame.Example.Monster.prototype.testhashu64Fnv1 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 42)
|
||||
var offset = this.bb.__offset(this.bb_pos, 42);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -964,7 +964,7 @@ MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1 = function(value) {
|
||||
|
||||
this.bb.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -979,7 +979,7 @@ MyGame.Example.Monster.prototype.testhashs32Fnv1a = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1a = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 44)
|
||||
var offset = this.bb.__offset(this.bb_pos, 44);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -987,7 +987,7 @@ MyGame.Example.Monster.prototype.mutate_testhashs32_fnv1a = function(value) {
|
||||
|
||||
this.bb.writeInt32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -1002,7 +1002,7 @@ MyGame.Example.Monster.prototype.testhashu32Fnv1a = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1a = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 46)
|
||||
var offset = this.bb.__offset(this.bb_pos, 46);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -1010,7 +1010,7 @@ MyGame.Example.Monster.prototype.mutate_testhashu32_fnv1a = function(value) {
|
||||
|
||||
this.bb.writeUint32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {flatbuffers.Long}
|
||||
@@ -1025,7 +1025,7 @@ MyGame.Example.Monster.prototype.testhashs64Fnv1a = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1a = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 48)
|
||||
var offset = this.bb.__offset(this.bb_pos, 48);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -1033,7 +1033,7 @@ MyGame.Example.Monster.prototype.mutate_testhashs64_fnv1a = function(value) {
|
||||
|
||||
this.bb.writeInt64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {flatbuffers.Long}
|
||||
@@ -1048,7 +1048,7 @@ MyGame.Example.Monster.prototype.testhashu64Fnv1a = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1a = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 50)
|
||||
var offset = this.bb.__offset(this.bb_pos, 50);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -1056,7 +1056,7 @@ MyGame.Example.Monster.prototype.mutate_testhashu64_fnv1a = function(value) {
|
||||
|
||||
this.bb.writeUint64(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
@@ -1080,7 +1080,7 @@ MyGame.Example.Monster.prototype.testarrayofboolsLength = function() {
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.testarrayofboolsArray = function() {
|
||||
var offset = this.bb.__offset(this.bb_pos, 52);
|
||||
return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
return offset ? new Int8Array(this.bb.bytes().buffer, this.bb.bytes().byteOffset + this.bb.__vector(this.bb_pos + offset), this.bb.__vector_len(this.bb_pos + offset)) : null;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -1096,7 +1096,7 @@ MyGame.Example.Monster.prototype.testf = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testf = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 54)
|
||||
var offset = this.bb.__offset(this.bb_pos, 54);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -1104,7 +1104,7 @@ MyGame.Example.Monster.prototype.mutate_testf = function(value) {
|
||||
|
||||
this.bb.writeFloat32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -1119,7 +1119,7 @@ MyGame.Example.Monster.prototype.testf2 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testf2 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 56)
|
||||
var offset = this.bb.__offset(this.bb_pos, 56);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -1127,7 +1127,7 @@ MyGame.Example.Monster.prototype.mutate_testf2 = function(value) {
|
||||
|
||||
this.bb.writeFloat32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
@@ -1142,7 +1142,7 @@ MyGame.Example.Monster.prototype.testf3 = function() {
|
||||
* @returns {boolean}
|
||||
*/
|
||||
MyGame.Example.Monster.prototype.mutate_testf3 = function(value) {
|
||||
var offset = this.bb.__offset(this.bb_pos, 58)
|
||||
var offset = this.bb.__offset(this.bb_pos, 58);
|
||||
|
||||
if (offset === 0) {
|
||||
return false;
|
||||
@@ -1150,7 +1150,7 @@ MyGame.Example.Monster.prototype.mutate_testf3 = function(value) {
|
||||
|
||||
this.bb.writeFloat32(this.bb_pos + offset, value);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} index
|
||||
|
||||
@@ -6,13 +6,17 @@ namespace NamespaceA.NamespaceB
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class StructInNestedNS : Struct {
|
||||
public StructInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public struct StructInNestedNS : IFlatbufferObject
|
||||
{
|
||||
private Struct __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public int A { get { return bb.GetInt(bb_pos + 0); } }
|
||||
public void MutateA(int a) { bb.PutInt(bb_pos + 0, a); }
|
||||
public int B { get { return bb.GetInt(bb_pos + 4); } }
|
||||
public void MutateB(int b) { bb.PutInt(bb_pos + 4, b); }
|
||||
public int A { get { return __p.bb.GetInt(__p.bb_pos + 0); } }
|
||||
public void MutateA(int a) { __p.bb.PutInt(__p.bb_pos + 0, a); }
|
||||
public int B { get { return __p.bb.GetInt(__p.bb_pos + 4); } }
|
||||
public void MutateB(int b) { __p.bb.PutInt(__p.bb_pos + 4, b); }
|
||||
|
||||
public static Offset<StructInNestedNS> CreateStructInNestedNS(FlatBufferBuilder builder, int A, int B) {
|
||||
builder.Prep(4, 8);
|
||||
|
||||
@@ -15,6 +15,10 @@ func (rcv *StructInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *StructInNestedNS) Table() flatbuffers.Table {
|
||||
return rcv._tab.Table
|
||||
}
|
||||
|
||||
func (rcv *StructInNestedNS) A() int32 {
|
||||
return rcv._tab.GetInt32(rcv._tab.Pos + flatbuffers.UOffsetT(0))
|
||||
}
|
||||
|
||||
@@ -9,7 +9,8 @@ import com.google.flatbuffers.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class StructInNestedNS extends Struct {
|
||||
public StructInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public StructInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public int a() { return bb.getInt(bb_pos + 0); }
|
||||
public void mutateA(int a) { bb.putInt(bb_pos + 0, a); }
|
||||
|
||||
@@ -6,13 +6,17 @@ namespace NamespaceA.NamespaceB
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class TableInNestedNS : Table {
|
||||
public struct TableInNestedNS : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb) { return GetRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
|
||||
public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public TableInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TableInNestedNS GetRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public int Foo { get { int o = __offset(4); return o != 0 ? bb.GetInt(o + bb_pos) : (int)0; } }
|
||||
public bool MutateFoo(int foo) { int o = __offset(4); if (o != 0) { bb.PutInt(o + bb_pos, foo); return true; } else { return false; } }
|
||||
public int Foo { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetInt(o + __p.bb_pos) : (int)0; } }
|
||||
public bool MutateFoo(int foo) { int o = __p.__offset(4); if (o != 0) { __p.bb.PutInt(o + __p.bb_pos, foo); return true; } else { return false; } }
|
||||
|
||||
public static Offset<TableInNestedNS> CreateTableInNestedNS(FlatBufferBuilder builder,
|
||||
int foo = 0) {
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *TableInNestedNS) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *TableInNestedNS) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TableInNestedNS) Foo() int32 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
|
||||
@@ -10,8 +10,9 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class TableInNestedNS extends Table {
|
||||
public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb) { return getRootAsTableInNestedNS(_bb, new TableInNestedNS()); }
|
||||
public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public TableInNestedNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TableInNestedNS getRootAsTableInNestedNS(ByteBuffer _bb, TableInNestedNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public TableInNestedNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public int foo() { int o = __offset(4); return o != 0 ? bb.getInt(o + bb_pos) : 0; }
|
||||
public boolean mutateFoo(int foo) { int o = __offset(4); if (o != 0) { bb.putInt(o + bb_pos, foo); return true; } else { return false; } }
|
||||
|
||||
@@ -6,13 +6,16 @@ namespace NamespaceA
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class SecondTableInA : Table {
|
||||
public struct SecondTableInA : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb) { return GetRootAsSecondTableInA(_bb, new SecondTableInA()); }
|
||||
public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public SecondTableInA __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static SecondTableInA GetRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public NamespaceC.TableInC ReferToC { get { return GetReferToC(new NamespaceC.TableInC()); } }
|
||||
public NamespaceC.TableInC GetReferToC(NamespaceC.TableInC obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceC.TableInC? ReferToC { get { int o = __p.__offset(4); return o != 0 ? (NamespaceC.TableInC?)(new NamespaceC.TableInC()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||
|
||||
public static Offset<SecondTableInA> CreateSecondTableInA(FlatBufferBuilder builder,
|
||||
Offset<NamespaceC.TableInC> refer_to_cOffset = default(Offset<NamespaceC.TableInC>)) {
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *SecondTableInA) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *SecondTableInA) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *SecondTableInA) ReferToC(obj *TableInC) *TableInC {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
|
||||
@@ -10,11 +10,12 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class SecondTableInA extends Table {
|
||||
public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb) { return getRootAsSecondTableInA(_bb, new SecondTableInA()); }
|
||||
public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public SecondTableInA __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static SecondTableInA getRootAsSecondTableInA(ByteBuffer _bb, SecondTableInA obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public SecondTableInA __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public NamespaceC.TableInC referToC() { return referToC(new NamespaceC.TableInC()); }
|
||||
public NamespaceC.TableInC referToC(NamespaceC.TableInC obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceC.TableInC referToC(NamespaceC.TableInC obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||
|
||||
public static int createSecondTableInA(FlatBufferBuilder builder,
|
||||
int refer_to_cOffset) {
|
||||
|
||||
@@ -6,25 +6,27 @@ namespace NamespaceA
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class TableInFirstNS : Table {
|
||||
public struct TableInFirstNS : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb) { return GetRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
|
||||
public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public TableInFirstNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TableInFirstNS GetRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public NamespaceA.NamespaceB.TableInNestedNS FooTable { get { return GetFooTable(new NamespaceA.NamespaceB.TableInNestedNS()); } }
|
||||
public NamespaceA.NamespaceB.TableInNestedNS GetFooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get { int o = __offset(6); return o != 0 ? (NamespaceA.NamespaceB.EnumInNestedNS)bb.GetSbyte(o + bb_pos) : NamespaceA.NamespaceB.EnumInNestedNS.A; } }
|
||||
public bool MutateFooEnum(NamespaceA.NamespaceB.EnumInNestedNS foo_enum) { int o = __offset(6); if (o != 0) { bb.PutSbyte(o + bb_pos, (sbyte)foo_enum); return true; } else { return false; } }
|
||||
public NamespaceA.NamespaceB.StructInNestedNS FooStruct { get { return GetFooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); } }
|
||||
public NamespaceA.NamespaceB.StructInNestedNS GetFooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
||||
public NamespaceA.NamespaceB.TableInNestedNS? FooTable { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.NamespaceB.TableInNestedNS?)(new NamespaceA.NamespaceB.TableInNestedNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||
public NamespaceA.NamespaceB.EnumInNestedNS FooEnum { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.NamespaceB.EnumInNestedNS)__p.bb.GetSbyte(o + __p.bb_pos) : NamespaceA.NamespaceB.EnumInNestedNS.A; } }
|
||||
public bool MutateFooEnum(NamespaceA.NamespaceB.EnumInNestedNS foo_enum) { int o = __p.__offset(6); if (o != 0) { __p.bb.PutSbyte(o + __p.bb_pos, (sbyte)foo_enum); return true; } else { return false; } }
|
||||
public NamespaceA.NamespaceB.StructInNestedNS? FooStruct { get { int o = __p.__offset(8); return o != 0 ? (NamespaceA.NamespaceB.StructInNestedNS?)(new NamespaceA.NamespaceB.StructInNestedNS()).__assign(o + __p.bb_pos, __p.bb) : null; } }
|
||||
|
||||
public static void StartTableInFirstNS(FlatBufferBuilder builder) { builder.StartObject(3); }
|
||||
public static void AddFooTable(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.TableInNestedNS> fooTableOffset) { builder.AddOffset(0, fooTableOffset.Value, 0); }
|
||||
public static void AddFooEnum(FlatBufferBuilder builder, NamespaceA.NamespaceB.EnumInNestedNS fooEnum) { builder.AddSbyte(1, (sbyte)fooEnum, 0); }
|
||||
public static void AddFooStruct(FlatBufferBuilder builder, Offset<NamespaceA.NamespaceB.StructInNestedNS> fooStructOffset) { builder.AddStruct(2, fooStructOffset.Value, 0); }
|
||||
public static Offset<NamespaceA.TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
|
||||
public static Offset<TableInFirstNS> EndTableInFirstNS(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return new Offset<NamespaceA.TableInFirstNS>(o);
|
||||
return new Offset<TableInFirstNS>(o);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *TableInFirstNS) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *TableInFirstNS) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TableInFirstNS) FooTable(obj *TableInNestedNS) *TableInNestedNS {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
|
||||
@@ -10,15 +10,16 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class TableInFirstNS extends Table {
|
||||
public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb) { return getRootAsTableInFirstNS(_bb, new TableInFirstNS()); }
|
||||
public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public TableInFirstNS __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TableInFirstNS getRootAsTableInFirstNS(ByteBuffer _bb, TableInFirstNS obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public TableInFirstNS __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public NamespaceA.NamespaceB.TableInNestedNS fooTable() { return fooTable(new NamespaceA.NamespaceB.TableInNestedNS()); }
|
||||
public NamespaceA.NamespaceB.TableInNestedNS fooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceA.NamespaceB.TableInNestedNS fooTable(NamespaceA.NamespaceB.TableInNestedNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||
public byte fooEnum() { int o = __offset(6); return o != 0 ? bb.get(o + bb_pos) : 0; }
|
||||
public boolean mutateFooEnum(byte foo_enum) { int o = __offset(6); if (o != 0) { bb.put(o + bb_pos, foo_enum); return true; } else { return false; } }
|
||||
public NamespaceA.NamespaceB.StructInNestedNS fooStruct() { return fooStruct(new NamespaceA.NamespaceB.StructInNestedNS()); }
|
||||
public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__init(o + bb_pos, bb) : null; }
|
||||
public NamespaceA.NamespaceB.StructInNestedNS fooStruct(NamespaceA.NamespaceB.StructInNestedNS obj) { int o = __offset(8); return o != 0 ? obj.__assign(o + bb_pos, bb) : null; }
|
||||
|
||||
public static void startTableInFirstNS(FlatBufferBuilder builder) { builder.startObject(3); }
|
||||
public static void addFooTable(FlatBufferBuilder builder, int fooTableOffset) { builder.addOffset(0, fooTableOffset, 0); }
|
||||
|
||||
@@ -6,19 +6,21 @@ namespace NamespaceC
|
||||
using System;
|
||||
using FlatBuffers;
|
||||
|
||||
public sealed class TableInC : Table {
|
||||
public struct TableInC : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static TableInC GetRootAsTableInC(ByteBuffer _bb) { return GetRootAsTableInC(_bb, new TableInC()); }
|
||||
public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__init(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public TableInC __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TableInC GetRootAsTableInC(ByteBuffer _bb, TableInC obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p.bb_pos = _i; __p.bb = _bb; }
|
||||
public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public NamespaceA.TableInFirstNS ReferToA1 { get { return GetReferToA1(new NamespaceA.TableInFirstNS()); } }
|
||||
public NamespaceA.TableInFirstNS GetReferToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public SecondTableInA ReferToA2 { get { return GetReferToA2(new SecondTableInA()); } }
|
||||
public SecondTableInA GetReferToA2(SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceA.TableInFirstNS? ReferToA1 { get { int o = __p.__offset(4); return o != 0 ? (NamespaceA.TableInFirstNS?)(new NamespaceA.TableInFirstNS()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||
public NamespaceA.SecondTableInA? ReferToA2 { get { int o = __p.__offset(6); return o != 0 ? (NamespaceA.SecondTableInA?)(new NamespaceA.SecondTableInA()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||
|
||||
public static Offset<NamespaceC.TableInC> CreateTableInC(FlatBufferBuilder builder,
|
||||
public static Offset<TableInC> CreateTableInC(FlatBufferBuilder builder,
|
||||
Offset<NamespaceA.TableInFirstNS> refer_to_a1Offset = default(Offset<NamespaceA.TableInFirstNS>),
|
||||
Offset<SecondTableInA> refer_to_a2Offset = default(Offset<SecondTableInA>)) {
|
||||
Offset<NamespaceA.SecondTableInA> refer_to_a2Offset = default(Offset<NamespaceA.SecondTableInA>)) {
|
||||
builder.StartObject(2);
|
||||
TableInC.AddReferToA2(builder, refer_to_a2Offset);
|
||||
TableInC.AddReferToA1(builder, refer_to_a1Offset);
|
||||
@@ -27,10 +29,10 @@ public sealed class TableInC : Table {
|
||||
|
||||
public static void StartTableInC(FlatBufferBuilder builder) { builder.StartObject(2); }
|
||||
public static void AddReferToA1(FlatBufferBuilder builder, Offset<NamespaceA.TableInFirstNS> referToA1Offset) { builder.AddOffset(0, referToA1Offset.Value, 0); }
|
||||
public static void AddReferToA2(FlatBufferBuilder builder, Offset<SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
|
||||
public static Offset<NamespaceC.TableInC> EndTableInC(FlatBufferBuilder builder) {
|
||||
public static void AddReferToA2(FlatBufferBuilder builder, Offset<NamespaceA.SecondTableInA> referToA2Offset) { builder.AddOffset(1, referToA2Offset.Value, 0); }
|
||||
public static Offset<TableInC> EndTableInC(FlatBufferBuilder builder) {
|
||||
int o = builder.EndObject();
|
||||
return new Offset<NamespaceC.TableInC>(o);
|
||||
return new Offset<TableInC>(o);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,10 @@ func (rcv *TableInC) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *TableInC) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *TableInC) ReferToA1(obj *TableInFirstNS) *TableInFirstNS {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
|
||||
@@ -10,13 +10,14 @@ import com.google.flatbuffers.*;
|
||||
@SuppressWarnings("unused")
|
||||
public final class TableInC extends Table {
|
||||
public static TableInC getRootAsTableInC(ByteBuffer _bb) { return getRootAsTableInC(_bb, new TableInC()); }
|
||||
public static TableInC getRootAsTableInC(ByteBuffer _bb, TableInC obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__init(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public TableInC __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; return this; }
|
||||
public static TableInC getRootAsTableInC(ByteBuffer _bb, TableInC obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { bb_pos = _i; bb = _bb; }
|
||||
public TableInC __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public NamespaceA.TableInFirstNS referToA1() { return referToA1(new NamespaceA.TableInFirstNS()); }
|
||||
public NamespaceA.TableInFirstNS referToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public SecondTableInA referToA2() { return referToA2(new SecondTableInA()); }
|
||||
public SecondTableInA referToA2(SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__init(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceA.TableInFirstNS referToA1(NamespaceA.TableInFirstNS obj) { int o = __offset(4); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||
public NamespaceA.SecondTableInA referToA2() { return referToA2(new NamespaceA.SecondTableInA()); }
|
||||
public NamespaceA.SecondTableInA referToA2(NamespaceA.SecondTableInA obj) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||
|
||||
public static int createTableInC(FlatBufferBuilder builder,
|
||||
int refer_to_a1Offset,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user