mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-14 00:25:26 +00:00
Compare commits
246 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6df40a2471 | ||
|
|
0dba63909f | ||
|
|
0e3fdd0eea | ||
|
|
45a2b07cbd | ||
|
|
d10c163142 | ||
|
|
35abb7f89b | ||
|
|
9954e09ab7 | ||
|
|
95a21327fc | ||
|
|
89b6183ee9 | ||
|
|
5a98d65e86 | ||
|
|
f73d205bc7 | ||
|
|
7c37abe92d | ||
|
|
4749e77b0e | ||
|
|
6ff1898413 | ||
|
|
c9a30c9ca2 | ||
|
|
8c02d17bea | ||
|
|
34305c4ce4 | ||
|
|
cd88e6b2aa | ||
|
|
3ec7a53c62 | ||
|
|
6d44cede70 | ||
|
|
cc08c0835b | ||
|
|
54f8b787cb | ||
|
|
17557f9131 | ||
|
|
d54af8cd43 | ||
|
|
173e10fdf1 | ||
|
|
8f56990f6c | ||
|
|
6400c9b054 | ||
|
|
7418d85872 | ||
|
|
c580fa284c | ||
|
|
f2a1272303 | ||
|
|
316d7c2089 | ||
|
|
47026ea6ba | ||
|
|
3f677f2414 | ||
|
|
a593a11e59 | ||
|
|
7cdfc8475e | ||
|
|
bab2b0db48 | ||
|
|
89418eb848 | ||
|
|
9cadf05d89 | ||
|
|
6da1cf79d9 | ||
|
|
bee1df96dc | ||
|
|
01189d7edd | ||
|
|
c4b2b0a25d | ||
|
|
a4b2884e4e | ||
|
|
04d80f255d | ||
|
|
55686100aa | ||
|
|
718351831d | ||
|
|
d1b34f0f28 | ||
|
|
21b7061963 | ||
|
|
35daaf83d3 | ||
|
|
3b458f7a17 | ||
|
|
a5d9d0f7d3 | ||
|
|
3cd9b6434a | ||
|
|
355dfd48d1 | ||
|
|
bcd58a159b | ||
|
|
a2c12900aa | ||
|
|
901b89e733 | ||
|
|
31f8799083 | ||
|
|
8023d99e21 | ||
|
|
b4154405d1 | ||
|
|
04c17c7a76 | ||
|
|
62ec7d52ce | ||
|
|
7de668053f | ||
|
|
3a70e0b308 | ||
|
|
9b13201356 | ||
|
|
5e3916050c | ||
|
|
c957550511 | ||
|
|
44bf719883 | ||
|
|
3e8f15df90 | ||
|
|
602721a735 | ||
|
|
13c05f4da3 | ||
|
|
ce3a1c43a2 | ||
|
|
aa75e5734b | ||
|
|
2790fee257 | ||
|
|
eddebec1b6 | ||
|
|
030fee36ab | ||
|
|
f9724d1bde | ||
|
|
b20801ca40 | ||
|
|
a8e800bd7c | ||
|
|
d7530ae961 | ||
|
|
99d11e279f | ||
|
|
4fd8eb214b | ||
|
|
65f8703572 | ||
|
|
75823cc275 | ||
|
|
58e279244c | ||
|
|
3c964e10ab | ||
|
|
c3c32ec942 | ||
|
|
075e8d676b | ||
|
|
bcf1bd5c9e | ||
|
|
136d75fa65 | ||
|
|
091fa1fd1b | ||
|
|
ff3781dc2d | ||
|
|
6beb9f49cb | ||
|
|
80988ea869 | ||
|
|
0f2ff7eaa9 | ||
|
|
dda095023d | ||
|
|
adbcbba5d1 | ||
|
|
cbbd6aca04 | ||
|
|
405c64e07d | ||
|
|
42c08cbca6 | ||
|
|
33d5dd9bdd | ||
|
|
105dd528e9 | ||
|
|
f0f0efe7b8 | ||
|
|
e837d5a296 | ||
|
|
9834ee9787 | ||
|
|
44b2ab087c | ||
|
|
46ae3f80a6 | ||
|
|
7b38aa71e6 | ||
|
|
661bedd837 | ||
|
|
8526e12d73 | ||
|
|
3c7b660d62 | ||
|
|
964365ba69 | ||
|
|
32254b7acd | ||
|
|
521e255ad9 | ||
|
|
1b85292fd3 | ||
|
|
480815447a | ||
|
|
8d5e424c65 | ||
|
|
b4774d2354 | ||
|
|
26f238c248 | ||
|
|
e93c8c46e6 | ||
|
|
e21516b9d7 | ||
|
|
fbc11e8aec | ||
|
|
e9d29c21a7 | ||
|
|
8bfafc76de | ||
|
|
df3e8bf4a7 | ||
|
|
5665cfe492 | ||
|
|
5797540ed0 | ||
|
|
7f1af7cb02 | ||
|
|
32f47ad247 | ||
|
|
842f672baf | ||
|
|
d4cae0a623 | ||
|
|
f1147f65bb | ||
|
|
69d3fec488 | ||
|
|
cfb4ecf6f0 | ||
|
|
a92039687a | ||
|
|
625338d095 | ||
|
|
3f8ce99c50 | ||
|
|
0798b7b698 | ||
|
|
cbdf82e2fb | ||
|
|
e365c502ff | ||
|
|
97f3aa9174 | ||
|
|
2f5bb2eec4 | ||
|
|
917687c7a6 | ||
|
|
f9277e691d | ||
|
|
2706381eef | ||
|
|
b5560fcd52 | ||
|
|
782b865c55 | ||
|
|
3bfc86eaff | ||
|
|
c0282873fb | ||
|
|
4b870aca98 | ||
|
|
d0e3870c0f | ||
|
|
fb25eb87f2 | ||
|
|
cb35d3a0e5 | ||
|
|
8e6cabb31b | ||
|
|
bd31dd2425 | ||
|
|
65b67d2132 | ||
|
|
1fbb711324 | ||
|
|
cd75a36587 | ||
|
|
ec6b0bf297 | ||
|
|
c11b5d7447 | ||
|
|
4525c91be3 | ||
|
|
b97b342f59 | ||
|
|
c1058a903b | ||
|
|
3030449348 | ||
|
|
a2485d4ecc | ||
|
|
a20e71ac96 | ||
|
|
acc9990abd | ||
|
|
2d5315ff0e | ||
|
|
7de1a5e347 | ||
|
|
a4e3ad808e | ||
|
|
c953fa572b | ||
|
|
0c86085a5b | ||
|
|
a1f7ecd148 | ||
|
|
a20c55bea5 | ||
|
|
d7c2b388ef | ||
|
|
9fa8245e81 | ||
|
|
a5ca8bee4d | ||
|
|
09dea79a22 | ||
|
|
b632061eff | ||
|
|
da88be05e1 | ||
|
|
d4fa984f1d | ||
|
|
a0c0131e36 | ||
|
|
de9aa0cdee | ||
|
|
a752d1b88c | ||
|
|
db972be264 | ||
|
|
e304f8c115 | ||
|
|
47c7aa0361 | ||
|
|
7a63792929 | ||
|
|
7d7d796cd0 | ||
|
|
550b386995 | ||
|
|
5479adc80f | ||
|
|
b7012484f3 | ||
|
|
92e9f33036 | ||
|
|
ff1a22a05f | ||
|
|
9fb195cce8 | ||
|
|
7836e65dd4 | ||
|
|
123c7a4890 | ||
|
|
e635141d5b | ||
|
|
0d2cebccfe | ||
|
|
a80db8538c | ||
|
|
a6be1d0d74 | ||
|
|
a7e20b1996 | ||
|
|
4eb3efc221 | ||
|
|
a807fa9567 | ||
|
|
b80ad7e439 | ||
|
|
16aef8ac0d | ||
|
|
b59a1ca2f8 | ||
|
|
4fdfe0d468 | ||
|
|
95004218f7 | ||
|
|
bc7ede8fb3 | ||
|
|
b652fcc3a7 | ||
|
|
c978b9ef1f | ||
|
|
3a88e1031b | ||
|
|
51dd733ba4 | ||
|
|
79f0df3dfc | ||
|
|
9d92fd92e1 | ||
|
|
93f74c0363 | ||
|
|
43dbac5d25 | ||
|
|
53ea1ab1bd | ||
|
|
b10b050ab9 | ||
|
|
563dcd6893 | ||
|
|
30ac512a54 | ||
|
|
b04736f9bd | ||
|
|
bc240b3004 | ||
|
|
0f7e7fd209 | ||
|
|
766ed04422 | ||
|
|
c5e2d37337 | ||
|
|
fe83b68ac6 | ||
|
|
718ddea558 | ||
|
|
8d86b5347f | ||
|
|
39bd667fd0 | ||
|
|
0bb3ce6935 | ||
|
|
b56d60f058 | ||
|
|
bff7ffbc51 | ||
|
|
107c08988a | ||
|
|
f9ebfcb9c4 | ||
|
|
b701c7d56e | ||
|
|
103f61b685 | ||
|
|
e47ca7ab40 | ||
|
|
d79f4e9717 | ||
|
|
5d67693e8f | ||
|
|
af74f87ccd | ||
|
|
b8ef8c1521 | ||
|
|
6cc30b3272 | ||
|
|
e5b6125fa2 | ||
|
|
ac14c8906f | ||
|
|
9936adf473 |
@@ -19,6 +19,7 @@ call generate_code.bat -b %buildtype% || goto FAIL
|
|||||||
|
|
||||||
:: TODO: Release and Debug builds produce differences here for some reason.
|
:: TODO: Release and Debug builds produce differences here for some reason.
|
||||||
git checkout HEAD -- monster_test.bfbs
|
git checkout HEAD -- monster_test.bfbs
|
||||||
|
git checkout HEAD -- arrays_test.bfbs
|
||||||
|
|
||||||
git -c core.autocrlf=true diff --exit-code --quiet || goto :DIFFFOUND
|
git -c core.autocrlf=true diff --exit-code --quiet || goto :DIFFFOUND
|
||||||
goto SUCCESS
|
goto SUCCESS
|
||||||
|
|||||||
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,6 +1,8 @@
|
|||||||
Thank you for submitting a PR!
|
Thank you for submitting a PR!
|
||||||
|
|
||||||
Please make sure you include the names of the affected language(s) in your PR title.
|
Please delete this standard text once you've created your own description.
|
||||||
|
|
||||||
|
Make sure you include the names of the affected language(s) in your PR title.
|
||||||
This helps us get the correct maintainers to look at your issue.
|
This helps us get the correct maintainers to look at your issue.
|
||||||
|
|
||||||
If you make changes to any of the code generators, be sure to run
|
If you make changes to any of the code generators, be sure to run
|
||||||
@@ -11,6 +13,8 @@ If your PR includes C++ code, please adhere to the Google C++ Style Guide,
|
|||||||
and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
|
and don't forget we try to support older compilers (e.g. VS2010, GCC 4.6.3),
|
||||||
so only some C++11 support is available.
|
so only some C++11 support is available.
|
||||||
|
|
||||||
|
For any C++ changes, please make sure to run `sh src/clang-format-git.sh`
|
||||||
|
|
||||||
Include other details as appropriate.
|
Include other details as appropriate.
|
||||||
|
|
||||||
Thanks!
|
Thanks!
|
||||||
|
|||||||
18
.github/stale.yml
vendored
Normal file
18
.github/stale.yml
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# Number of days of inactivity before an issue becomes stale
|
||||||
|
daysUntilStale: 365
|
||||||
|
# Number of days of inactivity before a stale issue is closed
|
||||||
|
daysUntilClose: 14
|
||||||
|
# Issues with these labels will never be considered stale
|
||||||
|
exemptLabels:
|
||||||
|
- pinned
|
||||||
|
- security
|
||||||
|
# Label to use when marking an issue as stale
|
||||||
|
staleLabel: stale
|
||||||
|
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||||
|
markComment: >
|
||||||
|
This issue has been automatically marked as stale because it has not had
|
||||||
|
activity for 1 year. It will be automatically closed if no further activity occurs.
|
||||||
|
To keep it open, simply post a new comment. Maintainers will re-open on
|
||||||
|
new activity. Thank you for your contributions.
|
||||||
|
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||||
|
closeComment: false
|
||||||
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,6 +1,12 @@
|
|||||||
*_wire.txt
|
*_wire.txt
|
||||||
*_wire.bin
|
*_wire.bin
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
**/.build
|
||||||
|
**/Packages
|
||||||
|
/*.xcodeproj
|
||||||
|
**/xcuserdata/
|
||||||
|
**/xcshareddata/
|
||||||
|
**/.swiftpm/
|
||||||
*.o
|
*.o
|
||||||
*.o.d
|
*.o.d
|
||||||
*.class
|
*.class
|
||||||
@@ -116,3 +122,6 @@ dart/doc/api/
|
|||||||
Cargo.lock
|
Cargo.lock
|
||||||
.corpus**
|
.corpus**
|
||||||
.seed**
|
.seed**
|
||||||
|
grpc/google/
|
||||||
|
**/Package.resolved
|
||||||
|
.clangd/**
|
||||||
|
|||||||
47
.travis.yml
47
.travis.yml
@@ -22,6 +22,21 @@ conan-linux: &conan-linux
|
|||||||
- ./conan/travis/build.sh
|
- ./conan/travis/build.sh
|
||||||
if: tag IS present
|
if: tag IS present
|
||||||
|
|
||||||
|
conan-linux-master: &conan-linux-master
|
||||||
|
os: linux
|
||||||
|
dist: xenial
|
||||||
|
language: python
|
||||||
|
python: "3.7"
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
install:
|
||||||
|
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/install.sh; fi'
|
||||||
|
script:
|
||||||
|
- 'if [ "$TRAVIS_PULL_REQUEST" = "false" ]; then bash ./conan/travis/build.sh; fi'
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
conan-osx: &conan-osx
|
conan-osx: &conan-osx
|
||||||
os: osx
|
os: osx
|
||||||
language: generic
|
language: generic
|
||||||
@@ -78,7 +93,7 @@ matrix:
|
|||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- BUILD_TYPE=Debug
|
- BUILD_TYPE=Debug
|
||||||
- BUILD_TYPE=Release CONAN=true
|
- BUILD_TYPE=Release
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
||||||
@@ -97,10 +112,9 @@ matrix:
|
|||||||
-DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
|
-DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install
|
||||||
-DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
|
-DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf
|
||||||
-DFLATBUFFERS_CODE_SANITIZE=ON
|
-DFLATBUFFERS_CODE_SANITIZE=ON
|
||||||
- cmake --build . -- -j${JOBS}
|
- cmake --build . --target all --clean-first -- -j${JOBS}
|
||||||
- LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
|
- LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
|
||||||
- bash .travis/check-generate-code.sh
|
- bash .travis/check-generate-code.sh
|
||||||
- if [ "$CONAN" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo pip install conan && conan create . flatbuffers/${TRAVIS_BRANCH}@google/testing -s build_type=$BUILD_TYPE -tf conan/test_package; fi
|
|
||||||
|
|
||||||
- language: cpp
|
- language: cpp
|
||||||
os: osx
|
os: osx
|
||||||
@@ -122,6 +136,8 @@ matrix:
|
|||||||
- DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
|
- DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ctest --extra-verbose --output-on-failure
|
||||||
- bash .travis/check-generate-code.sh
|
- bash .travis/check-generate-code.sh
|
||||||
|
|
||||||
|
- <<: *conan-linux-master
|
||||||
|
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
|
||||||
- <<: *conan-linux
|
- <<: *conan-linux
|
||||||
env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=conanio/gcc49
|
env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=conanio/gcc49
|
||||||
- <<: *conan-linux
|
- <<: *conan-linux
|
||||||
@@ -132,6 +148,8 @@ matrix:
|
|||||||
env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=conanio/gcc7
|
env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=conanio/gcc7
|
||||||
- <<: *conan-linux
|
- <<: *conan-linux
|
||||||
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
|
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/gcc8
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_GCC_VERSIONS=9 CONAN_DOCKER_IMAGE=conanio/gcc9
|
||||||
- <<: *conan-linux
|
- <<: *conan-linux
|
||||||
env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=conanio/clang39
|
env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=conanio/clang39
|
||||||
- <<: *conan-linux
|
- <<: *conan-linux
|
||||||
@@ -140,6 +158,10 @@ matrix:
|
|||||||
env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=conanio/clang50
|
env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=conanio/clang50
|
||||||
- <<: *conan-linux
|
- <<: *conan-linux
|
||||||
env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=conanio/clang60
|
env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=conanio/clang60
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_CLANG_VERSIONS=7.0 CONAN_DOCKER_IMAGE=conanio/clang7
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_CLANG_VERSIONS=8 CONAN_DOCKER_IMAGE=conanio/clang8
|
||||||
- <<: *conan-osx
|
- <<: *conan-osx
|
||||||
osx_image: xcode7.3
|
osx_image: xcode7.3
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=7.3
|
env: CONAN_APPLE_CLANG_VERSIONS=7.3
|
||||||
@@ -153,11 +175,12 @@ matrix:
|
|||||||
osx_image: xcode9.4
|
osx_image: xcode9.4
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=9.1
|
env: CONAN_APPLE_CLANG_VERSIONS=9.1
|
||||||
- <<: *conan-osx
|
- <<: *conan-osx
|
||||||
osx_image: xcode10
|
osx_image: xcode10.2
|
||||||
env: CONAN_APPLE_CLANG_VERSIONS=10.0
|
env: CONAN_APPLE_CLANG_VERSIONS=10.0
|
||||||
|
|
||||||
- language: android
|
- language: android
|
||||||
sudo: true
|
sudo: true
|
||||||
|
dist: trusty
|
||||||
android:
|
android:
|
||||||
components:
|
components:
|
||||||
- tools
|
- tools
|
||||||
@@ -171,8 +194,20 @@ matrix:
|
|||||||
before_install:
|
before_install:
|
||||||
# Output something every 10 minutes or Travis kills the job
|
# Output something every 10 minutes or Travis kills the job
|
||||||
- while sleep 540; do echo "=====[ $SECONDS seconds still running ]====="; done &
|
- while sleep 540; do echo "=====[ $SECONDS seconds still running ]====="; done &
|
||||||
- git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
|
# Install the r17c version of the NDK that still so that we can continue to test with gnustl
|
||||||
- export ANDROID_NDK_HOME=$HOME/android-ndk-root
|
# and stlport.
|
||||||
|
- export ANDROID_NDK_HOME=$HOME/android-ndk
|
||||||
|
- NDK_ZIP=$ANDROID_NDK_HOME/ndk.zip
|
||||||
|
- mkdir -p $ANDROID_NDK_HOME
|
||||||
|
- curl -o $NDK_ZIP https://dl.google.com/android/repository/android-ndk-r17c-linux-x86_64.zip
|
||||||
|
- unzip -q -d $ANDROID_NDK_HOME $NDK_ZIP
|
||||||
|
- rm $NDK_ZIP
|
||||||
|
- mv $ANDROID_NDK_HOME/android-ndk-*/* $ANDROID_NDK_HOME
|
||||||
|
- rmdir $ANDROID_NDK_HOME/android-ndk-*
|
||||||
|
- export CMAKE=$(which cmake)
|
||||||
|
# libc required for prebuilt llvm toolchain the NDK r17c.
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq libc6; fi
|
||||||
# Setup environment for Linux build which is required to build the sample.
|
# Setup environment for Linux build which is required to build the sample.
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
||||||
|
|||||||
@@ -15,10 +15,15 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
# build flatc on debian once to speed up the test loop below
|
docker build -t build_cpp_image -f tests/docker/Dockerfile.testing.cpp.debian_buster .
|
||||||
docker build -t build_flatc_debian_stretch -f tests/docker/Dockerfile.testing.build_flatc_debian_stretch .
|
# Run tests with sanitizers (--cap-add SYS_PTRACE), both GCC and Clang.
|
||||||
BUILD_CONTAINER_ID=$(docker create --read-only build_flatc_debian_stretch)
|
cpp_test_args="--cap-add SYS_PTRACE build_cpp_image sh ./tests/docker/cpp_test.run.sh Debug"
|
||||||
docker cp ${BUILD_CONTAINER_ID}:/code/flatc flatc_debian_stretch
|
docker run --rm $cpp_test_args
|
||||||
|
docker run --rm --env CC=/usr/bin/clang --env CXX=/usr/bin/clang++ $cpp_test_args
|
||||||
|
# Build flatc on debian once to speed up the test loop below.
|
||||||
|
docker run --name flatc_container build_cpp_image sh ./tests/docker/build_flatc.run.sh Debug
|
||||||
|
# All dependent dockers refer to 'flatc_debian_stretch'.
|
||||||
|
docker cp flatc_container:/flatbuffers/flatc flatc_debian_stretch
|
||||||
|
|
||||||
for f in $(ls tests/docker/languages | sort)
|
for f in $(ls tests/docker/languages | sort)
|
||||||
do
|
do
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ cd ..
|
|||||||
|
|
||||||
# TODO: Linux and macos builds produce differences here for some reason.
|
# TODO: Linux and macos builds produce differences here for some reason.
|
||||||
git checkout HEAD -- tests/monster_test.bfbs
|
git checkout HEAD -- tests/monster_test.bfbs
|
||||||
|
git checkout HEAD -- tests/arrays_test.bfbs
|
||||||
|
git checkout HEAD -- samples/monster.bfbs
|
||||||
|
|
||||||
if ! git diff --quiet; then
|
if ! git diff --quiet; then
|
||||||
echo >&2
|
echo >&2
|
||||||
|
|||||||
148
BUILD
148
BUILD
@@ -1,34 +1,22 @@
|
|||||||
licenses(["notice"])
|
licenses(["notice"])
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")
|
||||||
|
|
||||||
package(
|
package(
|
||||||
default_visibility = ["//visibility:public"],
|
default_visibility = ["//visibility:public"],
|
||||||
features = [
|
|
||||||
"-layering_check",
|
|
||||||
"-parse_headers",
|
|
||||||
],
|
|
||||||
)
|
)
|
||||||
|
|
||||||
exports_files([
|
exports_files([
|
||||||
"LICENSE",
|
"LICENSE",
|
||||||
])
|
])
|
||||||
|
|
||||||
load(":build_defs.bzl", "flatbuffer_cc_library")
|
|
||||||
|
|
||||||
# Public flatc library to compile flatbuffer files at runtime.
|
# Public flatc library to compile flatbuffer files at runtime.
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "flatbuffers",
|
name = "flatbuffers",
|
||||||
srcs = [
|
hdrs = ["//:public_headers"],
|
||||||
"src/code_generators.cpp",
|
|
||||||
"src/idl_gen_fbs.cpp",
|
|
||||||
"src/idl_gen_general.cpp",
|
|
||||||
"src/idl_gen_text.cpp",
|
|
||||||
"src/idl_parser.cpp",
|
|
||||||
"src/reflection.cpp",
|
|
||||||
"src/util.cpp",
|
|
||||||
],
|
|
||||||
hdrs = [":public_headers"],
|
|
||||||
includes = ["include/"],
|
|
||||||
linkstatic = 1,
|
linkstatic = 1,
|
||||||
|
strip_include_prefix = "/include",
|
||||||
|
deps = ["//src:flatbuffers"],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Public C++ headers for the Flatbuffers library.
|
# Public C++ headers for the Flatbuffers library.
|
||||||
@@ -44,6 +32,7 @@ filegroup(
|
|||||||
"include/flatbuffers/minireflect.h",
|
"include/flatbuffers/minireflect.h",
|
||||||
"include/flatbuffers/reflection.h",
|
"include/flatbuffers/reflection.h",
|
||||||
"include/flatbuffers/reflection_generated.h",
|
"include/flatbuffers/reflection_generated.h",
|
||||||
|
"include/flatbuffers/registry.h",
|
||||||
"include/flatbuffers/stl_emulation.h",
|
"include/flatbuffers/stl_emulation.h",
|
||||||
"include/flatbuffers/util.h",
|
"include/flatbuffers/util.h",
|
||||||
],
|
],
|
||||||
@@ -52,60 +41,29 @@ filegroup(
|
|||||||
# Public flatc compiler library.
|
# Public flatc compiler library.
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "flatc_library",
|
name = "flatc_library",
|
||||||
srcs = [
|
linkstatic = 1,
|
||||||
"src/code_generators.cpp",
|
deps = [
|
||||||
"src/flatc.cpp",
|
"//src:flatc_library",
|
||||||
"src/idl_gen_fbs.cpp",
|
|
||||||
"src/idl_parser.cpp",
|
|
||||||
"src/reflection.cpp",
|
|
||||||
"src/util.cpp",
|
|
||||||
],
|
|
||||||
hdrs = [
|
|
||||||
"include/flatbuffers/flatc.h",
|
|
||||||
":public_headers",
|
|
||||||
],
|
|
||||||
includes = [
|
|
||||||
"grpc/",
|
|
||||||
"include/",
|
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
# Public flatc compiler.
|
# Public flatc compiler.
|
||||||
cc_binary(
|
cc_binary(
|
||||||
name = "flatc",
|
name = "flatc",
|
||||||
srcs = [
|
|
||||||
"grpc/src/compiler/config.h",
|
|
||||||
"grpc/src/compiler/cpp_generator.cc",
|
|
||||||
"grpc/src/compiler/cpp_generator.h",
|
|
||||||
"grpc/src/compiler/go_generator.cc",
|
|
||||||
"grpc/src/compiler/go_generator.h",
|
|
||||||
"grpc/src/compiler/java_generator.cc",
|
|
||||||
"grpc/src/compiler/java_generator.h",
|
|
||||||
"grpc/src/compiler/schema_interface.h",
|
|
||||||
"src/flatc_main.cpp",
|
|
||||||
"src/idl_gen_cpp.cpp",
|
|
||||||
"src/idl_gen_dart.cpp",
|
|
||||||
"src/idl_gen_general.cpp",
|
|
||||||
"src/idl_gen_go.cpp",
|
|
||||||
"src/idl_gen_grpc.cpp",
|
|
||||||
"src/idl_gen_js_ts.cpp",
|
|
||||||
"src/idl_gen_json_schema.cpp",
|
|
||||||
"src/idl_gen_lobster.cpp",
|
|
||||||
"src/idl_gen_lua.cpp",
|
|
||||||
"src/idl_gen_php.cpp",
|
|
||||||
"src/idl_gen_python.cpp",
|
|
||||||
"src/idl_gen_rust.cpp",
|
|
||||||
"src/idl_gen_text.cpp",
|
|
||||||
],
|
|
||||||
includes = [
|
|
||||||
"grpc/",
|
|
||||||
"include/",
|
|
||||||
],
|
|
||||||
deps = [
|
deps = [
|
||||||
":flatc_library",
|
"//src:flatc",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "flatc_headers",
|
||||||
|
srcs = [
|
||||||
|
"include/flatbuffers/flatc.h",
|
||||||
|
],
|
||||||
|
visibility = ["//:__subpackages__"],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Library used by flatbuffer_cc_library rules.
|
||||||
cc_library(
|
cc_library(
|
||||||
name = "runtime_cc",
|
name = "runtime_cc",
|
||||||
hdrs = [
|
hdrs = [
|
||||||
@@ -115,72 +73,6 @@ cc_library(
|
|||||||
"include/flatbuffers/stl_emulation.h",
|
"include/flatbuffers/stl_emulation.h",
|
||||||
"include/flatbuffers/util.h",
|
"include/flatbuffers/util.h",
|
||||||
],
|
],
|
||||||
includes = ["include/"],
|
|
||||||
linkstatic = 1,
|
linkstatic = 1,
|
||||||
)
|
strip_include_prefix = "/include",
|
||||||
|
|
||||||
# Test binary.
|
|
||||||
cc_test(
|
|
||||||
name = "flatbuffers_test",
|
|
||||||
testonly = 1,
|
|
||||||
srcs = [
|
|
||||||
"include/flatbuffers/minireflect.h",
|
|
||||||
"include/flatbuffers/registry.h",
|
|
||||||
"src/code_generators.cpp",
|
|
||||||
"src/idl_gen_fbs.cpp",
|
|
||||||
"src/idl_gen_general.cpp",
|
|
||||||
"src/idl_gen_text.cpp",
|
|
||||||
"src/idl_parser.cpp",
|
|
||||||
"src/reflection.cpp",
|
|
||||||
"src/util.cpp",
|
|
||||||
"tests/namespace_test/namespace_test1_generated.h",
|
|
||||||
"tests/namespace_test/namespace_test2_generated.h",
|
|
||||||
"tests/test.cpp",
|
|
||||||
"tests/test_assert.cpp",
|
|
||||||
"tests/test_assert.h",
|
|
||||||
"tests/test_builder.cpp",
|
|
||||||
"tests/test_builder.h",
|
|
||||||
"tests/union_vector/union_vector_generated.h",
|
|
||||||
":public_headers",
|
|
||||||
],
|
|
||||||
copts = [
|
|
||||||
"-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
|
|
||||||
"-DBAZEL_TEST_DATA_PATH",
|
|
||||||
],
|
|
||||||
data = [
|
|
||||||
":tests/include_test/include_test1.fbs",
|
|
||||||
":tests/include_test/sub/include_test2.fbs",
|
|
||||||
":tests/monster_test.bfbs",
|
|
||||||
":tests/monster_test.fbs",
|
|
||||||
":tests/monsterdata_test.golden",
|
|
||||||
":tests/prototest/imported.proto",
|
|
||||||
":tests/prototest/test.golden",
|
|
||||||
":tests/prototest/test.proto",
|
|
||||||
":tests/prototest/test_union.golden",
|
|
||||||
":tests/unicode_test.json",
|
|
||||||
":tests/union_vector/union_vector.fbs",
|
|
||||||
":tests/union_vector/union_vector.json",
|
|
||||||
],
|
|
||||||
includes = ["include/"],
|
|
||||||
deps = [
|
|
||||||
":monster_extra_cc_fbs",
|
|
||||||
":monster_test_cc_fbs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
# Test bzl rules
|
|
||||||
|
|
||||||
flatbuffer_cc_library(
|
|
||||||
name = "monster_test_cc_fbs",
|
|
||||||
srcs = ["tests/monster_test.fbs"],
|
|
||||||
include_paths = ["tests/include_test"],
|
|
||||||
includes = [
|
|
||||||
"tests/include_test/include_test1.fbs",
|
|
||||||
"tests/include_test/sub/include_test2.fbs",
|
|
||||||
],
|
|
||||||
)
|
|
||||||
|
|
||||||
flatbuffer_cc_library(
|
|
||||||
name = "monster_extra_cc_fbs",
|
|
||||||
srcs = ["tests/monster_extra.fbs"],
|
|
||||||
)
|
)
|
||||||
|
|||||||
254
CMakeLists.txt
254
CMakeLists.txt
@@ -1,4 +1,4 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8.12)
|
||||||
# generate compile_commands.json
|
# generate compile_commands.json
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
include(CheckCXXSymbolExists)
|
include(CheckCXXSymbolExists)
|
||||||
@@ -13,6 +13,8 @@ option(FLATBUFFERS_BUILD_FLATLIB "Enable the build of the flatbuffers library"
|
|||||||
ON)
|
ON)
|
||||||
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
|
option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
|
||||||
ON)
|
ON)
|
||||||
|
option(FLATBUFFERS_STATIC_FLATC "Build flatbuffers compiler with -static flag"
|
||||||
|
OFF)
|
||||||
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
||||||
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
||||||
option(FLATBUFFERS_BUILD_SHAREDLIB
|
option(FLATBUFFERS_BUILD_SHAREDLIB
|
||||||
@@ -29,6 +31,13 @@ option(FLATBUFFERS_PACKAGE_REDHAT
|
|||||||
option(FLATBUFFERS_PACKAGE_DEBIAN
|
option(FLATBUFFERS_PACKAGE_DEBIAN
|
||||||
"Build an deb using the 'package' target."
|
"Build an deb using the 'package' target."
|
||||||
OFF)
|
OFF)
|
||||||
|
option(FLATBUFFERS_BUILD_CPP17
|
||||||
|
"Enable the build of c++17 test target. \"
|
||||||
|
Requirements: Clang6, GCC7, MSVC2017 (_MSC_VER >= 1914) or higher."
|
||||||
|
OFF)
|
||||||
|
option(FLATBUFFERS_BUILD_LEGACY
|
||||||
|
"Run C++ code generator with '--cpp-std c++0x' switch."
|
||||||
|
OFF)
|
||||||
|
|
||||||
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
||||||
message(WARNING
|
message(WARNING
|
||||||
@@ -42,18 +51,23 @@ if(DEFINED FLATBUFFERS_MAX_PARSING_DEPTH)
|
|||||||
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
|
message(STATUS "FLATBUFFERS_MAX_PARSING_DEPTH: ${FLATBUFFERS_MAX_PARSING_DEPTH}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Auto-detect locale-narrow 'strtod_l' function.
|
# Auto-detect locale-narrow 'strtod_l' and 'strtoull_l' functions.
|
||||||
if(NOT DEFINED FLATBUFFERS_LOCALE_INDEPENDENT)
|
if(NOT DEFINED FLATBUFFERS_LOCALE_INDEPENDENT)
|
||||||
|
set(FLATBUFFERS_LOCALE_INDEPENDENT 0)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_LOCALE_INDEPENDENT)
|
check_cxx_symbol_exists(_strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
|
||||||
|
check_cxx_symbol_exists(_strtoui64_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
|
||||||
else()
|
else()
|
||||||
check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_LOCALE_INDEPENDENT)
|
check_cxx_symbol_exists(strtof_l stdlib.h FLATBUFFERS_HAS_STRTOF_L)
|
||||||
|
check_cxx_symbol_exists(strtoull_l stdlib.h FLATBUFFERS_HAS_STRTOULL_L)
|
||||||
|
endif()
|
||||||
|
if(FLATBUFFERS_HAS_STRTOF_L AND FLATBUFFERS_HAS_STRTOULL_L)
|
||||||
|
set(FLATBUFFERS_LOCALE_INDEPENDENT 1)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
|
add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=$<BOOL:${FLATBUFFERS_LOCALE_INDEPENDENT}>)
|
||||||
|
|
||||||
set(FlatBuffers_Library_SRCS
|
set(FlatBuffers_Library_SRCS
|
||||||
include/flatbuffers/code_generators.h
|
|
||||||
include/flatbuffers/base.h
|
include/flatbuffers/base.h
|
||||||
include/flatbuffers/flatbuffers.h
|
include/flatbuffers/flatbuffers.h
|
||||||
include/flatbuffers/hash.h
|
include/flatbuffers/hash.h
|
||||||
@@ -65,7 +79,6 @@ set(FlatBuffers_Library_SRCS
|
|||||||
include/flatbuffers/flexbuffers.h
|
include/flatbuffers/flexbuffers.h
|
||||||
include/flatbuffers/registry.h
|
include/flatbuffers/registry.h
|
||||||
include/flatbuffers/minireflect.h
|
include/flatbuffers/minireflect.h
|
||||||
src/code_generators.cpp
|
|
||||||
src/idl_parser.cpp
|
src/idl_parser.cpp
|
||||||
src/idl_gen_text.cpp
|
src/idl_gen_text.cpp
|
||||||
src/reflection.cpp
|
src/reflection.cpp
|
||||||
@@ -75,9 +88,11 @@ set(FlatBuffers_Library_SRCS
|
|||||||
set(FlatBuffers_Compiler_SRCS
|
set(FlatBuffers_Compiler_SRCS
|
||||||
${FlatBuffers_Library_SRCS}
|
${FlatBuffers_Library_SRCS}
|
||||||
src/idl_gen_cpp.cpp
|
src/idl_gen_cpp.cpp
|
||||||
|
src/idl_gen_csharp.cpp
|
||||||
src/idl_gen_dart.cpp
|
src/idl_gen_dart.cpp
|
||||||
src/idl_gen_general.cpp
|
src/idl_gen_kotlin.cpp
|
||||||
src/idl_gen_go.cpp
|
src/idl_gen_go.cpp
|
||||||
|
src/idl_gen_java.cpp
|
||||||
src/idl_gen_js_ts.cpp
|
src/idl_gen_js_ts.cpp
|
||||||
src/idl_gen_php.cpp
|
src/idl_gen_php.cpp
|
||||||
src/idl_gen_python.cpp
|
src/idl_gen_python.cpp
|
||||||
@@ -87,8 +102,11 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
src/idl_gen_fbs.cpp
|
src/idl_gen_fbs.cpp
|
||||||
src/idl_gen_grpc.cpp
|
src/idl_gen_grpc.cpp
|
||||||
src/idl_gen_json_schema.cpp
|
src/idl_gen_json_schema.cpp
|
||||||
|
src/idl_gen_swift.cpp
|
||||||
src/flatc.cpp
|
src/flatc.cpp
|
||||||
src/flatc_main.cpp
|
src/flatc_main.cpp
|
||||||
|
include/flatbuffers/code_generators.h
|
||||||
|
src/code_generators.cpp
|
||||||
grpc/src/compiler/schema_interface.h
|
grpc/src/compiler/schema_interface.h
|
||||||
grpc/src/compiler/cpp_generator.h
|
grpc/src/compiler/cpp_generator.h
|
||||||
grpc/src/compiler/cpp_generator.cc
|
grpc/src/compiler/cpp_generator.cc
|
||||||
@@ -96,6 +114,11 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
grpc/src/compiler/go_generator.cc
|
grpc/src/compiler/go_generator.cc
|
||||||
grpc/src/compiler/java_generator.h
|
grpc/src/compiler/java_generator.h
|
||||||
grpc/src/compiler/java_generator.cc
|
grpc/src/compiler/java_generator.cc
|
||||||
|
grpc/src/compiler/python_generator.h
|
||||||
|
grpc/src/compiler/python_private_generator.h
|
||||||
|
grpc/src/compiler/python_generator.cc
|
||||||
|
grpc/src/compiler/swift_generator.h
|
||||||
|
grpc/src/compiler/swift_generator.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FlatHash_SRCS
|
set(FlatHash_SRCS
|
||||||
@@ -111,8 +134,35 @@ set(FlatBuffers_Tests_SRCS
|
|||||||
tests/test_assert.cpp
|
tests/test_assert.cpp
|
||||||
tests/test_builder.h
|
tests/test_builder.h
|
||||||
tests/test_builder.cpp
|
tests/test_builder.cpp
|
||||||
|
tests/native_type_test_impl.h
|
||||||
|
tests/native_type_test_impl.cpp
|
||||||
|
include/flatbuffers/code_generators.h
|
||||||
|
src/code_generators.cpp
|
||||||
# file generate by running compiler on tests/monster_test.fbs
|
# file generate by running compiler on tests/monster_test.fbs
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||||
|
# file generate by running compiler on namespace_test/namespace_test1.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test1_generated.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test2_generated.h
|
||||||
|
# file generate by running compiler on union_vector/union_vector.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/union_vector/union_vector_generated.h
|
||||||
|
# file generate by running compiler on tests/arrays_test.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/arrays_test_generated.h
|
||||||
|
# file generate by running compiler on tests/native_type_test.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/native_type_test_generated.h
|
||||||
|
# file generate by running compiler on tests/monster_extra.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_extra_generated.h
|
||||||
|
# file generate by running compiler on tests/monster_test.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_bfbs_generated.h
|
||||||
|
)
|
||||||
|
|
||||||
|
set(FlatBuffers_Tests_CPP17_SRCS
|
||||||
|
${FlatBuffers_Library_SRCS}
|
||||||
|
tests/test_assert.h
|
||||||
|
tests/test_assert.cpp
|
||||||
|
tests/cpp17/test_cpp17.cpp
|
||||||
|
# file generate by running compiler on tests/monster_test.fbs
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/monster_test_generated.h
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FlatBuffers_Sample_Binary_SRCS
|
set(FlatBuffers_Sample_Binary_SRCS
|
||||||
@@ -131,7 +181,6 @@ set(FlatBuffers_Sample_Text_SRCS
|
|||||||
|
|
||||||
set(FlatBuffers_Sample_BFBS_SRCS
|
set(FlatBuffers_Sample_BFBS_SRCS
|
||||||
${FlatBuffers_Library_SRCS}
|
${FlatBuffers_Library_SRCS}
|
||||||
src/idl_gen_general.cpp
|
|
||||||
samples/sample_bfbs.cpp
|
samples/sample_bfbs.cpp
|
||||||
# file generated by running compiler on samples/monster.fbs
|
# file generated by running compiler on samples/monster.fbs
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||||
@@ -140,6 +189,8 @@ set(FlatBuffers_Sample_BFBS_SRCS
|
|||||||
set(FlatBuffers_GRPCTest_SRCS
|
set(FlatBuffers_GRPCTest_SRCS
|
||||||
include/flatbuffers/flatbuffers.h
|
include/flatbuffers/flatbuffers.h
|
||||||
include/flatbuffers/grpc.h
|
include/flatbuffers/grpc.h
|
||||||
|
include/flatbuffers/util.h
|
||||||
|
src/util.cpp
|
||||||
tests/monster_test.grpc.fb.h
|
tests/monster_test.grpc.fb.h
|
||||||
tests/test_assert.h
|
tests/test_assert.h
|
||||||
tests/test_builder.h
|
tests/test_builder.h
|
||||||
@@ -148,8 +199,8 @@ set(FlatBuffers_GRPCTest_SRCS
|
|||||||
tests/test_builder.cpp
|
tests/test_builder.cpp
|
||||||
grpc/tests/grpctest.cpp
|
grpc/tests/grpctest.cpp
|
||||||
grpc/tests/message_builder_test.cpp
|
grpc/tests/message_builder_test.cpp
|
||||||
# file generated by running compiler on samples/monster.fbs
|
# file generate by running compiler on tests/monster_test.fbs
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||||
)
|
)
|
||||||
|
|
||||||
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
|
# source_group(Compiler FILES ${FlatBuffers_Compiler_SRCS})
|
||||||
@@ -226,23 +277,28 @@ if(FLATBUFFERS_CODE_COVERAGE)
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(add_fsanitize_to_target _target _sanitizer)
|
function(add_fsanitize_to_target _target _sanitizer)
|
||||||
# FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
|
if(WIN32)
|
||||||
# List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
|
target_compile_definitions(${_target} PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
|
||||||
if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
|
message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to ${_target}")
|
||||||
((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
|
else()
|
||||||
)
|
# FLATBUFFERS_CODE_SANITIZE: boolean {ON,OFF,YES,NO} or string with list of sanitizer.
|
||||||
set(_sanitizer_flags "=address,undefined")
|
# List of sanitizer is string starts with '=': "=address,undefined,thread,memory".
|
||||||
if(_sanitizer MATCHES "=.*")
|
if((${CMAKE_CXX_COMPILER_ID} MATCHES "Clang") OR
|
||||||
# override default by user-defined sanitizer list
|
((${CMAKE_CXX_COMPILER_ID} MATCHES "GNU") AND NOT (CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.9"))
|
||||||
set(_sanitizer_flags ${_sanitizer})
|
)
|
||||||
|
set(_sanitizer_flags "=address,undefined")
|
||||||
|
if(_sanitizer MATCHES "=.*")
|
||||||
|
# override default by user-defined sanitizer list
|
||||||
|
set(_sanitizer_flags ${_sanitizer})
|
||||||
|
endif()
|
||||||
|
target_compile_options(${_target} PRIVATE
|
||||||
|
-g -fsigned-char -fno-omit-frame-pointer
|
||||||
|
"-fsanitize${_sanitizer_flags}")
|
||||||
|
target_link_libraries(${_target} PRIVATE
|
||||||
|
"-fsanitize${_sanitizer_flags}")
|
||||||
|
set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
|
message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
|
||||||
endif()
|
endif()
|
||||||
target_compile_options(${_target} PRIVATE
|
|
||||||
-g -fsigned-char -fno-omit-frame-pointer
|
|
||||||
"-fsanitize${_sanitizer_flags}")
|
|
||||||
target_link_libraries(${_target} PRIVATE
|
|
||||||
"-fsanitize${_sanitizer_flags}")
|
|
||||||
set_property(TARGET ${_target} PROPERTY POSITION_INDEPENDENT_CODE ON)
|
|
||||||
message(STATUS "Sanitizer ${_sanitizer_flags} added to ${_target}")
|
|
||||||
endif()
|
endif()
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
@@ -256,7 +312,7 @@ include_directories(grpc)
|
|||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||||
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
|
add_library(flatbuffers STATIC ${FlatBuffers_Library_SRCS})
|
||||||
# CMake > 2.8.11: Attach header directory for when build via add_subdirectory().
|
# Attach header directory for when build via add_subdirectory().
|
||||||
target_include_directories(flatbuffers INTERFACE
|
target_include_directories(flatbuffers INTERFACE
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||||
target_compile_options(flatbuffers PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
|
target_compile_options(flatbuffers PRIVATE "${FLATBUFFERS_PRIVATE_CXX_FLAGS}")
|
||||||
@@ -275,6 +331,9 @@ if(FLATBUFFERS_BUILD_FLATC)
|
|||||||
# Make flatc.exe not depend on runtime dlls for easy distribution.
|
# Make flatc.exe not depend on runtime dlls for easy distribution.
|
||||||
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
|
target_compile_options(flatc PUBLIC $<$<CONFIG:Release>:/MT>)
|
||||||
endif()
|
endif()
|
||||||
|
if(FLATBUFFERS_STATIC_FLATC AND NOT MSVC)
|
||||||
|
target_link_libraries(flatc PRIVATE -static)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATHASH)
|
if(FLATBUFFERS_BUILD_FLATHASH)
|
||||||
@@ -289,57 +348,148 @@ if(FLATBUFFERS_BUILD_SHAREDLIB)
|
|||||||
# - minor updated when there are additions in API/ABI
|
# - minor updated when there are additions in API/ABI
|
||||||
# - major (ABI number) updated when there are changes in ABI (or removals)
|
# - major (ABI number) updated when there are changes in ABI (or removals)
|
||||||
set(FlatBuffers_Library_SONAME_MAJOR "1")
|
set(FlatBuffers_Library_SONAME_MAJOR "1")
|
||||||
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.11.0")
|
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.12.0")
|
||||||
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
|
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
|
||||||
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
|
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
|
||||||
VERSION "${FlatBuffers_Library_SONAME_FULL}")
|
VERSION "${FlatBuffers_Library_SONAME_FULL}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
# Global list of generated files.
|
||||||
|
# Use the global property to be independent of PARENT_SCOPE.
|
||||||
|
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
|
||||||
|
|
||||||
|
function(get_generated_output generated_files)
|
||||||
|
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
|
||||||
|
set(${generated_files} ${tmp} PARENT_SCOPE)
|
||||||
|
endfunction(get_generated_output)
|
||||||
|
|
||||||
|
function(register_generated_output file_name)
|
||||||
|
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
|
||||||
|
list(APPEND tmp ${file_name})
|
||||||
|
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS ${tmp})
|
||||||
|
endfunction(register_generated_output)
|
||||||
|
|
||||||
|
function(compile_flatbuffers_schema_to_cpp_opt SRC_FBS OPT)
|
||||||
|
if(FLATBUFFERS_BUILD_LEGACY)
|
||||||
|
set(OPT ${OPT};--cpp-std c++0x)
|
||||||
|
else()
|
||||||
|
# --cpp-std is defined by flatc default settings.
|
||||||
|
endif()
|
||||||
|
message(STATUS "`${SRC_FBS}`: add generation of C++ code with '${OPT}'")
|
||||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||||
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
|
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${GEN_HEADER}
|
OUTPUT ${GEN_HEADER}
|
||||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
|
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
|
||||||
--gen-object-api --gen-compare -o "${SRC_FBS_DIR}"
|
--cpp --gen-mutable --gen-object-api --reflect-names
|
||||||
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||||
--reflect-names
|
${OPT}
|
||||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||||
|
-o "${SRC_FBS_DIR}"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
DEPENDS flatc)
|
DEPENDS flatc
|
||||||
|
COMMENT "Run generation: '${GEN_HEADER}'")
|
||||||
|
register_generated_output(${GEN_HEADER})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
||||||
|
compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare")
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
function(compile_flatbuffers_schema_to_binary SRC_FBS)
|
function(compile_flatbuffers_schema_to_binary SRC_FBS)
|
||||||
|
message(STATUS "`${SRC_FBS}`: add generation of binary (.bfbs) schema")
|
||||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||||
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
|
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
|
||||||
|
# For details about flags see generate_code.bat(sh)
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${GEN_BINARY_SCHEMA}
|
OUTPUT ${GEN_BINARY_SCHEMA}
|
||||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -b --schema -o "${SRC_FBS_DIR}"
|
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
|
||||||
|
-b --schema --bfbs-comments --bfbs-builtins
|
||||||
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||||
|
-o "${SRC_FBS_DIR}"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
DEPENDS flatc)
|
DEPENDS flatc
|
||||||
|
COMMENT "Run generation: '${GEN_BINARY_SCHEMA}'")
|
||||||
|
register_generated_output(${GEN_BINARY_SCHEMA})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(compile_flatbuffers_schema_to_embedded_binary SRC_FBS OPT)
|
||||||
|
if(FLATBUFFERS_BUILD_LEGACY)
|
||||||
|
set(OPT ${OPT};--cpp-std c++0x)
|
||||||
|
else()
|
||||||
|
# --cpp-std is defined by flatc default settings.
|
||||||
|
endif()
|
||||||
|
message(STATUS "`${SRC_FBS}`: add generation of C++ embedded binary schema code with '${OPT}'")
|
||||||
|
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||||
|
string(REGEX REPLACE "\\.fbs$" "_bfbs_generated.h" GEN_BFBS_HEADER ${SRC_FBS})
|
||||||
|
# For details about flags see generate_code.bat(sh)
|
||||||
|
add_custom_command(
|
||||||
|
OUTPUT ${GEN_BFBS_HEADER}
|
||||||
|
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
|
||||||
|
--cpp --gen-mutable --gen-object-api --reflect-names
|
||||||
|
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||||
|
${OPT}
|
||||||
|
--bfbs-comments --bfbs-builtins --bfbs-gen-embed
|
||||||
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||||
|
-o "${SRC_FBS_DIR}"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
|
DEPENDS flatc
|
||||||
|
COMMENT "Run generation: '${GEN_BFBS_HEADER}'")
|
||||||
|
register_generated_output(${GEN_BFBS_HEADER})
|
||||||
endfunction()
|
endfunction()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_TESTS)
|
if(FLATBUFFERS_BUILD_TESTS)
|
||||||
|
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
|
|
||||||
|
# TODO Add (monster_test.fbs monsterdata_test.json)->monsterdata_test.mon
|
||||||
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
|
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
|
||||||
|
compile_flatbuffers_schema_to_binary(tests/monster_test.fbs)
|
||||||
|
compile_flatbuffers_schema_to_cpp(tests/namespace_test/namespace_test1.fbs)
|
||||||
|
compile_flatbuffers_schema_to_cpp(tests/namespace_test/namespace_test2.fbs)
|
||||||
|
compile_flatbuffers_schema_to_cpp(tests/union_vector/union_vector.fbs)
|
||||||
|
compile_flatbuffers_schema_to_cpp_opt(tests/native_type_test.fbs "")
|
||||||
|
compile_flatbuffers_schema_to_cpp_opt(tests/arrays_test.fbs "--scoped-enums;--gen-compare")
|
||||||
|
compile_flatbuffers_schema_to_binary(tests/arrays_test.fbs)
|
||||||
|
compile_flatbuffers_schema_to_embedded_binary(tests/monster_test.fbs "--no-includes;--gen-compare")
|
||||||
|
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
|
||||||
|
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
|
||||||
|
endif()
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
|
||||||
add_executable(flattests ${FlatBuffers_Tests_SRCS})
|
add_executable(flattests ${FlatBuffers_Tests_SRCS})
|
||||||
|
add_dependencies(flattests generated_code)
|
||||||
set_property(TARGET flattests
|
set_property(TARGET flattests
|
||||||
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
PROPERTY COMPILE_DEFINITIONS FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||||
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
|
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1)
|
||||||
if(FLATBUFFERS_CODE_SANITIZE)
|
if(FLATBUFFERS_CODE_SANITIZE)
|
||||||
if(WIN32)
|
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
|
||||||
target_compile_definitions(flattests PRIVATE FLATBUFFERS_MEMORY_LEAK_TRACKING)
|
|
||||||
message(STATUS "Sanitizer MSVC::_CrtDumpMemoryLeaks added to flattests")
|
|
||||||
else()
|
|
||||||
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
|
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
|
||||||
|
compile_flatbuffers_schema_to_binary(samples/monster.fbs)
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
|
||||||
add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
|
add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
|
||||||
|
add_dependencies(flatsamplebinary generated_code)
|
||||||
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
|
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
|
||||||
|
add_dependencies(flatsampletext generated_code)
|
||||||
add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
|
add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
|
||||||
|
add_dependencies(flatsamplebfbs generated_code)
|
||||||
|
|
||||||
|
if(FLATBUFFERS_BUILD_CPP17)
|
||||||
|
# Don't generate header for flattests_cpp17 target.
|
||||||
|
# This target uses "generated_cpp17/monster_test_generated.h"
|
||||||
|
# produced by direct call of generate_code.bat(sh) script.
|
||||||
|
add_executable(flattests_cpp17 ${FlatBuffers_Tests_CPP17_SRCS})
|
||||||
|
add_dependencies(flattests_cpp17 generated_code)
|
||||||
|
target_compile_features(flattests_cpp17 PRIVATE cxx_std_17)
|
||||||
|
target_compile_definitions(flattests_cpp17 PRIVATE
|
||||||
|
FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||||
|
FLATBUFFERS_DEBUG_VERIFICATION_FAILURE=1
|
||||||
|
)
|
||||||
|
if(FLATBUFFERS_CODE_SANITIZE)
|
||||||
|
add_fsanitize_to_target(flattests_cpp17 ${FLATBUFFERS_CODE_SANITIZE})
|
||||||
|
endif()
|
||||||
|
endif(FLATBUFFERS_BUILD_CPP17)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_GRPCTEST)
|
if(FLATBUFFERS_BUILD_GRPCTEST)
|
||||||
@@ -356,7 +506,12 @@ if(FLATBUFFERS_BUILD_GRPCTEST)
|
|||||||
INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
|
INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
|
||||||
LINK_DIRECTORIES(${GRPC_INSTALL_PATH}/lib)
|
LINK_DIRECTORIES(${GRPC_INSTALL_PATH}/lib)
|
||||||
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
||||||
target_link_libraries(grpctest grpc++_unsecure grpc_unsecure gpr pthread dl)
|
add_dependencies(grpctest generated_code)
|
||||||
|
target_link_libraries(grpctest PRIVATE grpc++_unsecure grpc_unsecure gpr pthread dl)
|
||||||
|
if(FLATBUFFERS_CODE_SANITIZE AND NOT WIN32)
|
||||||
|
# GRPC test has problems with alignment and will fail under ASAN/UBSAN.
|
||||||
|
# add_fsanitize_to_target(grpctest ${FLATBUFFERS_CODE_SANITIZE})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CMake/Version.cmake)
|
include(CMake/Version.cmake)
|
||||||
@@ -439,14 +594,25 @@ endif()
|
|||||||
if(FLATBUFFERS_BUILD_TESTS)
|
if(FLATBUFFERS_BUILD_TESTS)
|
||||||
enable_testing()
|
enable_testing()
|
||||||
|
|
||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION
|
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
|
||||||
add_test(NAME flattests COMMAND flattests)
|
add_test(NAME flattests COMMAND flattests)
|
||||||
|
if(FLATBUFFERS_BUILD_CPP17)
|
||||||
|
add_test(NAME flattests_cpp17 COMMAND flattests_cpp17)
|
||||||
|
endif()
|
||||||
if(FLATBUFFERS_BUILD_GRPCTEST)
|
if(FLATBUFFERS_BUILD_GRPCTEST)
|
||||||
add_test(NAME grpctest COMMAND grpctest)
|
add_test(NAME grpctest COMMAND grpctest)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# This target is sync-barrier.
|
||||||
|
# Other generate-dependent targets can depend on 'generated_code' only.
|
||||||
|
get_generated_output(fbs_generated)
|
||||||
|
if(fbs_generated)
|
||||||
|
# message(STATUS "Add generated_code target with files:${fbs_generated}")
|
||||||
|
add_custom_target(generated_code
|
||||||
|
DEPENDS ${fbs_generated}
|
||||||
|
COMMENT "All generated files were updated.")
|
||||||
|
endif()
|
||||||
|
|
||||||
include(CMake/BuildFlatBuffers.cmake)
|
include(CMake/BuildFlatBuffers.cmake)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
|
|||||||
@@ -187,7 +187,7 @@
|
|||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright 2014 Google Inc.
|
Copyright [yyyy] [name of copyright owner]
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
@@ -4,11 +4,14 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
|||||||
|
|
||||||
http_archive(
|
http_archive(
|
||||||
name = "io_bazel_rules_go",
|
name = "io_bazel_rules_go",
|
||||||
sha256 = "492c3ac68ed9dcf527a07e6a1b2dcbf199c6bf8b35517951467ac32e421c06c1",
|
urls = [
|
||||||
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.17.0/rules_go-0.17.0.tar.gz"],
|
"https://storage.googleapis.com/bazel-mirror/github.com/bazelbuild/rules_go/releases/download/v0.20.3/rules_go-v0.20.3.tar.gz",
|
||||||
|
"https://github.com/bazelbuild/rules_go/releases/download/v0.20.3/rules_go-v0.20.3.tar.gz",
|
||||||
|
],
|
||||||
|
sha256 = "e88471aea3a3a4f19ec1310a55ba94772d087e9ce46e41ae38ecebe17935de7b",
|
||||||
)
|
)
|
||||||
|
|
||||||
load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_dependencies")
|
load("@io_bazel_rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
|
||||||
|
|
||||||
go_rules_dependencies()
|
go_rules_dependencies()
|
||||||
|
|
||||||
|
|||||||
@@ -36,8 +36,7 @@ LOCAL_MODULE := flatbuffers_extra
|
|||||||
LOCAL_SRC_FILES := src/idl_parser.cpp \
|
LOCAL_SRC_FILES := src/idl_parser.cpp \
|
||||||
src/idl_gen_text.cpp \
|
src/idl_gen_text.cpp \
|
||||||
src/reflection.cpp \
|
src/reflection.cpp \
|
||||||
src/util.cpp \
|
src/util.cpp
|
||||||
src/code_generators.cpp
|
|
||||||
LOCAL_STATIC_LIBRARIES := flatbuffers
|
LOCAL_STATIC_LIBRARIES := flatbuffers
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
@@ -51,8 +50,10 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
|
|||||||
tests/test_builder.h \
|
tests/test_builder.h \
|
||||||
tests/test_assert.cpp \
|
tests/test_assert.cpp \
|
||||||
tests/test_builder.cpp \
|
tests/test_builder.cpp \
|
||||||
|
tests/native_type_test_impl.h \
|
||||||
|
tests/native_type_test_impl.cpp \
|
||||||
src/idl_gen_fbs.cpp \
|
src/idl_gen_fbs.cpp \
|
||||||
src/idl_gen_general.cpp
|
src/code_generators.cpp
|
||||||
LOCAL_LDLIBS := -llog -landroid -latomic
|
LOCAL_LDLIBS := -llog -landroid -latomic
|
||||||
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
|
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers_extra
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
|
|||||||
@@ -18,9 +18,6 @@
|
|||||||
|
|
||||||
extern int main(int argc, char **argv);
|
extern int main(int argc, char **argv);
|
||||||
|
|
||||||
void android_main(android_app *app) {
|
void android_main(android_app *) {
|
||||||
// Make sure glue isn't stripped.
|
|
||||||
app_dummy();
|
|
||||||
|
|
||||||
main(0, NULL);
|
main(0, NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
36
appveyor.yml
36
appveyor.yml
@@ -2,23 +2,36 @@ branches:
|
|||||||
only:
|
only:
|
||||||
- master
|
- master
|
||||||
|
|
||||||
os: Visual Studio 2015
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
||||||
global:
|
global:
|
||||||
# Workaround for https://github.com/conda/conda-build/issues/636
|
# Workaround for https://github.com/conda/conda-build/issues/636
|
||||||
PYTHONIOENCODING: UTF-8
|
PYTHONIOENCODING: UTF-8
|
||||||
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
|
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
|
||||||
|
CMAKE_OPTIONS: ""
|
||||||
|
CPP_TEST_OPTIONS: ""
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- CMAKE_VS_VERSION: "10 2010"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
CMAKE_VS_VERSION: "10 2010"
|
||||||
|
CMAKE_OPTIONS: "-DFLATBUFFERS_BUILD_LEGACY=1"
|
||||||
|
CPP_TEST_OPTIONS: "--std-cpp c++0x"
|
||||||
MONSTER_EXTRA: "skip"
|
MONSTER_EXTRA: "skip"
|
||||||
|
|
||||||
- CMAKE_VS_VERSION: "12 2013"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
CMAKE_VS_VERSION: "12 2013"
|
||||||
MONSTER_EXTRA: "skip"
|
MONSTER_EXTRA: "skip"
|
||||||
|
|
||||||
- CMAKE_VS_VERSION: "14 2015"
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
|
||||||
|
CMAKE_VS_VERSION: "14 2015"
|
||||||
|
MONSTER_EXTRA: ""
|
||||||
|
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017
|
||||||
|
CMAKE_VS_VERSION: "15 2017"
|
||||||
|
MONSTER_EXTRA: ""
|
||||||
|
|
||||||
|
- APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019
|
||||||
|
CMAKE_VS_VERSION: "16 2019"
|
||||||
MONSTER_EXTRA: ""
|
MONSTER_EXTRA: ""
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
@@ -31,9 +44,11 @@ configuration:
|
|||||||
|
|
||||||
before_build:
|
before_build:
|
||||||
- set MONSTER_EXTRA=%MONSTER_EXTRA%
|
- set MONSTER_EXTRA=%MONSTER_EXTRA%
|
||||||
- cmake -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 .
|
- cmake . -G"Visual Studio %CMAKE_VS_VERSION%" -DFLATBUFFERS_CODE_SANITIZE=1 %CMAKE_OPTIONS%
|
||||||
# This cuts down on a lot of noise generated by xamarin warnings.
|
# 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"
|
- if exist "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\14.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
|
||||||
|
- if exist "C:\Program Files (x86)\MSBuild\15.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\15.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
|
||||||
|
- if exist "C:\Program Files (x86)\MSBuild\16.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets" del "C:\Program Files (x86)\MSBuild\16.0\Microsoft.Common.targets\ImportAfter\Xamarin.Common.targets"
|
||||||
|
|
||||||
build:
|
build:
|
||||||
project: ALL_BUILD.vcxproj
|
project: ALL_BUILD.vcxproj
|
||||||
@@ -55,7 +70,7 @@ test_script:
|
|||||||
- call .appveyor\check-generate-code.bat -b %CONFIGURATION%
|
- call .appveyor\check-generate-code.bat -b %CONFIGURATION%
|
||||||
- "cd tests"
|
- "cd tests"
|
||||||
- rem "Building all code"
|
- rem "Building all code"
|
||||||
- generate_code.bat -b %CONFIGURATION%
|
- generate_code.bat -b %CONFIGURATION% %CPP_TEST_OPTIONS%
|
||||||
- 7z a GeneratedMyGameCode.zip MyGame\
|
- 7z a GeneratedMyGameCode.zip MyGame\
|
||||||
- rem "---------------- C++ -----------------"
|
- rem "---------------- C++ -----------------"
|
||||||
- "cd .."
|
- "cd .."
|
||||||
@@ -90,6 +105,11 @@ test_script:
|
|||||||
# Have to compile this here rather than in "build" above because AppVeyor only
|
# Have to compile this here rather than in "build" above because AppVeyor only
|
||||||
# supports building one project??
|
# supports building one project??
|
||||||
- "cd FlatBuffers.Test"
|
- "cd FlatBuffers.Test"
|
||||||
|
- "copy ..\\monsterdata_test.mon Resources\\"
|
||||||
|
- "copy ..\\monsterdata_test.json Resources\\"
|
||||||
|
- "dotnet new sln"
|
||||||
|
- "dotnet sln add FlatBuffers.Test.csproj"
|
||||||
|
- "nuget restore"
|
||||||
- "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
|
- "msbuild.exe /property:Configuration=Release;OutputPath=tempcs /verbosity:minimal FlatBuffers.Test.csproj"
|
||||||
- "tempcs\\FlatBuffers.Test.exe"
|
- "tempcs\\FlatBuffers.Test.exe"
|
||||||
# Run tests with UNSAFE_BYTEBUFFER
|
# Run tests with UNSAFE_BYTEBUFFER
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
Rules for building C++ flatbuffers with Bazel.
|
Rules for building C++ flatbuffers with Bazel.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||||
|
|
||||||
flatc_path = "@com_github_google_flatbuffers//:flatc"
|
flatc_path = "@com_github_google_flatbuffers//:flatc"
|
||||||
|
|
||||||
DEFAULT_INCLUDE_PATHS = [
|
DEFAULT_INCLUDE_PATHS = [
|
||||||
@@ -32,7 +34,9 @@ def flatbuffer_library_public(
|
|||||||
include_paths = DEFAULT_INCLUDE_PATHS,
|
include_paths = DEFAULT_INCLUDE_PATHS,
|
||||||
flatc_args = DEFAULT_FLATC_ARGS,
|
flatc_args = DEFAULT_FLATC_ARGS,
|
||||||
reflection_name = "",
|
reflection_name = "",
|
||||||
reflection_visiblity = None,
|
reflection_visibility = None,
|
||||||
|
compatible_with = None,
|
||||||
|
restricted_to = None,
|
||||||
output_to_bindir = False):
|
output_to_bindir = False):
|
||||||
"""Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
|
"""Generates code files for reading/writing the given flatbuffers in the requested language using the public compiler.
|
||||||
|
|
||||||
@@ -48,7 +52,12 @@ def flatbuffer_library_public(
|
|||||||
flatc_args: Optional, list of additional arguments to pass to flatc.
|
flatc_args: Optional, list of additional arguments to pass to flatc.
|
||||||
reflection_name: Optional, if set this will generate the flatbuffer
|
reflection_name: Optional, if set this will generate the flatbuffer
|
||||||
reflection binaries for the schemas.
|
reflection binaries for the schemas.
|
||||||
reflection_visiblity: The visibility of the generated reflection Fileset.
|
reflection_visibility: The visibility of the generated reflection Fileset.
|
||||||
|
output_to_bindir: Passed to genrule for output to bin directory.
|
||||||
|
compatible_with: Optional, The list of environments this rule can be
|
||||||
|
built for, in addition to default-supported environments.
|
||||||
|
restricted_to: Optional, The list of environments this rule can be built
|
||||||
|
for, instead of default-supported environments.
|
||||||
output_to_bindir: Passed to genrule for output to bin directory.
|
output_to_bindir: Passed to genrule for output to bin directory.
|
||||||
|
|
||||||
|
|
||||||
@@ -82,6 +91,8 @@ def flatbuffer_library_public(
|
|||||||
output_to_bindir = output_to_bindir,
|
output_to_bindir = output_to_bindir,
|
||||||
tools = [flatc_path],
|
tools = [flatc_path],
|
||||||
cmd = genrule_cmd,
|
cmd = genrule_cmd,
|
||||||
|
compatible_with = compatible_with,
|
||||||
|
restricted_to = restricted_to,
|
||||||
message = "Generating flatbuffer files for %s:" % (name),
|
message = "Generating flatbuffer files for %s:" % (name),
|
||||||
)
|
)
|
||||||
if reflection_name:
|
if reflection_name:
|
||||||
@@ -107,16 +118,17 @@ def flatbuffer_library_public(
|
|||||||
outs = reflection_outs,
|
outs = reflection_outs,
|
||||||
output_to_bindir = output_to_bindir,
|
output_to_bindir = output_to_bindir,
|
||||||
tools = [flatc_path],
|
tools = [flatc_path],
|
||||||
|
compatible_with = compatible_with,
|
||||||
|
restricted_to = restricted_to,
|
||||||
cmd = reflection_genrule_cmd,
|
cmd = reflection_genrule_cmd,
|
||||||
message = "Generating flatbuffer reflection binary for %s:" % (name),
|
message = "Generating flatbuffer reflection binary for %s:" % (name),
|
||||||
)
|
)
|
||||||
native.Fileset(
|
native.filegroup(
|
||||||
name = reflection_name,
|
name = "%s_out" % reflection_name,
|
||||||
out = "%s_out" % reflection_name,
|
srcs = reflection_outs,
|
||||||
entries = [
|
visibility = reflection_visibility,
|
||||||
native.FilesetEntry(files = reflection_outs),
|
compatible_with = compatible_with,
|
||||||
],
|
restricted_to = restricted_to,
|
||||||
visibility = reflection_visiblity,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
def flatbuffer_cc_library(
|
def flatbuffer_cc_library(
|
||||||
@@ -128,6 +140,8 @@ def flatbuffer_cc_library(
|
|||||||
include_paths = DEFAULT_INCLUDE_PATHS,
|
include_paths = DEFAULT_INCLUDE_PATHS,
|
||||||
flatc_args = DEFAULT_FLATC_ARGS,
|
flatc_args = DEFAULT_FLATC_ARGS,
|
||||||
visibility = None,
|
visibility = None,
|
||||||
|
compatible_with = None,
|
||||||
|
restricted_to = None,
|
||||||
srcs_filegroup_visibility = None,
|
srcs_filegroup_visibility = None,
|
||||||
gen_reflections = False):
|
gen_reflections = False):
|
||||||
'''A cc_library with the generated reader/writers for the given flatbuffer definitions.
|
'''A cc_library with the generated reader/writers for the given flatbuffer definitions.
|
||||||
@@ -151,6 +165,10 @@ def flatbuffer_cc_library(
|
|||||||
By default, use the value of the visibility parameter above.
|
By default, use the value of the visibility parameter above.
|
||||||
gen_reflections: Optional, if true this will generate the flatbuffer
|
gen_reflections: Optional, if true this will generate the flatbuffer
|
||||||
reflection binaries for the schemas.
|
reflection binaries for the schemas.
|
||||||
|
compatible_with: Optional, The list of environments this rule can be built
|
||||||
|
for, in addition to default-supported environments.
|
||||||
|
restricted_to: Optional, The list of environments this rule can be built
|
||||||
|
for, instead of default-supported environments.
|
||||||
|
|
||||||
This produces:
|
This produces:
|
||||||
filegroup([name]_srcs): all generated .h files.
|
filegroup([name]_srcs): all generated .h files.
|
||||||
@@ -206,10 +224,12 @@ def flatbuffer_cc_library(
|
|||||||
includes = includes,
|
includes = includes,
|
||||||
include_paths = include_paths,
|
include_paths = include_paths,
|
||||||
flatc_args = flatc_args,
|
flatc_args = flatc_args,
|
||||||
|
compatible_with = compatible_with,
|
||||||
|
restricted_to = restricted_to,
|
||||||
reflection_name = reflection_name,
|
reflection_name = reflection_name,
|
||||||
reflection_visiblity = visibility,
|
reflection_visibility = visibility,
|
||||||
)
|
)
|
||||||
native.cc_library(
|
cc_library(
|
||||||
name = name,
|
name = name,
|
||||||
hdrs = [
|
hdrs = [
|
||||||
":" + srcs_lib,
|
":" + srcs_lib,
|
||||||
@@ -224,6 +244,8 @@ def flatbuffer_cc_library(
|
|||||||
"@com_github_google_flatbuffers//:runtime_cc",
|
"@com_github_google_flatbuffers//:runtime_cc",
|
||||||
],
|
],
|
||||||
includes = [],
|
includes = [],
|
||||||
|
compatible_with = compatible_with,
|
||||||
|
restricted_to = restricted_to,
|
||||||
linkstatic = 1,
|
linkstatic = 1,
|
||||||
visibility = visibility,
|
visibility = visibility,
|
||||||
)
|
)
|
||||||
@@ -233,5 +255,7 @@ def flatbuffer_cc_library(
|
|||||||
native.filegroup(
|
native.filegroup(
|
||||||
name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
|
name = srcs_filegroup_name if srcs_filegroup_name else "%s_includes" % (name),
|
||||||
srcs = srcs,
|
srcs = srcs,
|
||||||
|
compatible_with = compatible_with,
|
||||||
|
restricted_to = restricted_to,
|
||||||
visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
|
visibility = srcs_filegroup_visibility if srcs_filegroup_visibility != None else visibility,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -492,7 +492,7 @@ class Builder {
|
|||||||
/// Write the given list of 64-bit float [values].
|
/// Write the given list of 64-bit float [values].
|
||||||
int writeListFloat64(List<double> values) {
|
int writeListFloat64(List<double> values) {
|
||||||
_ensureNoVTable();
|
_ensureNoVTable();
|
||||||
_prepare(4, 1 + (2 * values.length));
|
_prepare(_sizeofFloat64, values.length, additionalBytes: _sizeofUint32);
|
||||||
final int result = _tail;
|
final int result = _tail;
|
||||||
int tail = _tail;
|
int tail = _tail;
|
||||||
_setUint32AtTail(_buf, tail, values.length);
|
_setUint32AtTail(_buf, tail, values.length);
|
||||||
@@ -522,7 +522,7 @@ class Builder {
|
|||||||
/// Write the given list of signed 64-bit integer [values].
|
/// Write the given list of signed 64-bit integer [values].
|
||||||
int writeListInt64(List<int> values) {
|
int writeListInt64(List<int> values) {
|
||||||
_ensureNoVTable();
|
_ensureNoVTable();
|
||||||
_prepare(_sizeofUint32, 2 * values.length);
|
_prepare(_sizeofInt64, values.length, additionalBytes: _sizeofUint32);
|
||||||
final int result = _tail;
|
final int result = _tail;
|
||||||
int tail = _tail;
|
int tail = _tail;
|
||||||
_setUint32AtTail(_buf, tail, values.length);
|
_setUint32AtTail(_buf, tail, values.length);
|
||||||
@@ -537,7 +537,7 @@ class Builder {
|
|||||||
/// Write the given list of signed 64-bit integer [values].
|
/// Write the given list of signed 64-bit integer [values].
|
||||||
int writeListUint64(List<int> values) {
|
int writeListUint64(List<int> values) {
|
||||||
_ensureNoVTable();
|
_ensureNoVTable();
|
||||||
_prepare(_sizeofUint32, 2 * values.length);
|
_prepare(_sizeofUint64, values.length, additionalBytes: _sizeofUint32);
|
||||||
final int result = _tail;
|
final int result = _tail;
|
||||||
int tail = _tail;
|
int tail = _tail;
|
||||||
_setUint32AtTail(_buf, tail, values.length);
|
_setUint32AtTail(_buf, tail, values.length);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: flat_buffers
|
name: flat_buffers
|
||||||
version: 1.11.0
|
version: 1.12.0
|
||||||
description: >
|
description: >
|
||||||
FlatBuffers reading and writing library for Dart. Use the flatc compiler to
|
FlatBuffers reading and writing library for Dart. Use the flatc compiler to
|
||||||
generate Dart classes for a FlatBuffers schema, and this library to assist with
|
generate Dart classes for a FlatBuffers schema, and this library to assist with
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import 'include_test2_my_game.example_generated.dart';
|
|||||||
import './monster_test_my_game_generated.dart' as my_game;
|
import './monster_test_my_game_generated.dart' as my_game;
|
||||||
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
|
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
|
||||||
|
|
||||||
|
/// Composite components of Monster color.
|
||||||
class Color {
|
class Color {
|
||||||
final int value;
|
final int value;
|
||||||
const Color._(this.value);
|
const Color._(this.value);
|
||||||
@@ -26,7 +27,12 @@ class Color {
|
|||||||
static bool containsValue(int value) => values.containsKey(value);
|
static bool containsValue(int value) => values.containsKey(value);
|
||||||
|
|
||||||
static const Color Red = const Color._(1);
|
static const Color Red = const Color._(1);
|
||||||
|
|
||||||
|
/// \brief color Green
|
||||||
|
/// Green is bit_flag with value (1u << 1)
|
||||||
static const Color Green = const Color._(2);
|
static const Color Green = const Color._(2);
|
||||||
|
|
||||||
|
/// \brief color Blue (1u << 3)
|
||||||
static const Color Blue = const Color._(8);
|
static const Color Blue = const Color._(8);
|
||||||
static get values => {1: Red,2: Green,8: Blue,};
|
static get values => {1: Red,2: Green,8: Blue,};
|
||||||
|
|
||||||
@@ -46,7 +52,48 @@ class _ColorReader extends fb.Reader<Color> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Color read(fb.BufferContext bc, int offset) =>
|
Color read(fb.BufferContext bc, int offset) =>
|
||||||
new Color.fromValue(const fb.Int8Reader().read(bc, offset));
|
new Color.fromValue(const fb.Uint8Reader().read(bc, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Race {
|
||||||
|
final int value;
|
||||||
|
const Race._(this.value);
|
||||||
|
|
||||||
|
factory Race.fromValue(int value) {
|
||||||
|
if (value == null) value = 0;
|
||||||
|
if (!values.containsKey(value)) {
|
||||||
|
throw new StateError('Invalid value $value for bit flag enum Race');
|
||||||
|
}
|
||||||
|
return values[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int minValue = -1;
|
||||||
|
static const int maxValue = 2;
|
||||||
|
static bool containsValue(int value) => values.containsKey(value);
|
||||||
|
|
||||||
|
static const Race None = const Race._(-1);
|
||||||
|
static const Race Human = const Race._(0);
|
||||||
|
static const Race Dwarf = const Race._(1);
|
||||||
|
static const Race Elf = const Race._(2);
|
||||||
|
static get values => {-1: None,0: Human,1: Dwarf,2: Elf,};
|
||||||
|
|
||||||
|
static const fb.Reader<Race> reader = const _RaceReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Race{value: $value}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _RaceReader extends fb.Reader<Race> {
|
||||||
|
const _RaceReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get size => 1;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Race read(fb.BufferContext bc, int offset) =>
|
||||||
|
new Race.fromValue(const fb.Int8Reader().read(bc, offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
class AnyTypeId {
|
class AnyTypeId {
|
||||||
@@ -108,9 +155,9 @@ class AnyUniqueAliasesTypeId {
|
|||||||
|
|
||||||
static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
|
static const AnyUniqueAliasesTypeId NONE = const AnyUniqueAliasesTypeId._(0);
|
||||||
static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
|
static const AnyUniqueAliasesTypeId M = const AnyUniqueAliasesTypeId._(1);
|
||||||
static const AnyUniqueAliasesTypeId T = const AnyUniqueAliasesTypeId._(2);
|
static const AnyUniqueAliasesTypeId TS = const AnyUniqueAliasesTypeId._(2);
|
||||||
static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
|
static const AnyUniqueAliasesTypeId M2 = const AnyUniqueAliasesTypeId._(3);
|
||||||
static get values => {0: NONE,1: M,2: T,3: M2,};
|
static get values => {0: NONE,1: M,2: TS,3: M2,};
|
||||||
|
|
||||||
static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
|
static const fb.Reader<AnyUniqueAliasesTypeId> reader = const _AnyUniqueAliasesTypeIdReader();
|
||||||
|
|
||||||
@@ -259,7 +306,7 @@ class TestSimpleTableWithEnum {
|
|||||||
final fb.BufferContext _bc;
|
final fb.BufferContext _bc;
|
||||||
final int _bcOffset;
|
final int _bcOffset;
|
||||||
|
|
||||||
Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 4, 2));
|
Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 4, 2));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
@@ -287,7 +334,7 @@ class TestSimpleTableWithEnumBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int addColor(Color color) {
|
int addColor(Color color) {
|
||||||
fbBuilder.addInt8(0, color?.value);
|
fbBuilder.addUint8(0, color?.value);
|
||||||
return fbBuilder.offset;
|
return fbBuilder.offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -311,7 +358,7 @@ class TestSimpleTableWithEnumObjectBuilder extends fb.ObjectBuilder {
|
|||||||
assert(fbBuilder != null);
|
assert(fbBuilder != null);
|
||||||
|
|
||||||
fbBuilder.startTable();
|
fbBuilder.startTable();
|
||||||
fbBuilder.addInt8(0, _color?.value);
|
fbBuilder.addUint8(0, _color?.value);
|
||||||
return fbBuilder.endTable();
|
return fbBuilder.endTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -335,7 +382,7 @@ class Vec3 {
|
|||||||
double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
|
double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
|
||||||
double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
|
double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
|
||||||
double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
|
double get test1 => const fb.Float64Reader().read(_bc, _bcOffset + 16);
|
||||||
Color get test2 => new Color.fromValue(const fb.Int8Reader().read(_bc, _bcOffset + 24));
|
Color get test2 => new Color.fromValue(const fb.Uint8Reader().read(_bc, _bcOffset + 24));
|
||||||
Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
|
Test get test3 => Test.reader.read(_bc, _bcOffset + 26);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -366,7 +413,7 @@ class Vec3Builder {
|
|||||||
fbBuilder.pad(2);
|
fbBuilder.pad(2);
|
||||||
test3();
|
test3();
|
||||||
fbBuilder.pad(1);
|
fbBuilder.pad(1);
|
||||||
fbBuilder.putInt8(test2?.value);
|
fbBuilder.putUint8(test2?.value);
|
||||||
fbBuilder.putFloat64(test1);
|
fbBuilder.putFloat64(test1);
|
||||||
fbBuilder.pad(4);
|
fbBuilder.pad(4);
|
||||||
fbBuilder.putFloat32(z);
|
fbBuilder.putFloat32(z);
|
||||||
@@ -409,7 +456,7 @@ class Vec3ObjectBuilder extends fb.ObjectBuilder {
|
|||||||
fbBuilder.pad(2);
|
fbBuilder.pad(2);
|
||||||
_test3.finish(fbBuilder);
|
_test3.finish(fbBuilder);
|
||||||
fbBuilder.pad(1);
|
fbBuilder.pad(1);
|
||||||
fbBuilder.putInt8(_test2?.value);
|
fbBuilder.putUint8(_test2?.value);
|
||||||
fbBuilder.putFloat64(_test1);
|
fbBuilder.putFloat64(_test1);
|
||||||
fbBuilder.pad(4);
|
fbBuilder.pad(4);
|
||||||
fbBuilder.putFloat32(_z);
|
fbBuilder.putFloat32(_z);
|
||||||
@@ -690,7 +737,7 @@ class Monster {
|
|||||||
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
|
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
|
||||||
String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
|
String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 10, null);
|
||||||
List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
|
List<int> get inventory => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 14, null);
|
||||||
Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 8));
|
Color get color => new Color.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 16, 8));
|
||||||
AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
|
AnyTypeId get testType => new AnyTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 18, 0));
|
||||||
dynamic get test {
|
dynamic get test {
|
||||||
switch (testType?.value) {
|
switch (testType?.value) {
|
||||||
@@ -702,8 +749,8 @@ class Monster {
|
|||||||
}
|
}
|
||||||
List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
|
List<Test> get test4 => const fb.ListReader<Test>(Test.reader).vTableGet(_bc, _bcOffset, 22, null);
|
||||||
List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
|
List<String> get testarrayofstring => const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 24, null);
|
||||||
/// an example documentation comment: this will end up in the generated code
|
/// an example documentation comment: this will end up in the generated code
|
||||||
/// multiline too
|
/// multiline too
|
||||||
List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
|
List<Monster> get testarrayoftables => const fb.ListReader<Monster>(Monster.reader).vTableGet(_bc, _bcOffset, 26, null);
|
||||||
Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
|
Monster get enemy => Monster.reader.vTableGet(_bc, _bcOffset, 28, null);
|
||||||
List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
|
List<int> get testnestedflatbuffer => const fb.ListReader<int>(const fb.Uint8Reader()).vTableGet(_bc, _bcOffset, 30, null);
|
||||||
@@ -740,7 +787,7 @@ class Monster {
|
|||||||
dynamic get anyUnique {
|
dynamic get anyUnique {
|
||||||
switch (anyUniqueType?.value) {
|
switch (anyUniqueType?.value) {
|
||||||
case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
|
case 1: return M.reader.vTableGet(_bc, _bcOffset, 92, null);
|
||||||
case 2: return T.reader.vTableGet(_bc, _bcOffset, 92, null);
|
case 2: return TS.reader.vTableGet(_bc, _bcOffset, 92, null);
|
||||||
case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
|
case 3: return M2.reader.vTableGet(_bc, _bcOffset, 92, null);
|
||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
@@ -755,10 +802,11 @@ class Monster {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
|
List<Color> get vectorOfEnums => const fb.ListReader<Color>(Color.reader).vTableGet(_bc, _bcOffset, 98, null);
|
||||||
|
Race get signedEnum => new Race.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 100, -1));
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums}';
|
return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, testType: $testType, test: $test, test4: $test4, testarrayofstring: $testarrayofstring, testarrayoftables: $testarrayoftables, enemy: $enemy, testnestedflatbuffer: $testnestedflatbuffer, testempty: $testempty, testbool: $testbool, testhashs32Fnv1: $testhashs32Fnv1, testhashu32Fnv1: $testhashu32Fnv1, testhashs64Fnv1: $testhashs64Fnv1, testhashu64Fnv1: $testhashu64Fnv1, testhashs32Fnv1a: $testhashs32Fnv1a, testhashu32Fnv1a: $testhashu32Fnv1a, testhashs64Fnv1a: $testhashs64Fnv1a, testhashu64Fnv1a: $testhashu64Fnv1a, testarrayofbools: $testarrayofbools, testf: $testf, testf2: $testf2, testf3: $testf3, testarrayofstring2: $testarrayofstring2, testarrayofsortedstruct: $testarrayofsortedstruct, flex: $flex, test5: $test5, vectorOfLongs: $vectorOfLongs, vectorOfDoubles: $vectorOfDoubles, parentNamespaceTest: $parentNamespaceTest, vectorOfReferrables: $vectorOfReferrables, singleWeakReference: $singleWeakReference, vectorOfWeakReferences: $vectorOfWeakReferences, vectorOfStrongReferrables: $vectorOfStrongReferrables, coOwningReference: $coOwningReference, vectorOfCoOwningReferences: $vectorOfCoOwningReferences, nonOwningReference: $nonOwningReference, vectorOfNonOwningReferences: $vectorOfNonOwningReferences, anyUniqueType: $anyUniqueType, anyUnique: $anyUnique, anyAmbiguousType: $anyAmbiguousType, anyAmbiguous: $anyAmbiguous, vectorOfEnums: $vectorOfEnums, signedEnum: $signedEnum}';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -802,7 +850,7 @@ class MonsterBuilder {
|
|||||||
return fbBuilder.offset;
|
return fbBuilder.offset;
|
||||||
}
|
}
|
||||||
int addColor(Color color) {
|
int addColor(Color color) {
|
||||||
fbBuilder.addInt8(6, color?.value);
|
fbBuilder.addUint8(6, color?.value);
|
||||||
return fbBuilder.offset;
|
return fbBuilder.offset;
|
||||||
}
|
}
|
||||||
int addTestType(AnyTypeId testType) {
|
int addTestType(AnyTypeId testType) {
|
||||||
@@ -969,6 +1017,10 @@ class MonsterBuilder {
|
|||||||
fbBuilder.addOffset(47, offset);
|
fbBuilder.addOffset(47, offset);
|
||||||
return fbBuilder.offset;
|
return fbBuilder.offset;
|
||||||
}
|
}
|
||||||
|
int addSignedEnum(Race signedEnum) {
|
||||||
|
fbBuilder.addInt8(48, signedEnum?.value);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
|
||||||
int finish() {
|
int finish() {
|
||||||
return fbBuilder.endTable();
|
return fbBuilder.endTable();
|
||||||
@@ -1023,6 +1075,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
|
|||||||
final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
|
final AnyAmbiguousAliasesTypeId _anyAmbiguousType;
|
||||||
final dynamic _anyAmbiguous;
|
final dynamic _anyAmbiguous;
|
||||||
final List<Color> _vectorOfEnums;
|
final List<Color> _vectorOfEnums;
|
||||||
|
final Race _signedEnum;
|
||||||
|
|
||||||
MonsterObjectBuilder({
|
MonsterObjectBuilder({
|
||||||
Vec3ObjectBuilder pos,
|
Vec3ObjectBuilder pos,
|
||||||
@@ -1072,6 +1125,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
|
|||||||
AnyAmbiguousAliasesTypeId anyAmbiguousType,
|
AnyAmbiguousAliasesTypeId anyAmbiguousType,
|
||||||
dynamic anyAmbiguous,
|
dynamic anyAmbiguous,
|
||||||
List<Color> vectorOfEnums,
|
List<Color> vectorOfEnums,
|
||||||
|
Race signedEnum,
|
||||||
})
|
})
|
||||||
: _pos = pos,
|
: _pos = pos,
|
||||||
_mana = mana,
|
_mana = mana,
|
||||||
@@ -1119,7 +1173,8 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
|
|||||||
_anyUnique = anyUnique,
|
_anyUnique = anyUnique,
|
||||||
_anyAmbiguousType = anyAmbiguousType,
|
_anyAmbiguousType = anyAmbiguousType,
|
||||||
_anyAmbiguous = anyAmbiguous,
|
_anyAmbiguous = anyAmbiguous,
|
||||||
_vectorOfEnums = vectorOfEnums;
|
_vectorOfEnums = vectorOfEnums,
|
||||||
|
_signedEnum = signedEnum;
|
||||||
|
|
||||||
/// Finish building, and store into the [fbBuilder].
|
/// Finish building, and store into the [fbBuilder].
|
||||||
@override
|
@override
|
||||||
@@ -1185,7 +1240,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
|
|||||||
final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
|
final int anyUniqueOffset = _anyUnique?.getOrCreateOffset(fbBuilder);
|
||||||
final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
|
final int anyAmbiguousOffset = _anyAmbiguous?.getOrCreateOffset(fbBuilder);
|
||||||
final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
|
final int vectorOfEnumsOffset = _vectorOfEnums?.isNotEmpty == true
|
||||||
? fbBuilder.writeListInt8(_vectorOfEnums.map((f) => f.value))
|
? fbBuilder.writeListUint8(_vectorOfEnums.map((f) => f.value))
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
fbBuilder.startTable();
|
fbBuilder.startTable();
|
||||||
@@ -1200,7 +1255,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
|
|||||||
if (inventoryOffset != null) {
|
if (inventoryOffset != null) {
|
||||||
fbBuilder.addOffset(5, inventoryOffset);
|
fbBuilder.addOffset(5, inventoryOffset);
|
||||||
}
|
}
|
||||||
fbBuilder.addInt8(6, _color?.value);
|
fbBuilder.addUint8(6, _color?.value);
|
||||||
fbBuilder.addUint8(7, _testType?.value);
|
fbBuilder.addUint8(7, _testType?.value);
|
||||||
if (testOffset != null) {
|
if (testOffset != null) {
|
||||||
fbBuilder.addOffset(8, testOffset);
|
fbBuilder.addOffset(8, testOffset);
|
||||||
@@ -1288,6 +1343,7 @@ class MonsterObjectBuilder extends fb.ObjectBuilder {
|
|||||||
if (vectorOfEnumsOffset != null) {
|
if (vectorOfEnumsOffset != null) {
|
||||||
fbBuilder.addOffset(47, vectorOfEnumsOffset);
|
fbBuilder.addOffset(47, vectorOfEnumsOffset);
|
||||||
}
|
}
|
||||||
|
fbBuilder.addInt8(48, _signedEnum?.value);
|
||||||
return fbBuilder.endTable();
|
return fbBuilder.endTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,19 @@ Building should also produce two sample executables, `flatsamplebinary` and
|
|||||||
*Note that you MUST be in the root of the FlatBuffers distribution when you
|
*Note that you MUST be in the root of the FlatBuffers distribution when you
|
||||||
run 'flattests' or `flatsampletext`, or it will fail to load its files.*
|
run 'flattests' or `flatsampletext`, or it will fail to load its files.*
|
||||||
|
|
||||||
|
## Building with VCPKG
|
||||||
|
|
||||||
|
You can download and install flatbuffers using the [vcpkg](https://github.com/Microsoft/vcpkg/) dependency manager:
|
||||||
|
|
||||||
|
git clone https://github.com/Microsoft/vcpkg.git
|
||||||
|
cd vcpkg
|
||||||
|
./bootstrap-vcpkg.sh
|
||||||
|
./vcpkg integrate install
|
||||||
|
./vcpkg install flatbuffers
|
||||||
|
|
||||||
|
The flatbuffers port in vcpkg is kept up to date by Microsoft team members and community contributors.
|
||||||
|
If the version is out of date, please [create an issue or pull request](https://github.com/Microsoft/vcpkg) on the vcpkg repository.
|
||||||
|
|
||||||
## Building for Android
|
## Building for Android
|
||||||
|
|
||||||
There is a `flatbuffers/android` directory that contains all you need to build
|
There is a `flatbuffers/android` directory that contains all you need to build
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ Using the schema compiler {#flatbuffers_guide_using_schema_compiler}
|
|||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] [ -S ] FILES...
|
flatc [ GENERATOR OPTIONS ] [ -o PATH ] [ -I PATH ] FILES...
|
||||||
[ -- FILES...]
|
[ -- FILES...]
|
||||||
|
|
||||||
The files are read and parsed in order, and can contain either schemas
|
The files are read and parsed in order, and can contain either schemas
|
||||||
@@ -23,6 +23,8 @@ For any schema input files, one or more generators can be specified:
|
|||||||
|
|
||||||
- `--java`, `-j` : Generate Java code.
|
- `--java`, `-j` : Generate Java code.
|
||||||
|
|
||||||
|
- `--kotlin`, `-k` : Generate Kotlin code.
|
||||||
|
|
||||||
- `--csharp`, `-n` : Generate C# code.
|
- `--csharp`, `-n` : Generate C# code.
|
||||||
|
|
||||||
- `--go`, `-g` : Generate Go code.
|
- `--go`, `-g` : Generate Go code.
|
||||||
@@ -45,6 +47,8 @@ For any schema input files, one or more generators can be specified:
|
|||||||
|
|
||||||
- `--rust`, `-r` : Generate Rust code.
|
- `--rust`, `-r` : Generate Rust code.
|
||||||
|
|
||||||
|
- `--swift`: Generate Swift code.
|
||||||
|
|
||||||
For any data input files:
|
For any data input files:
|
||||||
|
|
||||||
- `--binary`, `-b` : If data is contained in this file, generate a
|
- `--binary`, `-b` : If data is contained in this file, generate a
|
||||||
@@ -92,7 +96,7 @@ Additional options:
|
|||||||
statements) use `--no-includes.`
|
statements) use `--no-includes.`
|
||||||
|
|
||||||
- `--no-includes` : Don't generate include statements for included schemas the
|
- `--no-includes` : Don't generate include statements for included schemas the
|
||||||
generated file depends on (C++).
|
generated file depends on (C++ / Python).
|
||||||
|
|
||||||
- `--gen-mutable` : Generate additional non-const accessors for mutating
|
- `--gen-mutable` : Generate additional non-const accessors for mutating
|
||||||
FlatBuffers in-place.
|
FlatBuffers in-place.
|
||||||
@@ -117,6 +121,8 @@ Additional options:
|
|||||||
output (by default the case for C++ and JS), all code will end up in
|
output (by default the case for C++ and JS), all code will end up in
|
||||||
this one file.
|
this one file.
|
||||||
|
|
||||||
|
- `--cpp-include` : Adds an #include in generated file
|
||||||
|
|
||||||
- `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
|
- `--cpp-ptr-type T` : Set object API pointer type (default std::unique_ptr)
|
||||||
|
|
||||||
- `--cpp-str-type T` : Set object API string type (default std::string)
|
- `--cpp-str-type T` : Set object API string type (default std::string)
|
||||||
@@ -128,6 +134,11 @@ Additional options:
|
|||||||
std::string from Flatbuffers, but (char* + length). This allows efficient
|
std::string from Flatbuffers, but (char* + length). This allows efficient
|
||||||
construction of custom string types, including zero-copy construction.
|
construction of custom string types, including zero-copy construction.
|
||||||
|
|
||||||
|
- `--cpp-std CPP_STD` : Generate a C++ code using features of selected C++ standard.
|
||||||
|
Supported `CPP_STD` values:
|
||||||
|
* `c++0x` - generate code compatible with old compilers (VS2010).
|
||||||
|
* `c++11` - use C++11 code generator (default);
|
||||||
|
|
||||||
- `--object-prefix` : Customise class prefix for C++ object-based API.
|
- `--object-prefix` : Customise class prefix for C++ object-based API.
|
||||||
|
|
||||||
- `--object-suffix` : Customise class suffix for C++ object-based API.
|
- `--object-suffix` : Customise class suffix for C++ object-based API.
|
||||||
@@ -177,6 +188,13 @@ Additional options:
|
|||||||
- `--conform-includes PATH` : Include path for the schema given with
|
- `--conform-includes PATH` : Include path for the schema given with
|
||||||
`--conform PATH`.
|
`--conform PATH`.
|
||||||
|
|
||||||
|
- `--filename-suffix SUFFIX` : The suffix appended to the generated
|
||||||
|
file names. Default is '_generated'.
|
||||||
|
|
||||||
|
- `--filename-ext EXTENSION` : The extension appended to the generated
|
||||||
|
file names. Default is language-specific (e.g. "h" for C++). This
|
||||||
|
should not be used when multiple languages are specified.
|
||||||
|
|
||||||
- `--include-prefix PATH` : Prefix this path to any generated include
|
- `--include-prefix PATH` : Prefix this path to any generated include
|
||||||
statements.
|
statements.
|
||||||
|
|
||||||
@@ -199,5 +217,8 @@ Additional options:
|
|||||||
- `--force-empty` : When serializing from object API representation, force
|
- `--force-empty` : When serializing from object API representation, force
|
||||||
strings and vectors to empty rather than null.
|
strings and vectors to empty rather than null.
|
||||||
|
|
||||||
|
- `--force-empty-vectors` : When serializing from object API representation, force
|
||||||
|
vectors to empty rather than null.
|
||||||
|
|
||||||
NOTE: short-form options for generators are deprecated, use the long form
|
NOTE: short-form options for generators are deprecated, use the long form
|
||||||
whenever possible.
|
whenever possible.
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ The test code itself is located in
|
|||||||
[test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp).
|
[test.cpp](https://github.com/google/flatbuffers/blob/master/tests/test.cpp).
|
||||||
|
|
||||||
This test file is built alongside `flatc`. To review how to build the project,
|
This test file is built alongside `flatc`. To review how to build the project,
|
||||||
please read the [Building](@ref flatbuffers_guide_building) documenation.
|
please read the [Building](@ref flatbuffers_guide_building) documentation.
|
||||||
|
|
||||||
To run the tests, execute `flattests` from the root `flatbuffers/` directory.
|
To run the tests, execute `flattests` from the root `flatbuffers/` directory.
|
||||||
For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
|
For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
|
||||||
@@ -114,7 +114,7 @@ To use:
|
|||||||
MonsterT monsterobj;
|
MonsterT monsterobj;
|
||||||
|
|
||||||
// Deserialize from buffer into object.
|
// Deserialize from buffer into object.
|
||||||
UnPackTo(&monsterobj, flatbuffer);
|
GetMonster(flatbuffer)->UnPackTo(&monsterobj);
|
||||||
|
|
||||||
// Update object directly like a C++ class instance.
|
// Update object directly like a C++ class instance.
|
||||||
cout << monsterobj->name; // This is now a std::string!
|
cout << monsterobj->name; // This is now a std::string!
|
||||||
@@ -122,7 +122,7 @@ To use:
|
|||||||
|
|
||||||
// Serialize into new flatbuffer.
|
// Serialize into new flatbuffer.
|
||||||
FlatBufferBuilder fbb;
|
FlatBufferBuilder fbb;
|
||||||
Pack(fbb, &monsterobj);
|
fbb.Finish(Monster::Pack(fbb, &monsterobj));
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
The following attributes are specific to the object-based API code generation:
|
The following attributes are specific to the object-based API code generation:
|
||||||
@@ -426,6 +426,8 @@ it, this will provide you an easy way to use that data directly.
|
|||||||
(see the schema documentation for some specifics on the JSON format
|
(see the schema documentation for some specifics on the JSON format
|
||||||
accepted).
|
accepted).
|
||||||
|
|
||||||
|
Schema evolution compatibility for the JSON format follows the same rules as the binary format (JSON formatted data will be forwards/backwards compatible with schemas that evolve in a compatible way).
|
||||||
|
|
||||||
There are two ways to use text formats:
|
There are two ways to use text formats:
|
||||||
|
|
||||||
#### Using the compiler as a conversion tool
|
#### Using the compiler as a conversion tool
|
||||||
@@ -477,7 +479,7 @@ include paths. If not specified, any include statements try to resolve from
|
|||||||
the current directory.
|
the current directory.
|
||||||
|
|
||||||
If there were any parsing errors, `Parse` will return `false`, and
|
If there were any parsing errors, `Parse` will return `false`, and
|
||||||
`Parser::err` contains a human readable error string with a line number
|
`Parser::error_` contains a human readable error string with a line number
|
||||||
etc, which you should present to the creator of that file.
|
etc, which you should present to the creator of that file.
|
||||||
|
|
||||||
After each JSON file, the `Parser::fbb` member variable is the
|
After each JSON file, the `Parser::fbb` member variable is the
|
||||||
@@ -546,21 +548,63 @@ locale-independent or locale-narrow functions `strtof_l`, `strtod_l`,
|
|||||||
These functions use specified locale rather than the global or per-thread
|
These functions use specified locale rather than the global or per-thread
|
||||||
locale instead. They are part of POSIX-2008 but not part of the C/C++
|
locale instead. They are part of POSIX-2008 but not part of the C/C++
|
||||||
standard library, therefore, may be missing on some platforms.
|
standard library, therefore, may be missing on some platforms.
|
||||||
|
|
||||||
The Flatbuffers library try to detect these functions at configuration and
|
The Flatbuffers library try to detect these functions at configuration and
|
||||||
compile time:
|
compile time:
|
||||||
- `_MSC_VER >= 1900`: check MSVC2012 or higher for MSVC buid
|
- CMake `"CMakeLists.txt"`:
|
||||||
- `_XOPEN_SOURCE>=700`: check POSIX-2008 for GCC/Clang build
|
- Check existence of `strtol_l` and `strtod_l` in the `<stdlib.h>`.
|
||||||
- `check_cxx_symbol_exists(strtof_l stdlib.h)`: CMake check of `strtod_f`
|
- Compile-time `"/include/base.h"`:
|
||||||
|
- `_MSC_VER >= 1900`: MSVC2012 or higher if build with MSVC.
|
||||||
|
- `_XOPEN_SOURCE>=700`: POSIX-2008 if build with GCC/Clang.
|
||||||
|
|
||||||
After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be
|
After detection, the definition `FLATBUFFERS_LOCALE_INDEPENDENT` will be
|
||||||
set to `0` or `1`.
|
set to `0` or `1`.
|
||||||
|
To override or stop this detection use CMake `-DFLATBUFFERS_LOCALE_INDEPENDENT={0|1}`
|
||||||
|
or predefine `FLATBUFFERS_LOCALE_INDEPENDENT` symbol.
|
||||||
|
|
||||||
It is possible to test the compatibility of the Flatbuffers library with
|
To test the compatibility of the Flatbuffers library with
|
||||||
a specific locale using the environment variable `FLATBUFFERS_TEST_LOCALE`:
|
a specific locale use the environment variable `FLATBUFFERS_TEST_LOCALE`:
|
||||||
```sh
|
```sh
|
||||||
>FLATBUFFERS_TEST_LOCALE="" ./flattests
|
>FLATBUFFERS_TEST_LOCALE="" ./flattests
|
||||||
>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests
|
>FLATBUFFERS_TEST_LOCALE="ru_RU.CP1251" ./flattests
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Support of floating-point numbers
|
||||||
|
The Flatbuffers library assumes that a C++ compiler and a CPU are
|
||||||
|
compatible with the `IEEE-754` floating-point standard.
|
||||||
|
The schema and json parser may fail if `fast-math` or `/fp:fast` mode is active.
|
||||||
|
|
||||||
|
### Support of hexadecimal and special floating-point numbers
|
||||||
|
According to the [grammar](@ref flatbuffers_grammar) `fbs` and `json` files
|
||||||
|
may use hexadecimal and special (`NaN`, `Inf`) floating-point literals.
|
||||||
|
The Flatbuffers uses `strtof` and `strtod` functions to parse floating-point
|
||||||
|
literals. The Flatbuffers library has a code to detect a compiler compatibility
|
||||||
|
with the literals. If necessary conditions are met the preprocessor constant
|
||||||
|
`FLATBUFFERS_HAS_NEW_STRTOD` will be set to `1`.
|
||||||
|
The support of floating-point literals will be limited at compile time
|
||||||
|
if `FLATBUFFERS_HAS_NEW_STRTOD` constant is less than `1`.
|
||||||
|
In this case, schemas with hexadecimal or special literals cannot be used.
|
||||||
|
|
||||||
|
### Comparison of floating-point NaN values
|
||||||
|
The floating-point `NaN` (`not a number`) is special value which
|
||||||
|
representing an undefined or unrepresentable value.
|
||||||
|
`NaN` may be explicitly assigned to variables, typically as a representation
|
||||||
|
for missing values or may be a result of a mathematical operation.
|
||||||
|
The `IEEE-754` defines two kind of `NaNs`:
|
||||||
|
- Quiet NaNs, or `qNaNs`.
|
||||||
|
- Signaling NaNs, or `sNaNs`.
|
||||||
|
|
||||||
|
According to the `IEEE-754`, a comparison with `NaN` always returns
|
||||||
|
an unordered result even when compared with itself. As a result, a whole
|
||||||
|
Flatbuffers object will be not equal to itself if has one or more `NaN`.
|
||||||
|
Flatbuffers scalar fields that have the default value are not actually stored
|
||||||
|
in the serialized data but are generated in code (see [Writing a schema](@ref flatbuffers_guide_writing_schema)).
|
||||||
|
Scalar fields with `NaN` defaults break this behavior.
|
||||||
|
If a schema has a lot of `NaN` defaults the Flatbuffers can override
|
||||||
|
the unordered comparison by the ordered: `(NaN==NaN)->true`.
|
||||||
|
This ordered comparison is enabled when compiling a program with the symbol
|
||||||
|
`FLATBUFFERS_NAN_DEFAULTS` defined.
|
||||||
|
Additional computations added by `FLATBUFFERS_NAN_DEFAULTS` are very cheap
|
||||||
|
if GCC or Clang used. These compilers have a compile-time implementation
|
||||||
|
of `isnan` checking which MSVC does not.
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
175
docs/source/CsharpUsage.md
Normal file
175
docs/source/CsharpUsage.md
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
Use in C# {#flatbuffers_guide_use_c-sharp}
|
||||||
|
==============
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in C#, it should be noted that
|
||||||
|
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
|
||||||
|
general FlatBuffers usage in all of the supported languages (including C#).
|
||||||
|
This page is designed to cover the nuances of FlatBuffers usage,
|
||||||
|
specific to C#.
|
||||||
|
|
||||||
|
You should also have read the [Building](@ref flatbuffers_guide_building)
|
||||||
|
documentation to build `flatc` and should be familiar with
|
||||||
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
|
||||||
|
[Writing a schema](@ref flatbuffers_guide_writing_schema).
|
||||||
|
|
||||||
|
## FlatBuffers C-sharp code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers C# library can be found at
|
||||||
|
`flatbuffers/net/FlatBuffers`. You can browse the library on the
|
||||||
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
|
||||||
|
FlatBuffers).
|
||||||
|
|
||||||
|
## Testing the FlatBuffers C-sharp libraries
|
||||||
|
|
||||||
|
The code to test the libraries can be found at `flatbuffers/tests`.
|
||||||
|
|
||||||
|
The test code for C# is located in the [FlatBuffers.Test](https://github.com/
|
||||||
|
google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
|
||||||
|
tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
|
||||||
|
https://www.visualstudio.com), and compile/run the project.
|
||||||
|
|
||||||
|
Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
|
||||||
|
Once you have installed `Mono`, you can run the tests from the command line
|
||||||
|
by running the following commands from inside the `FlatBuffers.Test` folder:
|
||||||
|
|
||||||
|
~~~{.sh}
|
||||||
|
mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
|
||||||
|
mono Assert.exe
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Using the FlatBuffers C# library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in C#.*
|
||||||
|
|
||||||
|
FlatBuffers supports reading and writing binary FlatBuffers in C#.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate C# classes from your
|
||||||
|
schema with the `--csharp` option to `flatc`.
|
||||||
|
Then you can include both FlatBuffers and the generated code to read
|
||||||
|
or write a FlatBuffer.
|
||||||
|
|
||||||
|
For example, here is how you would read a FlatBuffer binary file in C#:
|
||||||
|
First, import the library and generated code. Then, you read a FlatBuffer binary
|
||||||
|
file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
|
||||||
|
pass to the `GetRootAsMyRootType` function:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
|
||||||
|
using MyGame.Example;
|
||||||
|
using FlatBuffers;
|
||||||
|
|
||||||
|
// This snippet ignores exceptions for brevity.
|
||||||
|
byte[] data = File.ReadAllBytes("monsterdata_test.mon");
|
||||||
|
|
||||||
|
ByteBuffer bb = new ByteBuffer(data);
|
||||||
|
Monster monster = Monster.GetRootAsMonster(bb);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Now you can access the data from the `Monster monster`:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
|
||||||
|
short hp = monster.Hp;
|
||||||
|
Vec3 pos = monster.Pos;
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
C# code naming follows standard C# style with `PascalCasing` identifiers,
|
||||||
|
e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
|
||||||
|
available as properties instead of parameterless accessor methods.
|
||||||
|
The performance-enhancing methods to which you can pass an already created
|
||||||
|
object are prefixed with `Get`, e.g.:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
|
||||||
|
// property
|
||||||
|
var pos = monster.Pos;
|
||||||
|
|
||||||
|
// method filling a preconstructed object
|
||||||
|
var preconstructedPos = new Vec3();
|
||||||
|
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 the "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 `CreateSortedVectorOfMonster` in C#
|
||||||
|
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
|
||||||
|
the `ByKey` accessor to access elements of the vector, e.g.:
|
||||||
|
`monster.TestarrayoftablesByKey("Frodo")` in C#,
|
||||||
|
which returns an object of the corresponding table type,
|
||||||
|
or `null` if not found.
|
||||||
|
`ByKey` performs a binary search, so should have a similar
|
||||||
|
speed to `Dictionary`, though may be faster because of better caching.
|
||||||
|
`ByKey` 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
|
||||||
|
from C#, though you could use the C++ parser through native call
|
||||||
|
interfaces available to each language. Please see the
|
||||||
|
C++ documentation for more on text parsing.
|
||||||
|
|
||||||
|
## Object based API
|
||||||
|
|
||||||
|
FlatBuffers is all about memory efficiency, which is why its base API is written
|
||||||
|
around using as little as possible of it. This does make the API clumsier
|
||||||
|
(requiring pre-order construction of all data, and making mutation harder).
|
||||||
|
|
||||||
|
For times when efficiency is less important a more convenient object based API
|
||||||
|
can be used (through `--gen-object-api`) that is able to unpack & pack a
|
||||||
|
FlatBuffer into objects and standard System.Collections.Generic containers, allowing for convenient
|
||||||
|
construction, access and mutation.
|
||||||
|
|
||||||
|
To use:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
|
||||||
|
// Deserialize from buffer into object.
|
||||||
|
MonsterT monsterobj = GetMonster(flatbuffer).UnPack();
|
||||||
|
|
||||||
|
// Update object directly like a C# class instance.
|
||||||
|
Console.WriteLine(monsterobj.Name);
|
||||||
|
monsterobj.Name = "Bob"; // Change the name.
|
||||||
|
|
||||||
|
// Serialize into new flatbuffer.
|
||||||
|
FlatBufferBuilder fbb = new FlatBufferBuilder(1);
|
||||||
|
fbb.Finish(Monster.Pack(fbb, monsterobj).Value);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
### Json Serialization
|
||||||
|
|
||||||
|
An additional feature of the object API is the ability to allow you to
|
||||||
|
serialize & deserialize a JSON text.
|
||||||
|
To use Json Serialization, add `--gen-json-serializer` option to `flatc` and
|
||||||
|
add `Newtonsoft.Json` nuget package to csproj.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
|
||||||
|
// Deserialize MonsterT from json
|
||||||
|
string jsonText = File.ReadAllText(@"Resources/monsterdata_test.json");
|
||||||
|
MonsterT mon = MonsterT.DeserializeFromJson(jsonText);
|
||||||
|
|
||||||
|
// Serialize MonsterT to json
|
||||||
|
string jsonText2 = mon.SerializeToJson();
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
* Limitation
|
||||||
|
* `hash` attribute currentry not supported.
|
||||||
|
* NuGet package Dependency
|
||||||
|
* [Newtonsoft.Json](https://github.com/JamesNK/Newtonsoft.Json)
|
||||||
|
|
||||||
|
<br>
|
||||||
@@ -4,7 +4,7 @@ FlatBuffers {#flatbuffers_index}
|
|||||||
# Overview {#flatbuffers_overview}
|
# Overview {#flatbuffers_overview}
|
||||||
|
|
||||||
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
|
[FlatBuffers](@ref flatbuffers_overview) is an efficient cross platform
|
||||||
serialization library for C++, C#, C, Go, Java, JavaScript, Lobster, Lua, TypeScript, PHP, Python, and Rust.
|
serialization library for C++, C#, C, Go, Java, Kotlin, JavaScript, Lobster, Lua, TypeScript, PHP, Python, Rust and Swift.
|
||||||
It was originally created at Google for game development and other
|
It was originally created at Google for game development and other
|
||||||
performance-critical applications.
|
performance-critical applications.
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ under the Apache license, v2 (see LICENSE.txt).
|
|||||||
needed (faster and more memory efficient than other JSON
|
needed (faster and more memory efficient than other JSON
|
||||||
parsers).
|
parsers).
|
||||||
|
|
||||||
Java and Go code supports object-reuse. C# has efficient struct based
|
Java, Kotlin and Go code supports object-reuse. C# has efficient struct based
|
||||||
accessors.
|
accessors.
|
||||||
|
|
||||||
- **Cross platform code with no dependencies** - C++ code will work
|
- **Cross platform code with no dependencies** - C++ code will work
|
||||||
@@ -108,7 +108,7 @@ sections provide a more in-depth usage guide.
|
|||||||
present for every object instance.
|
present for every object instance.
|
||||||
|
|
||||||
- Use `flatc` (the FlatBuffer compiler) to generate a C++ header (or
|
- Use `flatc` (the FlatBuffer compiler) to generate a C++ header (or
|
||||||
Java/C#/Go/Python.. classes) with helper classes to access and construct
|
Java/Kotlin/C#/Go/Python.. classes) with helper classes to access and construct
|
||||||
serialized data. This header (say `mydata_generated.h`) only depends on
|
serialized data. This header (say `mydata_generated.h`) only depends on
|
||||||
`flatbuffers.h`, which defines the core functionality.
|
`flatbuffers.h`, which defines the core functionality.
|
||||||
|
|
||||||
@@ -130,8 +130,12 @@ sections provide a more in-depth usage guide.
|
|||||||
- How to [write a schema](@ref flatbuffers_guide_writing_schema).
|
- How to [write a schema](@ref flatbuffers_guide_writing_schema).
|
||||||
- How to [use the generated C++ code](@ref flatbuffers_guide_use_cpp) in your
|
- How to [use the generated C++ code](@ref flatbuffers_guide_use_cpp) in your
|
||||||
own programs.
|
own programs.
|
||||||
- How to [use the generated Java/C# code](@ref flatbuffers_guide_use_java_c-sharp)
|
- How to [use the generated Java code](@ref flatbuffers_guide_use_java)
|
||||||
in your own programs.
|
in your own programs.
|
||||||
|
- How to [use the generated C# code](@ref flatbuffers_guide_use_c-sharp)
|
||||||
|
in your own programs.
|
||||||
|
- How to [use the generated Kotlin code](@ref flatbuffers_guide_use_kotlin)
|
||||||
|
in your own programs.
|
||||||
- How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
|
- How to [use the generated Go code](@ref flatbuffers_guide_use_go) in your
|
||||||
own programs.
|
own programs.
|
||||||
- How to [use the generated Lua code](@ref flatbuffers_guide_use_lua) in your
|
- How to [use the generated Lua code](@ref flatbuffers_guide_use_lua) in your
|
||||||
@@ -146,6 +150,8 @@ sections provide a more in-depth usage guide.
|
|||||||
own programs.
|
own programs.
|
||||||
- How to [use the generated Rust code](@ref flatbuffers_guide_use_rust) in your
|
- How to [use the generated Rust code](@ref flatbuffers_guide_use_rust) in your
|
||||||
own programs.
|
own programs.
|
||||||
|
- How to [use the generated Swift code](@ref flatbuffers_guide_use_swift) in your
|
||||||
|
own programs.
|
||||||
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
|
- [Support matrix](@ref flatbuffers_support) for platforms/languages/features.
|
||||||
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
|
- Some [benchmarks](@ref flatbuffers_benchmarks) showing the advantage of
|
||||||
using FlatBuffers.
|
using FlatBuffers.
|
||||||
@@ -161,6 +167,7 @@ sections provide a more in-depth usage guide.
|
|||||||
- [GitHub repository](http://github.com/google/flatbuffers)
|
- [GitHub repository](http://github.com/google/flatbuffers)
|
||||||
- [Landing page](http://google.github.io/flatbuffers)
|
- [Landing page](http://google.github.io/flatbuffers)
|
||||||
- [FlatBuffers Google Group](https://groups.google.com/forum/#!forum/flatbuffers)
|
- [FlatBuffers Google Group](https://groups.google.com/forum/#!forum/flatbuffers)
|
||||||
|
- [Discord](https://discord.gg/6qgKs3R) and [Gitter](https://gitter.im/lobster_programming_language/community) chat.
|
||||||
- [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
|
- [FlatBuffers Issues Tracker](http://github.com/google/flatbuffers/issues)
|
||||||
- Independent implementations & tools:
|
- Independent implementations & tools:
|
||||||
- [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
|
- [FlatCC](https://github.com/dvidelabs/flatcc) Alternative FlatBuffers
|
||||||
@@ -176,3 +183,6 @@ sections provide a more in-depth usage guide.
|
|||||||
- [FlatBuffers in Android](http://frogermcs.github.io/flatbuffers-in-android-introdution/)
|
- [FlatBuffers in Android](http://frogermcs.github.io/flatbuffers-in-android-introdution/)
|
||||||
- [Parsing JSON to FlatBuffers in Java](http://frogermcs.github.io/json-parsing-with-flatbuffers-in-android/)
|
- [Parsing JSON to FlatBuffers in Java](http://frogermcs.github.io/json-parsing-with-flatbuffers-in-android/)
|
||||||
- [FlatBuffers in Unity](http://exiin.com/blog/flatbuffers-for-unity-sample-code/)
|
- [FlatBuffers in Unity](http://exiin.com/blog/flatbuffers-for-unity-sample-code/)
|
||||||
|
- [FlexBuffers C#](https://github.com/mzaks/FlexBuffers-CSharp) and
|
||||||
|
[article](https://medium.com/@icex33/flexbuffers-for-unity3d-4d1ab5c53fbe?)
|
||||||
|
on its use.
|
||||||
|
|||||||
@@ -29,9 +29,7 @@ FlexBuffers is still slower than regular FlatBuffers though, so we recommend to
|
|||||||
only use it if you need it.
|
only use it if you need it.
|
||||||
|
|
||||||
|
|
||||||
# Usage
|
# Usage in C++
|
||||||
|
|
||||||
This is for C++, other languages may follow.
|
|
||||||
|
|
||||||
Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
|
Include the header `flexbuffers.h`, which in turn depends on `flatbuffers.h`
|
||||||
and `util.h`.
|
and `util.h`.
|
||||||
@@ -98,10 +96,10 @@ allows a single type, and uses a bit less memory.
|
|||||||
`IndirectFloat` is an interesting feature that allows you to store values
|
`IndirectFloat` is an interesting feature that allows you to store values
|
||||||
by offset rather than inline. Though that doesn't make any visible change
|
by offset rather than inline. Though that doesn't make any visible change
|
||||||
to the user, the consequence is that large values (especially doubles or
|
to the user, the consequence is that large values (especially doubles or
|
||||||
64 bit ints) that occur more than once can be shared. Another use case is
|
64 bit ints) that occur more than once can be shared (see ReuseValue).
|
||||||
inside of vectors, where the largest element makes up the size of all elements
|
Another use case is inside of vectors, where the largest element makes
|
||||||
(e.g. a single double forces all elements to 64bit), so storing a lot of small
|
up the size of all elements (e.g. a single double forces all elements to
|
||||||
integers together with a double is more efficient if the double is indirect.
|
64bit), so storing a lot of small integers together with a double is more efficient if the double is indirect.
|
||||||
|
|
||||||
Accessing it:
|
Accessing it:
|
||||||
|
|
||||||
@@ -122,6 +120,46 @@ map["unknown"].IsNull(); // true
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
# Usage in Java
|
||||||
|
|
||||||
|
Java implementation follows the C++ one, closely.
|
||||||
|
|
||||||
|
For creating the equivalent of the same JSON `{ vec: [ -100, "Fred", 4.0 ], foo: 100 }`,
|
||||||
|
one could use the following code:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
|
||||||
|
FlexBuffersBuilder builder = new FlexBuffersBuilder(ByteBuffer.allocate(512),
|
||||||
|
FlexBuffersBuilder.BUILDER_FLAG_SHARE_KEYS_AND_STRINGS);
|
||||||
|
int smap = builder.startMap();
|
||||||
|
int svec = builder.startVector();
|
||||||
|
builder.putInt(-100);
|
||||||
|
builder.putString("Fred");
|
||||||
|
builder.putFloat(4.0);
|
||||||
|
builder.endVector("vec", svec, false, false);
|
||||||
|
builder.putInt("foo", 100);
|
||||||
|
builder.endMap(null, smap);
|
||||||
|
ByteBuffer bb = builder.finish();
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Similarly, to read the data, just:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
|
||||||
|
FlexBuffers.Map map = FlexBuffers.getRoot(bb).asMap();
|
||||||
|
map.size(); // 2
|
||||||
|
FlexBuffers.Vector vec = map.get("vec").asVector();
|
||||||
|
vec.size(); // 3
|
||||||
|
vec.get(0).asLong(); // -100;
|
||||||
|
vec.get(1).asString(); // "Fred";
|
||||||
|
vec.get(1).asLong(); // 0 (Number parsing failed).
|
||||||
|
vec.get(2).asFloat(); // 4.0
|
||||||
|
vec.get(2).asString().isEmpty(); // true (Wrong Type).
|
||||||
|
vec.get(2).asString(); // "" (This still works though).
|
||||||
|
vec.get(2).toString(); // "4.0" (Or have it converted).
|
||||||
|
map.get("foo").asUInt(); // 100
|
||||||
|
map.get("unknown").isNull(); // true
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
# Binary encoding
|
# Binary encoding
|
||||||
|
|
||||||
A description of how FlexBuffers are encoded is in the
|
A description of how FlexBuffers are encoded is in the
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ all commonly used CPUs today. FlatBuffers will also work on big-endian
|
|||||||
machines, but will be slightly slower because of additional
|
machines, but will be slightly slower because of additional
|
||||||
byte-swap intrinsics.
|
byte-swap intrinsics.
|
||||||
|
|
||||||
|
It is assumed that the following conditions are met, to ensure
|
||||||
|
cross-platform interoperability:
|
||||||
|
- The binary `IEEE-754` format is used for floating-point numbers.
|
||||||
|
- The `two's complemented` representation is used for signed integers.
|
||||||
|
- The endianness is the same for floating-point numbers as for integers.
|
||||||
|
|
||||||
On purpose, the format leaves a lot of details about where exactly
|
On purpose, the format leaves a lot of details about where exactly
|
||||||
things live in memory undefined, e.g. fields in a table can have any
|
things live in memory undefined, e.g. fields in a table can have any
|
||||||
order, and objects to some extent can be stored in many orders. This is
|
order, and objects to some extent can be stored in many orders. This is
|
||||||
|
|||||||
@@ -1,41 +1,30 @@
|
|||||||
Use in Java/C# {#flatbuffers_guide_use_java_c-sharp}
|
Use in Java {#flatbuffers_guide_use_java}
|
||||||
==============
|
==============
|
||||||
|
|
||||||
## Before you get started
|
## Before you get started
|
||||||
|
|
||||||
Before diving into the FlatBuffers usage in Java or C#, it should be noted that
|
Before diving into the FlatBuffers usage in Java, it should be noted that
|
||||||
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
|
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
|
||||||
general FlatBuffers usage in all of the supported languages (including both Java
|
general FlatBuffers usage in all of the supported languages (including Java).
|
||||||
and C#). This page is designed to cover the nuances of FlatBuffers usage,
|
This page is designed to cover the nuances of FlatBuffers usage,
|
||||||
specific to Java and C#.
|
specific to Java.
|
||||||
|
|
||||||
You should also have read the [Building](@ref flatbuffers_guide_building)
|
You should also have read the [Building](@ref flatbuffers_guide_building)
|
||||||
documentation to build `flatc` and should be familiar with
|
documentation to build `flatc` and should be familiar with
|
||||||
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
|
||||||
[Writing a schema](@ref flatbuffers_guide_writing_schema).
|
[Writing a schema](@ref flatbuffers_guide_writing_schema).
|
||||||
|
|
||||||
## FlatBuffers Java and C-sharp code location
|
## FlatBuffers Java code location
|
||||||
|
|
||||||
#### Java
|
|
||||||
|
|
||||||
The code for the FlatBuffers Java library can be found at
|
The code for the FlatBuffers Java library can be found at
|
||||||
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
|
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
|
||||||
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
|
||||||
java/com/google/flatbuffers).
|
java/com/google/flatbuffers).
|
||||||
|
|
||||||
#### C-sharp
|
## Testing the FlatBuffers Java libraries
|
||||||
|
|
||||||
The code for the FlatBuffers C# library can be found at
|
|
||||||
`flatbuffers/net/FlatBuffers`. You can browse the library on the
|
|
||||||
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/net/
|
|
||||||
FlatBuffers).
|
|
||||||
|
|
||||||
## Testing the FlatBuffers Java and C-sharp libraries
|
|
||||||
|
|
||||||
The code to test the libraries can be found at `flatbuffers/tests`.
|
The code to test the libraries can be found at `flatbuffers/tests`.
|
||||||
|
|
||||||
#### Java
|
|
||||||
|
|
||||||
The test code for Java is located in [JavaTest.java](https://github.com/google
|
The test code for Java is located in [JavaTest.java](https://github.com/google
|
||||||
/flatbuffers/blob/master/tests/JavaTest.java).
|
/flatbuffers/blob/master/tests/JavaTest.java).
|
||||||
|
|
||||||
@@ -47,31 +36,15 @@ system.
|
|||||||
*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
|
*Note: These scripts require that [Java](https://www.oracle.com/java/index.html)
|
||||||
is installed.*
|
is installed.*
|
||||||
|
|
||||||
#### C-sharp
|
## Using the FlatBuffers Java library
|
||||||
|
|
||||||
The test code for C# is located in the [FlatBuffers.Test](https://github.com/
|
|
||||||
google/flatbuffers/tree/master/tests/FlatBuffers.Test) subfolder. To run the
|
|
||||||
tests, open `FlatBuffers.Test.csproj` in [Visual Studio](
|
|
||||||
https://www.visualstudio.com), and compile/run the project.
|
|
||||||
|
|
||||||
Optionally, you can run this using [Mono](http://www.mono-project.com/) instead.
|
|
||||||
Once you have installed `Mono`, you can run the tests from the command line
|
|
||||||
by running the following commands from inside the `FlatBuffers.Test` folder:
|
|
||||||
|
|
||||||
~~~{.sh}
|
|
||||||
mcs *.cs ../MyGame/Example/*.cs ../../net/FlatBuffers/*.cs
|
|
||||||
mono Assert.exe
|
|
||||||
~~~
|
|
||||||
|
|
||||||
## Using the FlatBuffers Java (and C#) library
|
|
||||||
|
|
||||||
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
example of how to use FlatBuffers in Java or C#.*
|
example of how to use FlatBuffers in Java.*
|
||||||
|
|
||||||
FlatBuffers supports reading and writing binary FlatBuffers in Java and C#.
|
FlatBuffers supports reading and writing binary FlatBuffers in Java.
|
||||||
|
|
||||||
To use FlatBuffers in your own code, first generate Java classes from your
|
To use FlatBuffers in your own code, first generate Java classes from your
|
||||||
schema with the `--java` option to `flatc`. (Or for C# with `--csharp`).
|
schema with the `--java` option to `flatc`.
|
||||||
Then you can include both FlatBuffers and the generated code to read
|
Then you can include both FlatBuffers and the generated code to read
|
||||||
or write a FlatBuffer.
|
or write a FlatBuffer.
|
||||||
|
|
||||||
@@ -80,11 +53,6 @@ First, import the library and generated code. Then, you read a FlatBuffer binary
|
|||||||
file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
|
file into a `byte[]`. You then turn the `byte[]` into a `ByteBuffer`, which you
|
||||||
pass to the `getRootAsMyRootType` function:
|
pass to the `getRootAsMyRootType` function:
|
||||||
|
|
||||||
*Note: The code here is written from the perspective of Java. Code for both
|
|
||||||
languages is both generated and used in nearly the exact same way, with only
|
|
||||||
minor differences. These differences are
|
|
||||||
[explained in a section below](#differences_in_c-sharp).*
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.java}
|
||||||
import MyGame.Example.*;
|
import MyGame.Example.*;
|
||||||
import com.google.flatbuffers.FlatBufferBuilder;
|
import com.google.flatbuffers.FlatBufferBuilder;
|
||||||
@@ -107,30 +75,6 @@ Now you can access the data from the `Monster monster`:
|
|||||||
Vec3 pos = monster.pos();
|
Vec3 pos = monster.pos();
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
<a name="differences_in_c-sharp">
|
|
||||||
#### Differences in C-sharp
|
|
||||||
</a>
|
|
||||||
|
|
||||||
C# code works almost identically to Java, with only a few minor differences.
|
|
||||||
You can see an example of C# code in
|
|
||||||
`tests/FlatBuffers.Test/FlatBuffersExampleTests.cs` or
|
|
||||||
`samples/SampleBinary.cs`.
|
|
||||||
|
|
||||||
First of all, naming follows standard C# style with `PascalCasing` identifiers,
|
|
||||||
e.g. `GetRootAsMyRootType`. Also, values (except vectors and unions) are
|
|
||||||
available as properties instead of parameterless accessor methods as in Java.
|
|
||||||
The performance-enhancing methods to which you can pass an already created
|
|
||||||
object are prefixed with `Get`, e.g.:
|
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cs}
|
|
||||||
// property
|
|
||||||
var pos = monster.Pos;
|
|
||||||
|
|
||||||
// method filling a preconstructed object
|
|
||||||
var preconstructedPos = new Vec3();
|
|
||||||
monster.GetPos(preconstructedPos);
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
## Storing dictionaries in a FlatBuffer
|
## Storing dictionaries in a FlatBuffer
|
||||||
|
|
||||||
FlatBuffers doesn't support dictionaries natively, but there is support to
|
FlatBuffers doesn't support dictionaries natively, but there is support to
|
||||||
@@ -147,14 +91,12 @@ To use it:
|
|||||||
array.
|
array.
|
||||||
- Instead of calling standard generated method,
|
- Instead of calling standard generated method,
|
||||||
e.g.: `Monster.createTestarrayoftablesVector`,
|
e.g.: `Monster.createTestarrayoftablesVector`,
|
||||||
call `CreateSortedVectorOfMonster` in C# or
|
call `createSortedVectorOfTables` (from the `FlatBufferBuilder` object).
|
||||||
`createSortedVectorOfTables` (from the `FlatBufferBuilder` object) in Java,
|
|
||||||
which will first sort all offsets such that the tables they refer to
|
which will first sort all offsets such that the tables they refer to
|
||||||
are sorted by the key field, then serialize it.
|
are sorted by the key field, then serialize it.
|
||||||
- Now when you're accessing the FlatBuffer, you can use
|
- Now when you're accessing the FlatBuffer, you can use
|
||||||
the `ByKey` accessor to access elements of the vector, e.g.:
|
the `ByKey` accessor to access elements of the vector, e.g.:
|
||||||
`monster.testarrayoftablesByKey("Frodo")` in Java or
|
`monster.testarrayoftablesByKey("Frodo")`.
|
||||||
`monster.TestarrayoftablesByKey("Frodo")` in C#,
|
|
||||||
which returns an object of the corresponding table type,
|
which returns an object of the corresponding table type,
|
||||||
or `null` if not found.
|
or `null` if not found.
|
||||||
`ByKey` performs a binary search, so should have a similar
|
`ByKey` performs a binary search, so should have a similar
|
||||||
@@ -165,7 +107,7 @@ To use it:
|
|||||||
## Text parsing
|
## Text parsing
|
||||||
|
|
||||||
There currently is no support for parsing text (Schema's and JSON) directly
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
from Java or C#, though you could use the C++ parser through native call
|
from Java, though you could use the C++ parser through native call
|
||||||
interfaces available to each language. Please see the
|
interfaces available to each language. Please see the
|
||||||
C++ documentation for more on text parsing.
|
C++ documentation for more on text parsing.
|
||||||
|
|
||||||
84
docs/source/KotlinUsage.md
Normal file
84
docs/source/KotlinUsage.md
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
Use in Kotlin {#flatbuffers_guide_use_kotlin}
|
||||||
|
==============
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in Kotlin, it should be noted that
|
||||||
|
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide to
|
||||||
|
general FlatBuffers usage in all of the supported languages (including K).
|
||||||
|
|
||||||
|
This page is designed to cover the nuances of FlatBuffers usage, specific to Kotlin.
|
||||||
|
|
||||||
|
You should also have read the [Building](@ref flatbuffers_guide_building)
|
||||||
|
documentation to build `flatc` and should be familiar with
|
||||||
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
|
||||||
|
[Writing a schema](@ref flatbuffers_guide_writing_schema).
|
||||||
|
|
||||||
|
## Kotlin and FlatBuffers Java code location
|
||||||
|
|
||||||
|
Code generated for Kotlin currently uses the flatbuffers java runtime library. That means that Kotlin generated code can only have Java virtual machine as target architecture (which includes Android). Kotlin Native and Kotlin.js are currently not supported.
|
||||||
|
|
||||||
|
The code for the FlatBuffers Java library can be found at
|
||||||
|
`flatbuffers/java/com/google/flatbuffers`. You can browse the library on the
|
||||||
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
|
||||||
|
java/com/google/flatbuffers).
|
||||||
|
|
||||||
|
## Testing FlatBuffers Kotlin
|
||||||
|
|
||||||
|
The test code for Java is located in [KotlinTest.java](https://github.com/google
|
||||||
|
/flatbuffers/blob/master/tests/KotlinTest.kt).
|
||||||
|
|
||||||
|
To run the tests, use [KotlinTest.sh](https://github.com/google/
|
||||||
|
flatbuffers/blob/master/tests/KotlinTest.sh) shell script.
|
||||||
|
|
||||||
|
*Note: These scripts require that [Kotlin](https://kotlinlang.org/) is installed.*
|
||||||
|
|
||||||
|
## Using the FlatBuffers Kotlin library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in Kotlin.*
|
||||||
|
|
||||||
|
FlatBuffers supports reading and writing binary FlatBuffers in Kotlin.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate Java classes from your
|
||||||
|
schema with the `--kotlin` option to `flatc`.
|
||||||
|
Then you can include both FlatBuffers and the generated code to read
|
||||||
|
or write a FlatBuffer.
|
||||||
|
|
||||||
|
For example, here is how you would read a FlatBuffer binary file in Kotlin:
|
||||||
|
First, import the library and generated code. Then, you read a FlatBuffer binary
|
||||||
|
file into a `ByteArray`. You then turn the `ByteArray` into a `ByteBuffer`, which you
|
||||||
|
pass to the `getRootAsMyRootType` function:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
|
||||||
|
import MyGame.Example.*
|
||||||
|
import com.google.flatbuffers.FlatBufferBuilder
|
||||||
|
|
||||||
|
// This snippet ignores exceptions for brevity.
|
||||||
|
val data = RandomAccessFile(File("monsterdata_test.mon"), "r").use {
|
||||||
|
val temp = ByteArray(it.length().toInt())
|
||||||
|
it.readFully(temp)
|
||||||
|
temp
|
||||||
|
}
|
||||||
|
|
||||||
|
val bb = ByteBuffer.wrap(data)
|
||||||
|
val monster = Monster.getRootAsMonster(bb)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Now you can access the data from the `Monster monster`:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.kt}
|
||||||
|
val hp = monster.hp
|
||||||
|
val pos = monster.pos!!;
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
## Differences between Kotlin and Java code
|
||||||
|
|
||||||
|
Kotlin generated code was designed to be as close as possible to the java counterpart, as for now, we only support kotlin on java virtual machine. So the differences in implementation and usage are basically the ones introduced by the Kotlin language itself. You can find more in-depth information [here](https://kotlinlang.org/docs/reference/comparison-to-java.html).
|
||||||
|
|
||||||
|
The most obvious ones are:
|
||||||
|
|
||||||
|
* Fields as accessed as Kotlin [properties](https://kotlinlang.org/docs/reference/properties.html)
|
||||||
|
* Static methods are accessed in [companion object](https://kotlinlang.org/docs/reference/classes.html#companion-objects)
|
||||||
@@ -114,6 +114,27 @@ of same-size data where a `reinterpret_cast` would give you a desirable result,
|
|||||||
e.g. you could change a `uint` to an `int` if no values in current data use the
|
e.g. you could change a `uint` to an `int` if no values in current data use the
|
||||||
high bit yet.
|
high bit yet.
|
||||||
|
|
||||||
|
### Arrays
|
||||||
|
|
||||||
|
Arrays are a convenience short-hand for a fixed-length collection of elements.
|
||||||
|
Arrays can be used to replace the following schema:
|
||||||
|
|
||||||
|
struct Vec3 {
|
||||||
|
x:float;
|
||||||
|
y:float;
|
||||||
|
z:float;
|
||||||
|
}
|
||||||
|
|
||||||
|
with the following schema:
|
||||||
|
|
||||||
|
struct Vec3 {
|
||||||
|
v:[float:3];
|
||||||
|
}
|
||||||
|
|
||||||
|
Both representations are binary equivalent.
|
||||||
|
|
||||||
|
Arrays are currently only supported in a `struct`.
|
||||||
|
|
||||||
### (Default) Values
|
### (Default) Values
|
||||||
|
|
||||||
Values are a sequence of digits. Values may be optionally followed by a decimal
|
Values are a sequence of digits. Values may be optionally followed by a decimal
|
||||||
@@ -324,6 +345,9 @@ Current understood attributes:
|
|||||||
Note: currently not guaranteed to have an effect when used with
|
Note: currently not guaranteed to have an effect when used with
|
||||||
`--object-api`, since that may allocate objects at alignments less than
|
`--object-api`, since that may allocate objects at alignments less than
|
||||||
what you specify with `force_align`.
|
what you specify with `force_align`.
|
||||||
|
- `force_align: size` (on a vector): force the alignment of this vector to be
|
||||||
|
something different than what the element size would normally dictate.
|
||||||
|
Note: Now only work for generated C++ code.
|
||||||
- `bit_flags` (on an unsigned enum): the values of this field indicate bits,
|
- `bit_flags` (on an unsigned enum): the values of this field indicate bits,
|
||||||
meaning that any unsigned value N specified in the schema will end up
|
meaning that any unsigned value N specified in the schema will end up
|
||||||
representing 1<<N, or if you don't specify values at all, you'll get
|
representing 1<<N, or if you don't specify values at all, you'll get
|
||||||
@@ -418,14 +442,19 @@ numerical literals:
|
|||||||
For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals.
|
For example: `[0x123, +0x45, -0x67]` are equal to `[291, 69, -103]` decimals.
|
||||||
- The format of float-point numbers is fully compatible with C/C++ format.
|
- The format of float-point numbers is fully compatible with C/C++ format.
|
||||||
If a modern C++ compiler is used the parser accepts hexadecimal and special
|
If a modern C++ compiler is used the parser accepts hexadecimal and special
|
||||||
float-point literals as well:
|
floating-point literals as well:
|
||||||
`[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`.
|
`[-1.0, 2., .3e0, 3.e4, 0x21.34p-5, -inf, nan]`.
|
||||||
The exponent suffix of hexadecimal float-point number is mandatory.
|
|
||||||
|
|
||||||
Extended float-point support was tested with:
|
The following conventions for floating-point numbers are used:
|
||||||
|
- The exponent suffix of hexadecimal floating-point number is mandatory.
|
||||||
|
- Parsed `NaN` converted to unsigned IEEE-754 `quiet-NaN` value.
|
||||||
|
|
||||||
|
Extended floating-point support was tested with:
|
||||||
- x64 Windows: `MSVC2015` and higher.
|
- x64 Windows: `MSVC2015` and higher.
|
||||||
- x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher.
|
- x64 Linux: `LLVM 6.0`, `GCC 4.9` and higher.
|
||||||
|
|
||||||
|
For details, see [Use in C++](@ref flatbuffers_guide_use_cpp) section.
|
||||||
|
|
||||||
- For compatibility with a JSON lint tool all numeric literals of scalar
|
- For compatibility with a JSON lint tool all numeric literals of scalar
|
||||||
fields can be wrapped to quoted string:
|
fields can be wrapped to quoted string:
|
||||||
`"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`.
|
`"1", "2.0", "0x48A", "0x0C.0Ep-1", "-inf", "true"`.
|
||||||
@@ -537,7 +566,7 @@ with the new schema now cannot read nor write `a` anymore (any existing code
|
|||||||
that tries to do so will result in compile errors), but can still read
|
that tries to do so will result in compile errors), but can still read
|
||||||
old data (they will ignore the field).
|
old data (they will ignore the field).
|
||||||
|
|
||||||
table { c:int a:int; b:int; }
|
table { c:int; a:int; b:int; }
|
||||||
|
|
||||||
This is NOT ok, as this makes the schemas incompatible. Old code reading newer
|
This is NOT ok, as this makes the schemas incompatible. Old code reading newer
|
||||||
data will interpret `c` as if it was `a`, and new code reading old data
|
data will interpret `c` as if it was `a`, and new code reading old data
|
||||||
|
|||||||
@@ -18,23 +18,23 @@ In general:
|
|||||||
|
|
||||||
NOTE: this table is a start, it needs to be extended.
|
NOTE: this table is a start, it needs to be extended.
|
||||||
|
|
||||||
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust
|
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust | Swift
|
||||||
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ----
|
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ------- | ------
|
||||||
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes
|
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes | Yes
|
||||||
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No
|
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No | No
|
||||||
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No
|
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No | No
|
||||||
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No
|
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No | No
|
||||||
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No
|
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No | No
|
||||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes
|
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
||||||
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes
|
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes | No
|
||||||
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb
|
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb | ?
|
||||||
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes
|
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes | No
|
||||||
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
|
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
||||||
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
|
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes | Yes
|
||||||
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
|
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | No
|
||||||
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
|
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ? | Yes
|
||||||
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ?
|
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ? | No
|
||||||
Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw
|
Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw | mi*/mz*
|
||||||
|
|
||||||
* aard = aardappel (previously: gwvo)
|
* aard = aardappel (previously: gwvo)
|
||||||
* ev = evolutional
|
* ev = evolutional
|
||||||
@@ -42,5 +42,7 @@ Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | ev
|
|||||||
* mik = mikkelfj
|
* mik = mikkelfj
|
||||||
* ch = chobie
|
* ch = chobie
|
||||||
* kr = krojew
|
* kr = krojew
|
||||||
|
* mi = mustiikhalil
|
||||||
|
* mz = mzaks
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
91
docs/source/SwiftUsage.md
Normal file
91
docs/source/SwiftUsage.md
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
Use in Swift {#flatbuffers_guide_use_swift}
|
||||||
|
=========
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in Swift, it should be noted that
|
||||||
|
the [Tutorial](@ref flatbuffers_guide_tutorial) page has a complete guide
|
||||||
|
to general FlatBuffers usage in all of the supported languages (including Swift).
|
||||||
|
This page is designed to cover the nuances of FlatBuffers usage, specific to
|
||||||
|
Swift.
|
||||||
|
|
||||||
|
You should also have read the [Building](@ref flatbuffers_guide_building)
|
||||||
|
documentation to build `flatc` and should be familiar with
|
||||||
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler) and
|
||||||
|
[Writing a schema](@ref flatbuffers_guide_writing_schema).
|
||||||
|
|
||||||
|
## FlatBuffers Swift library code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers Swift library can be found at
|
||||||
|
`flatbuffers/swift`. You can browse the library code on the [FlatBuffers
|
||||||
|
GitHub page](https://github.com/google/flatbuffers/tree/master/swift).
|
||||||
|
|
||||||
|
## Testing the FlatBuffers Swift library
|
||||||
|
|
||||||
|
The code to test the Swift library can be found at `flatbuffers/Flatbuffers.Test.Swift`.
|
||||||
|
The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift).
|
||||||
|
|
||||||
|
To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift/SwiftTest.sh) shell script.
|
||||||
|
|
||||||
|
*Note: The shell script requires [Swift](https://swift.org) to
|
||||||
|
be installed.*
|
||||||
|
|
||||||
|
## Using the FlatBuffers Swift library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in Swift.*
|
||||||
|
|
||||||
|
FlatBuffers supports reading and writing binary FlatBuffers in Swift.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate Swift structs from your
|
||||||
|
schema with the `--swift` option to `flatc`. Then include FlatBuffers using `SPM` in
|
||||||
|
by adding the path to `FlatBuffers/swift` into it. The generated code should also be
|
||||||
|
added to xcode or the path of the package you will be using. Note: sometimes xcode cant
|
||||||
|
and wont see the generated files, so it's better that you copy them to xcode.
|
||||||
|
|
||||||
|
For example, here is how you would read a FlatBuffer binary file in Swift: First,
|
||||||
|
include the library and copy thegenerated code. Then read a FlatBuffer binary file or
|
||||||
|
a data object from the server, which you can pass into the `GetRootAsMonster` function.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
|
||||||
|
import FlatBuffers
|
||||||
|
|
||||||
|
typealias Monster1 = MyGame.Sample.Monster
|
||||||
|
typealias Vec3 = MyGame.Sample.Vec3
|
||||||
|
|
||||||
|
let path = FileManager.default.currentDirectoryPath
|
||||||
|
let url = URL(fileURLWithPath: path, isDirectory: true).appendingPathComponent("monsterdata_test").appendingPathExtension("mon")
|
||||||
|
guard let data = try? Data(contentsOf: url) else { return }
|
||||||
|
|
||||||
|
let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Now you can access values like this:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
|
||||||
|
let hp = monster.hp
|
||||||
|
let pos = monster.pos
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
In some cases it's necessary to modify values in an existing FlatBuffer in place (without creating a copy). For this reason, scalar fields of a Flatbuffer table or struct can be mutated.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.swift}
|
||||||
|
let monster = Monster.getRootAsMonster(bb: ByteBuffer(data: data))
|
||||||
|
|
||||||
|
if !monster.mutate(hp: 10) {
|
||||||
|
fatalError("couldn't mutate")
|
||||||
|
}
|
||||||
|
// mutate a struct field
|
||||||
|
let vec = monster.pos.mutate(z: 4)
|
||||||
|
|
||||||
|
// This mutation will fail because the mana field is not available in
|
||||||
|
// the buffer. It should be set when creating the buffer.
|
||||||
|
if !monster.mutate(mana: 20) {
|
||||||
|
fatalError("couldn't mutate")
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The term `mutate` is used instead of `set` to indicate that this is a special use case. All mutate functions return a boolean value which is false if the field we're trying to mutate is not available in the buffer.
|
||||||
|
|
||||||
|
<br>
|
||||||
@@ -23,6 +23,7 @@ Please select your desired language for our quest:
|
|||||||
<form>
|
<form>
|
||||||
<input type="radio" name="language" value="cpp" checked="checked">C++</input>
|
<input type="radio" name="language" value="cpp" checked="checked">C++</input>
|
||||||
<input type="radio" name="language" value="java">Java</input>
|
<input type="radio" name="language" value="java">Java</input>
|
||||||
|
<input type="radio" name="language" value="kotlin">Kotlin</input>
|
||||||
<input type="radio" name="language" value="csharp">C#</input>
|
<input type="radio" name="language" value="csharp">C#</input>
|
||||||
<input type="radio" name="language" value="go">Go</input>
|
<input type="radio" name="language" value="go">Go</input>
|
||||||
<input type="radio" name="language" value="python">Python</input>
|
<input type="radio" name="language" value="python">Python</input>
|
||||||
@@ -34,6 +35,7 @@ Please select your desired language for our quest:
|
|||||||
<input type="radio" name="language" value="lua">Lua</input>
|
<input type="radio" name="language" value="lua">Lua</input>
|
||||||
<input type="radio" name="language" value="lobster">Lobster</input>
|
<input type="radio" name="language" value="lobster">Lobster</input>
|
||||||
<input type="radio" name="language" value="rust">Rust</input>
|
<input type="radio" name="language" value="rust">Rust</input>
|
||||||
|
<input type="radio" name="language" value="swift">Swift</input>
|
||||||
</form>
|
</form>
|
||||||
\endhtmlonly
|
\endhtmlonly
|
||||||
|
|
||||||
@@ -115,6 +117,9 @@ For your chosen language, please cross-reference with:
|
|||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
[SampleBinary.java](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.java)
|
[SampleBinary.java](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.java)
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
[SampleBinary.kt](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.kt)
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
[SampleBinary.cs](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.cs)
|
[SampleBinary.cs](https://github.com/google/flatbuffers/blob/master/samples/SampleBinary.cs)
|
||||||
</div>
|
</div>
|
||||||
@@ -148,6 +153,9 @@ For your chosen language, please cross-reference with:
|
|||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
[sample_binary.rs](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs)
|
[sample_binary.rs](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs)
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
[sample_binary.swift](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.swift)
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
## Writing the Monsters' FlatBuffer Schema
|
## Writing the Monsters' FlatBuffer Schema
|
||||||
@@ -284,6 +292,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
|
|||||||
./../flatc --java monster.fbs
|
./../flatc --java monster.fbs
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.sh}
|
||||||
|
cd flatbuffers/samples
|
||||||
|
./../flatc --kotlin monster.fbs
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.sh}
|
~~~{.sh}
|
||||||
cd flatbuffers/samples
|
cd flatbuffers/samples
|
||||||
@@ -353,6 +367,12 @@ Please be aware of the difference between `flatc` and `flatcc` tools.
|
|||||||
./../flatc --rust monster.fbs
|
./../flatc --rust monster.fbs
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.sh}
|
||||||
|
cd flatbuffers/samples
|
||||||
|
./../flatc --swift monster.fbs
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
For a more complete guide to using the `flatc` compiler, please read the
|
For a more complete guide to using the `flatc` compiler, please read the
|
||||||
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
|
||||||
@@ -382,6 +402,13 @@ The first step is to import/include the library, generated files, etc.
|
|||||||
import com.google.flatbuffers.FlatBufferBuilder;
|
import com.google.flatbuffers.FlatBufferBuilder;
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kotlin}
|
||||||
|
import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
|
||||||
|
|
||||||
|
import com.google.flatbuffers.FlatBufferBuilder
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
using FlatBuffers;
|
using FlatBuffers;
|
||||||
@@ -424,7 +451,7 @@ The first step is to import/include the library, generated files, etc.
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-typescript">
|
<div class="language-typescript">
|
||||||
// note: import flabuffers with your desired import method
|
// note: import flatbuffers with your desired import method
|
||||||
|
|
||||||
import { MyGame } from './monster_generated';
|
import { MyGame } from './monster_generated';
|
||||||
</div>
|
</div>
|
||||||
@@ -485,8 +512,8 @@ The first step is to import/include the library, generated files, etc.
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-lobster">
|
<div class="language-lobster">
|
||||||
~~~{.lobster}
|
~~~{.lobster}
|
||||||
include from "../lobster/" // Where to find flatbuffers.lobster
|
import from "../lobster/" // Where to find flatbuffers.lobster
|
||||||
include "monster_generated.lobster"
|
import monster_generated
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
@@ -506,6 +533,21 @@ The first step is to import/include the library, generated files, etc.
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
/**
|
||||||
|
// make sure that monster_generated.swift is included in your project
|
||||||
|
*/
|
||||||
|
import Flatbuffers
|
||||||
|
|
||||||
|
// typealiases for convenience
|
||||||
|
typealias Monster = MyGame1.Sample.Monster
|
||||||
|
typealias Weapon = MyGame1.Sample.Weapon
|
||||||
|
typealias Color = MyGame1.Sample.Color
|
||||||
|
typealias Vec3 = MyGame1.Sample.Vec3
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Now we are ready to start building some buffers. In order to start, we need
|
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
|
to create an instance of the `FlatBufferBuilder`, which will contain the buffer
|
||||||
as it grows. You can pass an initial size of the buffer (here 1024 bytes),
|
as it grows. You can pass an initial size of the buffer (here 1024 bytes),
|
||||||
@@ -525,6 +567,13 @@ which will grow automatically if needed:
|
|||||||
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
|
FlatBufferBuilder builder = new FlatBufferBuilder(1024);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
|
// monsters' FlatBuffers.
|
||||||
|
val builder = FlatBufferBuilder(1024)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Create a `FlatBufferBuilder`, which will be used to create our
|
// Create a `FlatBufferBuilder`, which will be used to create our
|
||||||
@@ -592,7 +641,7 @@ which will grow automatically if needed:
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-lobster">
|
<div class="language-lobster">
|
||||||
~~~{.lobster}
|
~~~{.lobster}
|
||||||
-- get access to the builder
|
// get access to the builder
|
||||||
let builder = flatbuffers_builder {}
|
let builder = flatbuffers_builder {}
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -603,6 +652,12 @@ which will grow automatically if needed:
|
|||||||
let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);
|
let mut builder = flatbuffers::FlatBufferBuilder::new_with_capacity(1024);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// create a `FlatBufferBuilder`, which will be used to serialize objects
|
||||||
|
let builder = FlatBufferBuilder(initialSize: 1024)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
After creating the `builder`, we can start serializing our data. Before we make
|
After creating the `builder`, we can start serializing our data. Before we make
|
||||||
our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
||||||
@@ -633,6 +688,19 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
|||||||
int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
|
int axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val weaponOneName = builder.createString("Sword")
|
||||||
|
val weaponOneDamage: Short = 3;
|
||||||
|
|
||||||
|
val weaponTwoName = builder.createString("Axe")
|
||||||
|
val weaponTwoDamage: Short = 5;
|
||||||
|
|
||||||
|
// Use the `createWeapon()` helper function to create the weapons, since we set every field.
|
||||||
|
val sword = Weapon.createWeapon(builder, weaponOneName, weaponOneDamage)
|
||||||
|
val axe = Weapon.createWeapon(builder, weaponTwoName, weaponTwoDamage)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
var weaponOneName = builder.CreateString("Sword");
|
var weaponOneName = builder.CreateString("Sword");
|
||||||
@@ -813,12 +881,13 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
|||||||
let weapon_names = [ "Sword", "Axe" ]
|
let weapon_names = [ "Sword", "Axe" ]
|
||||||
let weapon_damages = [ 3, 5 ]
|
let weapon_damages = [ 3, 5 ]
|
||||||
|
|
||||||
weapon_offsets := map(weapon_names) name, i:
|
let weapon_offsets = map(weapon_names) name, i:
|
||||||
let ns = builder.CreateString(name)
|
let ns = builder.CreateString(name)
|
||||||
builder.MyGame_Sample_WeaponStart()
|
MyGame_Sample_WeaponBuilder { b }
|
||||||
builder.MyGame_Sample_WeaponAddName(ns)
|
.start()
|
||||||
builder.MyGame_Sample_WeaponAddDamage(weapon_damages[i])
|
.add_name(ns)
|
||||||
builder.MyGame_Sample_WeaponEnd()
|
.add_damage(weapon_damages[i])
|
||||||
|
.end()
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
@@ -840,6 +909,25 @@ our `orc` Monster, lets create some `Weapon`s: a `Sword` and an `Axe`.
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
let weapon1Name = builder.create(string: "Sword")
|
||||||
|
let weapon2Name = builder.create(string: "Axe")
|
||||||
|
|
||||||
|
// start creating the weapon by calling startWeapon
|
||||||
|
let weapon1Start = Weapon.startWeapon(builder)
|
||||||
|
Weapon.add(name: weapon1Name, builder)
|
||||||
|
Weapon.add(damage: 3, builder)
|
||||||
|
// end the object by passing the start point for the weapon 1
|
||||||
|
let sword = Weapon.endWeapon(builder, start: weapon1Start)
|
||||||
|
|
||||||
|
let weapon2Start = Weapon.startWeapon(builder)
|
||||||
|
Weapon.add(name: weapon2Name, builder)
|
||||||
|
Weapon.add(damage: 5, builder)
|
||||||
|
let axe = Weapon.endWeapon(builder, start: weapon2Start)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Now let's create our monster, the `orc`. For this `orc`, lets make him
|
Now let's create our monster, the `orc`. For this `orc`, lets make him
|
||||||
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
|
`red` with rage, positioned at `(1.0, 2.0, 3.0)`, and give him
|
||||||
a large pool of hit points with `300`. We can give him a vector of weapons
|
a large pool of hit points with `300`. We can give him a vector of weapons
|
||||||
@@ -874,6 +962,17 @@ traversal. This is generally easy to do on any tree structures.
|
|||||||
int inv = Monster.createInventoryVector(builder, treasure);
|
int inv = Monster.createInventoryVector(builder, treasure);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
// Serialize a name for our monster, called "Orc".
|
||||||
|
val name = builder.createString("Orc")
|
||||||
|
|
||||||
|
// Create a `vector` representing the inventory of the Orc. Each number
|
||||||
|
// could correspond to an item that can be claimed after he is slain.
|
||||||
|
val treasure = byteArrayOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
|
||||||
|
val inv = Monster.createInventoryVector(builder, treasure)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Serialize a name for our monster, called "Orc".
|
// Serialize a name for our monster, called "Orc".
|
||||||
@@ -1019,6 +1118,16 @@ traversal. This is generally easy to do on any tree structures.
|
|||||||
let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
let inventory = builder.create_vector(&[0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// Name of the Monster.
|
||||||
|
let name = builder.create(string: "Orc")
|
||||||
|
|
||||||
|
// create inventory
|
||||||
|
let inventory: [Byte] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
let inventoryOffset = builder.createVector(inventory)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
We serialized two built-in data types (`string` and `vector`) and captured
|
We serialized two built-in data types (`string` and `vector`) and captured
|
||||||
their return values. These values are offsets into the serialized data,
|
their return values. These values are offsets into the serialized data,
|
||||||
@@ -1059,6 +1168,16 @@ offsets.
|
|||||||
int weapons = Monster.createWeaponsVector(builder, weaps);
|
int weapons = Monster.createWeaponsVector(builder, weaps);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
// Place the two weapons into an array, and pass it to the `createWeaponsVector()` method to
|
||||||
|
// create a FlatBuffer vector.
|
||||||
|
val weaps = intArrayOf(sword, axe)
|
||||||
|
|
||||||
|
// Pass the `weaps` array into the `createWeaponsVector()` method to create a FlatBuffer vector.
|
||||||
|
val weapons = Monster.createWeaponsVector(builder, weaps)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
var weaps = new Offset<Weapon>[2];
|
var weaps = new Offset<Weapon>[2];
|
||||||
@@ -1153,6 +1272,13 @@ offsets.
|
|||||||
let weapons = builder.create_vector(&[sword, axe]);
|
let weapons = builder.create_vector(&[sword, axe]);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// Create a FlatBuffer `vector` that contains offsets to the sword and axe
|
||||||
|
// we created above.
|
||||||
|
let weaponsOffset = builder.createVector(ofOffsets: [sword, axe])
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
Note there's additional convenience overloads of `CreateVector`, allowing you
|
Note there's additional convenience overloads of `CreateVector`, allowing you
|
||||||
@@ -1179,6 +1305,14 @@ for the `path` field above:
|
|||||||
int path = fbb.endVector();
|
int path = fbb.endVector();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
Monster.startPathVector(fbb, 2)
|
||||||
|
Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f)
|
||||||
|
Vec3.createVec3(builder, 4.0f, 5.0f, 6.0f)
|
||||||
|
val path = fbb.endVector()
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
Monster.StartPathVector(fbb, 2);
|
Monster.StartPathVector(fbb, 2);
|
||||||
@@ -1281,6 +1415,15 @@ for the `path` field above:
|
|||||||
// let path = builder.create_vector(&[&x, &y]);
|
// let path = builder.create_vector(&[&x, &y]);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
//
|
||||||
|
let points = builder.createVector(structs: [MyGame.Sample.createVec3(x: 1, y: 2, z: 3),
|
||||||
|
MyGame.Sample.createVec3(x: 4, y: 5, z: 6)],
|
||||||
|
type: Vec3.self)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
We have now serialized the non-scalar components of the orc, so we
|
We have now serialized the non-scalar components of the orc, so we
|
||||||
can serialize the monster itself:
|
can serialize the monster itself:
|
||||||
@@ -1317,6 +1460,22 @@ can serialize the monster itself:
|
|||||||
int orc = Monster.endMonster(builder);
|
int orc = Monster.endMonster(builder);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
// Create our monster using `startMonster()` and `endMonster()`.
|
||||||
|
Monster.startMonster(builder)
|
||||||
|
Monster.addPos(builder, Vec3.createVec3(builder, 1.0f, 2.0f, 3.0f))
|
||||||
|
Monster.addName(builder, name)
|
||||||
|
Monster.addColor(builder, Color.Red)
|
||||||
|
Monster.addHp(builder, 300.toShort())
|
||||||
|
Monster.addInventory(builder, inv)
|
||||||
|
Monster.addWeapons(builder, weapons)
|
||||||
|
Monster.addEquippedType(builder, Equipment.Weapon)
|
||||||
|
Monster.addEquipped(builder, axe)
|
||||||
|
Monster.addPath(builder, path)
|
||||||
|
val orc = Monster.endMonster(builder)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Create our monster using `StartMonster()` and `EndMonster()`.
|
// Create our monster using `StartMonster()` and `EndMonster()`.
|
||||||
@@ -1503,17 +1662,18 @@ can serialize the monster itself:
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-lobster">
|
<div class="language-lobster">
|
||||||
~~~{.lobster}
|
~~~{.lobster}
|
||||||
builder.MyGame_Sample_MonsterStart()
|
let orc = MyGame_Sample_MonsterBuilder { b }
|
||||||
builder.MyGame_Sample_MonsterAddPos(builder.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
|
.start()
|
||||||
builder.MyGame_Sample_MonsterAddHp(300)
|
.add_pos(b.MyGame_Sample_CreateVec3(1.0, 2.0, 3.0))
|
||||||
builder.MyGame_Sample_MonsterAddName(name)
|
.add_hp(300)
|
||||||
builder.MyGame_Sample_MonsterAddInventory(inv)
|
.add_name(name)
|
||||||
builder.MyGame_Sample_MonsterAddColor(MyGame_Sample_Color_Red)
|
.add_inventory(inv)
|
||||||
builder.MyGame_Sample_MonsterAddWeapons(weapons)
|
.add_color(MyGame_Sample_Color_Red)
|
||||||
builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
|
.add_weapons(weapons)
|
||||||
builder.MyGame_Sample_MonsterAddEquipped(weapon_offsets[1])
|
.add_equipped_type(MyGame_Sample_Equipment_Weapon)
|
||||||
builder.MyGame_Sample_MonsterAddPath(path)
|
.add_equipped(weapon_offsets[1])
|
||||||
let orc = builder.MyGame_Sample_MonsterEnd()
|
.add_path(path)
|
||||||
|
.end()
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
@@ -1537,6 +1697,19 @@ can serialize the monster itself:
|
|||||||
});
|
});
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
let orc = Monster.createMonster(builder,
|
||||||
|
offsetOfPos: pos,
|
||||||
|
hp: 300,
|
||||||
|
offsetOfName: name,
|
||||||
|
vectorOfInventory: inventoryOffset,
|
||||||
|
color: .red,
|
||||||
|
vectorOfWeapons: weaponsOffset,
|
||||||
|
equippedType: .weapon,
|
||||||
|
offsetOfEquipped: axe)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Note how we create `Vec3` struct in-line in the table. Unlike tables, structs
|
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
|
are simple combinations of scalars that are always stored inline, just like
|
||||||
@@ -1602,6 +1775,21 @@ a bit more flexibility.
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
let start = Monster.startMonster(builder)
|
||||||
|
Monster.add(pos: pos, builder)
|
||||||
|
Monster.add(hp: 300, builder)
|
||||||
|
Monster.add(name: name, builder)
|
||||||
|
Monster.addVectorOf(inventory: inventoryOffset, builder)
|
||||||
|
Monster.add(color: .red, builder)
|
||||||
|
Monster.addVectorOf(weapons: weaponsOffset, builder)
|
||||||
|
Monster.add(equippedType: .weapon, builder)
|
||||||
|
Monster.add(equipped: axe, builder)
|
||||||
|
var orc = Monster.endMonster(builder, start: start)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Before finishing the serialization, let's take a quick look at FlatBuffer
|
Before finishing the serialization, let's take a quick look at FlatBuffer
|
||||||
`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
|
`union Equipped`. There are two parts to each FlatBuffer `union`. The first, is
|
||||||
a hidden field `_type`, that is generated to hold the type of `table` referred
|
a hidden field `_type`, that is generated to hold the type of `table` referred
|
||||||
@@ -1625,6 +1813,12 @@ Here is a repetition these lines, to help highlight them more clearly:
|
|||||||
Monster.addEquipped(axe); // Union data
|
Monster.addEquipped(axe); // Union data
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
Monster.addEquippedType(builder, Equipment.Weapon) // Union type
|
||||||
|
Monster.addEquipped(axe) // Union data
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
Monster.AddEquippedType(builder, Equipment.Weapon); // Union type
|
Monster.AddEquippedType(builder, Equipment.Weapon); // Union type
|
||||||
@@ -1687,8 +1881,8 @@ Here is a repetition these lines, to help highlight them more clearly:
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-lobster">
|
<div class="language-lobster">
|
||||||
~~~{.lobster}
|
~~~{.lobster}
|
||||||
builder.MyGame_Sample_MonsterAddEquippedType(MyGame_Sample_Equipment_Weapon)
|
.add_equipped_type(MyGame_Sample_Equipment_Weapon)
|
||||||
builder.MyGame_Sample_MonsterAddEquipped(axe)
|
.add_equipped(axe)
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
@@ -1699,6 +1893,13 @@ Here is a repetition these lines, to help highlight them more clearly:
|
|||||||
monster_builder.add_equipped(axe.as_union_value()); // Union data
|
monster_builder.add_equipped(axe.as_union_value()); // Union data
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
Monster.add(equippedType: .weapon, builder) // Type of union
|
||||||
|
Monster.add(equipped: axe, builder) // Union data
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
After you have created your buffer, you will have the offset to the root of the
|
After you have created your buffer, you will have the offset to the root of the
|
||||||
data in the `orc` variable, so you can finish the buffer by calling the
|
data in the `orc` variable, so you can finish the buffer by calling the
|
||||||
@@ -1720,6 +1921,12 @@ appropriate `finish` method.
|
|||||||
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
|
builder.finish(orc); // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
// Call `finish()` to instruct the builder that this monster is complete.
|
||||||
|
builder.finish(orc) // You could also call `Monster.finishMonsterBuffer(builder, orc);`.
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// Call `Finish()` to instruct the builder that this monster is complete.
|
// Call `Finish()` to instruct the builder that this monster is complete.
|
||||||
@@ -1788,6 +1995,12 @@ appropriate `finish` method.
|
|||||||
builder.finish(orc, None);
|
builder.finish(orc, None);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// Call `finish(offset:)` to instruct the builder that this monster is complete.
|
||||||
|
builder.finish(offset: orc)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
The buffer is now ready to be stored somewhere, sent over the network, be
|
The buffer is now ready to be stored somewhere, sent over the network, be
|
||||||
compressed, or whatever you'd like to do with it. You can access the buffer
|
compressed, or whatever you'd like to do with it. You can access the buffer
|
||||||
@@ -1812,6 +2025,17 @@ like so:
|
|||||||
byte[] buf = builder.sizedByteArray();
|
byte[] buf = builder.sizedByteArray();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
// This must be called after `finish()`.
|
||||||
|
val buf = builder.dataBuffer()
|
||||||
|
// The data in this ByteBuffer does NOT start at 0, but at buf.position().
|
||||||
|
// The number of bytes is buf.remaining().
|
||||||
|
|
||||||
|
// Alternatively this copies the above data out of the ByteBuffer for you:
|
||||||
|
val buf = builder.sizedByteArray()
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// This must be called after `Finish()`.
|
// This must be called after `Finish()`.
|
||||||
@@ -1905,6 +2129,15 @@ like so:
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// This must be called after `finish()`.
|
||||||
|
// `sizedByteArray` returns the finished buf of type [UInt8].
|
||||||
|
let buf = builder.sizedByteArray
|
||||||
|
// or you can use to get an object of type Data
|
||||||
|
let bufData = ByteBuffer(data: builder.data)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Now you can write the bytes to a file, send them over the network..
|
Now you can write the bytes to a file, send them over the network..
|
||||||
**Make sure your file mode (or transfer protocol) is set to BINARY, not text.**
|
**Make sure your file mode (or transfer protocol) is set to BINARY, not text.**
|
||||||
@@ -1934,6 +2167,13 @@ before:
|
|||||||
import com.google.flatbuffers.FlatBufferBuilder;
|
import com.google.flatbuffers.FlatBufferBuilder;
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
import MyGame.Sample.* //The `flatc` generated files. (Monster, Vec3, etc.)
|
||||||
|
|
||||||
|
import com.google.flatbuffers.FlatBufferBuilder
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
using FlatBuffers;
|
using FlatBuffers;
|
||||||
@@ -2033,8 +2273,8 @@ import './monster_my_game.sample_generated.dart' as myGame;
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-lobster">
|
<div class="language-lobster">
|
||||||
~~~{.lobster}
|
~~~{.lobster}
|
||||||
include from "../lobster/" // Where to find flatbuffers.lobster
|
import from "../lobster/" // Where to find flatbuffers.lobster
|
||||||
include "monster_generated.lobster"
|
import monster_generated
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
@@ -2082,6 +2322,15 @@ won't work**
|
|||||||
Monster monster = Monster.getRootAsMonster(buf);
|
Monster monster = Monster.getRootAsMonster(buf);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val bytes = /* the data you just read */
|
||||||
|
val buf = java.nio.ByteBuffer.wrap(bytes)
|
||||||
|
|
||||||
|
// Get an accessor to the root object inside the buffer.
|
||||||
|
Monster monster = Monster.getRootAsMonster(buf)
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
byte[] bytes = /* the data you just read */
|
byte[] bytes = /* the data you just read */
|
||||||
@@ -2189,6 +2438,16 @@ myGame.Monster monster = new myGame.Monster(data);
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// create a ByteBuffer(:) from an [UInt8] or Data()
|
||||||
|
let buf = // Get your data
|
||||||
|
|
||||||
|
// Get an accessor to the root object inside the buffer.
|
||||||
|
let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
If you look in the generated files from the schema compiler, you will see it generated
|
If you look in the generated files from the schema compiler, you will see it generated
|
||||||
accessors for all non-`deprecated` fields. For example:
|
accessors for all non-`deprecated` fields. For example:
|
||||||
|
|
||||||
@@ -2206,6 +2465,13 @@ accessors for all non-`deprecated` fields. For example:
|
|||||||
String name = monster.name();
|
String name = monster.name();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val hp = monster.hp
|
||||||
|
val mana = monster.mana
|
||||||
|
val name = monster.name
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
// For C#, unlike most other languages support by FlatBuffers, most values (except for
|
// For C#, unlike most other languages support by FlatBuffers, most values (except for
|
||||||
@@ -2289,6 +2555,14 @@ accessors for all non-`deprecated` fields. For example:
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
let hp = monster.hp
|
||||||
|
let mana = monster.mana
|
||||||
|
let name = monster.name // returns an optional string
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
These should hold `300`, `150`, and `"Orc"` respectively.
|
These should hold `300`, `150`, and `"Orc"` respectively.
|
||||||
|
|
||||||
*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.*
|
*Note: The default value `150` wasn't stored in `mana`, but we are still able to retrieve it.*
|
||||||
@@ -2311,6 +2585,14 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
|||||||
float z = pos.z();
|
float z = pos.z();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val pos = monster.pos!!
|
||||||
|
val x = pos.x
|
||||||
|
val y = pos.y
|
||||||
|
val z = pos.z
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
var pos = monster.Pos.Value;
|
var pos = monster.Pos.Value;
|
||||||
@@ -2406,6 +2688,15 @@ To access sub-objects, in the case of our `pos`, which is a `Vec3`:
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
let pos = monster.pos
|
||||||
|
let x = pos.x
|
||||||
|
let y = pos.y
|
||||||
|
let z = pos.z
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
|
`x`, `y`, and `z` will contain `1.0`, `2.0`, and `3.0`, respectively.
|
||||||
|
|
||||||
*Note: Had we not set `pos` during serialization, it would be a `NULL`-value.*
|
*Note: Had we not set `pos` during serialization, it would be a `NULL`-value.*
|
||||||
@@ -2417,7 +2708,7 @@ FlatBuffers `vector`.
|
|||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`.
|
auto inv = monster->inventory(); // A pointer to a `flatbuffers::Vector<>`.
|
||||||
auto inv_len = inv->Length();
|
auto inv_len = inv->size();
|
||||||
auto third_item = inv->Get(2);
|
auto third_item = inv->Get(2);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -2427,6 +2718,12 @@ FlatBuffers `vector`.
|
|||||||
byte thirdItem = monster.inventory(2);
|
byte thirdItem = monster.inventory(2);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kotlin}
|
||||||
|
val invLength = monster.inventoryLength
|
||||||
|
val thirdItem = monster.inventory(2)!!
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
int invLength = monster.InventoryLength;
|
int invLength = monster.InventoryLength;
|
||||||
@@ -2500,13 +2797,27 @@ FlatBuffers `vector`.
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// Get a the count of objects in the vector
|
||||||
|
let count = monster.inventoryCount
|
||||||
|
|
||||||
|
// get item at index 4
|
||||||
|
let object = monster.inventory(at: 4)
|
||||||
|
|
||||||
|
// or you can fetch the entire array
|
||||||
|
let inv = monster.inventory
|
||||||
|
// inv[4] should equal object
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
For `vector`s of `table`s, you can access the elements like any other vector,
|
For `vector`s of `table`s, you can access the elements like any other vector,
|
||||||
except your need to handle the result as a FlatBuffer `table`:
|
except your need to handle the result as a FlatBuffer `table`:
|
||||||
|
|
||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`.
|
auto weapons = monster->weapons(); // A pointer to a `flatbuffers::Vector<>`.
|
||||||
auto weapon_len = weapons->Length();
|
auto weapon_len = weapons->size();
|
||||||
auto second_weapon_name = weapons->Get(1)->name()->str();
|
auto second_weapon_name = weapons->Get(1)->name()->str();
|
||||||
auto second_weapon_damage = weapons->Get(1)->damage()
|
auto second_weapon_damage = weapons->Get(1)->damage()
|
||||||
~~~
|
~~~
|
||||||
@@ -2518,6 +2829,13 @@ except your need to handle the result as a FlatBuffer `table`:
|
|||||||
short secondWeaponDamage = monster.weapons(1).damage();
|
short secondWeaponDamage = monster.weapons(1).damage();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val weaponsLength = monster.weaponsLength
|
||||||
|
val secondWeaponName = monster.weapons(1)!!.name
|
||||||
|
val secondWeaponDamage = monster.weapons(1)!!.damage
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
int weaponsLength = monster.WeaponsLength;
|
int weaponsLength = monster.WeaponsLength;
|
||||||
@@ -2605,6 +2923,16 @@ except your need to handle the result as a FlatBuffer `table`:
|
|||||||
let second_weapon_damage = wep2.damage();
|
let second_weapon_damage = wep2.damage();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// Get the count of weapon objects
|
||||||
|
let wepsCount = monster.weaponsCount
|
||||||
|
|
||||||
|
let weapon2 = monster.weapons(at: 1)
|
||||||
|
let weaponName = weapon2.name
|
||||||
|
let weaponDmg = weapon2.damage
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
|
Last, we can access our `Equipped` FlatBuffer `union`. Just like when we created
|
||||||
the `union`, we need to get both parts of the `union`: the type and the data.
|
the `union`, we need to get both parts of the `union`: the type and the data.
|
||||||
@@ -2638,6 +2966,19 @@ We can access the type to dynamically cast the data as needed (since the
|
|||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val unionType = monster.EquippedType
|
||||||
|
|
||||||
|
if (unionType == Equipment.Weapon) {
|
||||||
|
val weapon = monster.equipped(Weapon()) as Weapon // Requires explicit cast
|
||||||
|
// to `Weapon`.
|
||||||
|
|
||||||
|
val weaponName = weapon.name // "Axe"
|
||||||
|
val weaponDamage = weapon.damage // 5
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
var unionType = monster.EquippedType;
|
var unionType = monster.EquippedType;
|
||||||
@@ -2779,6 +3120,17 @@ We can access the type to dynamically cast the data as needed (since the
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
// Get and check if the monster has an equipped item
|
||||||
|
if monster.equippedType == .weapon {
|
||||||
|
let _weapon = monster.equipped(type: Weapon.self)
|
||||||
|
let name = _weapon.name // should return "Axe"
|
||||||
|
let dmg = _weapon.damage // should return 5
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
## Mutating FlatBuffers
|
## Mutating FlatBuffers
|
||||||
|
|
||||||
As you saw above, typically once you have created a FlatBuffer, it is read-only
|
As you saw above, typically once you have created a FlatBuffer, it is read-only
|
||||||
@@ -2814,6 +3166,14 @@ mutators like so:
|
|||||||
monster.mutateInventory(0, 1); // Set vector element.
|
monster.mutateInventory(0, 1); // Set vector element.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
~~~{.kt}
|
||||||
|
val monster = Monster.getRootAsMonster(buf)
|
||||||
|
monster.mutateHp(10) // Set table field.
|
||||||
|
monster.pos!!.mutateZ(4) // Set struct field.
|
||||||
|
monster.mutateInventory(0, 1) // Set vector element.
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
~~~{.cs}
|
~~~{.cs}
|
||||||
var monster = Monster.GetRootAsMonster(buf);
|
var monster = Monster.GetRootAsMonster(buf);
|
||||||
@@ -2874,6 +3234,15 @@ mutators like so:
|
|||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="language-swift">
|
||||||
|
~~~{.swift}
|
||||||
|
let monster = Monster.getRootAsMonster(bb: ByteBuffer(bytes: buf))
|
||||||
|
monster.mutate(hp: 10) // mutates a value in a table
|
||||||
|
monster.pos.mutate(z: 4) // mutates a value in a struct
|
||||||
|
monster.mutate(inventory: 6, at index: 0) // mutates a value in an Scalar array
|
||||||
|
~~~
|
||||||
|
</div>
|
||||||
|
|
||||||
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
|
We use the somewhat verbose term `mutate` instead of `set` to indicate that this
|
||||||
is a special use case, not to be confused with the default way of constructing
|
is a special use case, not to be confused with the default way of constructing
|
||||||
FlatBuffer data.
|
FlatBuffer data.
|
||||||
@@ -2897,16 +3266,18 @@ If this is not sufficient, other ways of mutating FlatBuffers may be supported
|
|||||||
in your language through an object based API (`--gen-object-api`) or reflection.
|
in your language through an object based API (`--gen-object-api`) or reflection.
|
||||||
See the individual language documents for support.
|
See the individual language documents for support.
|
||||||
|
|
||||||
## JSON with FlatBuffers
|
## Using `flatc` as a JSON Conversion Tool
|
||||||
|
|
||||||
#### Using `flatc` as a Conversion Tool
|
If you are working with C, C++, or Lobster, you can parse JSON at runtime.
|
||||||
|
If your language does not support JSON at the moment, `flatc` may provide an
|
||||||
This is often the preferred method to use JSON with FlatBuffers, as it doesn't
|
alternative. Using `flatc` is often the preferred method, as it doesn't require you to
|
||||||
require you to add any new code to your program. It is also efficient, since you
|
add any new code to your program. It is also efficient, since you can ship with
|
||||||
can ship with the binary data. The drawback is that it requires an extra step
|
the binary data. The drawback is that it requires an extra step for your
|
||||||
for your users/developers to perform (although it may be able to be automated
|
users/developers to perform (although it may be able to be automated
|
||||||
as part of your compilation).
|
as part of your compilation).
|
||||||
|
|
||||||
|
#### JSON to binary representation
|
||||||
|
|
||||||
Lets say you have a JSON file that describes your monster. In this example,
|
Lets say you have a JSON file that describes your monster. In this example,
|
||||||
we will use the file `flatbuffers/samples/monsterdata.json`.
|
we will use the file `flatbuffers/samples/monsterdata.json`.
|
||||||
|
|
||||||
@@ -2915,16 +3286,31 @@ Here are the contents of the file:
|
|||||||
~~~{.json}
|
~~~{.json}
|
||||||
{
|
{
|
||||||
pos: {
|
pos: {
|
||||||
x: 1,
|
x: 1.0,
|
||||||
y: 2,
|
y: 2.0,
|
||||||
z: 3
|
z: 3.0
|
||||||
},
|
},
|
||||||
hp: 300,
|
hp: 300,
|
||||||
name: "Orc"
|
name: "Orc",
|
||||||
|
weapons: [
|
||||||
|
{
|
||||||
|
name: "axe",
|
||||||
|
damage: 100
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "bow",
|
||||||
|
damage: 90
|
||||||
|
}
|
||||||
|
],
|
||||||
|
equipped_type: "Weapon",
|
||||||
|
equipped: {
|
||||||
|
name: "bow",
|
||||||
|
damage: 90
|
||||||
|
}
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
You can run this file through the `flatc` compile with the `-b` flag and
|
You can run this file through the `flatc` compiler with the `-b` flag and
|
||||||
our `monster.fbs` schema to produce a FlatBuffer binary file.
|
our `monster.fbs` schema to produce a FlatBuffer binary file.
|
||||||
|
|
||||||
~~~{.sh}
|
~~~{.sh}
|
||||||
@@ -2953,6 +3339,30 @@ for `flatcc` to support this.*
|
|||||||
Guide for more information.*
|
Guide for more information.*
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
#### FlatBuffer binary to JSON
|
||||||
|
|
||||||
|
Converting from a FlatBuffer binary representation to JSON is supported as well:
|
||||||
|
~~~{.sh}
|
||||||
|
./../flatc --json --raw-binary monster.fbs -- monsterdata.bin
|
||||||
|
~~~
|
||||||
|
This will convert `monsterdata.bin` back to its original JSON representation.
|
||||||
|
You need to pass the corresponding FlatBuffers schema so that flatc knows how to
|
||||||
|
interpret the binary buffer. Since `monster.fbs` does not specify an explicit
|
||||||
|
`file_identifier` for binary buffers, `flatc` needs to be forced into reading
|
||||||
|
the `.bin` file using the `--raw-binary` option.
|
||||||
|
|
||||||
|
The FlatBuffer binary representation does not explicitly encode default values,
|
||||||
|
therefore they are not present in the resulting JSON unless you specify
|
||||||
|
`--defaults-json`.
|
||||||
|
|
||||||
|
If you intend to process the JSON with other tools, you may consider switching
|
||||||
|
on `--strict-json` so that identifiers are quoted properly.
|
||||||
|
|
||||||
|
*Note: The resulting JSON file is not necessarily identical with the original JSON.
|
||||||
|
If the binary representation contains floating point numbers, floats and doubles
|
||||||
|
are rounded to 6 and 12 digits, respectively, in order to represent them as
|
||||||
|
decimals in the JSON document. *
|
||||||
|
|
||||||
## Advanced Features for Each Language
|
## Advanced Features for Each Language
|
||||||
|
|
||||||
Each language has a dedicated `Use in XXX` page in the Programmer's Guide
|
Each language has a dedicated `Use in XXX` page in the Programmer's Guide
|
||||||
@@ -2964,10 +3374,13 @@ For your chosen language, see:
|
|||||||
[Use in C++](@ref flatbuffers_guide_use_cpp)
|
[Use in C++](@ref flatbuffers_guide_use_cpp)
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
|
[Use in Java](@ref flatbuffers_guide_use_java)
|
||||||
|
</div>
|
||||||
|
<div class="language-kotlin">
|
||||||
|
[Use in Kotlin](@ref flatbuffers_guide_use_kotlin)
|
||||||
</div>
|
</div>
|
||||||
<div class="language-csharp">
|
<div class="language-csharp">
|
||||||
[Use in Java/C#](@ref flatbuffers_guide_use_java_c-sharp)
|
[Use in C#](@ref flatbuffers_guide_use_c-sharp)
|
||||||
</div>
|
</div>
|
||||||
<div class="language-go">
|
<div class="language-go">
|
||||||
[Use in Go](@ref flatbuffers_guide_use_go)
|
[Use in Go](@ref flatbuffers_guide_use_go)
|
||||||
@@ -2999,5 +3412,7 @@ For your chosen language, see:
|
|||||||
<div class="language-rust">
|
<div class="language-rust">
|
||||||
[Use in Rust](@ref flatbuffers_guide_use_rust)
|
[Use in Rust](@ref flatbuffers_guide_use_rust)
|
||||||
</div>
|
</div>
|
||||||
|
<div class="language-swift">
|
||||||
|
[Use in Swift](@ref flatbuffers_guide_use_swift)
|
||||||
|
</div>
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ First, include the library and generated code. Then read the file into an
|
|||||||
the ByteBuffer to the `getRootAsMonster` function.
|
the ByteBuffer to the `getRootAsMonster` function.
|
||||||
|
|
||||||
~~~{.ts}
|
~~~{.ts}
|
||||||
// note: import flabuffers with your desired import method
|
// note: import flatbuffers with your desired import method
|
||||||
|
|
||||||
import { MyGame } from './monster_generated';
|
import { MyGame } from './monster_generated';
|
||||||
|
|
||||||
|
|||||||
@@ -778,7 +778,7 @@ INPUT = "FlatBuffers.md" \
|
|||||||
"../../php/FlatbufferBuilder.php" \
|
"../../php/FlatbufferBuilder.php" \
|
||||||
"../../net/FlatBuffers/FlatBufferBuilder.cs" \
|
"../../net/FlatBuffers/FlatBufferBuilder.cs" \
|
||||||
"../../include/flatbuffers/flatbuffers.h" \
|
"../../include/flatbuffers/flatbuffers.h" \
|
||||||
"../../go/builder.go"
|
"../../go/builder.go" \
|
||||||
"../../rust/flatbuffers/src/builder.rs"
|
"../../rust/flatbuffers/src/builder.rs"
|
||||||
|
|
||||||
# This tag can be used to specify the character encoding of the source files
|
# This tag can be used to specify the character encoding of the source files
|
||||||
|
|||||||
@@ -29,8 +29,10 @@
|
|||||||
title="Use in C"/>
|
title="Use in C"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_go"
|
<tab type="user" url="@ref flatbuffers_guide_use_go"
|
||||||
title="Use in Go"/>
|
title="Use in Go"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_java_c-sharp"
|
<tab type="user" url="@ref flatbuffers_guide_use_java"
|
||||||
title="Use in Java/C#"/>
|
title="Use in Java"/>
|
||||||
|
<tab type="user" url="@ref flatbuffers_guide_use_c-sharp"
|
||||||
|
title="Use in C#"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_javascript"
|
<tab type="user" url="@ref flatbuffers_guide_use_javascript"
|
||||||
title="Use in JavaScript"/>
|
title="Use in JavaScript"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_typescript"
|
<tab type="user" url="@ref flatbuffers_guide_use_typescript"
|
||||||
@@ -48,7 +50,7 @@
|
|||||||
<tab type="user" url="@ref flatbuffers_guide_use_rust"
|
<tab type="user" url="@ref flatbuffers_guide_use_rust"
|
||||||
title="Use in Rust"/>
|
title="Use in Rust"/>
|
||||||
<tab type="user" url="@ref flexbuffers"
|
<tab type="user" url="@ref flexbuffers"
|
||||||
title="Schema-less version"/>
|
title="FlexBuffers (Schema-less version)"/>
|
||||||
<tab type="usergroup" url="" title="gRPC">
|
<tab type="usergroup" url="" title="gRPC">
|
||||||
<tab type="user" url="@ref flatbuffers_grpc_guide_use_cpp"
|
<tab type="user" url="@ref flatbuffers_grpc_guide_use_cpp"
|
||||||
title="Use in C++"/>
|
title="Use in C++"/>
|
||||||
|
|||||||
@@ -1,5 +1,11 @@
|
|||||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
alias(
|
||||||
|
name = "go_default_library",
|
||||||
|
actual = ":go",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
go_library(
|
go_library(
|
||||||
name = "go",
|
name = "go",
|
||||||
srcs = [
|
srcs = [
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ type Builder struct {
|
|||||||
head UOffsetT
|
head UOffsetT
|
||||||
nested bool
|
nested bool
|
||||||
finished bool
|
finished bool
|
||||||
|
|
||||||
|
sharedStrings map[string]UOffsetT
|
||||||
}
|
}
|
||||||
|
|
||||||
const fileIdentifierLength = 4
|
const fileIdentifierLength = 4
|
||||||
@@ -33,7 +35,6 @@ func NewBuilder(initialSize int) *Builder {
|
|||||||
b.head = UOffsetT(initialSize)
|
b.head = UOffsetT(initialSize)
|
||||||
b.minalign = 1
|
b.minalign = 1
|
||||||
b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity
|
b.vtables = make([]UOffsetT, 0, 16) // sensible default capacity
|
||||||
|
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -307,6 +308,20 @@ func (b *Builder) EndVector(vectorNumElems int) UOffsetT {
|
|||||||
return b.Offset()
|
return b.Offset()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CreateSharedString Checks if the string is already written
|
||||||
|
// to the buffer before calling CreateString
|
||||||
|
func (b *Builder) CreateSharedString(s string) UOffsetT {
|
||||||
|
if b.sharedStrings == nil {
|
||||||
|
b.sharedStrings = make(map[string]UOffsetT)
|
||||||
|
}
|
||||||
|
if v, ok := b.sharedStrings[s]; ok {
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
off := b.CreateString(s)
|
||||||
|
b.sharedStrings[s] = off
|
||||||
|
return off
|
||||||
|
}
|
||||||
|
|
||||||
// CreateString writes a null-terminated string as a vector.
|
// CreateString writes a null-terminated string as a vector.
|
||||||
func (b *Builder) CreateString(s string) UOffsetT {
|
func (b *Builder) CreateString(s string) UOffsetT {
|
||||||
b.assertNotNested()
|
b.assertNotNested()
|
||||||
|
|||||||
15
go/grpc.go
15
go/grpc.go
@@ -3,21 +3,36 @@ package flatbuffers
|
|||||||
// Codec implements gRPC-go Codec which is used to encode and decode messages.
|
// Codec implements gRPC-go Codec which is used to encode and decode messages.
|
||||||
var Codec = "flatbuffers"
|
var Codec = "flatbuffers"
|
||||||
|
|
||||||
|
// FlatbuffersCodec defines the interface gRPC uses to encode and decode messages. Note
|
||||||
|
// that implementations of this interface must be thread safe; a Codec's
|
||||||
|
// methods can be called from concurrent goroutines.
|
||||||
type FlatbuffersCodec struct{}
|
type FlatbuffersCodec struct{}
|
||||||
|
|
||||||
|
// Marshal returns the wire format of v.
|
||||||
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
|
func (FlatbuffersCodec) Marshal(v interface{}) ([]byte, error) {
|
||||||
return v.(*Builder).FinishedBytes(), nil
|
return v.(*Builder).FinishedBytes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Unmarshal parses the wire format into v.
|
||||||
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
|
func (FlatbuffersCodec) Unmarshal(data []byte, v interface{}) error {
|
||||||
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
|
v.(flatbuffersInit).Init(data, GetUOffsetT(data))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String old gRPC Codec interface func
|
||||||
func (FlatbuffersCodec) String() string {
|
func (FlatbuffersCodec) String() string {
|
||||||
return Codec
|
return Codec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the Codec implementation. The returned string
|
||||||
|
// will be used as part of content type in transmission. The result must be
|
||||||
|
// static; the result cannot change between calls.
|
||||||
|
//
|
||||||
|
// add Name() for ForceCodec interface
|
||||||
|
func (FlatbuffersCodec) Name() string {
|
||||||
|
return Codec
|
||||||
|
}
|
||||||
|
|
||||||
type flatbuffersInit interface {
|
type flatbuffersInit interface {
|
||||||
Init(data []byte, i UOffsetT)
|
Init(data []byte, i UOffsetT)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-parent</artifactId>
|
<artifactId>flatbuffers-parent</artifactId>
|
||||||
<version>1.11.0</version>
|
<version>1.12.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>flatbuffers-java-grpc</artifactId>
|
<artifactId>flatbuffers-java-grpc</artifactId>
|
||||||
<name>${project.artifactId}</name>
|
<name>${project.artifactId}</name>
|
||||||
@@ -24,7 +24,7 @@
|
|||||||
</developer>
|
</developer>
|
||||||
</developers>
|
</developers>
|
||||||
<properties>
|
<properties>
|
||||||
<gRPC.version>1.11.0</gRPC.version>
|
<gRPC.version>1.12.0</gRPC.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-parent</artifactId>
|
<artifactId>flatbuffers-parent</artifactId>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<version>1.11.0</version>
|
<version>1.12.0</version>
|
||||||
<name>flatbuffers-parent</name>
|
<name>flatbuffers-parent</name>
|
||||||
<description>parent pom for flatbuffers java artifacts</description>
|
<description>parent pom for flatbuffers java artifacts</description>
|
||||||
<properties>
|
<properties>
|
||||||
|
|||||||
@@ -12,7 +12,8 @@ class GreeterServiceImpl final : public Greeter::Service {
|
|||||||
grpc::ServerContext *context,
|
grpc::ServerContext *context,
|
||||||
const flatbuffers::grpc::Message<HelloRequest> *request_msg,
|
const flatbuffers::grpc::Message<HelloRequest> *request_msg,
|
||||||
flatbuffers::grpc::Message<HelloReply> *response_msg) override {
|
flatbuffers::grpc::Message<HelloReply> *response_msg) override {
|
||||||
// flatbuffers::grpc::MessageBuilder mb_;
|
flatbuffers::grpc::MessageBuilder mb_;
|
||||||
|
|
||||||
// We call GetRoot to "parse" the message. Verification is already
|
// We call GetRoot to "parse" the message. Verification is already
|
||||||
// performed by default. See the notes below for more details.
|
// performed by default. See the notes below for more details.
|
||||||
const HelloRequest *request = request_msg->GetRoot();
|
const HelloRequest *request = request_msg->GetRoot();
|
||||||
|
|||||||
107
grpc/src/compiler/BUILD
Normal file
107
grpc/src/compiler/BUILD
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
load("@rules_cc//cc:defs.bzl", "cc_library")
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
|
|
||||||
|
filegroup(
|
||||||
|
name = "common_headers",
|
||||||
|
srcs = [
|
||||||
|
"config.h",
|
||||||
|
"schema_interface.h",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "cpp_generator",
|
||||||
|
srcs = [
|
||||||
|
"cpp_generator.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"cpp_generator.h",
|
||||||
|
":common_headers",
|
||||||
|
],
|
||||||
|
include_prefix = "src/compiler",
|
||||||
|
strip_include_prefix = "/grpc/src/compiler",
|
||||||
|
deps = [
|
||||||
|
"//:flatbuffers",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "go_generator",
|
||||||
|
srcs = [
|
||||||
|
"go_generator.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"go_generator.h",
|
||||||
|
":common_headers",
|
||||||
|
],
|
||||||
|
include_prefix = "src/compiler",
|
||||||
|
strip_include_prefix = "/grpc/src/compiler",
|
||||||
|
deps = [
|
||||||
|
"//:flatbuffers",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "java_generator",
|
||||||
|
srcs = [
|
||||||
|
"java_generator.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"java_generator.h",
|
||||||
|
":common_headers",
|
||||||
|
],
|
||||||
|
include_prefix = "src/compiler",
|
||||||
|
strip_include_prefix = "/grpc/src/compiler",
|
||||||
|
deps = [
|
||||||
|
"//:flatbuffers",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "python_generator",
|
||||||
|
hdrs = [
|
||||||
|
"python_generator.h",
|
||||||
|
],
|
||||||
|
include_prefix = "src/compiler",
|
||||||
|
strip_include_prefix = "/grpc/src/compiler",
|
||||||
|
deps = [
|
||||||
|
":python_generator_private",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "python_generator_private",
|
||||||
|
srcs = [
|
||||||
|
"python_generator.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"python_generator.h",
|
||||||
|
"python_private_generator.h",
|
||||||
|
":common_headers",
|
||||||
|
],
|
||||||
|
include_prefix = "src/compiler",
|
||||||
|
strip_include_prefix = "/grpc/src/compiler",
|
||||||
|
visibility = ["//visibility:private"],
|
||||||
|
deps = [
|
||||||
|
"//:flatbuffers",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
cc_library(
|
||||||
|
name = "swift_generator",
|
||||||
|
srcs = [
|
||||||
|
"swift_generator.cc",
|
||||||
|
],
|
||||||
|
hdrs = [
|
||||||
|
"swift_generator.h",
|
||||||
|
":common_headers",
|
||||||
|
],
|
||||||
|
include_prefix = "src/compiler",
|
||||||
|
strip_include_prefix = "/grpc/src/compiler",
|
||||||
|
deps = [
|
||||||
|
"//:flatbuffers",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "java_generator.h"
|
#include "src/compiler/java_generator.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|||||||
624
grpc/src/compiler/python_generator.cc
Normal file
624
grpc/src/compiler/python_generator.cc
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015 gRPC authors.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <ostream>
|
||||||
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
#include <tuple>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
#include "src/compiler/python_generator.h"
|
||||||
|
#include "src/compiler/python_private_generator.h"
|
||||||
|
|
||||||
|
using std::make_pair;
|
||||||
|
using std::map;
|
||||||
|
using std::pair;
|
||||||
|
using std::replace;
|
||||||
|
using std::tuple;
|
||||||
|
using std::vector;
|
||||||
|
using std::set;
|
||||||
|
|
||||||
|
namespace grpc_python_generator {
|
||||||
|
|
||||||
|
grpc::string generator_file_name;
|
||||||
|
|
||||||
|
typedef map<grpc::string, grpc::string> StringMap;
|
||||||
|
typedef vector<grpc::string> StringVector;
|
||||||
|
typedef tuple<grpc::string, grpc::string> StringPair;
|
||||||
|
typedef set<StringPair> StringPairSet;
|
||||||
|
|
||||||
|
// Provides RAII indentation handling. Use as:
|
||||||
|
// {
|
||||||
|
// IndentScope raii_my_indent_var_name_here(my_py_printer);
|
||||||
|
// // constructor indented my_py_printer
|
||||||
|
// ...
|
||||||
|
// // destructor called at end of scope, un-indenting my_py_printer
|
||||||
|
// }
|
||||||
|
class IndentScope {
|
||||||
|
public:
|
||||||
|
explicit IndentScope(grpc_generator::Printer* printer) : printer_(printer) {
|
||||||
|
printer_->Indent();
|
||||||
|
}
|
||||||
|
|
||||||
|
~IndentScope() { printer_->Outdent(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
grpc_generator::Printer* printer_;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
|
||||||
|
const grpc::string& to, bool replace_all) {
|
||||||
|
size_t pos = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
pos = str.find(from, pos);
|
||||||
|
if (pos == grpc::string::npos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
str.replace(pos, from.length(), to);
|
||||||
|
pos += to.length();
|
||||||
|
} while (replace_all);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline grpc::string StringReplace(grpc::string str, const grpc::string& from,
|
||||||
|
const grpc::string& to) {
|
||||||
|
return StringReplace(str, from, to, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string ModuleName(const grpc::string& filename,
|
||||||
|
const grpc::string& import_prefix) {
|
||||||
|
grpc::string basename = flatbuffers::StripExtension(filename);
|
||||||
|
basename = StringReplace(basename, "-", "_");
|
||||||
|
basename = StringReplace(basename, "/", ".");
|
||||||
|
return import_prefix + basename + "_fb";
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string ModuleAlias(const grpc::string& filename,
|
||||||
|
const grpc::string& import_prefix) {
|
||||||
|
grpc::string module_name = ModuleName(filename, import_prefix);
|
||||||
|
// We can't have dots in the module name, so we replace each with _dot_.
|
||||||
|
// But that could lead to a collision between a.b and a_dot_b, so we also
|
||||||
|
// duplicate each underscore.
|
||||||
|
module_name = StringReplace(module_name, "_", "__");
|
||||||
|
module_name = StringReplace(module_name, ".", "_dot_");
|
||||||
|
return module_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
PrivateGenerator::PrivateGenerator(const GeneratorConfiguration& config_,
|
||||||
|
const grpc_generator::File* file_)
|
||||||
|
: config(config_), file(file_) {}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintBetaServicer(const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out) {
|
||||||
|
StringMap service_dict;
|
||||||
|
service_dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(service_dict, "class Beta$Service$Servicer(object):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_class_indent(out);
|
||||||
|
out->Print(
|
||||||
|
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
|
||||||
|
"\nIt is recommended to use the GA API (classes and functions in this\n"
|
||||||
|
"file not marked beta) for all further purposes. This class was "
|
||||||
|
"generated\n"
|
||||||
|
"only to ease transition from grpcio<0.15.0 to "
|
||||||
|
"grpcio>=0.15.0.\"\"\"\n");
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
grpc::string arg_name =
|
||||||
|
method->ClientStreaming() ? "request_iterator" : "request";
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["Method"] = method->name();
|
||||||
|
method_dict["ArgName"] = arg_name;
|
||||||
|
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_method_indent(out);
|
||||||
|
out->Print("context.code(beta_interfaces.StatusCode.UNIMPLEMENTED)\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintBetaStub(const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out) {
|
||||||
|
StringMap service_dict;
|
||||||
|
service_dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(service_dict, "class Beta$Service$Stub(object):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_class_indent(out);
|
||||||
|
out->Print(
|
||||||
|
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
|
||||||
|
"\nIt is recommended to use the GA API (classes and functions in this\n"
|
||||||
|
"file not marked beta) for all further purposes. This class was "
|
||||||
|
"generated\n"
|
||||||
|
"only to ease transition from grpcio<0.15.0 to "
|
||||||
|
"grpcio>=0.15.0.\"\"\"\n");
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
grpc::string arg_name =
|
||||||
|
method->ClientStreaming() ? "request_iterator" : "request";
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["Method"] = method->name();
|
||||||
|
method_dict["ArgName"] = arg_name;
|
||||||
|
out->Print(method_dict,
|
||||||
|
"def $Method$(self, $ArgName$, timeout, metadata=None, "
|
||||||
|
"with_call=False, protocol_options=None):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_method_indent(out);
|
||||||
|
out->Print("raise NotImplementedError()\n");
|
||||||
|
}
|
||||||
|
if (!method->ServerStreaming()) {
|
||||||
|
out->Print(method_dict, "$Method$.future = None\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintBetaServerFactory(
|
||||||
|
const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service, grpc_generator::Printer* out) {
|
||||||
|
StringMap service_dict;
|
||||||
|
service_dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(service_dict,
|
||||||
|
"def beta_create_$Service$_server(servicer, pool=None, "
|
||||||
|
"pool_size=None, default_timeout=None, maximum_timeout=None):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_create_server_indent(out);
|
||||||
|
out->Print(
|
||||||
|
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
|
||||||
|
"\nIt is recommended to use the GA API (classes and functions in this\n"
|
||||||
|
"file not marked beta) for all further purposes. This function was\n"
|
||||||
|
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
|
||||||
|
"\"\"\"\n");
|
||||||
|
StringMap method_implementation_constructors;
|
||||||
|
StringMap input_message_modules_and_classes;
|
||||||
|
StringMap output_message_modules_and_classes;
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
const grpc::string method_implementation_constructor =
|
||||||
|
grpc::string(method->ClientStreaming() ? "stream_" : "unary_") +
|
||||||
|
grpc::string(method->ServerStreaming() ? "stream_" : "unary_") +
|
||||||
|
"inline";
|
||||||
|
grpc::string input_message_module_and_class = method->get_fb_builder();
|
||||||
|
grpc::string output_message_module_and_class = method->get_fb_builder();
|
||||||
|
method_implementation_constructors.insert(
|
||||||
|
make_pair(method->name(), method_implementation_constructor));
|
||||||
|
input_message_modules_and_classes.insert(
|
||||||
|
make_pair(method->name(), input_message_module_and_class));
|
||||||
|
output_message_modules_and_classes.insert(
|
||||||
|
make_pair(method->name(), output_message_module_and_class));
|
||||||
|
}
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
|
||||||
|
// out->Print("request_deserializers = {\n");
|
||||||
|
// for (StringMap::iterator name_and_input_module_class_pair =
|
||||||
|
// input_message_modules_and_classes.begin();
|
||||||
|
// name_and_input_module_class_pair !=
|
||||||
|
// input_message_modules_and_classes.end();
|
||||||
|
// name_and_input_module_class_pair++) {
|
||||||
|
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
|
||||||
|
// method_dict["InputTypeModuleAndClass"] =
|
||||||
|
// name_and_input_module_class_pair->second;
|
||||||
|
// IndentScope raii_indent(out);
|
||||||
|
// out->Print(method_dict,
|
||||||
|
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
|
||||||
|
// "$InputTypeModuleAndClass$.FromString,\n");
|
||||||
|
// }
|
||||||
|
// out->Print("}\n");
|
||||||
|
// out->Print("response_serializers = {\n");
|
||||||
|
// for (StringMap::iterator name_and_output_module_class_pair =
|
||||||
|
// output_message_modules_and_classes.begin();
|
||||||
|
// name_and_output_module_class_pair !=
|
||||||
|
// output_message_modules_and_classes.end();
|
||||||
|
// name_and_output_module_class_pair++) {
|
||||||
|
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
|
||||||
|
// method_dict["OutputTypeModuleAndClass"] =
|
||||||
|
// name_and_output_module_class_pair->second;
|
||||||
|
// IndentScope raii_indent(out);
|
||||||
|
// out->Print(method_dict,
|
||||||
|
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
|
||||||
|
// "$OutputTypeModuleAndClass$.SerializeToString,\n");
|
||||||
|
// }
|
||||||
|
// out->Print("}\n");
|
||||||
|
out->Print("method_implementations = {\n");
|
||||||
|
for (StringMap::iterator name_and_implementation_constructor =
|
||||||
|
method_implementation_constructors.begin();
|
||||||
|
name_and_implementation_constructor !=
|
||||||
|
method_implementation_constructors.end();
|
||||||
|
name_and_implementation_constructor++) {
|
||||||
|
method_dict["Method"] = name_and_implementation_constructor->first;
|
||||||
|
method_dict["Constructor"] = name_and_implementation_constructor->second;
|
||||||
|
IndentScope raii_descriptions_indent(out);
|
||||||
|
const grpc::string method_name =
|
||||||
|
name_and_implementation_constructor->first;
|
||||||
|
out->Print(method_dict,
|
||||||
|
"(\'$PackageQualifiedServiceName$\', \'$Method$\'): "
|
||||||
|
"face_utilities.$Constructor$(servicer.$Method$),\n");
|
||||||
|
}
|
||||||
|
out->Print("}\n");
|
||||||
|
out->Print(
|
||||||
|
"server_options = beta_implementations.server_options("
|
||||||
|
"thread_pool=pool, thread_pool_size=pool_size, "
|
||||||
|
"default_timeout=default_timeout, "
|
||||||
|
"maximum_timeout=maximum_timeout)\n");
|
||||||
|
out->Print(
|
||||||
|
"return beta_implementations.server(method_implementations, "
|
||||||
|
"options=server_options)\n");
|
||||||
|
//"request_deserializers=request_deserializers, "
|
||||||
|
//"response_serializers=response_serializers, "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintBetaStubFactory(
|
||||||
|
const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service, grpc_generator::Printer* out) {
|
||||||
|
StringMap dict;
|
||||||
|
dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(dict,
|
||||||
|
"def beta_create_$Service$_stub(channel, host=None,"
|
||||||
|
" metadata_transformer=None, pool=None, pool_size=None):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_create_server_indent(out);
|
||||||
|
out->Print(
|
||||||
|
"\"\"\"The Beta API is deprecated for 0.15.0 and later.\n"
|
||||||
|
"\nIt is recommended to use the GA API (classes and functions in this\n"
|
||||||
|
"file not marked beta) for all further purposes. This function was\n"
|
||||||
|
"generated only to ease transition from grpcio<0.15.0 to grpcio>=0.15.0"
|
||||||
|
"\"\"\"\n");
|
||||||
|
StringMap method_cardinalities;
|
||||||
|
StringMap input_message_modules_and_classes;
|
||||||
|
StringMap output_message_modules_and_classes;
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
const grpc::string method_cardinality =
|
||||||
|
grpc::string(method->ClientStreaming() ? "STREAM" : "UNARY") +
|
||||||
|
"_" +
|
||||||
|
grpc::string(method->ServerStreaming() ? "STREAM" : "UNARY");
|
||||||
|
grpc::string input_message_module_and_class = method->get_fb_builder();
|
||||||
|
grpc::string output_message_module_and_class = method->get_fb_builder();
|
||||||
|
method_cardinalities.insert(
|
||||||
|
make_pair(method->name(), method_cardinality));
|
||||||
|
input_message_modules_and_classes.insert(
|
||||||
|
make_pair(method->name(), input_message_module_and_class));
|
||||||
|
output_message_modules_and_classes.insert(
|
||||||
|
make_pair(method->name(), output_message_module_and_class));
|
||||||
|
}
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
|
||||||
|
// out->Print("request_serializers = {\n");
|
||||||
|
// for (StringMap::iterator name_and_input_module_class_pair =
|
||||||
|
// input_message_modules_and_classes.begin();
|
||||||
|
// name_and_input_module_class_pair !=
|
||||||
|
// input_message_modules_and_classes.end();
|
||||||
|
// name_and_input_module_class_pair++) {
|
||||||
|
// method_dict["MethodName"] = name_and_input_module_class_pair->first;
|
||||||
|
// method_dict["InputTypeModuleAndClass"] =
|
||||||
|
// name_and_input_module_class_pair->second;
|
||||||
|
// IndentScope raii_indent(out);
|
||||||
|
// out->Print(method_dict,
|
||||||
|
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
|
||||||
|
// "$InputTypeModuleAndClass$.SerializeToString,\n");
|
||||||
|
// }
|
||||||
|
// out->Print("}\n");
|
||||||
|
// out->Print("response_deserializers = {\n");
|
||||||
|
// for (StringMap::iterator name_and_output_module_class_pair =
|
||||||
|
// output_message_modules_and_classes.begin();
|
||||||
|
// name_and_output_module_class_pair !=
|
||||||
|
// output_message_modules_and_classes.end();
|
||||||
|
// name_and_output_module_class_pair++) {
|
||||||
|
// method_dict["MethodName"] = name_and_output_module_class_pair->first;
|
||||||
|
// method_dict["OutputTypeModuleAndClass"] =
|
||||||
|
// name_and_output_module_class_pair->second;
|
||||||
|
// IndentScope raii_indent(out);
|
||||||
|
// out->Print(method_dict,
|
||||||
|
// "(\'$PackageQualifiedServiceName$\', \'$MethodName$\'): "
|
||||||
|
// "$OutputTypeModuleAndClass$.FromString,\n");
|
||||||
|
// }
|
||||||
|
// out->Print("}\n");
|
||||||
|
out->Print("cardinalities = {\n");
|
||||||
|
for (StringMap::iterator name_and_cardinality =
|
||||||
|
method_cardinalities.begin();
|
||||||
|
name_and_cardinality != method_cardinalities.end();
|
||||||
|
name_and_cardinality++) {
|
||||||
|
method_dict["Method"] = name_and_cardinality->first;
|
||||||
|
method_dict["Cardinality"] = name_and_cardinality->second;
|
||||||
|
IndentScope raii_descriptions_indent(out);
|
||||||
|
out->Print(method_dict,
|
||||||
|
"\'$Method$\': cardinality.Cardinality.$Cardinality$,\n");
|
||||||
|
}
|
||||||
|
out->Print("}\n");
|
||||||
|
out->Print(
|
||||||
|
"stub_options = beta_implementations.stub_options("
|
||||||
|
"host=host, metadata_transformer=metadata_transformer, "
|
||||||
|
"thread_pool=pool, thread_pool_size=pool_size)\n");
|
||||||
|
out->Print(method_dict,
|
||||||
|
"return beta_implementations.dynamic_stub(channel, "
|
||||||
|
"\'$PackageQualifiedServiceName$\', "
|
||||||
|
"cardinalities, options=stub_options)\n");
|
||||||
|
// "request_serializers=request_serializers, "
|
||||||
|
//"response_deserializers=response_deserializers, "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintStub(
|
||||||
|
const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service, grpc_generator::Printer* out) {
|
||||||
|
StringMap dict;
|
||||||
|
dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(dict, "class $Service$Stub(object):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_class_indent(out);
|
||||||
|
out->Print("\n");
|
||||||
|
out->Print("def __init__(self, channel):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_init_indent(out);
|
||||||
|
out->Print("\"\"\"Constructor.\n");
|
||||||
|
out->Print("\n");
|
||||||
|
out->Print("Args:\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_args_indent(out);
|
||||||
|
out->Print("channel: A grpc.Channel.\n");
|
||||||
|
}
|
||||||
|
out->Print("\"\"\"\n");
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
grpc::string multi_callable_constructor =
|
||||||
|
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
|
||||||
|
"_" +
|
||||||
|
grpc::string(method->ServerStreaming() ? "stream" : "unary");
|
||||||
|
grpc::string request_module_and_class = method->get_fb_builder();
|
||||||
|
grpc::string response_module_and_class = method->get_fb_builder();
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["Method"] = method->name();
|
||||||
|
method_dict["MultiCallableConstructor"] = multi_callable_constructor;
|
||||||
|
out->Print(method_dict,
|
||||||
|
"self.$Method$ = channel.$MultiCallableConstructor$(\n");
|
||||||
|
{
|
||||||
|
method_dict["PackageQualifiedService"] =
|
||||||
|
package_qualified_service_name;
|
||||||
|
method_dict["RequestModuleAndClass"] = request_module_and_class;
|
||||||
|
method_dict["ResponseModuleAndClass"] = response_module_and_class;
|
||||||
|
IndentScope raii_first_attribute_indent(out);
|
||||||
|
IndentScope raii_second_attribute_indent(out);
|
||||||
|
out->Print(method_dict, "'/$PackageQualifiedService$/$Method$',\n");
|
||||||
|
out->Print(method_dict,"\n");
|
||||||
|
out->Print(
|
||||||
|
method_dict,"\n");
|
||||||
|
out->Print(")\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintServicer(const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out) {
|
||||||
|
StringMap service_dict;
|
||||||
|
service_dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(service_dict, "class $Service$Servicer(object):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_class_indent(out);
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
grpc::string arg_name =
|
||||||
|
method->ClientStreaming() ? "request_iterator" : "request";
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["Method"] = method->name();
|
||||||
|
method_dict["ArgName"] = arg_name;
|
||||||
|
out->Print("\n");
|
||||||
|
out->Print(method_dict, "def $Method$(self, $ArgName$, context):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_method_indent(out);
|
||||||
|
out->Print("context.set_code(grpc.StatusCode.UNIMPLEMENTED)\n");
|
||||||
|
out->Print("context.set_details('Method not implemented!')\n");
|
||||||
|
out->Print("raise NotImplementedError('Method not implemented!')\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintAddServicerToServer(
|
||||||
|
const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service, grpc_generator::Printer* out) {
|
||||||
|
StringMap service_dict;
|
||||||
|
service_dict["Service"] = service->name();
|
||||||
|
out->Print("\n\n");
|
||||||
|
out->Print(service_dict,
|
||||||
|
"def add_$Service$Servicer_to_server(servicer, server):\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_class_indent(out);
|
||||||
|
out->Print("rpc_method_handlers = {\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_dict_first_indent(out);
|
||||||
|
IndentScope raii_dict_second_indent(out);
|
||||||
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
|
auto method = service->method(i);
|
||||||
|
grpc::string method_handler_constructor =
|
||||||
|
grpc::string(method->ClientStreaming() ? "stream" : "unary") +
|
||||||
|
"_" +
|
||||||
|
grpc::string(method->ServerStreaming() ? "stream" : "unary") +
|
||||||
|
"_rpc_method_handler";
|
||||||
|
grpc::string request_module_and_class = method->get_fb_builder();
|
||||||
|
grpc::string response_module_and_class = method->get_fb_builder();
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["Method"] = method->name();
|
||||||
|
method_dict["MethodHandlerConstructor"] = method_handler_constructor;
|
||||||
|
method_dict["RequestModuleAndClass"] = request_module_and_class;
|
||||||
|
method_dict["ResponseModuleAndClass"] = response_module_and_class;
|
||||||
|
out->Print(method_dict,
|
||||||
|
"'$Method$': grpc.$MethodHandlerConstructor$(\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_call_first_indent(out);
|
||||||
|
IndentScope raii_call_second_indent(out);
|
||||||
|
out->Print(method_dict, "servicer.$Method$,\n");
|
||||||
|
out->Print(
|
||||||
|
method_dict,"\n");
|
||||||
|
out->Print(
|
||||||
|
method_dict,
|
||||||
|
"\n");
|
||||||
|
}
|
||||||
|
out->Print("),\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
StringMap method_dict;
|
||||||
|
method_dict["PackageQualifiedServiceName"] = package_qualified_service_name;
|
||||||
|
out->Print("}\n");
|
||||||
|
out->Print("generic_handler = grpc.method_handlers_generic_handler(\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_call_first_indent(out);
|
||||||
|
IndentScope raii_call_second_indent(out);
|
||||||
|
out->Print(method_dict,
|
||||||
|
"'$PackageQualifiedServiceName$', rpc_method_handlers)\n");
|
||||||
|
}
|
||||||
|
out->Print("server.add_generic_rpc_handlers((generic_handler,))\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintBetaPreamble(grpc_generator::Printer* out) {
|
||||||
|
StringMap var;
|
||||||
|
var["Package"] = config.beta_package_root;
|
||||||
|
out->Print(var,
|
||||||
|
"from $Package$ import implementations as beta_implementations\n");
|
||||||
|
out->Print(var, "from $Package$ import interfaces as beta_interfaces\n");
|
||||||
|
out->Print("from grpc.framework.common import cardinality\n");
|
||||||
|
out->Print(
|
||||||
|
"from grpc.framework.interfaces.face import utilities as "
|
||||||
|
"face_utilities\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintPreamble(grpc_generator::Printer* out) {
|
||||||
|
StringMap var;
|
||||||
|
var["Package"] = config.grpc_package_root;
|
||||||
|
out->Print(var, "import $Package$\n");
|
||||||
|
out->Print("\n");
|
||||||
|
StringPairSet imports_set;
|
||||||
|
for (int i = 0; i < file->service_count(); ++i) {
|
||||||
|
auto service = file->service(i);
|
||||||
|
for (int j = 0; j < service->method_count(); ++j) {
|
||||||
|
auto method = service.get()->method(j);
|
||||||
|
|
||||||
|
grpc::string input_type_file_name = method->get_fb_builder();
|
||||||
|
grpc::string input_module_name =
|
||||||
|
ModuleName(input_type_file_name, config.import_prefix);
|
||||||
|
grpc::string input_module_alias =
|
||||||
|
ModuleAlias(input_type_file_name, config.import_prefix);
|
||||||
|
imports_set.insert(
|
||||||
|
std::make_tuple(input_module_name, input_module_alias));
|
||||||
|
|
||||||
|
grpc::string output_type_file_name = method->get_fb_builder();
|
||||||
|
grpc::string output_module_name =
|
||||||
|
ModuleName(output_type_file_name, config.import_prefix);
|
||||||
|
grpc::string output_module_alias =
|
||||||
|
ModuleAlias(output_type_file_name, config.import_prefix);
|
||||||
|
imports_set.insert(
|
||||||
|
std::make_tuple(output_module_name, output_module_alias));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (StringPairSet::iterator it = imports_set.begin();
|
||||||
|
it != imports_set.end(); ++it) {
|
||||||
|
var["ModuleName"] = std::get<0>(*it);
|
||||||
|
var["ModuleAlias"] = std::get<1>(*it);
|
||||||
|
out->Print(var, "import $ModuleName$ as $ModuleAlias$\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintGAServices(grpc_generator::Printer* out) {
|
||||||
|
grpc::string package = file->package();
|
||||||
|
if (!package.empty()) {
|
||||||
|
package = package.append(".");
|
||||||
|
}
|
||||||
|
|
||||||
|
out->Print(file->additional_headers().c_str());
|
||||||
|
|
||||||
|
for (int i = 0; i < file->service_count(); ++i) {
|
||||||
|
auto service = file->service(i);
|
||||||
|
|
||||||
|
grpc::string package_qualified_service_name = package + service->name();
|
||||||
|
PrintStub(package_qualified_service_name, service.get(), out);
|
||||||
|
PrintServicer(service.get(), out);
|
||||||
|
PrintAddServicerToServer(package_qualified_service_name, service.get(),
|
||||||
|
out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrivateGenerator::PrintBetaServices(grpc_generator::Printer* out) {
|
||||||
|
grpc::string package = file->package();
|
||||||
|
if (!package.empty()) {
|
||||||
|
package = package.append(".");
|
||||||
|
}
|
||||||
|
for (int i = 0; i < file->service_count(); ++i) {
|
||||||
|
auto service = file->service(i);
|
||||||
|
|
||||||
|
grpc::string package_qualified_service_name = package + service->name();
|
||||||
|
PrintBetaServicer(service.get(), out);
|
||||||
|
PrintBetaStub(service.get(), out);
|
||||||
|
PrintBetaServerFactory(package_qualified_service_name, service.get(), out);
|
||||||
|
PrintBetaStubFactory(package_qualified_service_name, service.get(), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string PrivateGenerator::GetGrpcServices() {
|
||||||
|
grpc::string output;
|
||||||
|
{
|
||||||
|
// Scope the output stream so it closes and finalizes output to the string.
|
||||||
|
auto out = file->CreatePrinter(&output);
|
||||||
|
out->Print(
|
||||||
|
"# Generated by the gRPC Python protocol compiler plugin. "
|
||||||
|
"DO NOT EDIT!\n");
|
||||||
|
StringMap var;
|
||||||
|
var["Package"] = config.grpc_package_root;
|
||||||
|
out->Print(var, "import $Package$\n");
|
||||||
|
PrintGAServices(out.get());
|
||||||
|
out->Print("try:\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_dict_try_indent(out.get());
|
||||||
|
out->Print(
|
||||||
|
"# THESE ELEMENTS WILL BE DEPRECATED.\n"
|
||||||
|
"# Please use the generated *_pb2_grpc.py files instead.\n");
|
||||||
|
out->Print(var, "import $Package$\n");
|
||||||
|
PrintBetaPreamble(out.get());
|
||||||
|
PrintGAServices(out.get());
|
||||||
|
PrintBetaServices(out.get());
|
||||||
|
}
|
||||||
|
out->Print("except ImportError:\n");
|
||||||
|
{
|
||||||
|
IndentScope raii_dict_except_indent(out.get());
|
||||||
|
out->Print("pass");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace grpc_python_generator
|
||||||
40
grpc/src/compiler/python_generator.h
Normal file
40
grpc/src/compiler/python_generator.h
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015 gRPC authors.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
|
||||||
|
#define GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
|
||||||
|
namespace grpc_python_generator {
|
||||||
|
|
||||||
|
// Data pertaining to configuration of the generator with respect to anything
|
||||||
|
// that may be used internally at Google.
|
||||||
|
struct GeneratorConfiguration {
|
||||||
|
grpc::string grpc_package_root;
|
||||||
|
// TODO(https://github.com/grpc/grpc/issues/8622): Drop this.
|
||||||
|
grpc::string beta_package_root;
|
||||||
|
// TODO(https://github.com/google/protobuf/issues/888): Drop this.
|
||||||
|
grpc::string import_prefix;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace grpc_python_generator
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_PYTHON_GENERATOR_H
|
||||||
72
grpc/src/compiler/python_private_generator.h
Normal file
72
grpc/src/compiler/python_private_generator.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2015 gRPC authors.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
|
||||||
|
#define GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/compiler/python_generator.h"
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
|
||||||
|
namespace grpc_python_generator {
|
||||||
|
|
||||||
|
// Tucks all generator state in an anonymous namespace away from
|
||||||
|
// PythonGrpcGenerator and the header file, mostly to encourage future changes
|
||||||
|
// to not require updates to the grpcio-tools C++ code part. Assumes that it is
|
||||||
|
// only ever used from a single thread.
|
||||||
|
struct PrivateGenerator {
|
||||||
|
const GeneratorConfiguration& config;
|
||||||
|
const grpc_generator::File* file;
|
||||||
|
|
||||||
|
PrivateGenerator(const GeneratorConfiguration& config,
|
||||||
|
const grpc_generator::File* file);
|
||||||
|
|
||||||
|
grpc::string GetGrpcServices();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void PrintPreamble(grpc_generator::Printer* out);
|
||||||
|
void PrintBetaPreamble(grpc_generator::Printer* out);
|
||||||
|
void PrintGAServices(grpc_generator::Printer* out);
|
||||||
|
void PrintBetaServices(grpc_generator::Printer* out);
|
||||||
|
|
||||||
|
void PrintAddServicerToServer(
|
||||||
|
const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service, grpc_generator::Printer* out);
|
||||||
|
void PrintServicer(const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out);
|
||||||
|
void PrintStub(const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out);
|
||||||
|
|
||||||
|
void PrintBetaServicer(const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out);
|
||||||
|
void PrintBetaServerFactory(
|
||||||
|
const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service, grpc_generator::Printer* out);
|
||||||
|
void PrintBetaStub(const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out);
|
||||||
|
void PrintBetaStubFactory(const grpc::string& package_qualified_service_name,
|
||||||
|
const grpc_generator::Service* service,
|
||||||
|
grpc_generator::Printer* out);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace grpc_python_generator
|
||||||
|
|
||||||
|
#endif // GRPC_INTERNAL_COMPILER_PYTHON_PRIVATE_GENERATOR_H
|
||||||
@@ -1,44 +1,29 @@
|
|||||||
/*
|
/*
|
||||||
*
|
*
|
||||||
* Copyright 2015, Google Inc.
|
* Copyright 2015 gRPC authors.
|
||||||
* All rights reserved.
|
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* modification, are permitted provided that the following conditions are
|
* you may not use this file except in compliance with the License.
|
||||||
* met:
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* * Redistributions of source code must retain the above copyright
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
* See the License for the specific language governing permissions and
|
||||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
* limitations under the License.
|
||||||
* 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
|
#ifndef GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
#define GRPC_INTERNAL_COMPILER_SCHEMA_INTERFACE_H
|
||||||
|
|
||||||
#include "src/compiler/config.h"
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/compiler/config.h"
|
||||||
|
|
||||||
#ifndef GRPC_CUSTOM_STRING
|
#ifndef GRPC_CUSTOM_STRING
|
||||||
# include <string>
|
# include <string>
|
||||||
# define GRPC_CUSTOM_STRING std::string
|
# define GRPC_CUSTOM_STRING std::string
|
||||||
@@ -79,6 +64,9 @@ struct Method : public CommentHolder {
|
|||||||
|
|
||||||
virtual grpc::string get_input_type_name() const = 0;
|
virtual grpc::string get_input_type_name() const = 0;
|
||||||
virtual grpc::string get_output_type_name() const = 0;
|
virtual grpc::string get_output_type_name() const = 0;
|
||||||
|
|
||||||
|
virtual grpc::string get_fb_builder() const = 0;
|
||||||
|
|
||||||
virtual bool NoStreaming() const = 0;
|
virtual bool NoStreaming() const = 0;
|
||||||
virtual bool ClientStreaming() const = 0;
|
virtual bool ClientStreaming() const = 0;
|
||||||
virtual bool ServerStreaming() const = 0;
|
virtual bool ServerStreaming() const = 0;
|
||||||
|
|||||||
308
grpc/src/compiler/swift_generator.cc
Normal file
308
grpc/src/compiler/swift_generator.cc
Normal file
@@ -0,0 +1,308 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NOTE: The following implementation is a translation for the Swift-grpc
|
||||||
|
* generator since flatbuffers doesnt allow plugins for now. if an issue arises
|
||||||
|
* please open an issue in the flatbuffers repository. This file should always
|
||||||
|
* be maintained according to the Swift-grpc repository
|
||||||
|
*/
|
||||||
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
#include "src/compiler/swift_generator.h"
|
||||||
|
|
||||||
|
namespace grpc_swift_generator {
|
||||||
|
|
||||||
|
grpc::string GenerateMessage(const grpc::string &name) {
|
||||||
|
return "Message<" + name + ">";
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Client
|
||||||
|
|
||||||
|
grpc::string GenerateClientFuncName(const grpc_generator::Method *method) {
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
return "$GenAccess$ func $MethodName$(_ request: $Input$"
|
||||||
|
", callOptions: CallOptions?$isNil$) -> UnaryCall<$Input$,$Output$>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method->ClientStreaming()) {
|
||||||
|
return "$GenAccess$ func $MethodName$"
|
||||||
|
"(callOptions: CallOptions?$isNil$) -> "
|
||||||
|
"ClientStreamingCall<$Input$,$Output$>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method->ServerStreaming()) {
|
||||||
|
return "$GenAccess$ func $MethodName$(_ request: $Input$"
|
||||||
|
", callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
|
||||||
|
") -> Void) -> ServerStreamingCall<$Input$, $Output$>";
|
||||||
|
}
|
||||||
|
return "$GenAccess$ func $MethodName$"
|
||||||
|
"(callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
|
||||||
|
") -> Void) -> BidirectionalStreamingCall<$Input$, $Output$>";
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string GenerateClientFuncBody(const grpc_generator::Method *method) {
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
return "return self.makeUnaryCall(path: "
|
||||||
|
"\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
|
||||||
|
"callOptions: callOptions ?? self.defaultCallOptions)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method->ClientStreaming()) {
|
||||||
|
return "return self.makeClientStreamingCall(path: "
|
||||||
|
"\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
|
||||||
|
"self.defaultCallOptions)";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method->ServerStreaming()) {
|
||||||
|
return "return self.makeServerStreamingCall(path: "
|
||||||
|
"\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
|
||||||
|
"callOptions: callOptions ?? self.defaultCallOptions, handler: "
|
||||||
|
"handler)";
|
||||||
|
}
|
||||||
|
return "return self.makeBidirectionalStreamingCall(path: "
|
||||||
|
"\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
|
||||||
|
"self.defaultCallOptions, handler: handler)";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateClientProtocol(const grpc_generator::Service *service,
|
||||||
|
grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> *dictonary) {
|
||||||
|
auto vars = *dictonary;
|
||||||
|
printer->Print(vars, "$ACCESS$ protocol $ServiceName$Service {\n");
|
||||||
|
vars["GenAccess"] = "";
|
||||||
|
for (auto it = 0; it < service->method_count(); it++) {
|
||||||
|
auto method = service->method(it);
|
||||||
|
vars["Input"] = GenerateMessage(method->get_input_type_name());
|
||||||
|
vars["Output"] = GenerateMessage(method->get_output_type_name());
|
||||||
|
vars["MethodName"] = method->name();
|
||||||
|
vars["isNil"] = "";
|
||||||
|
printer->Print("\t");
|
||||||
|
auto func = GenerateClientFuncName(method.get());
|
||||||
|
printer->Print(vars, func.c_str());
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateClientClass(const grpc_generator::Service *service,
|
||||||
|
grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> *dictonary) {
|
||||||
|
auto vars = *dictonary;
|
||||||
|
printer->Print(vars,
|
||||||
|
"$ACCESS$ final class $ServiceName$ServiceClient: GRPCClient, "
|
||||||
|
"$ServiceName$Service {\n");
|
||||||
|
printer->Print(vars, "\t$ACCESS$ let connection: ClientConnection\n");
|
||||||
|
printer->Print(vars, "\t$ACCESS$ var defaultCallOptions: CallOptions\n");
|
||||||
|
printer->Print("\n");
|
||||||
|
printer->Print(vars,
|
||||||
|
"\t$ACCESS$ init(connection: ClientConnection, "
|
||||||
|
"defaultCallOptions: CallOptions = CallOptions()) {\n");
|
||||||
|
printer->Print("\t\tself.connection = connection\n");
|
||||||
|
printer->Print("\t\tself.defaultCallOptions = defaultCallOptions\n");
|
||||||
|
printer->Print("\t}");
|
||||||
|
printer->Print("\n");
|
||||||
|
vars["GenAccess"] = "public";
|
||||||
|
for (auto it = 0; it < service->method_count(); it++) {
|
||||||
|
auto method = service->method(it);
|
||||||
|
vars["Input"] = GenerateMessage(method->get_input_type_name());
|
||||||
|
vars["Output"] = GenerateMessage(method->get_output_type_name());
|
||||||
|
vars["MethodName"] = method->name();
|
||||||
|
vars["isNil"] = " = nil";
|
||||||
|
printer->Print("\n\t");
|
||||||
|
auto func = GenerateClientFuncName(method.get());
|
||||||
|
printer->Print(vars, func.c_str());
|
||||||
|
printer->Print(" {\n");
|
||||||
|
auto body = GenerateClientFuncBody(method.get());
|
||||||
|
printer->Print("\t\t");
|
||||||
|
printer->Print(vars, body.c_str());
|
||||||
|
printer->Print("\n\t}\n");
|
||||||
|
}
|
||||||
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Server
|
||||||
|
|
||||||
|
grpc::string GenerateServerFuncName(const grpc_generator::Method *method) {
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
return "func $MethodName$(_ request: $Input$"
|
||||||
|
", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method->ClientStreaming()) {
|
||||||
|
return "func $MethodName$(context: UnaryResponseCallContext<$Output$>) -> "
|
||||||
|
"EventLoopFuture<(StreamEvent<$Input$"
|
||||||
|
">) -> Void>";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (method->ServerStreaming()) {
|
||||||
|
return "func $MethodName$(request: $Input$"
|
||||||
|
", context: StreamingResponseCallContext<$Output$>) -> "
|
||||||
|
"EventLoopFuture<GRPCStatus>";
|
||||||
|
}
|
||||||
|
return "func $MethodName$(context: StreamingResponseCallContext<$Output$>) "
|
||||||
|
"-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>";
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string GenerateServerExtensionBody(const grpc_generator::Method *method) {
|
||||||
|
grpc::string start = "\t\tcase \"$MethodName$\":\n\t\t";
|
||||||
|
if (method->NoStreaming()) {
|
||||||
|
return start +
|
||||||
|
"return UnaryCallHandler(callHandlerContext: callHandlerContext) { "
|
||||||
|
"context in"
|
||||||
|
"\n\t\t\t"
|
||||||
|
"return { request in"
|
||||||
|
"\n\t\t\t\t"
|
||||||
|
"self.$MethodName$(request, context: context)"
|
||||||
|
"\n\t\t\t}"
|
||||||
|
"\n\t\t}";
|
||||||
|
}
|
||||||
|
if (method->ClientStreaming()) {
|
||||||
|
return start +
|
||||||
|
"return ClientStreamingCallHandler(callHandlerContext: "
|
||||||
|
"callHandlerContext) { context in"
|
||||||
|
"\n\t\t\t"
|
||||||
|
"return { request in"
|
||||||
|
"\n\t\t\t\t"
|
||||||
|
"self.$MethodName$(request: request, context: context)"
|
||||||
|
"\n\t\t\t}"
|
||||||
|
"\n\t\t}";
|
||||||
|
}
|
||||||
|
if (method->ServerStreaming()) {
|
||||||
|
return start +
|
||||||
|
"return ServerStreamingCallHandler(callHandlerContext: "
|
||||||
|
"callHandlerContext) { context in"
|
||||||
|
"\n\t\t\t"
|
||||||
|
"return { request in"
|
||||||
|
"\n\t\t\t\t"
|
||||||
|
"self.$MethodName$(request: request, context: context)"
|
||||||
|
"\n\t\t\t}"
|
||||||
|
"\n\t\t}";
|
||||||
|
}
|
||||||
|
if (method->BidiStreaming()) {
|
||||||
|
return start +
|
||||||
|
"return BidirectionalStreamingCallHandler(callHandlerContext: "
|
||||||
|
"callHandlerContext) { context in"
|
||||||
|
"\n\t\t\t"
|
||||||
|
"return { request in"
|
||||||
|
"\n\t\t\t\t"
|
||||||
|
"self.$MethodName$(request: request, context: context)"
|
||||||
|
"\n\t\t\t}"
|
||||||
|
"\n\t\t}";
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
void GenerateServerProtocol(const grpc_generator::Service *service,
|
||||||
|
grpc_generator::Printer *printer,
|
||||||
|
std::map<grpc::string, grpc::string> *dictonary) {
|
||||||
|
auto vars = *dictonary;
|
||||||
|
printer->Print(
|
||||||
|
vars, "$ACCESS$ protocol $ServiceName$Provider: CallHandlerProvider {\n");
|
||||||
|
for (auto it = 0; it < service->method_count(); it++) {
|
||||||
|
auto method = service->method(it);
|
||||||
|
vars["Input"] = GenerateMessage(method->get_input_type_name());
|
||||||
|
vars["Output"] = GenerateMessage(method->get_output_type_name());
|
||||||
|
vars["MethodName"] = method->name();
|
||||||
|
printer->Print("\t");
|
||||||
|
auto func = GenerateServerFuncName(method.get());
|
||||||
|
printer->Print(vars, func.c_str());
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
|
||||||
|
printer->Print(vars, "$ACCESS$ extension $ServiceName$Provider {\n");
|
||||||
|
printer->Print(vars,
|
||||||
|
"\tvar serviceName: String { return "
|
||||||
|
"\"$PATH$$ServiceName$\" }\n");
|
||||||
|
printer->Print(
|
||||||
|
"\tfunc handleMethod(_ methodName: String, callHandlerContext: "
|
||||||
|
"CallHandlerContext) -> GRPCCallHandler? {\n");
|
||||||
|
printer->Print("\t\tswitch methodName {\n");
|
||||||
|
for (auto it = 0; it < service->method_count(); it++) {
|
||||||
|
auto method = service->method(it);
|
||||||
|
vars["Input"] = GenerateMessage(method->get_input_type_name());
|
||||||
|
vars["Output"] = GenerateMessage(method->get_output_type_name());
|
||||||
|
vars["MethodName"] = method->name();
|
||||||
|
auto body = GenerateServerExtensionBody(method.get());
|
||||||
|
printer->Print(vars, body.c_str());
|
||||||
|
printer->Print("\n");
|
||||||
|
}
|
||||||
|
printer->Print("\t\tdefault: return nil;\n");
|
||||||
|
printer->Print("\t\t}\n");
|
||||||
|
printer->Print("\t}\n\n");
|
||||||
|
printer->Print("}\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string Generate(grpc_generator::File *file,
|
||||||
|
const grpc_generator::Service *service) {
|
||||||
|
grpc::string output;
|
||||||
|
std::map<grpc::string, grpc::string> vars;
|
||||||
|
vars["PATH"] = file->package();
|
||||||
|
if (!file->package().empty()) { vars["PATH"].append("."); }
|
||||||
|
vars["ServiceName"] = service->name();
|
||||||
|
vars["ACCESS"] = "public";
|
||||||
|
auto printer = file->CreatePrinter(&output);
|
||||||
|
printer->Print(vars,
|
||||||
|
"/// Usage: instantiate $ServiceName$ServiceClient, then call "
|
||||||
|
"methods of this protocol to make API calls.\n");
|
||||||
|
GenerateClientProtocol(service, &*printer, &vars);
|
||||||
|
GenerateClientClass(service, &*printer, &vars);
|
||||||
|
printer->Print("\n");
|
||||||
|
GenerateServerProtocol(service, &*printer, &vars);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
grpc::string GenerateHeader() {
|
||||||
|
grpc::string code;
|
||||||
|
code +=
|
||||||
|
"/// The following code is generated by the Flatbuffers library which "
|
||||||
|
"might not be in sync with grpc-swift\n";
|
||||||
|
code +=
|
||||||
|
"/// in case of an issue please open github issue, though it would be "
|
||||||
|
"maintained\n";
|
||||||
|
code += "import Foundation\n";
|
||||||
|
code += "import GRPC\n";
|
||||||
|
code += "import NIO\n";
|
||||||
|
code += "import NIOHTTP1\n";
|
||||||
|
code += "import FlatBuffers\n";
|
||||||
|
code += "\n";
|
||||||
|
code +=
|
||||||
|
"public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage "
|
||||||
|
"{}\n";
|
||||||
|
|
||||||
|
code += "public extension GRPCFlatBufPayload {\n";
|
||||||
|
code += " init(serializedByteBuffer: inout NIO.ByteBuffer) throws {\n";
|
||||||
|
code +=
|
||||||
|
" self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: "
|
||||||
|
"serializedByteBuffer.readableBytesView, count: "
|
||||||
|
"serializedByteBuffer.readableBytes))\n";
|
||||||
|
code += " }\n";
|
||||||
|
|
||||||
|
code += " func serialize(into buffer: inout NIO.ByteBuffer) throws {\n";
|
||||||
|
code +=
|
||||||
|
" let buf = UnsafeRawBufferPointer(start: self.rawPointer, count: "
|
||||||
|
"Int(self.size))\n";
|
||||||
|
code += " buffer.writeBytes(buf)\n";
|
||||||
|
code += " }\n";
|
||||||
|
code += "}\n";
|
||||||
|
code += "extension Message: GRPCFlatBufPayload {}\n";
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
} // namespace grpc_swift_generator
|
||||||
55
grpc/src/compiler/swift_generator.h
Normal file
55
grpc/src/compiler/swift_generator.h
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* Copyright 2020, Google Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* * Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following disclaimer
|
||||||
|
* in the documentation and/or other materials provided with the
|
||||||
|
* distribution.
|
||||||
|
* * Neither the name of Google Inc. nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "src/compiler/config.h"
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
|
||||||
|
#ifndef GRPC_CUSTOM_STRING
|
||||||
|
# include <string>
|
||||||
|
# define GRPC_CUSTOM_STRING std::string
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace grpc {
|
||||||
|
|
||||||
|
typedef GRPC_CUSTOM_STRING string;
|
||||||
|
|
||||||
|
} // namespace grpc
|
||||||
|
|
||||||
|
namespace grpc_swift_generator {
|
||||||
|
grpc::string Generate(grpc_generator::File *file,
|
||||||
|
const grpc_generator::Service *service);
|
||||||
|
grpc::string GenerateHeader();
|
||||||
|
} // namespace grpc_swift_generator
|
||||||
@@ -141,7 +141,7 @@ public class JavaGrpcTest {
|
|||||||
channel = ManagedChannelBuilder.forAddress("localhost", port)
|
channel = ManagedChannelBuilder.forAddress("localhost", port)
|
||||||
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
|
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
|
||||||
// needing certificates.
|
// needing certificates.
|
||||||
.usePlaintext(true)
|
.usePlaintext()
|
||||||
.directExecutor()
|
.directExecutor()
|
||||||
.build();
|
.build();
|
||||||
blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
|
blockingStub = MonsterStorageGrpc.newBlockingStub(channel);
|
||||||
|
|||||||
@@ -14,17 +14,17 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
|
|
||||||
#include <grpc++/grpc++.h>
|
#include <grpc++/grpc++.h>
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
#include "monster_test.grpc.fb.h"
|
#include "monster_test.grpc.fb.h"
|
||||||
#include "monster_test_generated.h"
|
#include "monster_test_generated.h"
|
||||||
#include "test_assert.h"
|
#include "test_assert.h"
|
||||||
|
|
||||||
using namespace MyGame::Example;
|
using namespace MyGame::Example;
|
||||||
using flatbuffers::grpc::MessageBuilder;
|
|
||||||
using flatbuffers::FlatBufferBuilder;
|
using flatbuffers::FlatBufferBuilder;
|
||||||
|
using flatbuffers::grpc::MessageBuilder;
|
||||||
|
|
||||||
void message_builder_tests();
|
void message_builder_tests();
|
||||||
|
|
||||||
@@ -97,8 +97,7 @@ void RunServer() {
|
|||||||
server_instance->Wait();
|
server_instance->Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Builder>
|
template<class Builder> void StoreRPC(MonsterStorage::Stub *stub) {
|
||||||
void StoreRPC(MonsterStorage::Stub *stub) {
|
|
||||||
Builder fbb;
|
Builder fbb;
|
||||||
grpc::ClientContext context;
|
grpc::ClientContext context;
|
||||||
// Build a request with the name set.
|
// Build a request with the name set.
|
||||||
@@ -119,8 +118,7 @@ void StoreRPC(MonsterStorage::Stub *stub) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class Builder>
|
template<class Builder> void RetrieveRPC(MonsterStorage::Stub *stub) {
|
||||||
void RetrieveRPC(MonsterStorage::Stub *stub) {
|
|
||||||
Builder fbb;
|
Builder fbb;
|
||||||
grpc::ClientContext context;
|
grpc::ClientContext context;
|
||||||
fbb.Clear();
|
fbb.Clear();
|
||||||
@@ -155,7 +153,6 @@ int grpc_server_test() {
|
|||||||
RetrieveRPC<MessageBuilder>(stub.get());
|
RetrieveRPC<MessageBuilder>(stub.get());
|
||||||
RetrieveRPC<FlatBufferBuilder>(stub.get());
|
RetrieveRPC<FlatBufferBuilder>(stub.get());
|
||||||
|
|
||||||
|
|
||||||
#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
|
#if !FLATBUFFERS_GRPC_DISABLE_AUTO_VERIFICATION
|
||||||
{
|
{
|
||||||
// Test that an invalid request errors out correctly
|
// Test that an invalid request errors out correctly
|
||||||
@@ -181,7 +178,7 @@ int grpc_server_test() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int /*argc*/, const char * /*argv*/ []) {
|
int main(int /*argc*/, const char * /*argv*/[]) {
|
||||||
message_builder_tests();
|
message_builder_tests();
|
||||||
grpc_server_test();
|
grpc_server_test();
|
||||||
|
|
||||||
@@ -193,4 +190,3 @@ int main(int /*argc*/, const char * /*argv*/ []) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
174
grpc/tests/grpctest.py
Normal file
174
grpc/tests/grpctest.py
Normal file
@@ -0,0 +1,174 @@
|
|||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import grpc
|
||||||
|
import flatbuffers
|
||||||
|
|
||||||
|
from concurrent import futures
|
||||||
|
|
||||||
|
sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'tests'))
|
||||||
|
import MyGame.Example.Monster as Monster
|
||||||
|
import MyGame.Example.Stat as Stat
|
||||||
|
import MyGame.Example.Vec3 as Vec3
|
||||||
|
import MyGame.Example.Test as Test
|
||||||
|
import MyGame.Example.monster_test_grpc_fb as monster_grpc_fb
|
||||||
|
|
||||||
|
|
||||||
|
test_stat_id = "test_stat_id"
|
||||||
|
test_stat_val = 8
|
||||||
|
test_stat_count = 1
|
||||||
|
|
||||||
|
test_monster_name1 = "test_monster_name1"
|
||||||
|
test_monster_name2 = "test_monster_name2"
|
||||||
|
test_string = "test_string"
|
||||||
|
test_color = 2
|
||||||
|
test_X = 3.0
|
||||||
|
test_Y = 2.0
|
||||||
|
test_Z = 6.0
|
||||||
|
test_test1 = 4.0
|
||||||
|
test_a = 8
|
||||||
|
test_b = 5
|
||||||
|
test_hp = 67
|
||||||
|
test_inventory = [1, 1, 2, 3, 5, 8]
|
||||||
|
test_testtype = 4
|
||||||
|
|
||||||
|
test_monsters_name_retrieve = ["big_monster", "small_monster"]
|
||||||
|
test_no_of_monsters = 2
|
||||||
|
|
||||||
|
|
||||||
|
class MonsterStorage(monster_grpc_fb.MonsterStorageServicer):
|
||||||
|
|
||||||
|
def Store(self, request, context):
|
||||||
|
|
||||||
|
m = Monster.Monster().GetRootAsMonster(request, 0)
|
||||||
|
|
||||||
|
assert m.Name().decode("utf-8") == test_monster_name1
|
||||||
|
|
||||||
|
assert m.Pos().X() == test_X
|
||||||
|
assert m.Pos().Y() == test_Y
|
||||||
|
assert m.Pos().Z() == test_Z
|
||||||
|
assert m.Pos().Test1() == test_test1
|
||||||
|
assert m.Pos().Test2() == test_color
|
||||||
|
test3 = Test.Test()
|
||||||
|
assert m.Pos().Test3(test3).A() == test_a
|
||||||
|
assert m.Pos().Test3(test3).B() == test_b
|
||||||
|
|
||||||
|
assert m.Hp() == test_hp
|
||||||
|
|
||||||
|
assert m.Color() == test_color
|
||||||
|
|
||||||
|
assert m.InventoryLength() == len(test_inventory)
|
||||||
|
for i in range(0, len(test_inventory)):
|
||||||
|
assert m.Inventory(i) == test_inventory[len(test_inventory)-i -1]
|
||||||
|
|
||||||
|
assert m.TestType() == test_testtype
|
||||||
|
|
||||||
|
assert m.Test() is not None
|
||||||
|
table = m.Test()
|
||||||
|
|
||||||
|
m2 = Monster.Monster()
|
||||||
|
m2.Init(table.Bytes, table.Pos)
|
||||||
|
assert m2.Name().decode("utf-8") == test_monster_name2
|
||||||
|
|
||||||
|
m3 = m.Enemy()
|
||||||
|
assert m3.Name().decode("utf-8") == test_monster_name2
|
||||||
|
|
||||||
|
assert m.Testarrayofstring(0).decode("utf-8") == test_string
|
||||||
|
|
||||||
|
b = flatbuffers.Builder(0)
|
||||||
|
i = b.CreateString(test_stat_id)
|
||||||
|
Stat.StatStart(b)
|
||||||
|
Stat.StatAddId(b, i)
|
||||||
|
Stat.StatAddVal(b, test_stat_val)
|
||||||
|
Stat.StatAddCount(b, test_stat_count)
|
||||||
|
b.Finish(Stat.StatEnd(b))
|
||||||
|
return bytes(b.Output())
|
||||||
|
|
||||||
|
def Retrieve(self, request, context):
|
||||||
|
|
||||||
|
s = Stat.Stat().GetRootAsStat(request, 0)
|
||||||
|
|
||||||
|
no_of_monsters = test_no_of_monsters
|
||||||
|
for i in range(0, no_of_monsters):
|
||||||
|
b = flatbuffers.Builder(0)
|
||||||
|
i = b.CreateString(test_monsters_name_retrieve[i])
|
||||||
|
Monster.MonsterStart(b)
|
||||||
|
Monster.MonsterAddName(b, i)
|
||||||
|
b.Finish(Monster.MonsterEnd(b))
|
||||||
|
yield bytes(b.Output())
|
||||||
|
|
||||||
|
|
||||||
|
def serve():
|
||||||
|
|
||||||
|
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
|
||||||
|
monster_grpc_fb.add_MonsterStorageServicer_to_server(MonsterStorage(), server)
|
||||||
|
server.add_insecure_port('[::]:50051')
|
||||||
|
|
||||||
|
server.start()
|
||||||
|
|
||||||
|
run()
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
|
||||||
|
channel = grpc.insecure_channel('127.0.0.1:50051')
|
||||||
|
stub = monster_grpc_fb.MonsterStorageStub(channel)
|
||||||
|
|
||||||
|
b = flatbuffers.Builder(0)
|
||||||
|
name2 = b.CreateString(test_monster_name2)
|
||||||
|
name1 = b.CreateString(test_monster_name1)
|
||||||
|
Monster.MonsterStart(b)
|
||||||
|
Monster.MonsterAddName(b, name2)
|
||||||
|
monster2 = Monster.MonsterEnd(b)
|
||||||
|
test1 = b.CreateString(test_string)
|
||||||
|
|
||||||
|
Monster.MonsterStartInventoryVector(b, len(test_inventory))
|
||||||
|
for i in range(0, len(test_inventory)):
|
||||||
|
b.PrependByte(test_inventory[i])
|
||||||
|
inv = b.EndVector(len(test_inventory))
|
||||||
|
|
||||||
|
Monster.MonsterStartTest4Vector(b, 2)
|
||||||
|
Test.CreateTest(b, 10, 20)
|
||||||
|
Test.CreateTest(b, 30, 40)
|
||||||
|
test4 = b.EndVector(2)
|
||||||
|
|
||||||
|
Monster.MonsterStartTestarrayofstringVector(b, 1)
|
||||||
|
b.PrependUOffsetTRelative(test1)
|
||||||
|
test_array_of_string = b.EndVector(1)
|
||||||
|
|
||||||
|
Monster.MonsterStart(b)
|
||||||
|
|
||||||
|
Monster.MonsterAddHp(b, test_hp)
|
||||||
|
Monster.MonsterAddName(b, name1)
|
||||||
|
Monster.MonsterAddColor(b, test_color)
|
||||||
|
pos = Vec3.CreateVec3(b, test_X, test_Y, test_Z, test_test1, test_color, test_a, test_b)
|
||||||
|
Monster.MonsterAddPos(b, pos)
|
||||||
|
Monster.MonsterAddInventory(b, inv)
|
||||||
|
Monster.MonsterAddTestType(b, test_testtype)
|
||||||
|
Monster.MonsterAddTest(b, monster2)
|
||||||
|
Monster.MonsterAddTest4(b, test4)
|
||||||
|
Monster.MonsterAddEnemy(b, monster2)
|
||||||
|
Monster.MonsterAddTestarrayofstring(b, test_array_of_string)
|
||||||
|
monster = Monster.MonsterEnd(b)
|
||||||
|
|
||||||
|
b.Finish(monster)
|
||||||
|
|
||||||
|
stat_response = stub.Store(bytes(b.Output()))
|
||||||
|
|
||||||
|
s = Stat.Stat().GetRootAsStat(stat_response, 0)
|
||||||
|
|
||||||
|
assert s.Id().decode("utf-8") == test_stat_id
|
||||||
|
assert s.Val() == test_stat_val
|
||||||
|
assert s.Count() == test_stat_count
|
||||||
|
|
||||||
|
monster_reponses = stub.Retrieve(stat_response)
|
||||||
|
count = 0
|
||||||
|
for monster_reponse in monster_reponses:
|
||||||
|
m = Monster.Monster().GetRootAsMonster(monster_reponse, 0)
|
||||||
|
assert m.Name().decode("utf-8") == test_monsters_name_retrieve[count]
|
||||||
|
count = count + 1
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
serve()
|
||||||
@@ -3,22 +3,28 @@
|
|||||||
#include "test_assert.h"
|
#include "test_assert.h"
|
||||||
#include "test_builder.h"
|
#include "test_builder.h"
|
||||||
|
|
||||||
using MyGame::Example::Vec3;
|
|
||||||
using MyGame::Example::CreateStat;
|
|
||||||
using MyGame::Example::Any_NONE;
|
using MyGame::Example::Any_NONE;
|
||||||
|
using MyGame::Example::CreateStat;
|
||||||
|
using MyGame::Example::Vec3;
|
||||||
|
|
||||||
bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) {
|
bool verify(flatbuffers::grpc::Message<Monster> &msg,
|
||||||
|
const std::string &expected_name, Color expected_color) {
|
||||||
const Monster *monster = msg.GetRoot();
|
const Monster *monster = msg.GetRoot();
|
||||||
return (monster->name()->str() == expected_name) && (monster->color() == color);
|
const auto name = monster->name()->str();
|
||||||
|
const auto color = monster->color();
|
||||||
|
TEST_EQ(name, expected_name);
|
||||||
|
TEST_EQ(color, expected_color);
|
||||||
|
return (name == expected_name) && (color == expected_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) {
|
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb,
|
||||||
|
const std::string &expected_name, Color expected_color) {
|
||||||
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
|
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
|
||||||
const Monster *monster = msg.GetRoot();
|
return verify(msg, expected_name, expected_color);
|
||||||
return (monster->name()->str() == expected_name) && (monster->color() == color);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder dst) {
|
void builder_move_assign_after_releaseraw_test(
|
||||||
|
flatbuffers::grpc::MessageBuilder dst) {
|
||||||
auto root_offset1 = populate1(dst);
|
auto root_offset1 = populate1(dst);
|
||||||
dst.Finish(root_offset1);
|
dst.Finish(root_offset1);
|
||||||
size_t size, offset;
|
size_t size, offset;
|
||||||
@@ -31,17 +37,16 @@ void builder_move_assign_after_releaseraw_test(flatbuffers::grpc::MessageBuilder
|
|||||||
// Move into a released builder.
|
// Move into a released builder.
|
||||||
dst = std::move(src);
|
dst = std::move(src);
|
||||||
TEST_EQ(dst.GetSize(), src_size);
|
TEST_EQ(dst.GetSize(), src_size);
|
||||||
TEST_ASSERT(release_n_verify(dst, m2_name, m2_color));
|
TEST_ASSERT(release_n_verify(dst, m2_name(), m2_color()));
|
||||||
TEST_EQ(src.GetSize(), 0);
|
TEST_EQ(src.GetSize(), 0);
|
||||||
grpc_slice_unref(slice);
|
grpc_slice_unref(slice);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class SrcBuilder>
|
template<class SrcBuilder>
|
||||||
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
||||||
static void builder_reusable_after_release_message_test(TestSelector selector) {
|
static void builder_reusable_after_release_message_test(
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
|
TestSelector selector) {
|
||||||
return;
|
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) { return; }
|
||||||
}
|
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
|
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
|
||||||
@@ -49,17 +54,15 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
auto root_offset1 = populate1(mb);
|
auto root_offset1 = populate1(mb);
|
||||||
mb.Finish(root_offset1);
|
mb.Finish(root_offset1);
|
||||||
buffers.push_back(mb.ReleaseMessage<Monster>());
|
buffers.push_back(mb.ReleaseMessage<Monster>());
|
||||||
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_release_test(TestSelector selector) {
|
static void builder_reusable_after_release_test(TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE)) {
|
if (!selector.count(REUSABLE_AFTER_RELEASE)) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in SliceAllocator::allocate
|
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)) in
|
||||||
// in the second iteration.
|
// SliceAllocator::allocate in the second iteration.
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
std::vector<flatbuffers::DetachedBuffer> buffers;
|
std::vector<flatbuffers::DetachedBuffer> buffers;
|
||||||
@@ -67,14 +70,12 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
auto root_offset1 = populate1(mb);
|
auto root_offset1 = populate1(mb);
|
||||||
mb.Finish(root_offset1);
|
mb.Finish(root_offset1);
|
||||||
buffers.push_back(mb.Release());
|
buffers.push_back(mb.Release());
|
||||||
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
|
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
|
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) { return; }
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
@@ -83,18 +84,18 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
size_t size, offset;
|
size_t size, offset;
|
||||||
grpc_slice slice;
|
grpc_slice slice;
|
||||||
const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
|
const uint8_t *buf = mb.ReleaseRaw(size, offset, slice);
|
||||||
TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
|
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
|
||||||
grpc_slice_unref(slice);
|
grpc_slice_unref(slice);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
|
static void builder_reusable_after_release_and_move_assign_test(
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
|
TestSelector selector) {
|
||||||
return;
|
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) { return; }
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_))
|
// FIXME: Release-move_assign loop fails assert(p ==
|
||||||
// in DetachedBuffer destructor after all the iterations
|
// GRPC_SLICE_START_PTR(slice_)) in DetachedBuffer destructor after all the
|
||||||
|
// iterations
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder dst;
|
flatbuffers::grpc::MessageBuilder dst;
|
||||||
std::vector<flatbuffers::DetachedBuffer> buffers;
|
std::vector<flatbuffers::DetachedBuffer> buffers;
|
||||||
@@ -103,7 +104,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
auto root_offset1 = populate1(dst);
|
auto root_offset1 = populate1(dst);
|
||||||
dst.Finish(root_offset1);
|
dst.Finish(root_offset1);
|
||||||
buffers.push_back(dst.Release());
|
buffers.push_back(dst.Release());
|
||||||
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
|
||||||
|
|
||||||
// bring dst back to life.
|
// bring dst back to life.
|
||||||
SrcBuilder src;
|
SrcBuilder src;
|
||||||
@@ -113,7 +114,8 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) {
|
static void builder_reusable_after_release_message_and_move_assign_test(
|
||||||
|
TestSelector selector) {
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
|
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -125,7 +127,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
auto root_offset1 = populate1(dst);
|
auto root_offset1 = populate1(dst);
|
||||||
dst.Finish(root_offset1);
|
dst.Finish(root_offset1);
|
||||||
buffers.push_back(dst.ReleaseMessage<Monster>());
|
buffers.push_back(dst.ReleaseMessage<Monster>());
|
||||||
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name(), m1_color()));
|
||||||
|
|
||||||
// bring dst back to life.
|
// bring dst back to life.
|
||||||
SrcBuilder src;
|
SrcBuilder src;
|
||||||
@@ -135,10 +137,9 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
|
static void builder_reusable_after_releaseraw_and_move_assign_test(
|
||||||
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
|
TestSelector selector) {
|
||||||
return;
|
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) { return; }
|
||||||
}
|
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder dst;
|
flatbuffers::grpc::MessageBuilder dst;
|
||||||
for (int i = 0; i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
@@ -147,7 +148,7 @@ struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder, SrcBuilder> {
|
|||||||
size_t size, offset;
|
size_t size, offset;
|
||||||
grpc_slice slice = grpc_empty_slice();
|
grpc_slice slice = grpc_empty_slice();
|
||||||
const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
|
const uint8_t *buf = dst.ReleaseRaw(size, offset, slice);
|
||||||
TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
|
TEST_ASSERT_FUNC(verify(buf, offset, m1_name(), m1_color()));
|
||||||
grpc_slice_unref(slice);
|
grpc_slice_unref(slice);
|
||||||
|
|
||||||
SrcBuilder src;
|
SrcBuilder src;
|
||||||
@@ -175,11 +176,11 @@ void slice_allocator_tests() {
|
|||||||
uint8_t *buf = sa1.allocate(size);
|
uint8_t *buf = sa1.allocate(size);
|
||||||
TEST_ASSERT_FUNC(buf != 0);
|
TEST_ASSERT_FUNC(buf != 0);
|
||||||
buf[0] = 100;
|
buf[0] = 100;
|
||||||
buf[size-1] = 200;
|
buf[size - 1] = 200;
|
||||||
flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
|
flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
|
||||||
// buf should not be deleted after move-construct
|
// buf should not be deleted after move-construct
|
||||||
TEST_EQ_FUNC(buf[0], 100);
|
TEST_EQ_FUNC(buf[0], 100);
|
||||||
TEST_EQ_FUNC(buf[size-1], 200);
|
TEST_EQ_FUNC(buf[size - 1], 200);
|
||||||
// buf is freed here
|
// buf is freed here
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,13 +195,16 @@ void slice_allocator_tests() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function does not populate exactly the first half of the table. But it could.
|
/// This function does not populate exactly the first half of the table. But it
|
||||||
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper, flatbuffers::Offset<flatbuffers::String> name_offset) {
|
/// could.
|
||||||
|
void populate_first_half(MyGame::Example::MonsterBuilder &wrapper,
|
||||||
|
flatbuffers::Offset<flatbuffers::String> name_offset) {
|
||||||
wrapper.add_name(name_offset);
|
wrapper.add_name(name_offset);
|
||||||
wrapper.add_color(m1_color);
|
wrapper.add_color(m1_color());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function does not populate exactly the second half of the table. But it could.
|
/// This function does not populate exactly the second half of the table. But it
|
||||||
|
/// could.
|
||||||
void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
|
void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
|
||||||
wrapper.add_hp(77);
|
wrapper.add_hp(77);
|
||||||
wrapper.add_mana(88);
|
wrapper.add_mana(88);
|
||||||
@@ -208,114 +212,138 @@ void populate_second_half(MyGame::Example::MonsterBuilder &wrapper) {
|
|||||||
wrapper.add_pos(&vec3);
|
wrapper.add_pos(&vec3);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in the MonsterBuilder object.
|
/// This function is a hack to update the FlatBufferBuilder reference (fbb_) in
|
||||||
/// This function will break if fbb_ is not the first member in MonsterBuilder. In that case, some offset must be added.
|
/// the MonsterBuilder object. This function will break if fbb_ is not the first
|
||||||
/// This function is used exclusively for testing correctness of move operations between FlatBufferBuilders.
|
/// member in MonsterBuilder. In that case, some offset must be added. This
|
||||||
/// If MonsterBuilder had a fbb_ pointer, this hack would be unnecessary. That involves a code-generator change though.
|
/// function is used exclusively for testing correctness of move operations
|
||||||
void test_only_hack_update_fbb_reference(MyGame::Example::MonsterBuilder &monsterBuilder,
|
/// between FlatBufferBuilders. If MonsterBuilder had a fbb_ pointer, this hack
|
||||||
flatbuffers::grpc::MessageBuilder &mb) {
|
/// would be unnecessary. That involves a code-generator change though.
|
||||||
|
void test_only_hack_update_fbb_reference(
|
||||||
|
MyGame::Example::MonsterBuilder &monsterBuilder,
|
||||||
|
flatbuffers::grpc::MessageBuilder &mb) {
|
||||||
*reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
|
*reinterpret_cast<flatbuffers::FlatBufferBuilder **>(&monsterBuilder) = &mb;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
|
/// This test validates correctness of move conversion of FlatBufferBuilder to a
|
||||||
/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
|
/// MessageBuilder DURING a table construction. Half of the table is constructed
|
||||||
/// of the table is constructed using a MessageBuilder.
|
/// using FlatBufferBuilder and the other half of the table is constructed using
|
||||||
|
/// a MessageBuilder.
|
||||||
void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
|
void builder_move_ctor_conversion_before_finish_half_n_half_table_test() {
|
||||||
for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
|
for (size_t initial_size = 4; initial_size <= 2048; initial_size *= 2) {
|
||||||
flatbuffers::FlatBufferBuilder fbb(initial_size);
|
flatbuffers::FlatBufferBuilder fbb(initial_size);
|
||||||
auto name_offset = fbb.CreateString(m1_name);
|
auto name_offset = fbb.CreateString(m1_name());
|
||||||
MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder
|
MyGame::Example::MonsterBuilder monsterBuilder(
|
||||||
|
fbb); // starts a table in FlatBufferBuilder
|
||||||
populate_first_half(monsterBuilder, name_offset);
|
populate_first_half(monsterBuilder, name_offset);
|
||||||
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
|
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
|
||||||
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
|
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
|
||||||
populate_second_half(monsterBuilder);
|
populate_second_half(monsterBuilder);
|
||||||
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
|
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
|
||||||
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
|
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
|
||||||
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
|
/// This test populates a COMPLETE inner table before move conversion and later
|
||||||
|
/// populates more members in the outer table.
|
||||||
void builder_move_ctor_conversion_before_finish_test() {
|
void builder_move_ctor_conversion_before_finish_test() {
|
||||||
for (size_t initial_size = 4 ; initial_size <= 2048; initial_size *= 2) {
|
for (size_t initial_size = 1; initial_size <= 2048; initial_size += 1) {
|
||||||
flatbuffers::FlatBufferBuilder fbb(initial_size);
|
flatbuffers::FlatBufferBuilder fbb(initial_size);
|
||||||
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
|
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
|
||||||
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
|
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
|
||||||
auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
|
auto monster_offset =
|
||||||
|
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
|
||||||
|
m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
|
||||||
mb.Finish(monster_offset);
|
mb.Finish(monster_offset);
|
||||||
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
|
{
|
||||||
|
auto mon = flatbuffers::GetRoot<Monster>(mb.GetBufferPointer());
|
||||||
|
TEST_NOTNULL(mon);
|
||||||
|
TEST_NOTNULL(mon->name());
|
||||||
|
TEST_EQ_STR(mon->name()->c_str(), m1_name().c_str());
|
||||||
|
TEST_EQ(mon->color(), m1_color());
|
||||||
|
}
|
||||||
|
TEST_EQ(1, MyGame::Example::Color_Red);
|
||||||
|
TEST_EQ(1, m1_color());
|
||||||
|
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
|
||||||
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test validates correctness of move conversion of FlatBufferBuilder to a MessageBuilder DURING
|
/// This test validates correctness of move conversion of FlatBufferBuilder to a
|
||||||
/// a table construction. Half of the table is constructed using FlatBufferBuilder and the other half
|
/// MessageBuilder DURING a table construction. Half of the table is constructed
|
||||||
/// of the table is constructed using a MessageBuilder.
|
/// using FlatBufferBuilder and the other half of the table is constructed using
|
||||||
|
/// a MessageBuilder.
|
||||||
void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
|
void builder_move_assign_conversion_before_finish_half_n_half_table_test() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
|
|
||||||
for (int i = 0;i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
auto name_offset = fbb.CreateString(m1_name);
|
auto name_offset = fbb.CreateString(m1_name());
|
||||||
MyGame::Example::MonsterBuilder monsterBuilder(fbb); // starts a table in FlatBufferBuilder
|
MyGame::Example::MonsterBuilder monsterBuilder(
|
||||||
|
fbb); // starts a table in FlatBufferBuilder
|
||||||
populate_first_half(monsterBuilder, name_offset);
|
populate_first_half(monsterBuilder, name_offset);
|
||||||
mb = std::move(fbb);
|
mb = std::move(fbb);
|
||||||
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
|
test_only_hack_update_fbb_reference(monsterBuilder, mb); // hack
|
||||||
populate_second_half(monsterBuilder);
|
populate_second_half(monsterBuilder);
|
||||||
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
|
mb.Finish(monsterBuilder.Finish()); // ends the table in MessageBuilder
|
||||||
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
|
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
|
||||||
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test populates a COMPLETE inner table before move conversion and later populates more members in the outer table.
|
/// This test populates a COMPLETE inner table before move conversion and later
|
||||||
|
/// populates more members in the outer table.
|
||||||
void builder_move_assign_conversion_before_finish_test() {
|
void builder_move_assign_conversion_before_finish_test() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
|
|
||||||
for (int i = 0;i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
|
auto stat_offset = CreateStat(fbb, fbb.CreateString("SomeId"), 0, 0);
|
||||||
mb = std::move(fbb);
|
mb = std::move(fbb);
|
||||||
auto monster_offset = CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name), 0, m1_color, Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
|
auto monster_offset =
|
||||||
|
CreateMonster(mb, 0, 150, 100, mb.CreateString(m1_name()), 0,
|
||||||
|
m1_color(), Any_NONE, 0, 0, 0, 0, 0, 0, stat_offset);
|
||||||
mb.Finish(monster_offset);
|
mb.Finish(monster_offset);
|
||||||
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
|
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
|
||||||
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test populates data, finishes the buffer, and does move conversion after.
|
/// This test populates data, finishes the buffer, and does move conversion
|
||||||
|
/// after.
|
||||||
void builder_move_ctor_conversion_after_finish_test() {
|
void builder_move_ctor_conversion_after_finish_test() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
fbb.Finish(populate1(fbb));
|
fbb.Finish(populate1(fbb));
|
||||||
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
|
flatbuffers::grpc::MessageBuilder mb(std::move(fbb));
|
||||||
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
|
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
|
||||||
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This test populates data, finishes the buffer, and does move conversion after.
|
/// This test populates data, finishes the buffer, and does move conversion
|
||||||
|
/// after.
|
||||||
void builder_move_assign_conversion_after_finish_test() {
|
void builder_move_assign_conversion_after_finish_test() {
|
||||||
flatbuffers::FlatBufferBuilder fbb;
|
flatbuffers::FlatBufferBuilder fbb;
|
||||||
flatbuffers::grpc::MessageBuilder mb;
|
flatbuffers::grpc::MessageBuilder mb;
|
||||||
|
|
||||||
for (int i = 0;i < 5; ++i) {
|
for (int i = 0; i < 5; ++i) {
|
||||||
fbb.Finish(populate1(fbb));
|
fbb.Finish(populate1(fbb));
|
||||||
mb = std::move(fbb);
|
mb = std::move(fbb);
|
||||||
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name, m1_color));
|
TEST_ASSERT_FUNC(release_n_verify(mb, m1_name(), m1_color()));
|
||||||
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
TEST_EQ_FUNC(fbb.GetSize(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void message_builder_tests() {
|
void message_builder_tests() {
|
||||||
using flatbuffers::grpc::MessageBuilder;
|
|
||||||
using flatbuffers::FlatBufferBuilder;
|
using flatbuffers::FlatBufferBuilder;
|
||||||
|
using flatbuffers::grpc::MessageBuilder;
|
||||||
|
|
||||||
slice_allocator_tests();
|
slice_allocator_tests();
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
builder_move_ctor_conversion_before_finish_half_n_half_table_test();
|
builder_move_ctor_conversion_before_finish_half_n_half_table_test();
|
||||||
builder_move_assign_conversion_before_finish_half_n_half_table_test();
|
builder_move_assign_conversion_before_finish_half_n_half_table_test();
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
builder_move_ctor_conversion_before_finish_test();
|
builder_move_ctor_conversion_before_finish_test();
|
||||||
builder_move_assign_conversion_before_finish_test();
|
builder_move_assign_conversion_before_finish_test();
|
||||||
|
|
||||||
@@ -326,15 +354,18 @@ void message_builder_tests() {
|
|||||||
BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
|
BuilderTests<MessageBuilder, FlatBufferBuilder>::all_tests();
|
||||||
|
|
||||||
BuilderReuseTestSelector tests[6] = {
|
BuilderReuseTestSelector tests[6] = {
|
||||||
//REUSABLE_AFTER_RELEASE, // Assertion failed: (GRPC_SLICE_IS_EMPTY(slice_))
|
// REUSABLE_AFTER_RELEASE, // Assertion failed:
|
||||||
//REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p == GRPC_SLICE_START_PTR(slice_)
|
// (GRPC_SLICE_IS_EMPTY(slice_))
|
||||||
|
// REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN, // Assertion failed: (p ==
|
||||||
|
// GRPC_SLICE_START_PTR(slice_)
|
||||||
|
|
||||||
REUSABLE_AFTER_RELEASE_RAW,
|
REUSABLE_AFTER_RELEASE_RAW, REUSABLE_AFTER_RELEASE_MESSAGE,
|
||||||
REUSABLE_AFTER_RELEASE_MESSAGE,
|
|
||||||
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
|
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
|
||||||
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
|
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
|
||||||
};
|
};
|
||||||
|
|
||||||
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(TestSelector(tests, tests+6));
|
BuilderReuseTests<MessageBuilder, MessageBuilder>::run_tests(
|
||||||
BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(TestSelector(tests, tests+6));
|
TestSelector(tests, tests + 6));
|
||||||
|
BuilderReuseTests<MessageBuilder, FlatBufferBuilder>::run_tests(
|
||||||
|
TestSelector(tests, tests + 6));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,13 +4,13 @@
|
|||||||
<parent>
|
<parent>
|
||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-parent</artifactId>
|
<artifactId>flatbuffers-parent</artifactId>
|
||||||
<version>1.11.0</version>
|
<version>1.12.0</version>
|
||||||
</parent>
|
</parent>
|
||||||
<artifactId>grpc-test</artifactId>
|
<artifactId>grpc-test</artifactId>
|
||||||
<description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
|
<description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
|
||||||
</description>
|
</description>
|
||||||
<properties>
|
<properties>
|
||||||
<gRPC.version>1.11.0</gRPC.version>
|
<gRPC.version>1.12.0</gRPC.version>
|
||||||
</properties>
|
</properties>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|||||||
@@ -55,6 +55,10 @@
|
|||||||
|
|
||||||
#include "flatbuffers/stl_emulation.h"
|
#include "flatbuffers/stl_emulation.h"
|
||||||
|
|
||||||
|
#if defined(__ICCARM__)
|
||||||
|
#include <intrinsics.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
// Note the __clang__ check is needed, because clang presents itself
|
// Note the __clang__ check is needed, because clang presents itself
|
||||||
// as an older GNUC compiler (4.2).
|
// as an older GNUC compiler (4.2).
|
||||||
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
|
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
|
||||||
@@ -95,7 +99,7 @@
|
|||||||
#if !defined(__clang__) && \
|
#if !defined(__clang__) && \
|
||||||
defined(__GNUC__) && \
|
defined(__GNUC__) && \
|
||||||
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
|
(__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__ < 40600)
|
||||||
// Backwards compatability for g++ 4.4, and 4.5 which don't have the nullptr
|
// Backwards compatibility for g++ 4.4, and 4.5 which don't have the nullptr
|
||||||
// and constexpr keywords. Note the __clang__ check is needed, because clang
|
// and constexpr keywords. Note the __clang__ check is needed, because clang
|
||||||
// presents itself as an older GNUC compiler.
|
// presents itself as an older GNUC compiler.
|
||||||
#ifndef nullptr_t
|
#ifndef nullptr_t
|
||||||
@@ -117,7 +121,7 @@
|
|||||||
#define FLATBUFFERS_LITTLEENDIAN 0
|
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||||
#endif // __s390x__
|
#endif // __s390x__
|
||||||
#if !defined(FLATBUFFERS_LITTLEENDIAN)
|
#if !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||||
#if defined(__GNUC__) || defined(__clang__)
|
#if defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
|
||||||
#if (defined(__BIG_ENDIAN__) || \
|
#if (defined(__BIG_ENDIAN__) || \
|
||||||
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
(defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||||
#define FLATBUFFERS_LITTLEENDIAN 0
|
#define FLATBUFFERS_LITTLEENDIAN 0
|
||||||
@@ -136,10 +140,14 @@
|
|||||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||||
|
|
||||||
#define FLATBUFFERS_VERSION_MAJOR 1
|
#define FLATBUFFERS_VERSION_MAJOR 1
|
||||||
#define FLATBUFFERS_VERSION_MINOR 11
|
#define FLATBUFFERS_VERSION_MINOR 12
|
||||||
#define FLATBUFFERS_VERSION_REVISION 0
|
#define FLATBUFFERS_VERSION_REVISION 0
|
||||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||||
|
namespace flatbuffers {
|
||||||
|
// Returns version as string "MAJOR.MINOR.REVISION".
|
||||||
|
const char* FLATBUFFERS_VERSION();
|
||||||
|
}
|
||||||
|
|
||||||
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
|
#if (!defined(_MSC_VER) || _MSC_VER > 1600) && \
|
||||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
|
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 407)) || \
|
||||||
@@ -191,7 +199,7 @@
|
|||||||
// to detect a header that provides an implementation
|
// to detect a header that provides an implementation
|
||||||
#if defined(__has_include)
|
#if defined(__has_include)
|
||||||
// Check for std::string_view (in c++17)
|
// Check for std::string_view (in c++17)
|
||||||
#if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
|
#if __has_include(<string_view>) && (__cplusplus >= 201606 || (defined(_HAS_CXX17) && _HAS_CXX17))
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
typedef std::string_view string_view;
|
typedef std::string_view string_view;
|
||||||
@@ -204,6 +212,13 @@
|
|||||||
typedef std::experimental::string_view string_view;
|
typedef std::experimental::string_view string_view;
|
||||||
}
|
}
|
||||||
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||||
|
// Check for absl::string_view
|
||||||
|
#elif __has_include("absl/strings/string_view.h")
|
||||||
|
#include "absl/strings/string_view.h"
|
||||||
|
namespace flatbuffers {
|
||||||
|
typedef absl::string_view string_view;
|
||||||
|
}
|
||||||
|
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||||
#endif
|
#endif
|
||||||
#endif // __has_include
|
#endif // __has_include
|
||||||
#endif // !FLATBUFFERS_HAS_STRING_VIEW
|
#endif // !FLATBUFFERS_HAS_STRING_VIEW
|
||||||
@@ -234,7 +249,7 @@
|
|||||||
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
|
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
|
||||||
// - __supress_ubsan__("undefined")
|
// - __supress_ubsan__("undefined")
|
||||||
// - __supress_ubsan__("signed-integer-overflow")
|
// - __supress_ubsan__("signed-integer-overflow")
|
||||||
#if defined(__clang__)
|
#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
|
||||||
#define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
|
#define __supress_ubsan__(type) __attribute__((no_sanitize(type)))
|
||||||
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
|
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
|
||||||
#define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
|
#define __supress_ubsan__(type) __attribute__((no_sanitize_undefined))
|
||||||
@@ -288,7 +303,7 @@ typedef uint16_t voffset_t;
|
|||||||
typedef uintmax_t largest_scalar_t;
|
typedef uintmax_t largest_scalar_t;
|
||||||
|
|
||||||
// In 32bits, this evaluates to 2GB - 1
|
// In 32bits, this evaluates to 2GB - 1
|
||||||
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(soffset_t) * 8 - 1)) - 1)
|
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
|
||||||
|
|
||||||
// We support aligning the contents of buffers up to this size.
|
// We support aligning the contents of buffers up to this size.
|
||||||
#define FLATBUFFERS_MAX_ALIGNMENT 16
|
#define FLATBUFFERS_MAX_ALIGNMENT 16
|
||||||
@@ -303,6 +318,11 @@ template<typename T> T EndianSwap(T t) {
|
|||||||
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
|
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
|
||||||
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
|
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
|
||||||
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
|
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
|
||||||
|
#elif defined(__ICCARM__)
|
||||||
|
#define FLATBUFFERS_BYTESWAP16 __REV16
|
||||||
|
#define FLATBUFFERS_BYTESWAP32 __REV
|
||||||
|
#define FLATBUFFERS_BYTESWAP64(x) \
|
||||||
|
((__REV(static_cast<uint32_t>(x >> 32U))) | (static_cast<uint64_t>(__REV(static_cast<uint32_t>(x)))) << 32U)
|
||||||
#else
|
#else
|
||||||
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
|
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
|
||||||
// __builtin_bswap16 was missing prior to GCC 4.8.
|
// __builtin_bswap16 was missing prior to GCC 4.8.
|
||||||
@@ -317,22 +337,20 @@ template<typename T> T EndianSwap(T t) {
|
|||||||
if (sizeof(T) == 1) { // Compile-time if-then's.
|
if (sizeof(T) == 1) { // Compile-time if-then's.
|
||||||
return t;
|
return t;
|
||||||
} else if (sizeof(T) == 2) {
|
} else if (sizeof(T) == 2) {
|
||||||
union { T t; uint16_t i; } u;
|
union { T t; uint16_t i; } u = { t };
|
||||||
u.t = t;
|
|
||||||
u.i = FLATBUFFERS_BYTESWAP16(u.i);
|
u.i = FLATBUFFERS_BYTESWAP16(u.i);
|
||||||
return u.t;
|
return u.t;
|
||||||
} else if (sizeof(T) == 4) {
|
} else if (sizeof(T) == 4) {
|
||||||
union { T t; uint32_t i; } u;
|
union { T t; uint32_t i; } u = { t };
|
||||||
u.t = t;
|
|
||||||
u.i = FLATBUFFERS_BYTESWAP32(u.i);
|
u.i = FLATBUFFERS_BYTESWAP32(u.i);
|
||||||
return u.t;
|
return u.t;
|
||||||
} else if (sizeof(T) == 8) {
|
} else if (sizeof(T) == 8) {
|
||||||
union { T t; uint64_t i; } u;
|
union { T t; uint64_t i; } u = { t };
|
||||||
u.t = t;
|
|
||||||
u.i = FLATBUFFERS_BYTESWAP64(u.i);
|
u.i = FLATBUFFERS_BYTESWAP64(u.i);
|
||||||
return u.t;
|
return u.t;
|
||||||
} else {
|
} else {
|
||||||
FLATBUFFERS_ASSERT(0);
|
FLATBUFFERS_ASSERT(0);
|
||||||
|
return t;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -371,6 +389,7 @@ template<typename T> __supress_ubsan__("alignment") void WriteScalar(void *p, Of
|
|||||||
// Computes how many bytes you'd have to pad to be able to write an
|
// Computes how many bytes you'd have to pad to be able to write an
|
||||||
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
|
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
|
||||||
// memory).
|
// memory).
|
||||||
|
__supress_ubsan__("unsigned-integer-overflow")
|
||||||
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
|
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
|
||||||
return ((~buf_size) + 1) & (scalar_size - 1);
|
return ((~buf_size) + 1) & (scalar_size - 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
@@ -26,7 +27,7 @@ namespace flatbuffers {
|
|||||||
// Utility class to assist in generating code through use of text templates.
|
// Utility class to assist in generating code through use of text templates.
|
||||||
//
|
//
|
||||||
// Example code:
|
// Example code:
|
||||||
// CodeWriter code;
|
// CodeWriter code("\t");
|
||||||
// code.SetValue("NAME", "Foo");
|
// code.SetValue("NAME", "Foo");
|
||||||
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
|
// code += "void {{NAME}}() { printf("%s", "{{NAME}}"); }";
|
||||||
// code.SetValue("NAME", "Bar");
|
// code.SetValue("NAME", "Bar");
|
||||||
@@ -38,7 +39,8 @@ namespace flatbuffers {
|
|||||||
// void Bar() { printf("%s", "Bar"); }
|
// void Bar() { printf("%s", "Bar"); }
|
||||||
class CodeWriter {
|
class CodeWriter {
|
||||||
public:
|
public:
|
||||||
CodeWriter() {}
|
CodeWriter(std::string pad = std::string())
|
||||||
|
: pad_(pad), cur_ident_lvl_(0), ignore_ident_(false) {}
|
||||||
|
|
||||||
// Clears the current "written" code.
|
// Clears the current "written" code.
|
||||||
void Clear() {
|
void Clear() {
|
||||||
@@ -53,6 +55,11 @@ class CodeWriter {
|
|||||||
value_map_[key] = value;
|
value_map_[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GetValue(const std::string &key) const {
|
||||||
|
const auto it = value_map_.find(key);
|
||||||
|
return it == value_map_.end() ? "" : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
// Appends the given text to the generated code as well as a newline
|
// Appends the given text to the generated code as well as a newline
|
||||||
// character. Any text within {{ and }} delimeters is replaced by values
|
// character. Any text within {{ and }} delimeters is replaced by values
|
||||||
// previously stored in the CodeWriter by calling SetValue above. The newline
|
// previously stored in the CodeWriter by calling SetValue above. The newline
|
||||||
@@ -62,9 +69,22 @@ class CodeWriter {
|
|||||||
// Returns the current contents of the CodeWriter as a std::string.
|
// Returns the current contents of the CodeWriter as a std::string.
|
||||||
std::string ToString() const { return stream_.str(); }
|
std::string ToString() const { return stream_.str(); }
|
||||||
|
|
||||||
|
// Increase ident level for writing code
|
||||||
|
void IncrementIdentLevel() { cur_ident_lvl_++; }
|
||||||
|
// Decrease ident level for writing code
|
||||||
|
void DecrementIdentLevel() {
|
||||||
|
if (cur_ident_lvl_) cur_ident_lvl_--;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::map<std::string, std::string> value_map_;
|
std::map<std::string, std::string> value_map_;
|
||||||
std::stringstream stream_;
|
std::stringstream stream_;
|
||||||
|
std::string pad_;
|
||||||
|
int cur_ident_lvl_;
|
||||||
|
bool ignore_ident_;
|
||||||
|
|
||||||
|
// Add ident padding (tab or space) based on ident level
|
||||||
|
void AppendIdent(std::stringstream &stream);
|
||||||
};
|
};
|
||||||
|
|
||||||
class BaseGenerator {
|
class BaseGenerator {
|
||||||
@@ -74,16 +94,20 @@ class BaseGenerator {
|
|||||||
static std::string NamespaceDir(const Parser &parser, const std::string &path,
|
static std::string NamespaceDir(const Parser &parser, const std::string &path,
|
||||||
const Namespace &ns);
|
const Namespace &ns);
|
||||||
|
|
||||||
|
std::string GeneratedFileName(const std::string &path,
|
||||||
|
const std::string &file_name,
|
||||||
|
const IDLOptions &options) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BaseGenerator(const Parser &parser, const std::string &path,
|
BaseGenerator(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name,
|
const std::string &file_name, std::string qualifying_start,
|
||||||
const std::string qualifying_start,
|
std::string qualifying_separator, std::string default_extension)
|
||||||
const std::string qualifying_separator)
|
|
||||||
: parser_(parser),
|
: parser_(parser),
|
||||||
path_(path),
|
path_(path),
|
||||||
file_name_(file_name),
|
file_name_(file_name),
|
||||||
qualifying_start_(qualifying_start),
|
qualifying_start_(qualifying_start),
|
||||||
qualifying_separator_(qualifying_separator) {}
|
qualifying_separator_(qualifying_separator),
|
||||||
|
default_extension_(default_extension) {}
|
||||||
virtual ~BaseGenerator() {}
|
virtual ~BaseGenerator() {}
|
||||||
|
|
||||||
// No copy/assign.
|
// No copy/assign.
|
||||||
@@ -104,8 +128,9 @@ class BaseGenerator {
|
|||||||
// which works for js and php
|
// which works for js and php
|
||||||
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
|
virtual const Namespace *CurrentNameSpace() const { return nullptr; }
|
||||||
|
|
||||||
// Ensure that a type is prefixed with its namespace whenever it is used
|
// Ensure that a type is prefixed with its namespace even within
|
||||||
// outside of its namespace.
|
// its own namespace to avoid conflict between generated method
|
||||||
|
// names and similarly named classes or structs
|
||||||
std::string WrapInNameSpace(const Namespace *ns,
|
std::string WrapInNameSpace(const Namespace *ns,
|
||||||
const std::string &name) const;
|
const std::string &name) const;
|
||||||
|
|
||||||
@@ -118,6 +143,7 @@ class BaseGenerator {
|
|||||||
const std::string &file_name_;
|
const std::string &file_name_;
|
||||||
const std::string qualifying_start_;
|
const std::string qualifying_start_;
|
||||||
const std::string qualifying_separator_;
|
const std::string qualifying_separator_;
|
||||||
|
const std::string default_extension_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommentConfig {
|
struct CommentConfig {
|
||||||
|
|||||||
@@ -20,24 +20,43 @@
|
|||||||
#include "flatbuffers/base.h"
|
#include "flatbuffers/base.h"
|
||||||
|
|
||||||
#if defined(FLATBUFFERS_NAN_DEFAULTS)
|
#if defined(FLATBUFFERS_NAN_DEFAULTS)
|
||||||
#include <cmath>
|
# include <cmath>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
// Generic 'operator==' with conditional specialisations.
|
// Generic 'operator==' with conditional specialisations.
|
||||||
|
// T e - new value of a scalar field.
|
||||||
|
// T def - default of scalar (is known at compile-time).
|
||||||
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
|
template<typename T> inline bool IsTheSameAs(T e, T def) { return e == def; }
|
||||||
|
|
||||||
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
|
#if defined(FLATBUFFERS_NAN_DEFAULTS) && \
|
||||||
(!defined(_MSC_VER) || _MSC_VER >= 1800)
|
defined(FLATBUFFERS_HAS_NEW_STRTOD) && (FLATBUFFERS_HAS_NEW_STRTOD > 0)
|
||||||
// Like `operator==(e, def)` with weak NaN if T=(float|double).
|
// Like `operator==(e, def)` with weak NaN if T=(float|double).
|
||||||
|
template<typename T> inline bool IsFloatTheSameAs(T e, T def) {
|
||||||
|
return (e == def) || ((def != def) && (e != e));
|
||||||
|
}
|
||||||
template<> inline bool IsTheSameAs<float>(float e, float def) {
|
template<> inline bool IsTheSameAs<float>(float e, float def) {
|
||||||
return (e == def) || (std::isnan(def) && std::isnan(e));
|
return IsFloatTheSameAs(e, def);
|
||||||
}
|
}
|
||||||
template<> inline bool IsTheSameAs<double>(double e, double def) {
|
template<> inline bool IsTheSameAs<double>(double e, double def) {
|
||||||
return (e == def) || (std::isnan(def) && std::isnan(e));
|
return IsFloatTheSameAs(e, def);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Check 'v' is out of closed range [low; high].
|
||||||
|
// Workaround for GCC warning [-Werror=type-limits]:
|
||||||
|
// comparison is always true due to limited range of data type.
|
||||||
|
template<typename T>
|
||||||
|
inline bool IsOutRange(const T &v, const T &low, const T &high) {
|
||||||
|
return (v < low) || (high < v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check 'v' is in closed range [low; high].
|
||||||
|
template<typename T>
|
||||||
|
inline bool IsInRange(const T &v, const T &low, const T &high) {
|
||||||
|
return !IsOutRange(v, low, high);
|
||||||
|
}
|
||||||
|
|
||||||
// Wrapper for uoffset_t to allow safe template specialization.
|
// Wrapper for uoffset_t to allow safe template specialization.
|
||||||
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
|
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
|
||||||
template<typename T> struct Offset {
|
template<typename T> struct Offset {
|
||||||
@@ -198,17 +217,18 @@ template<typename T, typename IT> struct VectorIterator {
|
|||||||
const uint8_t *data_;
|
const uint8_t *data_;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename Iterator> struct VectorReverseIterator :
|
template<typename Iterator>
|
||||||
public std::reverse_iterator<Iterator> {
|
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
||||||
|
explicit VectorReverseIterator(Iterator iter)
|
||||||
|
: std::reverse_iterator<Iterator>(iter) {}
|
||||||
|
|
||||||
explicit VectorReverseIterator(Iterator iter) : iter_(iter) {}
|
typename Iterator::value_type operator*() const {
|
||||||
|
return *(std::reverse_iterator<Iterator>::current);
|
||||||
|
}
|
||||||
|
|
||||||
typename Iterator::value_type operator*() const { return *(iter_ - 1); }
|
typename Iterator::value_type operator->() const {
|
||||||
|
return *(std::reverse_iterator<Iterator>::current);
|
||||||
typename Iterator::value_type operator->() const { return *(iter_ - 1); }
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
Iterator iter_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct String;
|
struct String;
|
||||||
@@ -269,11 +289,15 @@ template<typename T> class Vector {
|
|||||||
iterator end() { return iterator(Data(), size()); }
|
iterator end() { return iterator(Data(), size()); }
|
||||||
const_iterator end() const { return const_iterator(Data(), size()); }
|
const_iterator end() const { return const_iterator(Data(), size()); }
|
||||||
|
|
||||||
reverse_iterator rbegin() { return reverse_iterator(end()); }
|
reverse_iterator rbegin() { return reverse_iterator(end() - 1); }
|
||||||
const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
|
const_reverse_iterator rbegin() const {
|
||||||
|
return const_reverse_iterator(end() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
reverse_iterator rend() { return reverse_iterator(end()); }
|
reverse_iterator rend() { return reverse_iterator(begin() - 1); }
|
||||||
const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
|
const_reverse_iterator rend() const {
|
||||||
|
return const_reverse_iterator(begin() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
const_iterator cbegin() const { return begin(); }
|
const_iterator cbegin() const { return begin(); }
|
||||||
|
|
||||||
@@ -341,6 +365,7 @@ template<typename T> class Vector {
|
|||||||
// This class is a pointer. Copying will therefore create an invalid object.
|
// This class is a pointer. Copying will therefore create an invalid object.
|
||||||
// Private and unimplemented copy constructor.
|
// Private and unimplemented copy constructor.
|
||||||
Vector(const Vector &);
|
Vector(const Vector &);
|
||||||
|
Vector &operator=(const Vector &);
|
||||||
|
|
||||||
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
|
template<typename K> static int KeyCompare(const void *ap, const void *bp) {
|
||||||
const K *key = reinterpret_cast<const K *>(ap);
|
const K *key = reinterpret_cast<const K *>(ap);
|
||||||
@@ -371,6 +396,7 @@ class VectorOfAny {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
VectorOfAny(const VectorOfAny &);
|
VectorOfAny(const VectorOfAny &);
|
||||||
|
VectorOfAny &operator=(const VectorOfAny &);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_CPP98_STL
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
@@ -393,6 +419,131 @@ template<typename T> static inline size_t VectorLength(const Vector<T> *v) {
|
|||||||
return v ? v->size() : 0;
|
return v ? v->size() : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is used as a helper type for accessing arrays.
|
||||||
|
template<typename T, uint16_t length> class Array {
|
||||||
|
typedef
|
||||||
|
typename flatbuffers::integral_constant<bool,
|
||||||
|
flatbuffers::is_scalar<T>::value>
|
||||||
|
scalar_tag;
|
||||||
|
typedef
|
||||||
|
typename flatbuffers::conditional<scalar_tag::value, T, const T *>::type
|
||||||
|
IndirectHelperType;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef typename IndirectHelper<IndirectHelperType>::return_type return_type;
|
||||||
|
typedef VectorIterator<T, return_type> const_iterator;
|
||||||
|
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||||
|
|
||||||
|
FLATBUFFERS_CONSTEXPR uint16_t size() const { return length; }
|
||||||
|
|
||||||
|
return_type Get(uoffset_t i) const {
|
||||||
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
|
return IndirectHelper<IndirectHelperType>::Read(Data(), i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return_type operator[](uoffset_t i) const { return Get(i); }
|
||||||
|
|
||||||
|
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||||
|
// type. This function makes it convenient to retrieve value with enum
|
||||||
|
// type E.
|
||||||
|
template<typename E> E GetEnum(uoffset_t i) const {
|
||||||
|
return static_cast<E>(Get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
const_iterator begin() const { return const_iterator(Data(), 0); }
|
||||||
|
const_iterator end() const { return const_iterator(Data(), size()); }
|
||||||
|
|
||||||
|
const_reverse_iterator rbegin() const {
|
||||||
|
return const_reverse_iterator(end());
|
||||||
|
}
|
||||||
|
const_reverse_iterator rend() const { return const_reverse_iterator(end()); }
|
||||||
|
|
||||||
|
const_iterator cbegin() const { return begin(); }
|
||||||
|
const_iterator cend() const { return end(); }
|
||||||
|
|
||||||
|
const_reverse_iterator crbegin() const { return rbegin(); }
|
||||||
|
const_reverse_iterator crend() const { return rend(); }
|
||||||
|
|
||||||
|
// Get a mutable pointer to elements inside this array.
|
||||||
|
// This method used to mutate arrays of structs followed by a @p Mutate
|
||||||
|
// operation. For primitive types use @p Mutate directly.
|
||||||
|
// @warning Assignments and reads to/from the dereferenced pointer are not
|
||||||
|
// automatically converted to the correct endianness.
|
||||||
|
typename flatbuffers::conditional<scalar_tag::value, void, T *>::type
|
||||||
|
GetMutablePointer(uoffset_t i) const {
|
||||||
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
|
return const_cast<T *>(&data()[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Change elements if you have a non-const pointer to this object.
|
||||||
|
void Mutate(uoffset_t i, const T &val) { MutateImpl(scalar_tag(), i, val); }
|
||||||
|
|
||||||
|
// The raw data in little endian format. Use with care.
|
||||||
|
const uint8_t *Data() const { return data_; }
|
||||||
|
|
||||||
|
uint8_t *Data() { return data_; }
|
||||||
|
|
||||||
|
// Similarly, but typed, much like std::vector::data
|
||||||
|
const T *data() const { return reinterpret_cast<const T *>(Data()); }
|
||||||
|
T *data() { return reinterpret_cast<T *>(Data()); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void MutateImpl(flatbuffers::integral_constant<bool, true>, uoffset_t i,
|
||||||
|
const T &val) {
|
||||||
|
FLATBUFFERS_ASSERT(i < size());
|
||||||
|
WriteScalar(data() + i, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MutateImpl(flatbuffers::integral_constant<bool, false>, uoffset_t i,
|
||||||
|
const T &val) {
|
||||||
|
*(GetMutablePointer(i)) = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This class is only used to access pre-existing data. Don't ever
|
||||||
|
// try to construct these manually.
|
||||||
|
// 'constexpr' allows us to use 'size()' at compile time.
|
||||||
|
// @note Must not use 'FLATBUFFERS_CONSTEXPR' here, as const is not allowed on
|
||||||
|
// a constructor.
|
||||||
|
#if defined(__cpp_constexpr)
|
||||||
|
constexpr Array();
|
||||||
|
#else
|
||||||
|
Array();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t data_[length * sizeof(T)];
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class is a pointer. Copying will therefore create an invalid object.
|
||||||
|
// Private and unimplemented copy constructor.
|
||||||
|
Array(const Array &);
|
||||||
|
Array &operator=(const Array &);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialization for Array[struct] with access using Offset<void> pointer.
|
||||||
|
// This specialization used by idl_gen_text.cpp.
|
||||||
|
template<typename T, uint16_t length> class Array<Offset<T>, length> {
|
||||||
|
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef const void *return_type;
|
||||||
|
|
||||||
|
const uint8_t *Data() const { return data_; }
|
||||||
|
|
||||||
|
// Make idl_gen_text.cpp::PrintContainer happy.
|
||||||
|
return_type operator[](uoffset_t) const {
|
||||||
|
FLATBUFFERS_ASSERT(false);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// This class is only used to access pre-existing data.
|
||||||
|
Array();
|
||||||
|
Array(const Array &);
|
||||||
|
Array &operator=(const Array &);
|
||||||
|
|
||||||
|
uint8_t data_[1];
|
||||||
|
};
|
||||||
|
|
||||||
// Lexicographically compare two strings (possibly containing nulls), and
|
// Lexicographically compare two strings (possibly containing nulls), and
|
||||||
// return true if the first is less than the second.
|
// return true if the first is less than the second.
|
||||||
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
|
static inline bool StringLessThan(const char *a_data, uoffset_t a_size,
|
||||||
@@ -420,13 +571,13 @@ struct String : public Vector<char> {
|
|||||||
|
|
||||||
// Convenience function to get std::string from a String returning an empty
|
// Convenience function to get std::string from a String returning an empty
|
||||||
// string on null pointer.
|
// string on null pointer.
|
||||||
static inline std::string GetString(const String * str) {
|
static inline std::string GetString(const String *str) {
|
||||||
return str ? str->str() : "";
|
return str ? str->str() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function to get char* from a String returning an empty string on
|
// Convenience function to get char* from a String returning an empty string on
|
||||||
// null pointer.
|
// null pointer.
|
||||||
static inline const char * GetCstring(const String * str) {
|
static inline const char *GetCstring(const String *str) {
|
||||||
return str ? str->c_str() : "";
|
return str ? str->c_str() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,9 +614,9 @@ class Allocator {
|
|||||||
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
|
// to `new_p` of `new_size`. Only memory of size `in_use_front` and
|
||||||
// `in_use_back` will be copied from the front and back of the old memory
|
// `in_use_back` will be copied from the front and back of the old memory
|
||||||
// allocation.
|
// allocation.
|
||||||
void memcpy_downward(uint8_t *old_p, size_t old_size,
|
void memcpy_downward(uint8_t *old_p, size_t old_size, uint8_t *new_p,
|
||||||
uint8_t *new_p, size_t new_size,
|
size_t new_size, size_t in_use_back,
|
||||||
size_t in_use_back, size_t in_use_front) {
|
size_t in_use_front) {
|
||||||
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
|
memcpy(new_p + new_size - in_use_back, old_p + old_size - in_use_back,
|
||||||
in_use_back);
|
in_use_back);
|
||||||
memcpy(new_p, old_p, in_use_front);
|
memcpy(new_p, old_p, in_use_front);
|
||||||
@@ -479,13 +630,9 @@ class DefaultAllocator : public Allocator {
|
|||||||
return new uint8_t[size];
|
return new uint8_t[size];
|
||||||
}
|
}
|
||||||
|
|
||||||
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE {
|
void deallocate(uint8_t *p, size_t) FLATBUFFERS_OVERRIDE { delete[] p; }
|
||||||
delete[] p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void dealloc(void *p, size_t) {
|
static void dealloc(void *p, size_t) { delete[] static_cast<uint8_t *>(p); }
|
||||||
delete[] static_cast<uint8_t *>(p);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// These functions allow for a null allocator to mean use the default allocator,
|
// These functions allow for a null allocator to mean use the default allocator,
|
||||||
@@ -498,18 +645,19 @@ inline uint8_t *Allocate(Allocator *allocator, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
|
inline void Deallocate(Allocator *allocator, uint8_t *p, size_t size) {
|
||||||
if (allocator) allocator->deallocate(p, size);
|
if (allocator)
|
||||||
else DefaultAllocator().deallocate(p, size);
|
allocator->deallocate(p, size);
|
||||||
|
else
|
||||||
|
DefaultAllocator().deallocate(p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
|
inline uint8_t *ReallocateDownward(Allocator *allocator, uint8_t *old_p,
|
||||||
size_t old_size, size_t new_size,
|
size_t old_size, size_t new_size,
|
||||||
size_t in_use_back, size_t in_use_front) {
|
size_t in_use_back, size_t in_use_front) {
|
||||||
return allocator
|
return allocator ? allocator->reallocate_downward(old_p, old_size, new_size,
|
||||||
? allocator->reallocate_downward(old_p, old_size, new_size,
|
in_use_back, in_use_front)
|
||||||
in_use_back, in_use_front)
|
: DefaultAllocator().reallocate_downward(
|
||||||
: DefaultAllocator().reallocate_downward(old_p, old_size, new_size,
|
old_p, old_size, new_size, in_use_back, in_use_front);
|
||||||
in_use_back, in_use_front);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DetachedBuffer is a finished flatbuffer memory region, detached from its
|
// DetachedBuffer is a finished flatbuffer memory region, detached from its
|
||||||
@@ -554,6 +702,8 @@ class DetachedBuffer {
|
|||||||
#if !defined(FLATBUFFERS_CPP98_STL)
|
#if !defined(FLATBUFFERS_CPP98_STL)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
DetachedBuffer &operator=(DetachedBuffer &&other) {
|
DetachedBuffer &operator=(DetachedBuffer &&other) {
|
||||||
|
if (this == &other) return *this;
|
||||||
|
|
||||||
destroy();
|
destroy();
|
||||||
|
|
||||||
allocator_ = other.allocator_;
|
allocator_ = other.allocator_;
|
||||||
@@ -610,7 +760,7 @@ class DetachedBuffer {
|
|||||||
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Allocator *allocator_;
|
Allocator *allocator_;
|
||||||
bool own_allocator_;
|
bool own_allocator_;
|
||||||
uint8_t *buf_;
|
uint8_t *buf_;
|
||||||
@@ -642,10 +792,8 @@ protected:
|
|||||||
// Essentially, this supports 2 std::vectors in a single buffer.
|
// Essentially, this supports 2 std::vectors in a single buffer.
|
||||||
class vector_downward {
|
class vector_downward {
|
||||||
public:
|
public:
|
||||||
explicit vector_downward(size_t initial_size,
|
explicit vector_downward(size_t initial_size, Allocator *allocator,
|
||||||
Allocator *allocator,
|
bool own_allocator, size_t buffer_minalign)
|
||||||
bool own_allocator,
|
|
||||||
size_t buffer_minalign)
|
|
||||||
: allocator_(allocator),
|
: allocator_(allocator),
|
||||||
own_allocator_(own_allocator),
|
own_allocator_(own_allocator),
|
||||||
initial_size_(initial_size),
|
initial_size_(initial_size),
|
||||||
@@ -661,15 +809,15 @@ class vector_downward {
|
|||||||
#else
|
#else
|
||||||
vector_downward(vector_downward &other)
|
vector_downward(vector_downward &other)
|
||||||
#endif // defined(FLATBUFFERS_CPP98_STL)
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
// clang-format on
|
// clang-format on
|
||||||
: allocator_(other.allocator_),
|
: allocator_(other.allocator_),
|
||||||
own_allocator_(other.own_allocator_),
|
own_allocator_(other.own_allocator_),
|
||||||
initial_size_(other.initial_size_),
|
initial_size_(other.initial_size_),
|
||||||
buffer_minalign_(other.buffer_minalign_),
|
buffer_minalign_(other.buffer_minalign_),
|
||||||
reserved_(other.reserved_),
|
reserved_(other.reserved_),
|
||||||
buf_(other.buf_),
|
buf_(other.buf_),
|
||||||
cur_(other.cur_),
|
cur_(other.cur_),
|
||||||
scratch_(other.scratch_) {
|
scratch_(other.scratch_) {
|
||||||
// No change in other.allocator_
|
// No change in other.allocator_
|
||||||
// No change in other.initial_size_
|
// No change in other.initial_size_
|
||||||
// No change in other.buffer_minalign_
|
// No change in other.buffer_minalign_
|
||||||
@@ -713,9 +861,7 @@ class vector_downward {
|
|||||||
clear_scratch();
|
clear_scratch();
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_scratch() {
|
void clear_scratch() { scratch_ = buf_; }
|
||||||
scratch_ = buf_;
|
|
||||||
}
|
|
||||||
|
|
||||||
void clear_allocator() {
|
void clear_allocator() {
|
||||||
if (own_allocator_ && allocator_) { delete allocator_; }
|
if (own_allocator_ && allocator_) { delete allocator_; }
|
||||||
@@ -801,7 +947,7 @@ class vector_downward {
|
|||||||
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
|
uint8_t *data_at(size_t offset) const { return buf_ + reserved_ - offset; }
|
||||||
|
|
||||||
void push(const uint8_t *bytes, size_t num) {
|
void push(const uint8_t *bytes, size_t num) {
|
||||||
memcpy(make_space(num), bytes, num);
|
if (num > 0) { memcpy(make_space(num), bytes, num); }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialized version of push() that avoids memcpy call for small data.
|
// Specialized version of push() that avoids memcpy call for small data.
|
||||||
@@ -824,6 +970,7 @@ class vector_downward {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Version for when we know the size is larger.
|
// Version for when we know the size is larger.
|
||||||
|
// Precondition: zero_pad_bytes > 0
|
||||||
void fill_big(size_t zero_pad_bytes) {
|
void fill_big(size_t zero_pad_bytes) {
|
||||||
memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
|
memset(make_space(zero_pad_bytes), 0, zero_pad_bytes);
|
||||||
}
|
}
|
||||||
@@ -867,8 +1014,8 @@ class vector_downward {
|
|||||||
auto old_reserved = reserved_;
|
auto old_reserved = reserved_;
|
||||||
auto old_size = size();
|
auto old_size = size();
|
||||||
auto old_scratch_size = scratch_size();
|
auto old_scratch_size = scratch_size();
|
||||||
reserved_ += (std::max)(len,
|
reserved_ +=
|
||||||
old_reserved ? old_reserved / 2 : initial_size_);
|
(std::max)(len, old_reserved ? old_reserved / 2 : initial_size_);
|
||||||
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
|
reserved_ = (reserved_ + buffer_minalign_ - 1) & ~(buffer_minalign_ - 1);
|
||||||
if (buf_) {
|
if (buf_) {
|
||||||
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
|
buf_ = ReallocateDownward(allocator_, buf_, old_reserved, reserved_,
|
||||||
@@ -890,10 +1037,16 @@ inline voffset_t FieldIndexToOffset(voffset_t field_id) {
|
|||||||
|
|
||||||
template<typename T, typename Alloc>
|
template<typename T, typename Alloc>
|
||||||
const T *data(const std::vector<T, Alloc> &v) {
|
const T *data(const std::vector<T, Alloc> &v) {
|
||||||
return v.empty() ? nullptr : &v.front();
|
// Eventually the returned pointer gets passed down to memcpy, so
|
||||||
|
// we need it to be non-null to avoid undefined behavior.
|
||||||
|
static uint8_t t;
|
||||||
|
return v.empty() ? reinterpret_cast<const T *>(&t) : &v.front();
|
||||||
}
|
}
|
||||||
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
|
template<typename T, typename Alloc> T *data(std::vector<T, Alloc> &v) {
|
||||||
return v.empty() ? nullptr : &v.front();
|
// Eventually the returned pointer gets passed down to memcpy, so
|
||||||
|
// we need it to be non-null to avoid undefined behavior.
|
||||||
|
static uint8_t t;
|
||||||
|
return v.empty() ? reinterpret_cast<T *>(&t) : &v.front();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
@@ -920,11 +1073,10 @@ class FlatBufferBuilder {
|
|||||||
/// minimum alignment upon reallocation. Only needed if you intend to store
|
/// minimum alignment upon reallocation. Only needed if you intend to store
|
||||||
/// types with custom alignment AND you wish to read the buffer in-place
|
/// types with custom alignment AND you wish to read the buffer in-place
|
||||||
/// directly after creation.
|
/// directly after creation.
|
||||||
explicit FlatBufferBuilder(size_t initial_size = 1024,
|
explicit FlatBufferBuilder(
|
||||||
Allocator *allocator = nullptr,
|
size_t initial_size = 1024, Allocator *allocator = nullptr,
|
||||||
bool own_allocator = false,
|
bool own_allocator = false,
|
||||||
size_t buffer_minalign =
|
size_t buffer_minalign = AlignOf<largest_scalar_t>())
|
||||||
AlignOf<largest_scalar_t>())
|
|
||||||
: buf_(initial_size, allocator, own_allocator, buffer_minalign),
|
: buf_(initial_size, allocator, own_allocator, buffer_minalign),
|
||||||
num_field_loc(0),
|
num_field_loc(0),
|
||||||
max_voffset_(0),
|
max_voffset_(0),
|
||||||
@@ -1027,8 +1179,8 @@ class FlatBufferBuilder {
|
|||||||
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
|
/// @warning Do NOT attempt to use this FlatBufferBuilder afterwards!
|
||||||
/// @return A `FlatBuffer` that owns the buffer and its allocator and
|
/// @return A `FlatBuffer` that owns the buffer and its allocator and
|
||||||
/// behaves similar to a `unique_ptr` with a deleter.
|
/// behaves similar to a `unique_ptr` with a deleter.
|
||||||
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead")) DetachedBuffer
|
FLATBUFFERS_ATTRIBUTE(deprecated("use Release() instead"))
|
||||||
ReleaseBufferPointer() {
|
DetachedBuffer ReleaseBufferPointer() {
|
||||||
Finished();
|
Finished();
|
||||||
return buf_.release();
|
return buf_.release();
|
||||||
}
|
}
|
||||||
@@ -1041,13 +1193,14 @@ class FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Get the released pointer to the serialized buffer.
|
/// @brief Get the released pointer to the serialized buffer.
|
||||||
/// @param The size of the memory block containing
|
/// @param size The size of the memory block containing
|
||||||
/// the serialized `FlatBuffer`.
|
/// the serialized `FlatBuffer`.
|
||||||
/// @param The offset from the released pointer where the finished
|
/// @param offset The offset from the released pointer where the finished
|
||||||
/// `FlatBuffer` starts.
|
/// `FlatBuffer` starts.
|
||||||
/// @return A raw pointer to the start of the memory block containing
|
/// @return A raw pointer to the start of the memory block containing
|
||||||
/// the serialized `FlatBuffer`.
|
/// the serialized `FlatBuffer`.
|
||||||
/// @remark If the allocator is owned, it gets deleted when the destructor is called..
|
/// @remark If the allocator is owned, it gets deleted when the destructor is
|
||||||
|
/// called..
|
||||||
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
|
uint8_t *ReleaseRaw(size_t &size, size_t &offset) {
|
||||||
Finished();
|
Finished();
|
||||||
return buf_.release_raw(size, offset);
|
return buf_.release_raw(size, offset);
|
||||||
@@ -1076,12 +1229,13 @@ class FlatBufferBuilder {
|
|||||||
|
|
||||||
/// @brief In order to save space, fields that are set to their default value
|
/// @brief In order to save space, fields that are set to their default value
|
||||||
/// don't get serialized into the buffer.
|
/// don't get serialized into the buffer.
|
||||||
/// @param[in] bool fd When set to `true`, always serializes default values that are set.
|
/// @param[in] fd When set to `true`, always serializes default values that
|
||||||
/// Optional fields which are not set explicitly, will still not be serialized.
|
/// are set. Optional fields which are not set explicitly, will still not be
|
||||||
|
/// serialized.
|
||||||
void ForceDefaults(bool fd) { force_defaults_ = fd; }
|
void ForceDefaults(bool fd) { force_defaults_ = fd; }
|
||||||
|
|
||||||
/// @brief By default vtables are deduped in order to save space.
|
/// @brief By default vtables are deduped in order to save space.
|
||||||
/// @param[in] bool dedup When set to `true`, dedup vtables.
|
/// @param[in] dedup When set to `true`, dedup vtables.
|
||||||
void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
|
void DedupVtables(bool dedup) { dedup_vtables_ = dedup; }
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
@@ -1235,7 +1389,7 @@ class FlatBufferBuilder {
|
|||||||
it += sizeof(uoffset_t)) {
|
it += sizeof(uoffset_t)) {
|
||||||
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
|
auto vt_offset_ptr = reinterpret_cast<uoffset_t *>(it);
|
||||||
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
|
auto vt2 = reinterpret_cast<voffset_t *>(buf_.data_at(*vt_offset_ptr));
|
||||||
auto vt2_size = *vt2;
|
auto vt2_size = ReadScalar<voffset_t>(vt2);
|
||||||
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
|
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
|
||||||
vt_use = *vt_offset_ptr;
|
vt_use = *vt_offset_ptr;
|
||||||
buf_.pop(GetSize() - vtableoffsetloc);
|
buf_.pop(GetSize() - vtableoffsetloc);
|
||||||
@@ -1562,17 +1716,16 @@ class FlatBufferBuilder {
|
|||||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
|
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
|
||||||
size_t len) {
|
size_t len) {
|
||||||
extern T Pack(const S &);
|
extern T Pack(const S &);
|
||||||
typedef T (*Pack_t)(const S &);
|
|
||||||
std::vector<T> vv(len);
|
std::vector<T> vv(len);
|
||||||
std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
|
std::transform(v, v + len, vv.begin(), Pack);
|
||||||
return CreateVectorOfStructs<T>(vv.data(), vv.size());
|
return CreateVectorOfStructs<T>(data(vv), vv.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#ifndef FLATBUFFERS_CPP98_STL
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
||||||
/// @tparam T The data type of the struct array elements.
|
/// @tparam T The data type of the struct array elements.
|
||||||
/// @param[in] f A function that takes the current iteration 0..vector_size-1
|
/// @param[in] filler A function that takes the current iteration 0..vector_size-1
|
||||||
/// and a pointer to the struct that must be filled.
|
/// and a pointer to the struct that must be filled.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
@@ -1612,7 +1765,7 @@ class FlatBufferBuilder {
|
|||||||
|
|
||||||
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
|
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
|
||||||
/// @tparam T The data type of the `std::vector` struct elements.
|
/// @tparam T The data type of the `std::vector` struct elements.
|
||||||
/// @param[in]] v A const reference to the `std::vector` of structs to
|
/// @param[in] v A const reference to the `std::vector` of structs to
|
||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
@@ -1626,7 +1779,7 @@ class FlatBufferBuilder {
|
|||||||
/// `vector`.
|
/// `vector`.
|
||||||
/// @tparam T The data type of the `std::vector` struct elements.
|
/// @tparam T The data type of the `std::vector` struct elements.
|
||||||
/// @tparam S The data type of the `std::vector` native struct elements.
|
/// @tparam S The data type of the `std::vector` native struct elements.
|
||||||
/// @param[in]] v A const reference to the `std::vector` of structs to
|
/// @param[in] v A const reference to the `std::vector` of structs to
|
||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
@@ -1650,7 +1803,7 @@ class FlatBufferBuilder {
|
|||||||
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
|
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`
|
||||||
/// in sorted order.
|
/// in sorted order.
|
||||||
/// @tparam T The data type of the `std::vector` struct elements.
|
/// @tparam T The data type of the `std::vector` struct elements.
|
||||||
/// @param[in]] v A const reference to the `std::vector` of structs to
|
/// @param[in] v A const reference to the `std::vector` of structs to
|
||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
@@ -1663,7 +1816,7 @@ class FlatBufferBuilder {
|
|||||||
/// `vector` in sorted order.
|
/// `vector` in sorted order.
|
||||||
/// @tparam T The data type of the `std::vector` struct elements.
|
/// @tparam T The data type of the `std::vector` struct elements.
|
||||||
/// @tparam S The data type of the `std::vector` native struct elements.
|
/// @tparam S The data type of the `std::vector` native struct elements.
|
||||||
/// @param[in]] v A const reference to the `std::vector` of structs to
|
/// @param[in] v A const reference to the `std::vector` of structs to
|
||||||
/// serialize into the buffer as a `vector`.
|
/// serialize into the buffer as a `vector`.
|
||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
@@ -1702,13 +1855,14 @@ class FlatBufferBuilder {
|
|||||||
extern T Pack(const S &);
|
extern T Pack(const S &);
|
||||||
typedef T (*Pack_t)(const S &);
|
typedef T (*Pack_t)(const S &);
|
||||||
std::vector<T> vv(len);
|
std::vector<T> vv(len);
|
||||||
std::transform(v, v + len, vv.begin(), static_cast<Pack_t&>(Pack));
|
std::transform(v, v + len, vv.begin(), static_cast<Pack_t &>(Pack));
|
||||||
return CreateVectorOfSortedStructs<T>(vv, len);
|
return CreateVectorOfSortedStructs<T>(vv, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
template<typename T> struct TableKeyComparator {
|
template<typename T> struct TableKeyComparator {
|
||||||
TableKeyComparator(vector_downward &buf) : buf_(buf) {}
|
TableKeyComparator(vector_downward &buf) : buf_(buf) {}
|
||||||
|
TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
|
||||||
bool operator()(const Offset<T> &a, const Offset<T> &b) const {
|
bool operator()(const Offset<T> &a, const Offset<T> &b) const {
|
||||||
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
|
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
|
||||||
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
|
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
|
||||||
@@ -1717,7 +1871,10 @@ class FlatBufferBuilder {
|
|||||||
vector_downward &buf_;
|
vector_downward &buf_;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TableKeyComparator &operator=(const TableKeyComparator &);
|
TableKeyComparator &operator=(const TableKeyComparator &other) {
|
||||||
|
buf_ = other.buf_;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@@ -1783,12 +1940,12 @@ class FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
Offset<Vector<const T*>> CreateUninitializedVectorOfStructs(size_t len, T **buf) {
|
Offset<Vector<const T *>> CreateUninitializedVectorOfStructs(size_t len,
|
||||||
|
T **buf) {
|
||||||
return CreateUninitializedVector(len, sizeof(T),
|
return CreateUninitializedVector(len, sizeof(T),
|
||||||
reinterpret_cast<uint8_t **>(buf));
|
reinterpret_cast<uint8_t **>(buf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// @brief Create a vector of scalar type T given as input a vector of scalar
|
// @brief Create a vector of scalar type T given as input a vector of scalar
|
||||||
// type U, useful with e.g. pre "enum class" enums, or any existing scalar
|
// type U, useful with e.g. pre "enum class" enums, or any existing scalar
|
||||||
// data of the wrong type.
|
// data of the wrong type.
|
||||||
@@ -1837,8 +1994,7 @@ class FlatBufferBuilder {
|
|||||||
buf_.swap_allocator(other.buf_);
|
buf_.swap_allocator(other.buf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
// You shouldn't really be copying instances of this class.
|
// You shouldn't really be copying instances of this class.
|
||||||
FlatBufferBuilder(const FlatBufferBuilder &);
|
FlatBufferBuilder(const FlatBufferBuilder &);
|
||||||
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
|
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
|
||||||
@@ -1891,8 +2047,8 @@ protected:
|
|||||||
bool operator()(const Offset<String> &a, const Offset<String> &b) const {
|
bool operator()(const Offset<String> &a, const Offset<String> &b) const {
|
||||||
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
|
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
|
||||||
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
|
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
|
||||||
return StringLessThan(stra->data(), stra->size(),
|
return StringLessThan(stra->data(), stra->size(), strb->data(),
|
||||||
strb->data(), strb->size());
|
strb->size());
|
||||||
}
|
}
|
||||||
const vector_downward *buf_;
|
const vector_downward *buf_;
|
||||||
};
|
};
|
||||||
@@ -1956,13 +2112,15 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
|
|||||||
/// This function is UNDEFINED for FlatBuffers whose schema does not include
|
/// This function is UNDEFINED for FlatBuffers whose schema does not include
|
||||||
/// a file_identifier (likely points at padding or the start of a the root
|
/// a file_identifier (likely points at padding or the start of a the root
|
||||||
/// vtable).
|
/// vtable).
|
||||||
inline const char *GetBufferIdentifier(const void *buf, bool size_prefixed = false) {
|
inline const char *GetBufferIdentifier(const void *buf,
|
||||||
|
bool size_prefixed = false) {
|
||||||
return reinterpret_cast<const char *>(buf) +
|
return reinterpret_cast<const char *>(buf) +
|
||||||
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
|
((size_prefixed) ? 2 * sizeof(uoffset_t) : sizeof(uoffset_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper to see if the identifier in a buffer has the expected value.
|
// Helper to see if the identifier in a buffer has the expected value.
|
||||||
inline bool BufferHasIdentifier(const void *buf, const char *identifier, bool size_prefixed = false) {
|
inline bool BufferHasIdentifier(const void *buf, const char *identifier,
|
||||||
|
bool size_prefixed = false) {
|
||||||
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
|
return strncmp(GetBufferIdentifier(buf, size_prefixed), identifier,
|
||||||
FlatBufferBuilder::kFileIdentifierLength) == 0;
|
FlatBufferBuilder::kFileIdentifierLength) == 0;
|
||||||
}
|
}
|
||||||
@@ -1979,8 +2137,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
num_tables_(0),
|
num_tables_(0),
|
||||||
max_tables_(_max_tables),
|
max_tables_(_max_tables),
|
||||||
upper_bound_(0),
|
upper_bound_(0),
|
||||||
check_alignment_(_check_alignment)
|
check_alignment_(_check_alignment) {
|
||||||
{
|
|
||||||
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
|
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2011,7 +2168,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> bool VerifyAlignment(size_t elem) const {
|
template<typename T> bool VerifyAlignment(size_t elem) const {
|
||||||
return (elem & (sizeof(T) - 1)) == 0 || !check_alignment_;
|
return Check((elem & (sizeof(T) - 1)) == 0 || !check_alignment_);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify a range indicated by sizeof(T).
|
// Verify a range indicated by sizeof(T).
|
||||||
@@ -2019,13 +2176,18 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T));
|
return VerifyAlignment<T>(elem) && Verify(elem, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VerifyFromPointer(const uint8_t *p, size_t len) {
|
||||||
|
auto o = static_cast<size_t>(p - buf_);
|
||||||
|
return Verify(o, len);
|
||||||
|
}
|
||||||
|
|
||||||
// Verify relative to a known-good base pointer.
|
// Verify relative to a known-good base pointer.
|
||||||
bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const {
|
bool Verify(const uint8_t *base, voffset_t elem_off, size_t elem_len) const {
|
||||||
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
|
return Verify(static_cast<size_t>(base - buf_) + elem_off, elem_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> bool Verify(const uint8_t *base, voffset_t elem_off)
|
template<typename T>
|
||||||
const {
|
bool Verify(const uint8_t *base, voffset_t elem_off) const {
|
||||||
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
|
return Verify(static_cast<size_t>(base - buf_) + elem_off, sizeof(T));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2048,16 +2210,15 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
// Verify a pointer (may be NULL) to string.
|
// Verify a pointer (may be NULL) to string.
|
||||||
bool VerifyString(const String *str) const {
|
bool VerifyString(const String *str) const {
|
||||||
size_t end;
|
size_t end;
|
||||||
return !str ||
|
return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
|
||||||
(VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
|
1, &end) &&
|
||||||
1, &end) &&
|
Verify(end, 1) && // Must have terminator
|
||||||
Verify(end, 1) && // Must have terminator
|
Check(buf_[end] == '\0')); // Terminating byte must be 0.
|
||||||
Check(buf_[end] == '\0')); // Terminating byte must be 0.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Common code between vectors and strings.
|
// Common code between vectors and strings.
|
||||||
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
|
bool VerifyVectorOrString(const uint8_t *vec, size_t elem_size,
|
||||||
size_t *end = nullptr) const {
|
size_t *end = nullptr) const {
|
||||||
auto veco = static_cast<size_t>(vec - buf_);
|
auto veco = static_cast<size_t>(vec - buf_);
|
||||||
// Check we can read the size field.
|
// Check we can read the size field.
|
||||||
if (!Verify<uoffset_t>(veco)) return false;
|
if (!Verify<uoffset_t>(veco)) return false;
|
||||||
@@ -2092,11 +2253,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VerifyTableStart(const uint8_t *table) {
|
__supress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
|
||||||
|
const uint8_t *table) {
|
||||||
// Check the vtable offset.
|
// Check the vtable offset.
|
||||||
auto tableo = static_cast<size_t>(table - buf_);
|
auto tableo = static_cast<size_t>(table - buf_);
|
||||||
if (!Verify<soffset_t>(tableo)) return false;
|
if (!Verify<soffset_t>(tableo)) return false;
|
||||||
// This offset may be signed, but doing the substraction unsigned always
|
// This offset may be signed, but doing the subtraction unsigned always
|
||||||
// gives the result we want.
|
// gives the result we want.
|
||||||
auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
|
auto vtableo = tableo - static_cast<size_t>(ReadScalar<soffset_t>(table));
|
||||||
// Check the vtable size field, then check vtable fits in its entirety.
|
// Check the vtable size field, then check vtable fits in its entirety.
|
||||||
@@ -2107,9 +2269,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
bool VerifyBufferFromStart(const char *identifier, size_t start) {
|
bool VerifyBufferFromStart(const char *identifier, size_t start) {
|
||||||
if (identifier &&
|
if (identifier && (size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
|
||||||
(size_ < 2 * sizeof(flatbuffers::uoffset_t) ||
|
!BufferHasIdentifier(buf_ + start, identifier))) {
|
||||||
!BufferHasIdentifier(buf_ + start, identifier))) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2241,6 +2402,12 @@ class Struct FLATBUFFERS_FINAL_CLASS {
|
|||||||
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
|
uint8_t *GetAddressOf(uoffset_t o) { return &data_[o]; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// private constructor & copy constructor: you obtain instances of this
|
||||||
|
// class by pointing to existing data only
|
||||||
|
Struct();
|
||||||
|
Struct(const Struct &);
|
||||||
|
Struct &operator=(const Struct &);
|
||||||
|
|
||||||
uint8_t data_[1];
|
uint8_t data_[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2353,12 +2520,13 @@ class Table {
|
|||||||
// class by pointing to existing data only
|
// class by pointing to existing data only
|
||||||
Table();
|
Table();
|
||||||
Table(const Table &other);
|
Table(const Table &other);
|
||||||
|
Table &operator=(const Table &);
|
||||||
|
|
||||||
uint8_t data_[1];
|
uint8_t data_[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T> void FlatBufferBuilder::Required(Offset<T> table,
|
template<typename T>
|
||||||
voffset_t field) {
|
void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
|
||||||
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
|
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
|
||||||
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
|
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
|
||||||
// If this fails, the caller will show what field needs to be set.
|
// If this fails, the caller will show what field needs to be set.
|
||||||
@@ -2405,7 +2573,9 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief This return the prefixed size of a FlatBuffer.
|
/// @brief This return the prefixed size of a FlatBuffer.
|
||||||
inline uoffset_t GetPrefixedSize(const uint8_t* buf){ return ReadScalar<uoffset_t>(buf); }
|
inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
|
||||||
|
return ReadScalar<uoffset_t>(buf);
|
||||||
|
}
|
||||||
|
|
||||||
// Base class for native objects (FlatBuffer data de-serialized into native
|
// Base class for native objects (FlatBuffer data de-serialized into native
|
||||||
// C++ data structures).
|
// C++ data structures).
|
||||||
@@ -2473,7 +2643,7 @@ inline int LookupEnum(const char **names, const char *name) {
|
|||||||
#define FLATBUFFERS_STRUCT_END(name, size) \
|
#define FLATBUFFERS_STRUCT_END(name, size) \
|
||||||
__pragma(pack()) \
|
__pragma(pack()) \
|
||||||
static_assert(sizeof(name) == size, "compiler breaks packing rules")
|
static_assert(sizeof(name) == size, "compiler breaks packing rules")
|
||||||
#elif defined(__GNUC__) || defined(__clang__)
|
#elif defined(__GNUC__) || defined(__clang__) || defined(__ICCARM__)
|
||||||
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
|
#define FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(alignment) \
|
||||||
_Pragma("pack(1)") \
|
_Pragma("pack(1)") \
|
||||||
struct __attribute__((aligned(alignment)))
|
struct __attribute__((aligned(alignment)))
|
||||||
@@ -2548,10 +2718,10 @@ typedef const TypeTable *(*TypeFunction)();
|
|||||||
struct TypeTable {
|
struct TypeTable {
|
||||||
SequenceType st;
|
SequenceType st;
|
||||||
size_t num_elems; // of type_codes, values, names (but not type_refs).
|
size_t num_elems; // of type_codes, values, names (but not type_refs).
|
||||||
const TypeCode *type_codes; // num_elems count
|
const TypeCode *type_codes; // num_elems count
|
||||||
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
|
const TypeFunction *type_refs; // less than num_elems entries (see TypeCode).
|
||||||
const int64_t *values; // Only set for non-consecutive enum/union or structs.
|
const int64_t *values; // Only set for non-consecutive enum/union or structs.
|
||||||
const char * const *names; // Only set if compiled with --reflect-names.
|
const char *const *names; // Only set if compiled with --reflect-names.
|
||||||
};
|
};
|
||||||
|
|
||||||
// String which identifies the current version of FlatBuffers.
|
// String which identifies the current version of FlatBuffers.
|
||||||
|
|||||||
@@ -14,18 +14,22 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_FLATC_H_
|
||||||
|
#define FLATBUFFERS_FLATC_H_
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/idl.h"
|
#include "flatbuffers/idl.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
#ifndef FLATC_H_
|
|
||||||
# define FLATC_H_
|
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
extern void LogCompilerWarn(const std::string &warn);
|
||||||
|
extern void LogCompilerError(const std::string &err);
|
||||||
|
|
||||||
class FlatCompiler {
|
class FlatCompiler {
|
||||||
public:
|
public:
|
||||||
// Output generator for the various programming languages and formats we
|
// Output generator for the various programming languages and formats we
|
||||||
@@ -93,4 +97,4 @@ class FlatCompiler {
|
|||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATC_H_
|
#endif // FLATBUFFERS_FLATC_H_
|
||||||
|
|||||||
@@ -65,7 +65,9 @@ enum Type {
|
|||||||
FBT_VECTOR_UINT = 12,
|
FBT_VECTOR_UINT = 12,
|
||||||
FBT_VECTOR_FLOAT = 13,
|
FBT_VECTOR_FLOAT = 13,
|
||||||
FBT_VECTOR_KEY = 14,
|
FBT_VECTOR_KEY = 14,
|
||||||
FBT_VECTOR_STRING = 15,
|
// DEPRECATED, use FBT_VECTOR or FBT_VECTOR_KEY instead.
|
||||||
|
// Read test.cpp/FlexBuffersDeprecatedTest() for details on why.
|
||||||
|
FBT_VECTOR_STRING_DEPRECATED = 15,
|
||||||
FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
|
FBT_VECTOR_INT2 = 16, // Typed tuple (no type table, no size field).
|
||||||
FBT_VECTOR_UINT2 = 17,
|
FBT_VECTOR_UINT2 = 17,
|
||||||
FBT_VECTOR_FLOAT2 = 18,
|
FBT_VECTOR_FLOAT2 = 18,
|
||||||
@@ -88,7 +90,7 @@ inline bool IsTypedVectorElementType(Type t) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsTypedVector(Type t) {
|
inline bool IsTypedVector(Type t) {
|
||||||
return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING) ||
|
return (t >= FBT_VECTOR_INT && t <= FBT_VECTOR_STRING_DEPRECATED) ||
|
||||||
t == FBT_VECTOR_BOOL;
|
t == FBT_VECTOR_BOOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,26 +214,40 @@ class Object {
|
|||||||
uint8_t byte_width_;
|
uint8_t byte_width_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Stores size in `byte_width_` bytes before data_ pointer.
|
// Object that has a size, obtained either from size prefix, or elsewhere.
|
||||||
class Sized : public Object {
|
class Sized : public Object {
|
||||||
public:
|
public:
|
||||||
Sized(const uint8_t *data, uint8_t byte_width) : Object(data, byte_width) {}
|
// Size prefix.
|
||||||
size_t size() const {
|
Sized(const uint8_t *data, uint8_t byte_width)
|
||||||
|
: Object(data, byte_width), size_(read_size()) {}
|
||||||
|
// Manual size.
|
||||||
|
Sized(const uint8_t *data, uint8_t byte_width, size_t sz)
|
||||||
|
: Object(data, byte_width), size_(sz) {}
|
||||||
|
size_t size() const { return size_; }
|
||||||
|
// Access size stored in `byte_width_` bytes before data_ pointer.
|
||||||
|
size_t read_size() const {
|
||||||
return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
|
return static_cast<size_t>(ReadUInt64(data_ - byte_width_, byte_width_));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
size_t size_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class String : public Sized {
|
class String : public Sized {
|
||||||
public:
|
public:
|
||||||
|
// Size prefix.
|
||||||
String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
|
String(const uint8_t *data, uint8_t byte_width) : Sized(data, byte_width) {}
|
||||||
|
// Manual size.
|
||||||
|
String(const uint8_t *data, uint8_t byte_width, size_t sz)
|
||||||
|
: Sized(data, byte_width, sz) {}
|
||||||
|
|
||||||
size_t length() const { return size(); }
|
size_t length() const { return size(); }
|
||||||
const char *c_str() const { return reinterpret_cast<const char *>(data_); }
|
const char *c_str() const { return reinterpret_cast<const char *>(data_); }
|
||||||
std::string str() const { return std::string(c_str(), length()); }
|
std::string str() const { return std::string(c_str(), size()); }
|
||||||
|
|
||||||
static String EmptyString() {
|
static String EmptyString() {
|
||||||
static const uint8_t empty_string[] = { 0 /*len*/, 0 /*terminator*/ };
|
static const char *empty_string = "";
|
||||||
return String(empty_string + 1, 1);
|
return String(reinterpret_cast<const uint8_t *>(empty_string), 1, 0);
|
||||||
}
|
}
|
||||||
bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
|
bool IsTheEmptyString() const { return data_ == EmptyString().data_; }
|
||||||
};
|
};
|
||||||
@@ -279,6 +295,8 @@ class TypedVector : public Sized {
|
|||||||
|
|
||||||
Type ElementType() { return type_; }
|
Type ElementType() { return type_; }
|
||||||
|
|
||||||
|
friend Reference;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type type_;
|
Type type_;
|
||||||
|
|
||||||
@@ -339,16 +357,22 @@ class Map : public Vector {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
|
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
|
||||||
s += "[ ";
|
s += "[ ";
|
||||||
for (size_t i = 0; i < v.size(); i++) {
|
for (size_t i = 0; i < v.size(); i++) {
|
||||||
if (i) s += ", ";
|
if (i) s += ", ";
|
||||||
v[i].ToString(true, keys_quoted, s);
|
v[i].ToString(true, keys_quoted, s);
|
||||||
}
|
}
|
||||||
s += " ]";
|
s += " ]";
|
||||||
}
|
}
|
||||||
|
|
||||||
class Reference {
|
class Reference {
|
||||||
public:
|
public:
|
||||||
|
Reference()
|
||||||
|
: data_(nullptr),
|
||||||
|
parent_width_(0),
|
||||||
|
byte_width_(BIT_WIDTH_8),
|
||||||
|
type_(FBT_NULL) {}
|
||||||
|
|
||||||
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
|
Reference(const uint8_t *data, uint8_t parent_width, uint8_t byte_width,
|
||||||
Type type)
|
Type type)
|
||||||
: data_(data),
|
: data_(data),
|
||||||
@@ -378,15 +402,19 @@ class Reference {
|
|||||||
bool IsString() const { return type_ == FBT_STRING; }
|
bool IsString() const { return type_ == FBT_STRING; }
|
||||||
bool IsKey() const { return type_ == FBT_KEY; }
|
bool IsKey() const { return type_ == FBT_KEY; }
|
||||||
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
|
bool IsVector() const { return type_ == FBT_VECTOR || type_ == FBT_MAP; }
|
||||||
|
bool IsUntypedVector() const { return type_ == FBT_VECTOR; }
|
||||||
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
|
bool IsTypedVector() const { return flexbuffers::IsTypedVector(type_); }
|
||||||
bool IsFixedTypedVector() const { return flexbuffers::IsFixedTypedVector(type_); }
|
bool IsFixedTypedVector() const {
|
||||||
bool IsAnyVector() const { return (IsTypedVector() || IsFixedTypedVector() || IsVector());}
|
return flexbuffers::IsFixedTypedVector(type_);
|
||||||
|
}
|
||||||
|
bool IsAnyVector() const {
|
||||||
|
return (IsTypedVector() || IsFixedTypedVector() || IsVector());
|
||||||
|
}
|
||||||
bool IsMap() const { return type_ == FBT_MAP; }
|
bool IsMap() const { return type_ == FBT_MAP; }
|
||||||
bool IsBlob() const { return type_ == FBT_BLOB; }
|
bool IsBlob() const { return type_ == FBT_BLOB; }
|
||||||
|
|
||||||
bool AsBool() const {
|
bool AsBool() const {
|
||||||
return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
|
return (type_ == FBT_BOOL ? ReadUInt64(data_, parent_width_)
|
||||||
: AsUInt64()) != 0;
|
: AsUInt64()) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reads any type as a int64_t. Never fails, does most sensible conversion.
|
// Reads any type as a int64_t. Never fails, does most sensible conversion.
|
||||||
@@ -464,7 +492,11 @@ class Reference {
|
|||||||
case FBT_INDIRECT_UINT:
|
case FBT_INDIRECT_UINT:
|
||||||
return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
|
return static_cast<double>(ReadUInt64(Indirect(), byte_width_));
|
||||||
case FBT_NULL: return 0.0;
|
case FBT_NULL: return 0.0;
|
||||||
case FBT_STRING: return strtod(AsString().c_str(), nullptr);
|
case FBT_STRING: {
|
||||||
|
double d;
|
||||||
|
flatbuffers::StringToNumber(AsString().c_str(), &d);
|
||||||
|
return d;
|
||||||
|
}
|
||||||
case FBT_VECTOR: return static_cast<double>(AsVector().size());
|
case FBT_VECTOR: return static_cast<double>(AsVector().size());
|
||||||
case FBT_BOOL:
|
case FBT_BOOL:
|
||||||
return static_cast<double>(ReadUInt64(data_, parent_width_));
|
return static_cast<double>(ReadUInt64(data_, parent_width_));
|
||||||
@@ -477,17 +509,22 @@ class Reference {
|
|||||||
float AsFloat() const { return static_cast<float>(AsDouble()); }
|
float AsFloat() const { return static_cast<float>(AsDouble()); }
|
||||||
|
|
||||||
const char *AsKey() const {
|
const char *AsKey() const {
|
||||||
if (type_ == FBT_KEY) {
|
if (type_ == FBT_KEY || type_ == FBT_STRING) {
|
||||||
return reinterpret_cast<const char *>(Indirect());
|
return reinterpret_cast<const char *>(Indirect());
|
||||||
} else {
|
} else {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function returns the empty string if you try to read a not-string.
|
// This function returns the empty string if you try to read something that
|
||||||
|
// is not a string or key.
|
||||||
String AsString() const {
|
String AsString() const {
|
||||||
if (type_ == FBT_STRING) {
|
if (type_ == FBT_STRING) {
|
||||||
return String(Indirect(), byte_width_);
|
return String(Indirect(), byte_width_);
|
||||||
|
} else if (type_ == FBT_KEY) {
|
||||||
|
auto key = Indirect();
|
||||||
|
return String(key, byte_width_,
|
||||||
|
strlen(reinterpret_cast<const char *>(key)));
|
||||||
} else {
|
} else {
|
||||||
return String::EmptyString();
|
return String::EmptyString();
|
||||||
}
|
}
|
||||||
@@ -549,7 +586,8 @@ class Reference {
|
|||||||
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
|
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
|
||||||
} else if (IsBlob()) {
|
} else if (IsBlob()) {
|
||||||
auto blob = AsBlob();
|
auto blob = AsBlob();
|
||||||
flatbuffers::EscapeString(reinterpret_cast<const char*>(blob.data()), blob.size(), &s, true, false);
|
flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
|
||||||
|
blob.size(), &s, true, false);
|
||||||
} else {
|
} else {
|
||||||
s += "(?)";
|
s += "(?)";
|
||||||
}
|
}
|
||||||
@@ -577,8 +615,18 @@ class Reference {
|
|||||||
|
|
||||||
TypedVector AsTypedVector() const {
|
TypedVector AsTypedVector() const {
|
||||||
if (IsTypedVector()) {
|
if (IsTypedVector()) {
|
||||||
return TypedVector(Indirect(), byte_width_,
|
auto tv =
|
||||||
ToTypedVectorElementType(type_));
|
TypedVector(Indirect(), byte_width_, ToTypedVectorElementType(type_));
|
||||||
|
if (tv.type_ == FBT_STRING) {
|
||||||
|
// These can't be accessed as strings, since we don't know the bit-width
|
||||||
|
// of the size field, see the declaration of
|
||||||
|
// FBT_VECTOR_STRING_DEPRECATED above for details.
|
||||||
|
// We change the type here to be keys, which are a subtype of strings,
|
||||||
|
// and will ignore the size field. This will truncate strings with
|
||||||
|
// embedded nulls.
|
||||||
|
tv.type_ = FBT_KEY;
|
||||||
|
}
|
||||||
|
return tv;
|
||||||
} else {
|
} else {
|
||||||
return TypedVector::EmptyTypedVector();
|
return TypedVector::EmptyTypedVector();
|
||||||
}
|
}
|
||||||
@@ -723,9 +771,15 @@ template<> inline int32_t Reference::As<int32_t>() const { return AsInt32(); }
|
|||||||
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
|
template<> inline int64_t Reference::As<int64_t>() const { return AsInt64(); }
|
||||||
|
|
||||||
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
|
template<> inline uint8_t Reference::As<uint8_t>() const { return AsUInt8(); }
|
||||||
template<> inline uint16_t Reference::As<uint16_t>() const { return AsUInt16(); }
|
template<> inline uint16_t Reference::As<uint16_t>() const {
|
||||||
template<> inline uint32_t Reference::As<uint32_t>() const { return AsUInt32(); }
|
return AsUInt16();
|
||||||
template<> inline uint64_t Reference::As<uint64_t>() const { return AsUInt64(); }
|
}
|
||||||
|
template<> inline uint32_t Reference::As<uint32_t>() const {
|
||||||
|
return AsUInt32();
|
||||||
|
}
|
||||||
|
template<> inline uint64_t Reference::As<uint64_t>() const {
|
||||||
|
return AsUInt64();
|
||||||
|
}
|
||||||
|
|
||||||
template<> inline double Reference::As<double>() const { return AsDouble(); }
|
template<> inline double Reference::As<double>() const { return AsDouble(); }
|
||||||
template<> inline float Reference::As<float>() const { return AsFloat(); }
|
template<> inline float Reference::As<float>() const { return AsFloat(); }
|
||||||
@@ -1046,7 +1100,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
for (auto key = start; key < stack_.size(); key += 2) {
|
for (auto key = start; key < stack_.size(); key += 2) {
|
||||||
FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
|
FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
|
||||||
}
|
}
|
||||||
// Now sort values, so later we can do a binary seach lookup.
|
// Now sort values, so later we can do a binary search lookup.
|
||||||
// We want to sort 2 array elements at a time.
|
// We want to sort 2 array elements at a time.
|
||||||
struct TwoValue {
|
struct TwoValue {
|
||||||
Value key;
|
Value key;
|
||||||
@@ -1194,6 +1248,24 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
EndMap(start);
|
EndMap(start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If you wish to share a value explicitly (a value not shared automatically
|
||||||
|
// through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these
|
||||||
|
// functions. Or if you wish to turn those flags off for performance reasons
|
||||||
|
// and still do some explicit sharing. For example:
|
||||||
|
// builder.IndirectDouble(M_PI);
|
||||||
|
// auto id = builder.LastValue(); // Remember where we stored it.
|
||||||
|
// .. more code goes here ..
|
||||||
|
// builder.ReuseValue(id); // Refers to same double by offset.
|
||||||
|
// LastValue works regardless of wether the value has a key or not.
|
||||||
|
// Works on any data type.
|
||||||
|
struct Value;
|
||||||
|
Value LastValue() { return stack_.back(); }
|
||||||
|
void ReuseValue(Value v) { stack_.push_back(v); }
|
||||||
|
void ReuseValue(const char *key, Value v) {
|
||||||
|
Key(key);
|
||||||
|
ReuseValue(v);
|
||||||
|
}
|
||||||
|
|
||||||
// Overloaded Add that tries to call the correct function above.
|
// Overloaded Add that tries to call the correct function above.
|
||||||
void Add(int8_t i) { Int(i); }
|
void Add(int8_t i) { Int(i); }
|
||||||
void Add(int16_t i) { Int(i); }
|
void Add(int16_t i) { Int(i); }
|
||||||
@@ -1319,6 +1391,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
: FBT_INT);
|
: FBT_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
// This was really intended to be private, except for LastValue/ReuseValue.
|
||||||
struct Value {
|
struct Value {
|
||||||
union {
|
union {
|
||||||
int64_t i_;
|
int64_t i_;
|
||||||
@@ -1388,6 +1462,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
void WriteAny(const Value &val, uint8_t byte_width) {
|
void WriteAny(const Value &val, uint8_t byte_width) {
|
||||||
switch (val.type_) {
|
switch (val.type_) {
|
||||||
case FBT_NULL:
|
case FBT_NULL:
|
||||||
@@ -1420,6 +1495,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
// TODO: instead of asserting, could write vector with larger elements
|
// TODO: instead of asserting, could write vector with larger elements
|
||||||
// instead, though that would be wasteful.
|
// instead, though that would be wasteful.
|
||||||
FLATBUFFERS_ASSERT(WidthU(len) <= bit_width);
|
FLATBUFFERS_ASSERT(WidthU(len) <= bit_width);
|
||||||
|
Align(bit_width);
|
||||||
if (!fixed) Write<uint64_t>(len, byte_width);
|
if (!fixed) Write<uint64_t>(len, byte_width);
|
||||||
auto vloc = buf_.size();
|
auto vloc = buf_.size();
|
||||||
for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
|
for (size_t i = 0; i < len; i++) Write(elems[i], byte_width);
|
||||||
@@ -1431,7 +1507,9 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
|
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
|
||||||
bool fixed, const Value *keys = nullptr) {
|
bool fixed, const Value *keys = nullptr) {
|
||||||
FLATBUFFERS_ASSERT(!fixed || typed); // typed=false, fixed=true combination is not supported.
|
FLATBUFFERS_ASSERT(
|
||||||
|
!fixed ||
|
||||||
|
typed); // typed=false, fixed=true combination is not supported.
|
||||||
// Figure out smallest bit width we can store this vector with.
|
// Figure out smallest bit width we can store this vector with.
|
||||||
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
|
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
|
||||||
auto prefix_elems = 1;
|
auto prefix_elems = 1;
|
||||||
@@ -1511,7 +1589,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
typedef std::pair<size_t, size_t> StringOffset;
|
typedef std::pair<size_t, size_t> StringOffset;
|
||||||
struct StringOffsetCompare {
|
struct StringOffsetCompare {
|
||||||
explicit StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
|
explicit StringOffsetCompare(const std::vector<uint8_t> &buf)
|
||||||
|
: buf_(&buf) {}
|
||||||
bool operator()(const StringOffset &a, const StringOffset &b) const {
|
bool operator()(const StringOffset &a, const StringOffset &b) const {
|
||||||
auto stra = reinterpret_cast<const char *>(
|
auto stra = reinterpret_cast<const char *>(
|
||||||
flatbuffers::vector_data(*buf_) + a.first);
|
flatbuffers::vector_data(*buf_) + a.first);
|
||||||
@@ -1531,8 +1610,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
} // namespace flexbuffers
|
} // namespace flexbuffers
|
||||||
|
|
||||||
# if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
# pragma warning(pop)
|
# pragma warning(pop)
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
#endif // FLATBUFFERS_FLEXBUFFERS_H_
|
#endif // FLATBUFFERS_FLEXBUFFERS_H_
|
||||||
|
|||||||
@@ -88,8 +88,7 @@ class SliceAllocator : public Allocator {
|
|||||||
SliceAllocator(const SliceAllocator &other) = delete;
|
SliceAllocator(const SliceAllocator &other) = delete;
|
||||||
SliceAllocator &operator=(const SliceAllocator &other) = delete;
|
SliceAllocator &operator=(const SliceAllocator &other) = delete;
|
||||||
|
|
||||||
SliceAllocator(SliceAllocator &&other)
|
SliceAllocator(SliceAllocator &&other) : slice_(grpc_empty_slice()) {
|
||||||
: slice_(grpc_empty_slice()) {
|
|
||||||
// default-construct and swap idiom
|
// default-construct and swap idiom
|
||||||
swap(other);
|
swap(other);
|
||||||
}
|
}
|
||||||
@@ -164,34 +163,36 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
public FlatBufferBuilder {
|
public FlatBufferBuilder {
|
||||||
public:
|
public:
|
||||||
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
explicit MessageBuilder(uoffset_t initial_size = 1024)
|
||||||
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
: FlatBufferBuilder(initial_size, &slice_allocator_, false) {}
|
||||||
|
|
||||||
MessageBuilder(const MessageBuilder &other) = delete;
|
MessageBuilder(const MessageBuilder &other) = delete;
|
||||||
MessageBuilder &operator=(const MessageBuilder &other) = delete;
|
MessageBuilder &operator=(const MessageBuilder &other) = delete;
|
||||||
|
|
||||||
MessageBuilder(MessageBuilder &&other)
|
MessageBuilder(MessageBuilder &&other)
|
||||||
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
||||||
// Default construct and swap idiom.
|
// Default construct and swap idiom.
|
||||||
Swap(other);
|
Swap(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a MessageBuilder from a FlatBufferBuilder.
|
/// Create a MessageBuilder from a FlatBufferBuilder.
|
||||||
explicit MessageBuilder(FlatBufferBuilder &&src, void (*dealloc)(void*, size_t) = &DefaultAllocator::dealloc)
|
explicit MessageBuilder(FlatBufferBuilder &&src,
|
||||||
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
void (*dealloc)(void *,
|
||||||
|
size_t) = &DefaultAllocator::dealloc)
|
||||||
|
: FlatBufferBuilder(1024, &slice_allocator_, false) {
|
||||||
src.Swap(*this);
|
src.Swap(*this);
|
||||||
src.SwapBufAllocator(*this);
|
src.SwapBufAllocator(*this);
|
||||||
if (buf_.capacity()) {
|
if (buf_.capacity()) {
|
||||||
uint8_t *buf = buf_.scratch_data(); // pointer to memory
|
uint8_t *buf = buf_.scratch_data(); // pointer to memory
|
||||||
size_t capacity = buf_.capacity(); // size of memory
|
size_t capacity = buf_.capacity(); // size of memory
|
||||||
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
|
slice_allocator_.slice_ = grpc_slice_new_with_len(buf, capacity, dealloc);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
slice_allocator_.slice_ = grpc_empty_slice();
|
slice_allocator_.slice_ = grpc_empty_slice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
|
/// Move-assign a FlatBufferBuilder to a MessageBuilder.
|
||||||
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is supported.
|
/// Only FlatBufferBuilder with default allocator (basically, nullptr) is
|
||||||
|
/// supported.
|
||||||
MessageBuilder &operator=(FlatBufferBuilder &&src) {
|
MessageBuilder &operator=(FlatBufferBuilder &&src) {
|
||||||
// Move construct a temporary and swap
|
// Move construct a temporary and swap
|
||||||
MessageBuilder temp(std::move(src));
|
MessageBuilder temp(std::move(src));
|
||||||
@@ -209,10 +210,11 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
void Swap(MessageBuilder &other) {
|
void Swap(MessageBuilder &other) {
|
||||||
slice_allocator_.swap(other.slice_allocator_);
|
slice_allocator_.swap(other.slice_allocator_);
|
||||||
FlatBufferBuilder::Swap(other);
|
FlatBufferBuilder::Swap(other);
|
||||||
// After swapping the FlatBufferBuilder, we swap back the allocator, which restores
|
// After swapping the FlatBufferBuilder, we swap back the allocator, which
|
||||||
// the original allocator back in place. This is necessary because MessageBuilder's
|
// restores the original allocator back in place. This is necessary because
|
||||||
// allocator is its own member (SliceAllocatorMember). The allocator passed to
|
// MessageBuilder's allocator is its own member (SliceAllocatorMember). The
|
||||||
// FlatBufferBuilder::vector_downward must point to this member.
|
// allocator passed to FlatBufferBuilder::vector_downward must point to this
|
||||||
|
// member.
|
||||||
buf_.swap_allocator(other.buf_);
|
buf_.swap_allocator(other.buf_);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,10 +234,10 @@ class MessageBuilder : private detail::SliceAllocatorMember,
|
|||||||
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
|
// flatbuffers-encoded region and wraps it in a `Message<T>` to handle buffer
|
||||||
// ownership.
|
// ownership.
|
||||||
template<class T> Message<T> GetMessage() {
|
template<class T> Message<T> GetMessage() {
|
||||||
auto buf_data = buf_.scratch_data(); // pointer to memory
|
auto buf_data = buf_.scratch_data(); // pointer to memory
|
||||||
auto buf_size = buf_.capacity(); // size of memory
|
auto buf_size = buf_.capacity(); // size of memory
|
||||||
auto msg_data = buf_.data(); // pointer to msg
|
auto msg_data = buf_.data(); // pointer to msg
|
||||||
auto msg_size = buf_.size(); // size of msg
|
auto msg_size = buf_.size(); // size of msg
|
||||||
// Do some sanity checks on data/size
|
// Do some sanity checks on data/size
|
||||||
FLATBUFFERS_ASSERT(msg_data);
|
FLATBUFFERS_ASSERT(msg_data);
|
||||||
FLATBUFFERS_ASSERT(msg_size);
|
FLATBUFFERS_ASSERT(msg_size);
|
||||||
@@ -274,7 +276,7 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
|||||||
grpc_byte_buffer **buffer, bool *own_buffer) {
|
grpc_byte_buffer **buffer, bool *own_buffer) {
|
||||||
// We are passed in a `Message<T>`, which is a wrapper around a
|
// We are passed in a `Message<T>`, which is a wrapper around a
|
||||||
// `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast
|
// `grpc_slice`. We extract it here using `BorrowSlice()`. The const cast
|
||||||
// is necesary because the `grpc_raw_byte_buffer_create` func expects
|
// is necessary because the `grpc_raw_byte_buffer_create` func expects
|
||||||
// non-const slices in order to increment their refcounts.
|
// non-const slices in order to increment their refcounts.
|
||||||
grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice());
|
grpc_slice *slice = const_cast<grpc_slice *>(&msg.BorrowSlice());
|
||||||
// Now use `grpc_raw_byte_buffer_create` to package the single slice into a
|
// Now use `grpc_raw_byte_buffer_create` to package the single slice into a
|
||||||
@@ -306,7 +308,7 @@ template<class T> class SerializationTraits<flatbuffers::grpc::Message<T>> {
|
|||||||
grpc_byte_buffer_reader_init(&reader, buffer);
|
grpc_byte_buffer_reader_init(&reader, buffer);
|
||||||
grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
|
grpc_slice slice = grpc_byte_buffer_reader_readall(&reader);
|
||||||
grpc_byte_buffer_reader_destroy(&reader);
|
grpc_byte_buffer_reader_destroy(&reader);
|
||||||
// We wrap a `Message<T>` around the slice, but dont increment refcount
|
// We wrap a `Message<T>` around the slice, but don't increment refcount
|
||||||
*msg = flatbuffers::grpc::Message<T>(slice, false);
|
*msg = flatbuffers::grpc::Message<T>(slice, false);
|
||||||
}
|
}
|
||||||
grpc_byte_buffer_destroy(buffer);
|
grpc_byte_buffer_destroy(buffer);
|
||||||
|
|||||||
@@ -57,17 +57,17 @@ template<typename T> T HashFnv1a(const char *input) {
|
|||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline uint16_t HashFnv1<uint16_t>(const char *input) {
|
template<> inline uint16_t HashFnv1<uint16_t>(const char *input) {
|
||||||
uint32_t hash = HashFnv1<uint32_t>(input);
|
uint32_t hash = HashFnv1<uint32_t>(input);
|
||||||
return (hash >> 16) ^ (hash & 0xffff);
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
|
template<> inline uint16_t HashFnv1a<uint16_t>(const char *input) {
|
||||||
uint32_t hash = HashFnv1a<uint32_t>(input);
|
uint32_t hash = HashFnv1a<uint32_t>(input);
|
||||||
return (hash >> 16) ^ (hash & 0xffff);
|
return (hash >> 16) ^ (hash & 0xffff);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> struct NamedHashFunction {
|
template<typename T> struct NamedHashFunction {
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
typedef T (*HashFunction)(const char *);
|
typedef T (*HashFunction)(const char *);
|
||||||
@@ -75,7 +75,7 @@ template <typename T> struct NamedHashFunction {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
|
const NamedHashFunction<uint16_t> kHashFunctions16[] = {
|
||||||
{ "fnv1_16", HashFnv1<uint16_t> },
|
{ "fnv1_16", HashFnv1<uint16_t> },
|
||||||
{ "fnv1a_16", HashFnv1a<uint16_t> },
|
{ "fnv1a_16", HashFnv1a<uint16_t> },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -47,25 +47,26 @@ namespace flatbuffers {
|
|||||||
// of type tokens.
|
// of type tokens.
|
||||||
// clang-format off
|
// clang-format off
|
||||||
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
|
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
|
||||||
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8) \
|
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \
|
||||||
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8) /* begin scalar/int */ \
|
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) /* begin scalar/int */ \
|
||||||
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool) \
|
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool) \
|
||||||
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8) \
|
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8) \
|
||||||
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8) \
|
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8) \
|
||||||
TD(SHORT, "short", int16_t, short, int16, short, int16, i16) \
|
TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16) \
|
||||||
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16) \
|
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16) \
|
||||||
TD(INT, "int", int32_t, int, int32, int, int32, i32) \
|
TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32) \
|
||||||
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32) \
|
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32) \
|
||||||
TD(LONG, "long", int64_t, long, int64, long, int64, i64) \
|
TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64) \
|
||||||
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64) /* end int */ \
|
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64) /* end int */ \
|
||||||
TD(FLOAT, "float", float, float, float32, float, float32, f32) /* begin float */ \
|
TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32) /* begin float */ \
|
||||||
TD(DOUBLE, "double", double, double, float64, double, float64, f64) /* end float/scalar */
|
TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double) /* end float/scalar */
|
||||||
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
|
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
|
||||||
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused) \
|
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>) \
|
||||||
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused) \
|
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>) \
|
||||||
TD(STRUCT, "", Offset<void>, int, int, int, int, unused) \
|
TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>) \
|
||||||
TD(UNION, "", Offset<void>, int, int, int, int, unused)
|
TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>)
|
||||||
|
#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
|
||||||
|
TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>)
|
||||||
// The fields are:
|
// The fields are:
|
||||||
// - enum
|
// - enum
|
||||||
// - FlatBuffers schema type.
|
// - FlatBuffers schema type.
|
||||||
@@ -75,13 +76,28 @@ namespace flatbuffers {
|
|||||||
// - C# / .Net type.
|
// - C# / .Net type.
|
||||||
// - Python type.
|
// - Python type.
|
||||||
// - Rust type.
|
// - Rust type.
|
||||||
|
// - Kotlin type.
|
||||||
|
|
||||||
// using these macros, we can now write code dealing with types just once, e.g.
|
// using these macros, we can now write code dealing with types just once, e.g.
|
||||||
|
|
||||||
/*
|
/*
|
||||||
switch (type) {
|
switch (type) {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
|
||||||
RTYPE) \
|
RTYPE, KTYPE) \
|
||||||
|
case BASE_TYPE_ ## ENUM: \
|
||||||
|
// do something specific to CTYPE here
|
||||||
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
|
#undef FLATBUFFERS_TD
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
// If not all FLATBUFFERS_GEN_() arguments are necessary for implementation
|
||||||
|
// of FLATBUFFERS_TD, you can use a variadic macro (with __VA_ARGS__ if needed).
|
||||||
|
// In the above example, only CTYPE is used to generate the code, it can be rewritten:
|
||||||
|
|
||||||
|
/*
|
||||||
|
switch (type) {
|
||||||
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: \
|
||||||
// do something specific to CTYPE here
|
// do something specific to CTYPE here
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
@@ -91,24 +107,23 @@ switch (type) {
|
|||||||
|
|
||||||
#define FLATBUFFERS_GEN_TYPES(TD) \
|
#define FLATBUFFERS_GEN_TYPES(TD) \
|
||||||
FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
|
FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
|
||||||
FLATBUFFERS_GEN_TYPES_POINTER(TD)
|
FLATBUFFERS_GEN_TYPES_POINTER(TD) \
|
||||||
|
FLATBUFFERS_GEN_TYPE_ARRAY(TD)
|
||||||
|
|
||||||
// Create an enum for all the types above.
|
// Create an enum for all the types above.
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
|
__extension__ // Stop GCC complaining about trailing comma with -Wpendantic.
|
||||||
#endif
|
#endif
|
||||||
enum BaseType {
|
enum BaseType {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
|
#define FLATBUFFERS_TD(ENUM, ...) \
|
||||||
RTYPE) \
|
BASE_TYPE_ ## ENUM,
|
||||||
BASE_TYPE_ ## ENUM,
|
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
|
||||||
RTYPE) \
|
static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
|
||||||
static_assert(sizeof(CTYPE) <= sizeof(largest_scalar_t), \
|
"define largest_scalar_t as " #CTYPE);
|
||||||
"define largest_scalar_t as " #CTYPE);
|
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
|
|
||||||
@@ -123,6 +138,13 @@ inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
|||||||
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
|
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
|
||||||
inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
|
inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
|
||||||
t <= BASE_TYPE_UCHAR; }
|
t <= BASE_TYPE_UCHAR; }
|
||||||
|
|
||||||
|
inline bool IsUnsigned(BaseType t) {
|
||||||
|
return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) ||
|
||||||
|
(t == BASE_TYPE_USHORT) || (t == BASE_TYPE_UINT) ||
|
||||||
|
(t == BASE_TYPE_ULONG);
|
||||||
|
}
|
||||||
|
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
extern const char *const kTypeNames[];
|
extern const char *const kTypeNames[];
|
||||||
@@ -138,18 +160,21 @@ class Parser;
|
|||||||
// and additional information for vectors/structs_.
|
// and additional information for vectors/structs_.
|
||||||
struct Type {
|
struct Type {
|
||||||
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
|
explicit Type(BaseType _base_type = BASE_TYPE_NONE, StructDef *_sd = nullptr,
|
||||||
EnumDef *_ed = nullptr)
|
EnumDef *_ed = nullptr, uint16_t _fixed_length = 0)
|
||||||
: base_type(_base_type),
|
: base_type(_base_type),
|
||||||
element(BASE_TYPE_NONE),
|
element(BASE_TYPE_NONE),
|
||||||
struct_def(_sd),
|
struct_def(_sd),
|
||||||
enum_def(_ed) {}
|
enum_def(_ed),
|
||||||
|
fixed_length(_fixed_length) {}
|
||||||
|
|
||||||
bool operator==(const Type &o) {
|
bool operator==(const Type &o) {
|
||||||
return base_type == o.base_type && element == o.element &&
|
return base_type == o.base_type && element == o.element &&
|
||||||
struct_def == o.struct_def && enum_def == o.enum_def;
|
struct_def == o.struct_def && enum_def == o.enum_def;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type VectorType() const { return Type(element, struct_def, enum_def); }
|
Type VectorType() const {
|
||||||
|
return Type(element, struct_def, enum_def, fixed_length);
|
||||||
|
}
|
||||||
|
|
||||||
Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
|
Offset<reflection::Type> Serialize(FlatBufferBuilder *builder) const;
|
||||||
|
|
||||||
@@ -160,6 +185,7 @@ struct Type {
|
|||||||
StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT
|
StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT
|
||||||
EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
|
EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
|
||||||
// or for an integral type derived from an enum.
|
// or for an integral type derived from an enum.
|
||||||
|
uint16_t fixed_length; // only set if t == BASE_TYPE_ARRAY
|
||||||
};
|
};
|
||||||
|
|
||||||
// Represents a parsed scalar value, it's type, and field offset.
|
// Represents a parsed scalar value, it's type, and field offset.
|
||||||
@@ -224,6 +250,15 @@ struct Namespace {
|
|||||||
size_t from_table; // Part of the namespace corresponds to a message/table.
|
size_t from_table; // Part of the namespace corresponds to a message/table.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool operator<(const Namespace &a, const Namespace &b) {
|
||||||
|
size_t min_size = std::min(a.components.size(), b.components.size());
|
||||||
|
for (size_t i = 0; i < min_size; ++i) {
|
||||||
|
if (a.components[i] != b.components[i])
|
||||||
|
return a.components[i] < b.components[i];
|
||||||
|
}
|
||||||
|
return a.components.size() < b.components.size();
|
||||||
|
}
|
||||||
|
|
||||||
// Base class for all definition types (fields, structs_, enums_).
|
// Base class for all definition types (fields, structs_, enums_).
|
||||||
struct Definition {
|
struct Definition {
|
||||||
Definition()
|
Definition()
|
||||||
@@ -315,64 +350,138 @@ struct StructDef : public Definition {
|
|||||||
flatbuffers::unique_ptr<std::string> original_location;
|
flatbuffers::unique_ptr<std::string> original_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsStruct(const Type &type) {
|
struct EnumDef;
|
||||||
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
|
struct EnumValBuilder;
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t InlineSize(const Type &type) {
|
|
||||||
return IsStruct(type) ? type.struct_def->bytesize : SizeOf(type.base_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t InlineAlignment(const Type &type) {
|
|
||||||
return IsStruct(type) ? type.struct_def->minalign : SizeOf(type.base_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct EnumVal {
|
struct EnumVal {
|
||||||
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
|
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder,
|
||||||
EnumVal() : value(0) {}
|
const Parser &parser) const;
|
||||||
|
|
||||||
Offset<reflection::EnumVal> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
|
|
||||||
|
|
||||||
bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
|
bool Deserialize(const Parser &parser, const reflection::EnumVal *val);
|
||||||
|
|
||||||
|
uint64_t GetAsUInt64() const { return static_cast<uint64_t>(value); }
|
||||||
|
int64_t GetAsInt64() const { return value; }
|
||||||
bool IsZero() const { return 0 == value; }
|
bool IsZero() const { return 0 == value; }
|
||||||
bool IsNonZero() const { return !IsZero(); }
|
bool IsNonZero() const { return !IsZero(); }
|
||||||
|
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::string> doc_comment;
|
std::vector<std::string> doc_comment;
|
||||||
int64_t value;
|
|
||||||
Type union_type;
|
Type union_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend EnumDef;
|
||||||
|
friend EnumValBuilder;
|
||||||
|
friend bool operator==(const EnumVal &lhs, const EnumVal &rhs);
|
||||||
|
|
||||||
|
EnumVal(const std::string &_name, int64_t _val) : name(_name), value(_val) {}
|
||||||
|
EnumVal() : value(0) {}
|
||||||
|
|
||||||
|
int64_t value;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EnumDef : public Definition {
|
struct EnumDef : public Definition {
|
||||||
EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
|
EnumDef() : is_union(false), uses_multiple_type_instances(false) {}
|
||||||
|
|
||||||
EnumVal *ReverseLookup(int64_t enum_idx, bool skip_union_default = true) {
|
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder,
|
||||||
for (auto it = Vals().begin() +
|
const Parser &parser) const;
|
||||||
static_cast<int>(is_union && skip_union_default);
|
|
||||||
it != Vals().end(); ++it) {
|
|
||||||
if ((*it)->value == enum_idx) { return *it; }
|
|
||||||
}
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Offset<reflection::Enum> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
|
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::Enum *values);
|
bool Deserialize(Parser &parser, const reflection::Enum *values);
|
||||||
|
|
||||||
|
template<typename T> void ChangeEnumValue(EnumVal *ev, T new_val);
|
||||||
|
void SortByValue();
|
||||||
|
void RemoveDuplicates();
|
||||||
|
|
||||||
|
std::string AllFlags() const;
|
||||||
|
const EnumVal *MinValue() const;
|
||||||
|
const EnumVal *MaxValue() const;
|
||||||
|
// Returns the number of integer steps from v1 to v2.
|
||||||
|
uint64_t Distance(const EnumVal *v1, const EnumVal *v2) const;
|
||||||
|
// Returns the number of integer steps from Min to Max.
|
||||||
|
uint64_t Distance() const { return Distance(MinValue(), MaxValue()); }
|
||||||
|
|
||||||
|
EnumVal *ReverseLookup(int64_t enum_idx,
|
||||||
|
bool skip_union_default = false) const;
|
||||||
|
EnumVal *FindByValue(const std::string &constant) const;
|
||||||
|
|
||||||
|
std::string ToString(const EnumVal &ev) const {
|
||||||
|
return IsUInt64() ? NumToString(ev.GetAsUInt64())
|
||||||
|
: NumToString(ev.GetAsInt64());
|
||||||
|
}
|
||||||
|
|
||||||
size_t size() const { return vals.vec.size(); }
|
size_t size() const { return vals.vec.size(); }
|
||||||
|
|
||||||
const std::vector<EnumVal *> &Vals() const {
|
const std::vector<EnumVal *> &Vals() const {
|
||||||
return vals.vec;
|
return vals.vec;
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolTable<EnumVal> vals;
|
const EnumVal *Lookup(const std::string &enum_name) const {
|
||||||
|
return vals.Lookup(enum_name);
|
||||||
|
}
|
||||||
|
|
||||||
bool is_union;
|
bool is_union;
|
||||||
// Type is a union which uses type aliases where at least one type is
|
// Type is a union which uses type aliases where at least one type is
|
||||||
// available under two different names.
|
// available under two different names.
|
||||||
bool uses_multiple_type_instances;
|
bool uses_multiple_type_instances;
|
||||||
Type underlying_type;
|
Type underlying_type;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool IsUInt64() const {
|
||||||
|
return (BASE_TYPE_ULONG == underlying_type.base_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
friend EnumValBuilder;
|
||||||
|
SymbolTable<EnumVal> vals;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline bool IsStruct(const Type &type) {
|
||||||
|
return type.base_type == BASE_TYPE_STRUCT && type.struct_def->fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsUnion(const Type &type) {
|
||||||
|
return type.enum_def != nullptr && type.enum_def->is_union;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsVector(const Type &type) {
|
||||||
|
return type.base_type == BASE_TYPE_VECTOR;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsArray(const Type &type) {
|
||||||
|
return type.base_type == BASE_TYPE_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsSeries(const Type &type) {
|
||||||
|
return IsVector(type) || IsArray(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool IsEnum(const Type &type) {
|
||||||
|
return type.enum_def != nullptr && IsInteger(type.base_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t InlineSize(const Type &type) {
|
||||||
|
return IsStruct(type)
|
||||||
|
? type.struct_def->bytesize
|
||||||
|
: (IsArray(type)
|
||||||
|
? InlineSize(type.VectorType()) * type.fixed_length
|
||||||
|
: SizeOf(type.base_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline size_t InlineAlignment(const Type &type) {
|
||||||
|
if (IsStruct(type)) {
|
||||||
|
return type.struct_def->minalign;
|
||||||
|
} else if (IsArray(type)) {
|
||||||
|
return IsStruct(type.VectorType()) ? type.struct_def->minalign
|
||||||
|
: SizeOf(type.element);
|
||||||
|
} else {
|
||||||
|
return SizeOf(type.base_type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
inline bool operator==(const EnumVal &lhs, const EnumVal &rhs) {
|
||||||
|
return lhs.value == rhs.value;
|
||||||
|
}
|
||||||
|
inline bool operator!=(const EnumVal &lhs, const EnumVal &rhs) {
|
||||||
|
return !(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
inline bool EqualByName(const Type &a, const Type &b) {
|
inline bool EqualByName(const Type &a, const Type &b) {
|
||||||
return a.base_type == b.base_type && a.element == b.element &&
|
return a.base_type == b.base_type && a.element == b.element &&
|
||||||
(a.struct_def == b.struct_def ||
|
(a.struct_def == b.struct_def ||
|
||||||
@@ -381,7 +490,8 @@ inline bool EqualByName(const Type &a, const Type &b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RPCCall : public Definition {
|
struct RPCCall : public Definition {
|
||||||
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
|
Offset<reflection::RPCCall> Serialize(FlatBufferBuilder *builder,
|
||||||
|
const Parser &parser) const;
|
||||||
|
|
||||||
bool Deserialize(Parser &parser, const reflection::RPCCall *call);
|
bool Deserialize(Parser &parser, const reflection::RPCCall *call);
|
||||||
|
|
||||||
@@ -389,7 +499,8 @@ struct RPCCall : public Definition {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ServiceDef : public Definition {
|
struct ServiceDef : public Definition {
|
||||||
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder, const Parser &parser) const;
|
Offset<reflection::Service> Serialize(FlatBufferBuilder *builder,
|
||||||
|
const Parser &parser) const;
|
||||||
bool Deserialize(Parser &parser, const reflection::Service *service);
|
bool Deserialize(Parser &parser, const reflection::Service *service);
|
||||||
|
|
||||||
SymbolTable<RPCCall> calls;
|
SymbolTable<RPCCall> calls;
|
||||||
@@ -397,6 +508,8 @@ struct ServiceDef : public Definition {
|
|||||||
|
|
||||||
// Container of options that may apply to any of the source/text generators.
|
// Container of options that may apply to any of the source/text generators.
|
||||||
struct IDLOptions {
|
struct IDLOptions {
|
||||||
|
// Use flexbuffers instead for binary and text generation
|
||||||
|
bool use_flexbuffers;
|
||||||
bool strict_json;
|
bool strict_json;
|
||||||
bool skip_js_exports;
|
bool skip_js_exports;
|
||||||
bool use_goog_js_export_format;
|
bool use_goog_js_export_format;
|
||||||
@@ -420,6 +533,7 @@ struct IDLOptions {
|
|||||||
std::string cpp_object_api_string_type;
|
std::string cpp_object_api_string_type;
|
||||||
bool cpp_object_api_string_flexible_constructor;
|
bool cpp_object_api_string_flexible_constructor;
|
||||||
bool gen_nullable;
|
bool gen_nullable;
|
||||||
|
bool java_checkerframework;
|
||||||
bool gen_generated;
|
bool gen_generated;
|
||||||
std::string object_prefix;
|
std::string object_prefix;
|
||||||
std::string object_suffix;
|
std::string object_suffix;
|
||||||
@@ -430,6 +544,7 @@ struct IDLOptions {
|
|||||||
bool keep_include_path;
|
bool keep_include_path;
|
||||||
bool binary_schema_comments;
|
bool binary_schema_comments;
|
||||||
bool binary_schema_builtins;
|
bool binary_schema_builtins;
|
||||||
|
bool binary_schema_gen_embed;
|
||||||
bool skip_flatbuffers_import;
|
bool skip_flatbuffers_import;
|
||||||
std::string go_import;
|
std::string go_import;
|
||||||
std::string go_namespace;
|
std::string go_namespace;
|
||||||
@@ -439,6 +554,13 @@ struct IDLOptions {
|
|||||||
bool size_prefixed;
|
bool size_prefixed;
|
||||||
std::string root_type;
|
std::string root_type;
|
||||||
bool force_defaults;
|
bool force_defaults;
|
||||||
|
bool java_primitive_has_method;
|
||||||
|
bool cs_gen_json_serializer;
|
||||||
|
std::vector<std::string> cpp_includes;
|
||||||
|
std::string cpp_std;
|
||||||
|
std::string proto_namespace_suffix;
|
||||||
|
std::string filename_suffix;
|
||||||
|
std::string filename_extension;
|
||||||
|
|
||||||
// Possible options for the more general generator below.
|
// Possible options for the more general generator below.
|
||||||
enum Language {
|
enum Language {
|
||||||
@@ -457,6 +579,8 @@ struct IDLOptions {
|
|||||||
kLua = 1 << 12,
|
kLua = 1 << 12,
|
||||||
kLobster = 1 << 13,
|
kLobster = 1 << 13,
|
||||||
kRust = 1 << 14,
|
kRust = 1 << 14,
|
||||||
|
kKotlin = 1 << 15,
|
||||||
|
kSwift = 1 << 16,
|
||||||
kMAX
|
kMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -470,12 +594,17 @@ struct IDLOptions {
|
|||||||
// for code generation.
|
// for code generation.
|
||||||
unsigned long lang_to_generate;
|
unsigned long lang_to_generate;
|
||||||
|
|
||||||
// If set (default behavior), empty string and vector fields will be set to
|
// If set (default behavior), empty string fields will be set to nullptr to
|
||||||
// nullptr to make the flatbuffer more compact.
|
// make the flatbuffer more compact.
|
||||||
bool set_empty_to_null;
|
bool set_empty_strings_to_null;
|
||||||
|
|
||||||
|
// If set (default behavior), empty vector fields will be set to nullptr to
|
||||||
|
// make the flatbuffer more compact.
|
||||||
|
bool set_empty_vectors_to_null;
|
||||||
|
|
||||||
IDLOptions()
|
IDLOptions()
|
||||||
: strict_json(false),
|
: use_flexbuffers(false),
|
||||||
|
strict_json(false),
|
||||||
skip_js_exports(false),
|
skip_js_exports(false),
|
||||||
use_goog_js_export_format(false),
|
use_goog_js_export_format(false),
|
||||||
use_ES6_js_export_format(false),
|
use_ES6_js_export_format(false),
|
||||||
@@ -497,6 +626,7 @@ struct IDLOptions {
|
|||||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||||
cpp_object_api_string_flexible_constructor(false),
|
cpp_object_api_string_flexible_constructor(false),
|
||||||
gen_nullable(false),
|
gen_nullable(false),
|
||||||
|
java_checkerframework(false),
|
||||||
gen_generated(false),
|
gen_generated(false),
|
||||||
object_suffix("T"),
|
object_suffix("T"),
|
||||||
union_value_namespacing(true),
|
union_value_namespacing(true),
|
||||||
@@ -505,16 +635,22 @@ struct IDLOptions {
|
|||||||
keep_include_path(false),
|
keep_include_path(false),
|
||||||
binary_schema_comments(false),
|
binary_schema_comments(false),
|
||||||
binary_schema_builtins(false),
|
binary_schema_builtins(false),
|
||||||
|
binary_schema_gen_embed(false),
|
||||||
skip_flatbuffers_import(false),
|
skip_flatbuffers_import(false),
|
||||||
reexport_ts_modules(true),
|
reexport_ts_modules(true),
|
||||||
js_ts_short_names(false),
|
js_ts_short_names(false),
|
||||||
protobuf_ascii_alike(false),
|
protobuf_ascii_alike(false),
|
||||||
size_prefixed(false),
|
size_prefixed(false),
|
||||||
force_defaults(false),
|
force_defaults(false),
|
||||||
|
java_primitive_has_method(false),
|
||||||
|
cs_gen_json_serializer(false),
|
||||||
|
filename_suffix("_generated"),
|
||||||
|
filename_extension(),
|
||||||
lang(IDLOptions::kJava),
|
lang(IDLOptions::kJava),
|
||||||
mini_reflect(IDLOptions::kNone),
|
mini_reflect(IDLOptions::kNone),
|
||||||
lang_to_generate(0),
|
lang_to_generate(0),
|
||||||
set_empty_to_null(true) {}
|
set_empty_strings_to_null(true),
|
||||||
|
set_empty_vectors_to_null(true) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This encapsulates where the parser is in the current source file.
|
// This encapsulates where the parser is in the current source file.
|
||||||
@@ -607,15 +743,14 @@ class Parser : public ParserState {
|
|||||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
explicit Parser(const IDLOptions &options = IDLOptions())
|
||||||
: current_namespace_(nullptr),
|
: current_namespace_(nullptr),
|
||||||
empty_namespace_(nullptr),
|
empty_namespace_(nullptr),
|
||||||
|
flex_builder_(256, flexbuffers::BUILDER_FLAG_SHARE_ALL),
|
||||||
root_struct_def_(nullptr),
|
root_struct_def_(nullptr),
|
||||||
opts(options),
|
opts(options),
|
||||||
uses_flexbuffers_(false),
|
uses_flexbuffers_(false),
|
||||||
source_(nullptr),
|
source_(nullptr),
|
||||||
anonymous_counter(0),
|
anonymous_counter(0),
|
||||||
recurse_protection_counter(0) {
|
recurse_protection_counter(0) {
|
||||||
if (opts.force_defaults) {
|
if (opts.force_defaults) { builder_.ForceDefaults(true); }
|
||||||
builder_.ForceDefaults(true);
|
|
||||||
}
|
|
||||||
// Start out with the empty namespace being current.
|
// Start out with the empty namespace being current.
|
||||||
empty_namespace_ = new Namespace();
|
empty_namespace_ = new Namespace();
|
||||||
namespaces_.push_back(empty_namespace_);
|
namespaces_.push_back(empty_namespace_);
|
||||||
@@ -686,9 +821,9 @@ class Parser : public ParserState {
|
|||||||
|
|
||||||
// Fills internal structure as if the schema passed had been loaded by parsing
|
// Fills internal structure as if the schema passed had been loaded by parsing
|
||||||
// with Parse except that included filenames will not be populated.
|
// with Parse except that included filenames will not be populated.
|
||||||
bool Deserialize(const reflection::Schema* schema);
|
bool Deserialize(const reflection::Schema *schema);
|
||||||
|
|
||||||
Type* DeserializeType(const reflection::Type* type);
|
Type *DeserializeType(const reflection::Type *type);
|
||||||
|
|
||||||
// Checks that the schema represented by this parser is a safe evolution
|
// Checks that the schema represented by this parser is a safe evolution
|
||||||
// of the schema provided. Returns non-empty error on any problems.
|
// of the schema provided. Returns non-empty error on any problems.
|
||||||
@@ -701,7 +836,7 @@ class Parser : public ParserState {
|
|||||||
|
|
||||||
StructDef *LookupStruct(const std::string &id) const;
|
StructDef *LookupStruct(const std::string &id) const;
|
||||||
|
|
||||||
std::string UnqualifiedName(std::string fullQualifiedName);
|
std::string UnqualifiedName(const std::string &fullQualifiedName);
|
||||||
|
|
||||||
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
||||||
|
|
||||||
@@ -738,20 +873,26 @@ class Parser : public ParserState {
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
||||||
std::string *value, uoffset_t *ovalue);
|
std::string *value, uoffset_t *ovalue);
|
||||||
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
||||||
|
void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
|
||||||
|
const Value &val);
|
||||||
template<typename F>
|
template<typename F>
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
|
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
|
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
|
||||||
FieldDef *field, size_t fieldn);
|
FieldDef *field, size_t fieldn);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field,
|
FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
|
||||||
size_t fieldn,
|
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(
|
||||||
const StructDef *parent_struct_def);
|
Value &val, FieldDef *field, size_t fieldn,
|
||||||
|
const StructDef *parent_struct_def);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
|
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
|
||||||
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken, bool check, Value &e,
|
FLATBUFFERS_CHECKED_ERROR TryTypedValue(const std::string *name, int dtoken,
|
||||||
BaseType req, bool *destmatch);
|
bool check, Value &e, BaseType req,
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef* field);
|
bool *destmatch);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseHash(Value &e, FieldDef *field);
|
||||||
FLATBUFFERS_CHECKED_ERROR TokenError();
|
FLATBUFFERS_CHECKED_ERROR TokenError();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e, bool check_now);
|
FLATBUFFERS_CHECKED_ERROR ParseSingleValue(const std::string *name, Value &e,
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type, std::string *result);
|
bool check_now);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseEnumFromString(const Type &type,
|
||||||
|
std::string *result);
|
||||||
StructDef *LookupCreateStruct(const std::string &name,
|
StructDef *LookupCreateStruct(const std::string &name,
|
||||||
bool create_if_new = true,
|
bool create_if_new = true,
|
||||||
bool definition = false);
|
bool definition = false);
|
||||||
@@ -759,8 +900,7 @@ class Parser : public ParserState {
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
|
FLATBUFFERS_CHECKED_ERROR ParseNamespace();
|
||||||
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
|
FLATBUFFERS_CHECKED_ERROR StartStruct(const std::string &name,
|
||||||
StructDef **dest);
|
StructDef **dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name,
|
FLATBUFFERS_CHECKED_ERROR StartEnum(const std::string &name, bool is_union,
|
||||||
bool is_union,
|
|
||||||
EnumDef **dest);
|
EnumDef **dest);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseDecl();
|
FLATBUFFERS_CHECKED_ERROR ParseDecl();
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseService();
|
FLATBUFFERS_CHECKED_ERROR ParseService();
|
||||||
@@ -776,18 +916,18 @@ class Parser : public ParserState {
|
|||||||
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
||||||
const char *source_filename);
|
const char *source_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
|
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
|
||||||
const char **include_paths,
|
const char **include_paths,
|
||||||
const char *source_filename);
|
const char *source_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
||||||
const char **include_paths,
|
const char **include_paths,
|
||||||
const char *source_filename,
|
const char *source_filename,
|
||||||
const char *include_filename);
|
const char *include_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
|
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef *> &fields,
|
||||||
StructDef *struct_def,
|
StructDef *struct_def,
|
||||||
const char *suffix,
|
const char *suffix, BaseType baseType);
|
||||||
BaseType baseType);
|
|
||||||
|
|
||||||
bool SupportsAdvancedUnionFeatures() const;
|
bool SupportsAdvancedUnionFeatures() const;
|
||||||
|
bool SupportsAdvancedArrayFeatures() const;
|
||||||
Namespace *UniqueNamespace(Namespace *ns);
|
Namespace *UniqueNamespace(Namespace *ns);
|
||||||
|
|
||||||
FLATBUFFERS_CHECKED_ERROR RecurseError();
|
FLATBUFFERS_CHECKED_ERROR RecurseError();
|
||||||
@@ -801,9 +941,11 @@ class Parser : public ParserState {
|
|||||||
std::vector<Namespace *> namespaces_;
|
std::vector<Namespace *> namespaces_;
|
||||||
Namespace *current_namespace_;
|
Namespace *current_namespace_;
|
||||||
Namespace *empty_namespace_;
|
Namespace *empty_namespace_;
|
||||||
std::string error_; // User readable error_ if Parse() == false
|
std::string error_; // User readable error_ if Parse() == false
|
||||||
|
|
||||||
FlatBufferBuilder builder_; // any data contained in the file
|
FlatBufferBuilder builder_; // any data contained in the file
|
||||||
|
flexbuffers::Builder flex_builder_;
|
||||||
|
flexbuffers::Reference flex_root_;
|
||||||
StructDef *root_struct_def_;
|
StructDef *root_struct_def_;
|
||||||
std::string file_identifier_;
|
std::string file_identifier_;
|
||||||
std::string file_extension_;
|
std::string file_extension_;
|
||||||
@@ -832,6 +974,8 @@ class Parser : public ParserState {
|
|||||||
|
|
||||||
extern std::string MakeCamel(const std::string &in, bool first = true);
|
extern std::string MakeCamel(const std::string &in, bool first = true);
|
||||||
|
|
||||||
|
extern std::string MakeScreamingCamel(const std::string &in);
|
||||||
|
|
||||||
// Generate text (JSON) from a given FlatBuffer, and a given Parser
|
// Generate text (JSON) from a given FlatBuffer, and a given Parser
|
||||||
// object that has been populated with the corresponding schema.
|
// object that has been populated with the corresponding schema.
|
||||||
// If ident_step is 0, no indentation will be generated. Additionally,
|
// If ident_step is 0, no indentation will be generated. Additionally,
|
||||||
@@ -840,156 +984,154 @@ extern std::string MakeCamel(const std::string &in, bool first = true);
|
|||||||
// strict_json adds "quotes" around field names if true.
|
// strict_json adds "quotes" around field names if true.
|
||||||
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
||||||
// byte arrays in String values), returns false.
|
// byte arrays in String values), returns false.
|
||||||
extern bool GenerateTextFromTable(const Parser &parser,
|
extern bool GenerateTextFromTable(const Parser &parser, const void *table,
|
||||||
const void *table,
|
|
||||||
const std::string &tablename,
|
const std::string &tablename,
|
||||||
std::string *text);
|
std::string *text);
|
||||||
extern bool GenerateText(const Parser &parser,
|
extern bool GenerateText(const Parser &parser, const void *flatbuffer,
|
||||||
const void *flatbuffer,
|
|
||||||
std::string *text);
|
std::string *text);
|
||||||
extern bool GenerateTextFile(const Parser &parser,
|
extern bool GenerateTextFile(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate binary files from a given FlatBuffer, and a given Parser
|
// Generate binary files from a given FlatBuffer, and a given Parser
|
||||||
// object that has been populated with the corresponding schema.
|
// object that has been populated with the corresponding schema.
|
||||||
// See idl_gen_general.cpp.
|
// See code_generators.cpp.
|
||||||
extern bool GenerateBinary(const Parser &parser,
|
extern bool GenerateBinary(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a C++ header from the definitions in the Parser object.
|
// Generate a C++ header from the definitions in the Parser object.
|
||||||
// See idl_gen_cpp.
|
// See idl_gen_cpp.
|
||||||
extern bool GenerateCPP(const Parser &parser,
|
extern bool GenerateCPP(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
extern bool GenerateDart(const Parser &parser,
|
// Generate C# files from the definitions in the Parser object.
|
||||||
const std::string &path,
|
// See idl_gen_csharp.cpp.
|
||||||
|
extern bool GenerateCSharp(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
|
extern bool GenerateDart(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate JavaScript or TypeScript code from the definitions in the Parser object.
|
// Generate Java files from the definitions in the Parser object.
|
||||||
// See idl_gen_js.
|
// See idl_gen_java.cpp.
|
||||||
extern bool GenerateJSTS(const Parser &parser,
|
extern bool GenerateJava(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name);
|
||||||
const std::string &file_name);
|
|
||||||
|
// Generate JavaScript or TypeScript code from the definitions in the Parser
|
||||||
|
// object. See idl_gen_js.
|
||||||
|
extern bool GenerateJSTS(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Go files from the definitions in the Parser object.
|
// Generate Go files from the definitions in the Parser object.
|
||||||
// See idl_gen_go.cpp.
|
// See idl_gen_go.cpp.
|
||||||
extern bool GenerateGo(const Parser &parser,
|
extern bool GenerateGo(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Php code from the definitions in the Parser object.
|
// Generate Php code from the definitions in the Parser object.
|
||||||
// See idl_gen_php.
|
// See idl_gen_php.
|
||||||
extern bool GeneratePhp(const Parser &parser,
|
extern bool GeneratePhp(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Python files from the definitions in the Parser object.
|
// Generate Python files from the definitions in the Parser object.
|
||||||
// See idl_gen_python.cpp.
|
// See idl_gen_python.cpp.
|
||||||
extern bool GeneratePython(const Parser &parser,
|
extern bool GeneratePython(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Lobster files from the definitions in the Parser object.
|
// Generate Lobster files from the definitions in the Parser object.
|
||||||
// See idl_gen_lobster.cpp.
|
// See idl_gen_lobster.cpp.
|
||||||
extern bool GenerateLobster(const Parser &parser,
|
extern bool GenerateLobster(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Lua files from the definitions in the Parser object.
|
// Generate Lua files from the definitions in the Parser object.
|
||||||
// See idl_gen_lua.cpp.
|
// See idl_gen_lua.cpp.
|
||||||
extern bool GenerateLua(const Parser &parser,
|
extern bool GenerateLua(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name);
|
||||||
const std::string &file_name);
|
|
||||||
|
|
||||||
// Generate Rust files from the definitions in the Parser object.
|
// Generate Rust files from the definitions in the Parser object.
|
||||||
// See idl_gen_rust.cpp.
|
// See idl_gen_rust.cpp.
|
||||||
extern bool GenerateRust(const Parser &parser,
|
extern bool GenerateRust(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Json schema file
|
// Generate Json schema file
|
||||||
// See idl_gen_json_schema.cpp.
|
// See idl_gen_json_schema.cpp.
|
||||||
extern bool GenerateJsonSchema(const Parser &parser,
|
extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name);
|
||||||
|
|
||||||
|
extern bool GenerateKotlin(const Parser &parser, const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate Java/C#/.. files from the definitions in the Parser object.
|
// Generate Swift classes.
|
||||||
// See idl_gen_general.cpp.
|
// See idl_gen_swift.cpp
|
||||||
extern bool GenerateGeneral(const Parser &parser,
|
extern bool GenerateSwift(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name);
|
||||||
const std::string &file_name);
|
|
||||||
|
|
||||||
// Generate a schema file from the internal representation, useful after
|
// Generate a schema file from the internal representation, useful after
|
||||||
// parsing a .proto schema.
|
// parsing a .proto schema.
|
||||||
extern std::string GenerateFBS(const Parser &parser,
|
extern std::string GenerateFBS(const Parser &parser,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
extern bool GenerateFBS(const Parser &parser,
|
extern bool GenerateFBS(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a make rule for the generated JavaScript or TypeScript code.
|
// Generate a make rule for the generated JavaScript or TypeScript code.
|
||||||
// See idl_gen_js.cpp.
|
// See idl_gen_js.cpp.
|
||||||
extern std::string JSTSMakeRule(const Parser &parser,
|
extern std::string JSTSMakeRule(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
const std::string &file_name);
|
||||||
const std::string &file_name);
|
|
||||||
|
|
||||||
// Generate a make rule for the generated C++ header.
|
// Generate a make rule for the generated C++ header.
|
||||||
// See idl_gen_cpp.cpp.
|
// See idl_gen_cpp.cpp.
|
||||||
extern std::string CPPMakeRule(const Parser &parser,
|
extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a make rule for the generated Dart code
|
// Generate a make rule for the generated Dart code
|
||||||
// see idl_gen_dart.cpp
|
// see idl_gen_dart.cpp
|
||||||
extern std::string DartMakeRule(const Parser &parser,
|
extern std::string DartMakeRule(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a make rule for the generated Rust code.
|
// Generate a make rule for the generated Rust code.
|
||||||
// See idl_gen_rust.cpp.
|
// See idl_gen_rust.cpp.
|
||||||
extern std::string RustMakeRule(const Parser &parser,
|
extern std::string RustMakeRule(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a make rule for the generated Java/C#/... files.
|
// Generate a make rule for generated Java or C# files.
|
||||||
// See idl_gen_general.cpp.
|
// See code_generators.cpp.
|
||||||
extern std::string GeneralMakeRule(const Parser &parser,
|
extern std::string JavaCSharpMakeRule(const Parser &parser,
|
||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate a make rule for the generated text (JSON) files.
|
// Generate a make rule for the generated text (JSON) files.
|
||||||
// See idl_gen_text.cpp.
|
// See idl_gen_text.cpp.
|
||||||
extern std::string TextMakeRule(const Parser &parser,
|
extern std::string TextMakeRule(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_names);
|
const std::string &file_names);
|
||||||
|
|
||||||
// Generate a make rule for the generated binary files.
|
// Generate a make rule for the generated binary files.
|
||||||
// See idl_gen_general.cpp.
|
// See code_generators.cpp.
|
||||||
extern std::string BinaryMakeRule(const Parser &parser,
|
extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate GRPC Cpp interfaces.
|
// Generate GRPC Cpp interfaces.
|
||||||
// See idl_gen_grpc.cpp.
|
// See idl_gen_grpc.cpp.
|
||||||
bool GenerateCppGRPC(const Parser &parser,
|
bool GenerateCppGRPC(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate GRPC Go interfaces.
|
// Generate GRPC Go interfaces.
|
||||||
// See idl_gen_grpc.cpp.
|
// See idl_gen_grpc.cpp.
|
||||||
bool GenerateGoGRPC(const Parser &parser,
|
bool GenerateGoGRPC(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate GRPC Java classes.
|
// Generate GRPC Java classes.
|
||||||
// See idl_gen_grpc.cpp
|
// See idl_gen_grpc.cpp
|
||||||
bool GenerateJavaGRPC(const Parser &parser,
|
bool GenerateJavaGRPC(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
|
// Generate GRPC Python interfaces.
|
||||||
|
// See idl_gen_grpc.cpp.
|
||||||
|
bool GeneratePythonGRPC(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
|
// Generate GRPC Swift interfaces.
|
||||||
|
// See idl_gen_grpc.cpp.
|
||||||
|
extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATBUFFERS_IDL_H_
|
#endif // FLATBUFFERS_IDL_H_
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
|||||||
switch (type_table->st) {
|
switch (type_table->st) {
|
||||||
case ST_TABLE:
|
case ST_TABLE:
|
||||||
case ST_UNION: return 4;
|
case ST_UNION: return 4;
|
||||||
case ST_STRUCT: return static_cast<size_t>(type_table->values[type_table->num_elems]);
|
case ST_STRUCT:
|
||||||
|
return static_cast<size_t>(type_table->values[type_table->num_elems]);
|
||||||
default: FLATBUFFERS_ASSERT(false); return 1;
|
default: FLATBUFFERS_ASSERT(false); return 1;
|
||||||
}
|
}
|
||||||
default: FLATBUFFERS_ASSERT(false); return 1;
|
default: FLATBUFFERS_ASSERT(false); return 1;
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ inline std::string GetAnyVectorElemS(const VectorOfAny *vec,
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
|
T *GetAnyVectorElemPointer(const VectorOfAny *vec, size_t i) {
|
||||||
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
|
auto elem_ptr = vec->Data() + sizeof(uoffset_t) * i;
|
||||||
return reinterpret_cast<T*>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
|
return reinterpret_cast<T *>(elem_ptr + ReadScalar<uoffset_t>(elem_ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the inline-address of a vector element. Useful for Structs (pass Struct
|
// Get the inline-address of a vector element. Useful for Structs (pass Struct
|
||||||
|
|||||||
@@ -9,22 +9,31 @@
|
|||||||
namespace reflection {
|
namespace reflection {
|
||||||
|
|
||||||
struct Type;
|
struct Type;
|
||||||
|
struct TypeBuilder;
|
||||||
|
|
||||||
struct KeyValue;
|
struct KeyValue;
|
||||||
|
struct KeyValueBuilder;
|
||||||
|
|
||||||
struct EnumVal;
|
struct EnumVal;
|
||||||
|
struct EnumValBuilder;
|
||||||
|
|
||||||
struct Enum;
|
struct Enum;
|
||||||
|
struct EnumBuilder;
|
||||||
|
|
||||||
struct Field;
|
struct Field;
|
||||||
|
struct FieldBuilder;
|
||||||
|
|
||||||
struct Object;
|
struct Object;
|
||||||
|
struct ObjectBuilder;
|
||||||
|
|
||||||
struct RPCCall;
|
struct RPCCall;
|
||||||
|
struct RPCCallBuilder;
|
||||||
|
|
||||||
struct Service;
|
struct Service;
|
||||||
|
struct ServiceBuilder;
|
||||||
|
|
||||||
struct Schema;
|
struct Schema;
|
||||||
|
struct SchemaBuilder;
|
||||||
|
|
||||||
enum BaseType {
|
enum BaseType {
|
||||||
None = 0,
|
None = 0,
|
||||||
@@ -43,10 +52,11 @@ enum BaseType {
|
|||||||
String = 13,
|
String = 13,
|
||||||
Vector = 14,
|
Vector = 14,
|
||||||
Obj = 15,
|
Obj = 15,
|
||||||
Union = 16
|
Union = 16,
|
||||||
|
Array = 17
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const BaseType (&EnumValuesBaseType())[17] {
|
inline const BaseType (&EnumValuesBaseType())[18] {
|
||||||
static const BaseType values[] = {
|
static const BaseType values[] = {
|
||||||
None,
|
None,
|
||||||
UType,
|
UType,
|
||||||
@@ -64,13 +74,14 @@ inline const BaseType (&EnumValuesBaseType())[17] {
|
|||||||
String,
|
String,
|
||||||
Vector,
|
Vector,
|
||||||
Obj,
|
Obj,
|
||||||
Union
|
Union,
|
||||||
|
Array
|
||||||
};
|
};
|
||||||
return values;
|
return values;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char * const *EnumNamesBaseType() {
|
inline const char * const *EnumNamesBaseType() {
|
||||||
static const char * const names[] = {
|
static const char * const names[19] = {
|
||||||
"None",
|
"None",
|
||||||
"UType",
|
"UType",
|
||||||
"Bool",
|
"Bool",
|
||||||
@@ -88,53 +99,64 @@ inline const char * const *EnumNamesBaseType() {
|
|||||||
"Vector",
|
"Vector",
|
||||||
"Obj",
|
"Obj",
|
||||||
"Union",
|
"Union",
|
||||||
|
"Array",
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
return names;
|
return names;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const char *EnumNameBaseType(BaseType e) {
|
inline const char *EnumNameBaseType(BaseType e) {
|
||||||
if (e < None || e > Union) return "";
|
if (flatbuffers::IsOutRange(e, None, Array)) return "";
|
||||||
const size_t index = static_cast<size_t>(e);
|
const size_t index = static_cast<size_t>(e);
|
||||||
return EnumNamesBaseType()[index];
|
return EnumNamesBaseType()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Type FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef TypeBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_BASE_TYPE = 4,
|
VT_BASE_TYPE = 4,
|
||||||
VT_ELEMENT = 6,
|
VT_ELEMENT = 6,
|
||||||
VT_INDEX = 8
|
VT_INDEX = 8,
|
||||||
|
VT_FIXED_LENGTH = 10
|
||||||
};
|
};
|
||||||
BaseType base_type() const {
|
reflection::BaseType base_type() const {
|
||||||
return static_cast<BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
|
return static_cast<reflection::BaseType>(GetField<int8_t>(VT_BASE_TYPE, 0));
|
||||||
}
|
}
|
||||||
BaseType element() const {
|
reflection::BaseType element() const {
|
||||||
return static_cast<BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
|
return static_cast<reflection::BaseType>(GetField<int8_t>(VT_ELEMENT, 0));
|
||||||
}
|
}
|
||||||
int32_t index() const {
|
int32_t index() const {
|
||||||
return GetField<int32_t>(VT_INDEX, -1);
|
return GetField<int32_t>(VT_INDEX, -1);
|
||||||
}
|
}
|
||||||
|
uint16_t fixed_length() const {
|
||||||
|
return GetField<uint16_t>(VT_FIXED_LENGTH, 0);
|
||||||
|
}
|
||||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
|
VerifyField<int8_t>(verifier, VT_BASE_TYPE) &&
|
||||||
VerifyField<int8_t>(verifier, VT_ELEMENT) &&
|
VerifyField<int8_t>(verifier, VT_ELEMENT) &&
|
||||||
VerifyField<int32_t>(verifier, VT_INDEX) &&
|
VerifyField<int32_t>(verifier, VT_INDEX) &&
|
||||||
|
VerifyField<uint16_t>(verifier, VT_FIXED_LENGTH) &&
|
||||||
verifier.EndTable();
|
verifier.EndTable();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeBuilder {
|
struct TypeBuilder {
|
||||||
|
typedef Type Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_base_type(BaseType base_type) {
|
void add_base_type(reflection::BaseType base_type) {
|
||||||
fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
|
fbb_.AddElement<int8_t>(Type::VT_BASE_TYPE, static_cast<int8_t>(base_type), 0);
|
||||||
}
|
}
|
||||||
void add_element(BaseType element) {
|
void add_element(reflection::BaseType element) {
|
||||||
fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
|
fbb_.AddElement<int8_t>(Type::VT_ELEMENT, static_cast<int8_t>(element), 0);
|
||||||
}
|
}
|
||||||
void add_index(int32_t index) {
|
void add_index(int32_t index) {
|
||||||
fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
|
fbb_.AddElement<int32_t>(Type::VT_INDEX, index, -1);
|
||||||
}
|
}
|
||||||
|
void add_fixed_length(uint16_t fixed_length) {
|
||||||
|
fbb_.AddElement<uint16_t>(Type::VT_FIXED_LENGTH, fixed_length, 0);
|
||||||
|
}
|
||||||
explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
explicit TypeBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
: fbb_(_fbb) {
|
: fbb_(_fbb) {
|
||||||
start_ = fbb_.StartTable();
|
start_ = fbb_.StartTable();
|
||||||
@@ -149,17 +171,20 @@ struct TypeBuilder {
|
|||||||
|
|
||||||
inline flatbuffers::Offset<Type> CreateType(
|
inline flatbuffers::Offset<Type> CreateType(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
BaseType base_type = None,
|
reflection::BaseType base_type = reflection::None,
|
||||||
BaseType element = None,
|
reflection::BaseType element = reflection::None,
|
||||||
int32_t index = -1) {
|
int32_t index = -1,
|
||||||
|
uint16_t fixed_length = 0) {
|
||||||
TypeBuilder builder_(_fbb);
|
TypeBuilder builder_(_fbb);
|
||||||
builder_.add_index(index);
|
builder_.add_index(index);
|
||||||
|
builder_.add_fixed_length(fixed_length);
|
||||||
builder_.add_element(element);
|
builder_.add_element(element);
|
||||||
builder_.add_base_type(base_type);
|
builder_.add_base_type(base_type);
|
||||||
return builder_.Finish();
|
return builder_.Finish();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef KeyValueBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_KEY = 4,
|
VT_KEY = 4,
|
||||||
VT_VALUE = 6
|
VT_VALUE = 6
|
||||||
@@ -187,6 +212,7 @@ struct KeyValue FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct KeyValueBuilder {
|
struct KeyValueBuilder {
|
||||||
|
typedef KeyValue Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_key(flatbuffers::Offset<flatbuffers::String> key) {
|
void add_key(flatbuffers::Offset<flatbuffers::String> key) {
|
||||||
@@ -231,6 +257,7 @@ inline flatbuffers::Offset<KeyValue> CreateKeyValueDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef EnumValBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_NAME = 4,
|
VT_NAME = 4,
|
||||||
VT_VALUE = 6,
|
VT_VALUE = 6,
|
||||||
@@ -250,11 +277,11 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int KeyCompareWithValue(int64_t val) const {
|
int KeyCompareWithValue(int64_t val) const {
|
||||||
return static_cast<int>(value() > val) - static_cast<int>(value() < val);
|
return static_cast<int>(value() > val) - static_cast<int>(value() < val);
|
||||||
}
|
}
|
||||||
const Object *object() const {
|
const reflection::Object *object() const {
|
||||||
return GetPointer<const Object *>(VT_OBJECT);
|
return GetPointer<const reflection::Object *>(VT_OBJECT);
|
||||||
}
|
}
|
||||||
const Type *union_type() const {
|
const reflection::Type *union_type() const {
|
||||||
return GetPointer<const Type *>(VT_UNION_TYPE);
|
return GetPointer<const reflection::Type *>(VT_UNION_TYPE);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||||
@@ -276,6 +303,7 @@ struct EnumVal FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct EnumValBuilder {
|
struct EnumValBuilder {
|
||||||
|
typedef EnumVal Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
@@ -284,10 +312,10 @@ struct EnumValBuilder {
|
|||||||
void add_value(int64_t value) {
|
void add_value(int64_t value) {
|
||||||
fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
|
fbb_.AddElement<int64_t>(EnumVal::VT_VALUE, value, 0);
|
||||||
}
|
}
|
||||||
void add_object(flatbuffers::Offset<Object> object) {
|
void add_object(flatbuffers::Offset<reflection::Object> object) {
|
||||||
fbb_.AddOffset(EnumVal::VT_OBJECT, object);
|
fbb_.AddOffset(EnumVal::VT_OBJECT, object);
|
||||||
}
|
}
|
||||||
void add_union_type(flatbuffers::Offset<Type> union_type) {
|
void add_union_type(flatbuffers::Offset<reflection::Type> union_type) {
|
||||||
fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
|
fbb_.AddOffset(EnumVal::VT_UNION_TYPE, union_type);
|
||||||
}
|
}
|
||||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||||
@@ -310,8 +338,8 @@ inline flatbuffers::Offset<EnumVal> CreateEnumVal(
|
|||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||||
int64_t value = 0,
|
int64_t value = 0,
|
||||||
flatbuffers::Offset<Object> object = 0,
|
flatbuffers::Offset<reflection::Object> object = 0,
|
||||||
flatbuffers::Offset<Type> union_type = 0,
|
flatbuffers::Offset<reflection::Type> union_type = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||||
EnumValBuilder builder_(_fbb);
|
EnumValBuilder builder_(_fbb);
|
||||||
builder_.add_value(value);
|
builder_.add_value(value);
|
||||||
@@ -326,8 +354,8 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
|
|||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const char *name = nullptr,
|
const char *name = nullptr,
|
||||||
int64_t value = 0,
|
int64_t value = 0,
|
||||||
flatbuffers::Offset<Object> object = 0,
|
flatbuffers::Offset<reflection::Object> object = 0,
|
||||||
flatbuffers::Offset<Type> union_type = 0,
|
flatbuffers::Offset<reflection::Type> union_type = 0,
|
||||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||||
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
||||||
@@ -341,6 +369,7 @@ inline flatbuffers::Offset<EnumVal> CreateEnumValDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef EnumBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_NAME = 4,
|
VT_NAME = 4,
|
||||||
VT_VALUES = 6,
|
VT_VALUES = 6,
|
||||||
@@ -358,17 +387,17 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int KeyCompareWithValue(const char *val) const {
|
int KeyCompareWithValue(const char *val) const {
|
||||||
return strcmp(name()->c_str(), val);
|
return strcmp(name()->c_str(), val);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<EnumVal>> *values() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *values() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<EnumVal>> *>(VT_VALUES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>> *>(VT_VALUES);
|
||||||
}
|
}
|
||||||
bool is_union() const {
|
bool is_union() const {
|
||||||
return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
|
return GetField<uint8_t>(VT_IS_UNION, 0) != 0;
|
||||||
}
|
}
|
||||||
const Type *underlying_type() const {
|
const reflection::Type *underlying_type() const {
|
||||||
return GetPointer<const Type *>(VT_UNDERLYING_TYPE);
|
return GetPointer<const reflection::Type *>(VT_UNDERLYING_TYPE);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||||
@@ -394,21 +423,22 @@ struct Enum FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct EnumBuilder {
|
struct EnumBuilder {
|
||||||
|
typedef Enum Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
fbb_.AddOffset(Enum::VT_NAME, name);
|
fbb_.AddOffset(Enum::VT_NAME, name);
|
||||||
}
|
}
|
||||||
void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values) {
|
void add_values(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values) {
|
||||||
fbb_.AddOffset(Enum::VT_VALUES, values);
|
fbb_.AddOffset(Enum::VT_VALUES, values);
|
||||||
}
|
}
|
||||||
void add_is_union(bool is_union) {
|
void add_is_union(bool is_union) {
|
||||||
fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
|
fbb_.AddElement<uint8_t>(Enum::VT_IS_UNION, static_cast<uint8_t>(is_union), 0);
|
||||||
}
|
}
|
||||||
void add_underlying_type(flatbuffers::Offset<Type> underlying_type) {
|
void add_underlying_type(flatbuffers::Offset<reflection::Type> underlying_type) {
|
||||||
fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
|
fbb_.AddOffset(Enum::VT_UNDERLYING_TYPE, underlying_type);
|
||||||
}
|
}
|
||||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
|
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
|
||||||
fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
|
fbb_.AddOffset(Enum::VT_ATTRIBUTES, attributes);
|
||||||
}
|
}
|
||||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||||
@@ -432,10 +462,10 @@ struct EnumBuilder {
|
|||||||
inline flatbuffers::Offset<Enum> CreateEnum(
|
inline flatbuffers::Offset<Enum> CreateEnum(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<EnumVal>>> values = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::EnumVal>>> values = 0,
|
||||||
bool is_union = false,
|
bool is_union = false,
|
||||||
flatbuffers::Offset<Type> underlying_type = 0,
|
flatbuffers::Offset<reflection::Type> underlying_type = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||||
EnumBuilder builder_(_fbb);
|
EnumBuilder builder_(_fbb);
|
||||||
builder_.add_documentation(documentation);
|
builder_.add_documentation(documentation);
|
||||||
@@ -450,14 +480,14 @@ inline flatbuffers::Offset<Enum> CreateEnum(
|
|||||||
inline flatbuffers::Offset<Enum> CreateEnumDirect(
|
inline flatbuffers::Offset<Enum> CreateEnumDirect(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const char *name = nullptr,
|
const char *name = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<EnumVal>> *values = nullptr,
|
std::vector<flatbuffers::Offset<reflection::EnumVal>> *values = nullptr,
|
||||||
bool is_union = false,
|
bool is_union = false,
|
||||||
flatbuffers::Offset<Type> underlying_type = 0,
|
flatbuffers::Offset<reflection::Type> underlying_type = 0,
|
||||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||||
auto values__ = values ? _fbb.CreateVector<flatbuffers::Offset<EnumVal>>(*values) : 0;
|
auto values__ = values ? _fbb.CreateVectorOfSortedTables<reflection::EnumVal>(values) : 0;
|
||||||
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
|
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
|
||||||
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
||||||
return reflection::CreateEnum(
|
return reflection::CreateEnum(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -470,6 +500,7 @@ inline flatbuffers::Offset<Enum> CreateEnumDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef FieldBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_NAME = 4,
|
VT_NAME = 4,
|
||||||
VT_TYPE = 6,
|
VT_TYPE = 6,
|
||||||
@@ -492,8 +523,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int KeyCompareWithValue(const char *val) const {
|
int KeyCompareWithValue(const char *val) const {
|
||||||
return strcmp(name()->c_str(), val);
|
return strcmp(name()->c_str(), val);
|
||||||
}
|
}
|
||||||
const Type *type() const {
|
const reflection::Type *type() const {
|
||||||
return GetPointer<const Type *>(VT_TYPE);
|
return GetPointer<const reflection::Type *>(VT_TYPE);
|
||||||
}
|
}
|
||||||
uint16_t id() const {
|
uint16_t id() const {
|
||||||
return GetField<uint16_t>(VT_ID, 0);
|
return GetField<uint16_t>(VT_ID, 0);
|
||||||
@@ -516,8 +547,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
bool key() const {
|
bool key() const {
|
||||||
return GetField<uint8_t>(VT_KEY, 0) != 0;
|
return GetField<uint8_t>(VT_KEY, 0) != 0;
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||||
@@ -546,12 +577,13 @@ struct Field FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct FieldBuilder {
|
struct FieldBuilder {
|
||||||
|
typedef Field Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
fbb_.AddOffset(Field::VT_NAME, name);
|
fbb_.AddOffset(Field::VT_NAME, name);
|
||||||
}
|
}
|
||||||
void add_type(flatbuffers::Offset<Type> type) {
|
void add_type(flatbuffers::Offset<reflection::Type> type) {
|
||||||
fbb_.AddOffset(Field::VT_TYPE, type);
|
fbb_.AddOffset(Field::VT_TYPE, type);
|
||||||
}
|
}
|
||||||
void add_id(uint16_t id) {
|
void add_id(uint16_t id) {
|
||||||
@@ -575,7 +607,7 @@ struct FieldBuilder {
|
|||||||
void add_key(bool key) {
|
void add_key(bool key) {
|
||||||
fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
|
fbb_.AddElement<uint8_t>(Field::VT_KEY, static_cast<uint8_t>(key), 0);
|
||||||
}
|
}
|
||||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
|
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
|
||||||
fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
|
fbb_.AddOffset(Field::VT_ATTRIBUTES, attributes);
|
||||||
}
|
}
|
||||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||||
@@ -598,7 +630,7 @@ struct FieldBuilder {
|
|||||||
inline flatbuffers::Offset<Field> CreateField(
|
inline flatbuffers::Offset<Field> CreateField(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||||
flatbuffers::Offset<Type> type = 0,
|
flatbuffers::Offset<reflection::Type> type = 0,
|
||||||
uint16_t id = 0,
|
uint16_t id = 0,
|
||||||
uint16_t offset = 0,
|
uint16_t offset = 0,
|
||||||
int64_t default_integer = 0,
|
int64_t default_integer = 0,
|
||||||
@@ -606,7 +638,7 @@ inline flatbuffers::Offset<Field> CreateField(
|
|||||||
bool deprecated = false,
|
bool deprecated = false,
|
||||||
bool required = false,
|
bool required = false,
|
||||||
bool key = false,
|
bool key = false,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||||
FieldBuilder builder_(_fbb);
|
FieldBuilder builder_(_fbb);
|
||||||
builder_.add_default_real(default_real);
|
builder_.add_default_real(default_real);
|
||||||
@@ -626,7 +658,7 @@ inline flatbuffers::Offset<Field> CreateField(
|
|||||||
inline flatbuffers::Offset<Field> CreateFieldDirect(
|
inline flatbuffers::Offset<Field> CreateFieldDirect(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const char *name = nullptr,
|
const char *name = nullptr,
|
||||||
flatbuffers::Offset<Type> type = 0,
|
flatbuffers::Offset<reflection::Type> type = 0,
|
||||||
uint16_t id = 0,
|
uint16_t id = 0,
|
||||||
uint16_t offset = 0,
|
uint16_t offset = 0,
|
||||||
int64_t default_integer = 0,
|
int64_t default_integer = 0,
|
||||||
@@ -634,10 +666,10 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
|
|||||||
bool deprecated = false,
|
bool deprecated = false,
|
||||||
bool required = false,
|
bool required = false,
|
||||||
bool key = false,
|
bool key = false,
|
||||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||||
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
|
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
|
||||||
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
||||||
return reflection::CreateField(
|
return reflection::CreateField(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -655,6 +687,7 @@ inline flatbuffers::Offset<Field> CreateFieldDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef ObjectBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_NAME = 4,
|
VT_NAME = 4,
|
||||||
VT_FIELDS = 6,
|
VT_FIELDS = 6,
|
||||||
@@ -673,8 +706,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int KeyCompareWithValue(const char *val) const {
|
int KeyCompareWithValue(const char *val) const {
|
||||||
return strcmp(name()->c_str(), val);
|
return strcmp(name()->c_str(), val);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<Field>> *fields() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *fields() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Field>> *>(VT_FIELDS);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Field>> *>(VT_FIELDS);
|
||||||
}
|
}
|
||||||
bool is_struct() const {
|
bool is_struct() const {
|
||||||
return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
|
return GetField<uint8_t>(VT_IS_STRUCT, 0) != 0;
|
||||||
@@ -685,8 +718,8 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int32_t bytesize() const {
|
int32_t bytesize() const {
|
||||||
return GetField<int32_t>(VT_BYTESIZE, 0);
|
return GetField<int32_t>(VT_BYTESIZE, 0);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||||
@@ -712,12 +745,13 @@ struct Object FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ObjectBuilder {
|
struct ObjectBuilder {
|
||||||
|
typedef Object Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
fbb_.AddOffset(Object::VT_NAME, name);
|
fbb_.AddOffset(Object::VT_NAME, name);
|
||||||
}
|
}
|
||||||
void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Field>>> fields) {
|
void add_fields(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields) {
|
||||||
fbb_.AddOffset(Object::VT_FIELDS, fields);
|
fbb_.AddOffset(Object::VT_FIELDS, fields);
|
||||||
}
|
}
|
||||||
void add_is_struct(bool is_struct) {
|
void add_is_struct(bool is_struct) {
|
||||||
@@ -729,7 +763,7 @@ struct ObjectBuilder {
|
|||||||
void add_bytesize(int32_t bytesize) {
|
void add_bytesize(int32_t bytesize) {
|
||||||
fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
|
fbb_.AddElement<int32_t>(Object::VT_BYTESIZE, bytesize, 0);
|
||||||
}
|
}
|
||||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
|
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
|
||||||
fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
|
fbb_.AddOffset(Object::VT_ATTRIBUTES, attributes);
|
||||||
}
|
}
|
||||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||||
@@ -752,11 +786,11 @@ struct ObjectBuilder {
|
|||||||
inline flatbuffers::Offset<Object> CreateObject(
|
inline flatbuffers::Offset<Object> CreateObject(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Field>>> fields = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Field>>> fields = 0,
|
||||||
bool is_struct = false,
|
bool is_struct = false,
|
||||||
int32_t minalign = 0,
|
int32_t minalign = 0,
|
||||||
int32_t bytesize = 0,
|
int32_t bytesize = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||||
ObjectBuilder builder_(_fbb);
|
ObjectBuilder builder_(_fbb);
|
||||||
builder_.add_documentation(documentation);
|
builder_.add_documentation(documentation);
|
||||||
@@ -772,15 +806,15 @@ inline flatbuffers::Offset<Object> CreateObject(
|
|||||||
inline flatbuffers::Offset<Object> CreateObjectDirect(
|
inline flatbuffers::Offset<Object> CreateObjectDirect(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const char *name = nullptr,
|
const char *name = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<Field>> *fields = nullptr,
|
std::vector<flatbuffers::Offset<reflection::Field>> *fields = nullptr,
|
||||||
bool is_struct = false,
|
bool is_struct = false,
|
||||||
int32_t minalign = 0,
|
int32_t minalign = 0,
|
||||||
int32_t bytesize = 0,
|
int32_t bytesize = 0,
|
||||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||||
auto fields__ = fields ? _fbb.CreateVector<flatbuffers::Offset<Field>>(*fields) : 0;
|
auto fields__ = fields ? _fbb.CreateVectorOfSortedTables<reflection::Field>(fields) : 0;
|
||||||
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
|
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
|
||||||
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
||||||
return reflection::CreateObject(
|
return reflection::CreateObject(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -794,6 +828,7 @@ inline flatbuffers::Offset<Object> CreateObjectDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef RPCCallBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_NAME = 4,
|
VT_NAME = 4,
|
||||||
VT_REQUEST = 6,
|
VT_REQUEST = 6,
|
||||||
@@ -810,14 +845,14 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int KeyCompareWithValue(const char *val) const {
|
int KeyCompareWithValue(const char *val) const {
|
||||||
return strcmp(name()->c_str(), val);
|
return strcmp(name()->c_str(), val);
|
||||||
}
|
}
|
||||||
const Object *request() const {
|
const reflection::Object *request() const {
|
||||||
return GetPointer<const Object *>(VT_REQUEST);
|
return GetPointer<const reflection::Object *>(VT_REQUEST);
|
||||||
}
|
}
|
||||||
const Object *response() const {
|
const reflection::Object *response() const {
|
||||||
return GetPointer<const Object *>(VT_RESPONSE);
|
return GetPointer<const reflection::Object *>(VT_RESPONSE);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||||
@@ -841,18 +876,19 @@ struct RPCCall FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct RPCCallBuilder {
|
struct RPCCallBuilder {
|
||||||
|
typedef RPCCall Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
fbb_.AddOffset(RPCCall::VT_NAME, name);
|
fbb_.AddOffset(RPCCall::VT_NAME, name);
|
||||||
}
|
}
|
||||||
void add_request(flatbuffers::Offset<Object> request) {
|
void add_request(flatbuffers::Offset<reflection::Object> request) {
|
||||||
fbb_.AddOffset(RPCCall::VT_REQUEST, request);
|
fbb_.AddOffset(RPCCall::VT_REQUEST, request);
|
||||||
}
|
}
|
||||||
void add_response(flatbuffers::Offset<Object> response) {
|
void add_response(flatbuffers::Offset<reflection::Object> response) {
|
||||||
fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
|
fbb_.AddOffset(RPCCall::VT_RESPONSE, response);
|
||||||
}
|
}
|
||||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
|
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
|
||||||
fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
|
fbb_.AddOffset(RPCCall::VT_ATTRIBUTES, attributes);
|
||||||
}
|
}
|
||||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||||
@@ -876,9 +912,9 @@ struct RPCCallBuilder {
|
|||||||
inline flatbuffers::Offset<RPCCall> CreateRPCCall(
|
inline flatbuffers::Offset<RPCCall> CreateRPCCall(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||||
flatbuffers::Offset<Object> request = 0,
|
flatbuffers::Offset<reflection::Object> request = 0,
|
||||||
flatbuffers::Offset<Object> response = 0,
|
flatbuffers::Offset<reflection::Object> response = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||||
RPCCallBuilder builder_(_fbb);
|
RPCCallBuilder builder_(_fbb);
|
||||||
builder_.add_documentation(documentation);
|
builder_.add_documentation(documentation);
|
||||||
@@ -892,12 +928,12 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCall(
|
|||||||
inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
|
inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const char *name = nullptr,
|
const char *name = nullptr,
|
||||||
flatbuffers::Offset<Object> request = 0,
|
flatbuffers::Offset<reflection::Object> request = 0,
|
||||||
flatbuffers::Offset<Object> response = 0,
|
flatbuffers::Offset<reflection::Object> response = 0,
|
||||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||||
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
|
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
|
||||||
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
||||||
return reflection::CreateRPCCall(
|
return reflection::CreateRPCCall(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -909,6 +945,7 @@ inline flatbuffers::Offset<RPCCall> CreateRPCCallDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef ServiceBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_NAME = 4,
|
VT_NAME = 4,
|
||||||
VT_CALLS = 6,
|
VT_CALLS = 6,
|
||||||
@@ -924,11 +961,11 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
int KeyCompareWithValue(const char *val) const {
|
int KeyCompareWithValue(const char *val) const {
|
||||||
return strcmp(name()->c_str(), val);
|
return strcmp(name()->c_str(), val);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<RPCCall>> *calls() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *calls() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<RPCCall>> *>(VT_CALLS);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>> *>(VT_CALLS);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *attributes() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *attributes() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<KeyValue>> *>(VT_ATTRIBUTES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>> *>(VT_ATTRIBUTES);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *documentation() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>> *>(VT_DOCUMENTATION);
|
||||||
@@ -951,15 +988,16 @@ struct Service FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct ServiceBuilder {
|
struct ServiceBuilder {
|
||||||
|
typedef Service Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
void add_name(flatbuffers::Offset<flatbuffers::String> name) {
|
||||||
fbb_.AddOffset(Service::VT_NAME, name);
|
fbb_.AddOffset(Service::VT_NAME, name);
|
||||||
}
|
}
|
||||||
void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<RPCCall>>> calls) {
|
void add_calls(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls) {
|
||||||
fbb_.AddOffset(Service::VT_CALLS, calls);
|
fbb_.AddOffset(Service::VT_CALLS, calls);
|
||||||
}
|
}
|
||||||
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes) {
|
void add_attributes(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes) {
|
||||||
fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
|
fbb_.AddOffset(Service::VT_ATTRIBUTES, attributes);
|
||||||
}
|
}
|
||||||
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
void add_documentation(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation) {
|
||||||
@@ -981,8 +1019,8 @@ struct ServiceBuilder {
|
|||||||
inline flatbuffers::Offset<Service> CreateService(
|
inline flatbuffers::Offset<Service> CreateService(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::String> name = 0,
|
flatbuffers::Offset<flatbuffers::String> name = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<RPCCall>>> calls = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::RPCCall>>> calls = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<KeyValue>>> attributes = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>> documentation = 0) {
|
||||||
ServiceBuilder builder_(_fbb);
|
ServiceBuilder builder_(_fbb);
|
||||||
builder_.add_documentation(documentation);
|
builder_.add_documentation(documentation);
|
||||||
@@ -995,12 +1033,12 @@ inline flatbuffers::Offset<Service> CreateService(
|
|||||||
inline flatbuffers::Offset<Service> CreateServiceDirect(
|
inline flatbuffers::Offset<Service> CreateServiceDirect(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const char *name = nullptr,
|
const char *name = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<RPCCall>> *calls = nullptr,
|
std::vector<flatbuffers::Offset<reflection::RPCCall>> *calls = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<KeyValue>> *attributes = nullptr,
|
std::vector<flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
const std::vector<flatbuffers::Offset<flatbuffers::String>> *documentation = nullptr) {
|
||||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||||
auto calls__ = calls ? _fbb.CreateVector<flatbuffers::Offset<RPCCall>>(*calls) : 0;
|
auto calls__ = calls ? _fbb.CreateVectorOfSortedTables<reflection::RPCCall>(calls) : 0;
|
||||||
auto attributes__ = attributes ? _fbb.CreateVector<flatbuffers::Offset<KeyValue>>(*attributes) : 0;
|
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
|
||||||
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
auto documentation__ = documentation ? _fbb.CreateVector<flatbuffers::Offset<flatbuffers::String>>(*documentation) : 0;
|
||||||
return reflection::CreateService(
|
return reflection::CreateService(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -1011,6 +1049,7 @@ inline flatbuffers::Offset<Service> CreateServiceDirect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
||||||
|
typedef SchemaBuilder Builder;
|
||||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||||
VT_OBJECTS = 4,
|
VT_OBJECTS = 4,
|
||||||
VT_ENUMS = 6,
|
VT_ENUMS = 6,
|
||||||
@@ -1019,11 +1058,11 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
VT_ROOT_TABLE = 12,
|
VT_ROOT_TABLE = 12,
|
||||||
VT_SERVICES = 14
|
VT_SERVICES = 14
|
||||||
};
|
};
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<Object>> *objects() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *objects() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Object>> *>(VT_OBJECTS);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Object>> *>(VT_OBJECTS);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<Enum>> *enums() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *enums() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Enum>> *>(VT_ENUMS);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>> *>(VT_ENUMS);
|
||||||
}
|
}
|
||||||
const flatbuffers::String *file_ident() const {
|
const flatbuffers::String *file_ident() const {
|
||||||
return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
|
return GetPointer<const flatbuffers::String *>(VT_FILE_IDENT);
|
||||||
@@ -1031,11 +1070,11 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
const flatbuffers::String *file_ext() const {
|
const flatbuffers::String *file_ext() const {
|
||||||
return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
|
return GetPointer<const flatbuffers::String *>(VT_FILE_EXT);
|
||||||
}
|
}
|
||||||
const Object *root_table() const {
|
const reflection::Object *root_table() const {
|
||||||
return GetPointer<const Object *>(VT_ROOT_TABLE);
|
return GetPointer<const reflection::Object *>(VT_ROOT_TABLE);
|
||||||
}
|
}
|
||||||
const flatbuffers::Vector<flatbuffers::Offset<Service>> *services() const {
|
const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *services() const {
|
||||||
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<Service>> *>(VT_SERVICES);
|
return GetPointer<const flatbuffers::Vector<flatbuffers::Offset<reflection::Service>> *>(VT_SERVICES);
|
||||||
}
|
}
|
||||||
bool Verify(flatbuffers::Verifier &verifier) const {
|
bool Verify(flatbuffers::Verifier &verifier) const {
|
||||||
return VerifyTableStart(verifier) &&
|
return VerifyTableStart(verifier) &&
|
||||||
@@ -1059,12 +1098,13 @@ struct Schema FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct SchemaBuilder {
|
struct SchemaBuilder {
|
||||||
|
typedef Schema Table;
|
||||||
flatbuffers::FlatBufferBuilder &fbb_;
|
flatbuffers::FlatBufferBuilder &fbb_;
|
||||||
flatbuffers::uoffset_t start_;
|
flatbuffers::uoffset_t start_;
|
||||||
void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects) {
|
void add_objects(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects) {
|
||||||
fbb_.AddOffset(Schema::VT_OBJECTS, objects);
|
fbb_.AddOffset(Schema::VT_OBJECTS, objects);
|
||||||
}
|
}
|
||||||
void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums) {
|
void add_enums(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums) {
|
||||||
fbb_.AddOffset(Schema::VT_ENUMS, enums);
|
fbb_.AddOffset(Schema::VT_ENUMS, enums);
|
||||||
}
|
}
|
||||||
void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
|
void add_file_ident(flatbuffers::Offset<flatbuffers::String> file_ident) {
|
||||||
@@ -1073,10 +1113,10 @@ struct SchemaBuilder {
|
|||||||
void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
|
void add_file_ext(flatbuffers::Offset<flatbuffers::String> file_ext) {
|
||||||
fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
|
fbb_.AddOffset(Schema::VT_FILE_EXT, file_ext);
|
||||||
}
|
}
|
||||||
void add_root_table(flatbuffers::Offset<Object> root_table) {
|
void add_root_table(flatbuffers::Offset<reflection::Object> root_table) {
|
||||||
fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
|
fbb_.AddOffset(Schema::VT_ROOT_TABLE, root_table);
|
||||||
}
|
}
|
||||||
void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Service>>> services) {
|
void add_services(flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services) {
|
||||||
fbb_.AddOffset(Schema::VT_SERVICES, services);
|
fbb_.AddOffset(Schema::VT_SERVICES, services);
|
||||||
}
|
}
|
||||||
explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
explicit SchemaBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
@@ -1095,12 +1135,12 @@ struct SchemaBuilder {
|
|||||||
|
|
||||||
inline flatbuffers::Offset<Schema> CreateSchema(
|
inline flatbuffers::Offset<Schema> CreateSchema(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Object>>> objects = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Object>>> objects = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Enum>>> enums = 0,
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Enum>>> enums = 0,
|
||||||
flatbuffers::Offset<flatbuffers::String> file_ident = 0,
|
flatbuffers::Offset<flatbuffers::String> file_ident = 0,
|
||||||
flatbuffers::Offset<flatbuffers::String> file_ext = 0,
|
flatbuffers::Offset<flatbuffers::String> file_ext = 0,
|
||||||
flatbuffers::Offset<Object> root_table = 0,
|
flatbuffers::Offset<reflection::Object> root_table = 0,
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<Service>>> services = 0) {
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<reflection::Service>>> services = 0) {
|
||||||
SchemaBuilder builder_(_fbb);
|
SchemaBuilder builder_(_fbb);
|
||||||
builder_.add_services(services);
|
builder_.add_services(services);
|
||||||
builder_.add_root_table(root_table);
|
builder_.add_root_table(root_table);
|
||||||
@@ -1113,17 +1153,17 @@ inline flatbuffers::Offset<Schema> CreateSchema(
|
|||||||
|
|
||||||
inline flatbuffers::Offset<Schema> CreateSchemaDirect(
|
inline flatbuffers::Offset<Schema> CreateSchemaDirect(
|
||||||
flatbuffers::FlatBufferBuilder &_fbb,
|
flatbuffers::FlatBufferBuilder &_fbb,
|
||||||
const std::vector<flatbuffers::Offset<Object>> *objects = nullptr,
|
std::vector<flatbuffers::Offset<reflection::Object>> *objects = nullptr,
|
||||||
const std::vector<flatbuffers::Offset<Enum>> *enums = nullptr,
|
std::vector<flatbuffers::Offset<reflection::Enum>> *enums = nullptr,
|
||||||
const char *file_ident = nullptr,
|
const char *file_ident = nullptr,
|
||||||
const char *file_ext = nullptr,
|
const char *file_ext = nullptr,
|
||||||
flatbuffers::Offset<Object> root_table = 0,
|
flatbuffers::Offset<reflection::Object> root_table = 0,
|
||||||
const std::vector<flatbuffers::Offset<Service>> *services = nullptr) {
|
std::vector<flatbuffers::Offset<reflection::Service>> *services = nullptr) {
|
||||||
auto objects__ = objects ? _fbb.CreateVector<flatbuffers::Offset<Object>>(*objects) : 0;
|
auto objects__ = objects ? _fbb.CreateVectorOfSortedTables<reflection::Object>(objects) : 0;
|
||||||
auto enums__ = enums ? _fbb.CreateVector<flatbuffers::Offset<Enum>>(*enums) : 0;
|
auto enums__ = enums ? _fbb.CreateVectorOfSortedTables<reflection::Enum>(enums) : 0;
|
||||||
auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
|
auto file_ident__ = file_ident ? _fbb.CreateString(file_ident) : 0;
|
||||||
auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
|
auto file_ext__ = file_ext ? _fbb.CreateString(file_ext) : 0;
|
||||||
auto services__ = services ? _fbb.CreateVector<flatbuffers::Offset<Service>>(*services) : 0;
|
auto services__ = services ? _fbb.CreateVectorOfSortedTables<reflection::Service>(services) : 0;
|
||||||
return reflection::CreateSchema(
|
return reflection::CreateSchema(
|
||||||
_fbb,
|
_fbb,
|
||||||
objects__,
|
objects__,
|
||||||
|
|||||||
@@ -138,7 +138,12 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
|||||||
template <typename T, typename U> using is_same = std::is_same<T,U>;
|
template <typename T, typename U> using is_same = std::is_same<T,U>;
|
||||||
template <typename T> using is_floating_point = std::is_floating_point<T>;
|
template <typename T> using is_floating_point = std::is_floating_point<T>;
|
||||||
template <typename T> using is_unsigned = std::is_unsigned<T>;
|
template <typename T> using is_unsigned = std::is_unsigned<T>;
|
||||||
|
template <typename T> using is_enum = std::is_enum<T>;
|
||||||
template <typename T> using make_unsigned = std::make_unsigned<T>;
|
template <typename T> using make_unsigned = std::make_unsigned<T>;
|
||||||
|
template<bool B, class T, class F>
|
||||||
|
using conditional = std::conditional<B, T, F>;
|
||||||
|
template<class T, T v>
|
||||||
|
using integral_constant = std::integral_constant<T, v>;
|
||||||
#else
|
#else
|
||||||
// Map C++ TR1 templates defined by stlport.
|
// Map C++ TR1 templates defined by stlport.
|
||||||
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
|
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
|
||||||
@@ -146,6 +151,7 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
|||||||
template <typename T> using is_floating_point =
|
template <typename T> using is_floating_point =
|
||||||
std::tr1::is_floating_point<T>;
|
std::tr1::is_floating_point<T>;
|
||||||
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
|
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
|
||||||
|
template <typename T> using is_enum = std::tr1::is_enum<T>;
|
||||||
// Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
|
// Android NDK doesn't have std::make_unsigned or std::tr1::make_unsigned.
|
||||||
template<typename T> struct make_unsigned {
|
template<typename T> struct make_unsigned {
|
||||||
static_assert(is_unsigned<T>::value, "Specialization not implemented!");
|
static_assert(is_unsigned<T>::value, "Specialization not implemented!");
|
||||||
@@ -157,6 +163,10 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
|||||||
template<> struct make_unsigned<long> { using type = unsigned long; };
|
template<> struct make_unsigned<long> { using type = unsigned long; };
|
||||||
template<>
|
template<>
|
||||||
struct make_unsigned<long long> { using type = unsigned long long; };
|
struct make_unsigned<long long> { using type = unsigned long long; };
|
||||||
|
template<bool B, class T, class F>
|
||||||
|
using conditional = std::tr1::conditional<B, T, F>;
|
||||||
|
template<class T, T v>
|
||||||
|
using integral_constant = std::tr1::integral_constant<T, v>;
|
||||||
#endif // !FLATBUFFERS_CPP98_STL
|
#endif // !FLATBUFFERS_CPP98_STL
|
||||||
#else
|
#else
|
||||||
// MSVC 2010 doesn't support C++11 aliases.
|
// MSVC 2010 doesn't support C++11 aliases.
|
||||||
@@ -165,7 +175,12 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
|||||||
template <typename T> struct is_floating_point :
|
template <typename T> struct is_floating_point :
|
||||||
public std::is_floating_point<T> {};
|
public std::is_floating_point<T> {};
|
||||||
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
|
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
|
||||||
|
template <typename T> struct is_enum : public std::is_enum<T> {};
|
||||||
template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
|
template <typename T> struct make_unsigned : public std::make_unsigned<T> {};
|
||||||
|
template<bool B, class T, class F>
|
||||||
|
struct conditional : public std::conditional<B, T, F> {};
|
||||||
|
template<class T, T v>
|
||||||
|
struct integral_constant : public std::integral_constant<T, v> {};
|
||||||
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
#endif // defined(FLATBUFFERS_TEMPLATES_ALIASES)
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_CPP98_STL
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
@@ -268,6 +283,23 @@ inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
|||||||
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
|
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
|
||||||
return reinterpret_cast<intptr_t>(x.get()) == y;
|
return reinterpret_cast<intptr_t>(x.get()) == y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <class T> bool operator!=(const unique_ptr<T>& x, decltype(nullptr)) {
|
||||||
|
return !!x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> bool operator!=(decltype(nullptr), const unique_ptr<T>& x) {
|
||||||
|
return !!x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> bool operator==(const unique_ptr<T>& x, decltype(nullptr)) {
|
||||||
|
return !x;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> bool operator==(decltype(nullptr), const unique_ptr<T>& x) {
|
||||||
|
return !x;
|
||||||
|
}
|
||||||
|
|
||||||
#endif // !FLATBUFFERS_CPP98_STL
|
#endif // !FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
@@ -17,10 +17,10 @@
|
|||||||
#ifndef FLATBUFFERS_UTIL_H_
|
#ifndef FLATBUFFERS_UTIL_H_
|
||||||
#define FLATBUFFERS_UTIL_H_
|
#define FLATBUFFERS_UTIL_H_
|
||||||
|
|
||||||
#include "flatbuffers/base.h"
|
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_PREFER_PRINTF
|
#ifndef FLATBUFFERS_PREFER_PRINTF
|
||||||
# include <sstream>
|
# include <sstream>
|
||||||
#else // FLATBUFFERS_PREFER_PRINTF
|
#else // FLATBUFFERS_PREFER_PRINTF
|
||||||
@@ -102,7 +102,7 @@ std::string NumToStringImplWrapper(T t, const char *fmt, int precision = 0) {
|
|||||||
size_t string_width = NumToStringWidth(t, precision);
|
size_t string_width = NumToStringWidth(t, precision);
|
||||||
std::string s(string_width, 0x00);
|
std::string s(string_width, 0x00);
|
||||||
// Allow snprintf to use std::string trailing null to detect buffer overflow
|
// Allow snprintf to use std::string trailing null to detect buffer overflow
|
||||||
snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, precision, t);
|
snprintf(const_cast<char *>(s.data()), (s.size() + 1), fmt, string_width, t);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
#endif // FLATBUFFERS_PREFER_PRINTF
|
#endif // FLATBUFFERS_PREFER_PRINTF
|
||||||
@@ -327,7 +327,7 @@ template<typename T> inline bool StringToNumber(const char *s, T *val) {
|
|||||||
int64_t i64;
|
int64_t i64;
|
||||||
// The errno check isn't needed, will return MAX/MIN on overflow.
|
// The errno check isn't needed, will return MAX/MIN on overflow.
|
||||||
if (StringToIntegerImpl(&i64, s, 0, false)) {
|
if (StringToIntegerImpl(&i64, s, 0, false)) {
|
||||||
const int64_t max = flatbuffers::numeric_limits<T>::max();
|
const int64_t max = (flatbuffers::numeric_limits<T>::max)();
|
||||||
const int64_t min = flatbuffers::numeric_limits<T>::lowest();
|
const int64_t min = flatbuffers::numeric_limits<T>::lowest();
|
||||||
if (i64 > max) {
|
if (i64 > max) {
|
||||||
*val = static_cast<T>(max);
|
*val = static_cast<T>(max);
|
||||||
@@ -365,7 +365,7 @@ inline bool StringToNumber<uint64_t>(const char *str, uint64_t *val) {
|
|||||||
if (*s == '-') {
|
if (*s == '-') {
|
||||||
// For unsigned types return the max to distinguish from
|
// For unsigned types return the max to distinguish from
|
||||||
// "no conversion can be performed".
|
// "no conversion can be performed".
|
||||||
*val = flatbuffers::numeric_limits<uint64_t>::max();
|
*val = (flatbuffers::numeric_limits<uint64_t>::max)();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -636,6 +636,32 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline std::string BufferToHexText(const void *buffer, size_t buffer_size,
|
||||||
|
size_t max_length,
|
||||||
|
const std::string &wrapped_line_prefix,
|
||||||
|
const std::string &wrapped_line_suffix) {
|
||||||
|
std::string text = wrapped_line_prefix;
|
||||||
|
size_t start_offset = 0;
|
||||||
|
const char *s = reinterpret_cast<const char *>(buffer);
|
||||||
|
for (size_t i = 0; s && i < buffer_size; i++) {
|
||||||
|
// Last iteration or do we have more?
|
||||||
|
bool have_more = i + 1 < buffer_size;
|
||||||
|
text += "0x";
|
||||||
|
text += IntToStringHex(static_cast<uint8_t>(s[i]), 2);
|
||||||
|
if (have_more) { text += ','; }
|
||||||
|
// If we have more to process and we reached max_length
|
||||||
|
if (have_more &&
|
||||||
|
text.size() + wrapped_line_suffix.size() >= start_offset + max_length) {
|
||||||
|
text += wrapped_line_suffix;
|
||||||
|
text += '\n';
|
||||||
|
start_offset = text.size();
|
||||||
|
text += wrapped_line_prefix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
text += wrapped_line_suffix;
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
// Remove paired quotes in a string: "text"|'text' -> text.
|
// Remove paired quotes in a string: "text"|'text' -> text.
|
||||||
std::string RemoveStringQuotes(const std::string &s);
|
std::string RemoveStringQuotes(const std::string &s);
|
||||||
|
|
||||||
@@ -649,6 +675,9 @@ bool SetGlobalTestLocale(const char *locale_name,
|
|||||||
bool ReadEnvironmentVariable(const char *var_name,
|
bool ReadEnvironmentVariable(const char *var_name,
|
||||||
std::string *_value = nullptr);
|
std::string *_value = nullptr);
|
||||||
|
|
||||||
|
// MSVC specific: Send all assert reports to STDOUT to prevent CI hangs.
|
||||||
|
void SetupDefaultCRTReportMode();
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATBUFFERS_UTIL_H_
|
#endif // FLATBUFFERS_UTIL_H_
|
||||||
|
|||||||
241
java/com/google/flatbuffers/ArrayReadWriteBuf.java
Normal file
241
java/com/google/flatbuffers/ArrayReadWriteBuf.java
Normal file
@@ -0,0 +1,241 @@
|
|||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements {@code ReadBuf} using an array of bytes
|
||||||
|
* as a backing storage. Using array of bytes are
|
||||||
|
* usually faster than {@code ByteBuffer}.
|
||||||
|
*
|
||||||
|
* This class is not thread-safe, meaning that
|
||||||
|
* it must operate on a single thread. Operating from
|
||||||
|
* multiple thread leads into a undefined behavior
|
||||||
|
*/
|
||||||
|
public class ArrayReadWriteBuf implements ReadWriteBuf {
|
||||||
|
|
||||||
|
private byte[] buffer;
|
||||||
|
private int writePos;
|
||||||
|
|
||||||
|
public ArrayReadWriteBuf() {
|
||||||
|
this(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayReadWriteBuf(int initialCapacity) {
|
||||||
|
this(new byte[initialCapacity]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayReadWriteBuf(byte[] buffer) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
this.writePos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ArrayReadWriteBuf(byte[] buffer, int startPos) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
this.writePos = startPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(int index) {
|
||||||
|
return buffer[index] != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte get(int index) {
|
||||||
|
return buffer[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int index) {
|
||||||
|
return (short) ((buffer[index+ 1] << 8) | (buffer[index] & 0xff));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int index) {
|
||||||
|
return (((buffer[index + 3]) << 24) |
|
||||||
|
((buffer[index + 2] & 0xff) << 16) |
|
||||||
|
((buffer[index + 1] & 0xff) << 8) |
|
||||||
|
((buffer[index] & 0xff)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int index) {
|
||||||
|
return ((((long) buffer[index++] & 0xff)) |
|
||||||
|
(((long) buffer[index++] & 0xff) << 8) |
|
||||||
|
(((long) buffer[index++] & 0xff) << 16) |
|
||||||
|
(((long) buffer[index++] & 0xff) << 24) |
|
||||||
|
(((long) buffer[index++] & 0xff) << 32) |
|
||||||
|
(((long) buffer[index++] & 0xff) << 40) |
|
||||||
|
(((long) buffer[index++] & 0xff) << 48) |
|
||||||
|
(((long) buffer[index]) << 56));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFloat(int index) {
|
||||||
|
return Float.intBitsToFloat(getInt(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(int index) {
|
||||||
|
return Double.longBitsToDouble(getLong(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int start, int size) {
|
||||||
|
return Utf8Safe.decodeUtf8Array(buffer, start, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] data() {
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putBoolean(boolean value) {
|
||||||
|
setBoolean(writePos, value);
|
||||||
|
writePos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(byte[] value, int start, int length) {
|
||||||
|
set(writePos, value, start, length);
|
||||||
|
writePos+=length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(byte value) {
|
||||||
|
set(writePos, value);
|
||||||
|
writePos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putShort(short value) {
|
||||||
|
setShort(writePos, value);
|
||||||
|
writePos +=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putInt(int value) {
|
||||||
|
setInt(writePos, value);
|
||||||
|
writePos +=4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putLong(long value) {
|
||||||
|
setLong(writePos, value);
|
||||||
|
writePos +=8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putFloat(float value) {
|
||||||
|
setFloat(writePos, value);
|
||||||
|
writePos +=4;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putDouble(double value) {
|
||||||
|
setDouble(writePos, value);
|
||||||
|
writePos +=8;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBoolean(int index, boolean value) {
|
||||||
|
set(index, value ? (byte)1 : (byte)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int index, byte value) {
|
||||||
|
requestCapacity(index + 1);
|
||||||
|
buffer[index] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int index, byte[] toCopy, int start, int length) {
|
||||||
|
requestCapacity(index + (length - start));
|
||||||
|
System.arraycopy(toCopy, start, buffer, index, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShort(int index, short value) {
|
||||||
|
requestCapacity(index + 2);
|
||||||
|
|
||||||
|
buffer[index++] = (byte) ((value) & 0xff);
|
||||||
|
buffer[index ] = (byte) ((value >> 8) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInt(int index, int value) {
|
||||||
|
requestCapacity(index + 4);
|
||||||
|
|
||||||
|
buffer[index++] = (byte) ((value) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((value >> 8) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((value >> 16) & 0xff);
|
||||||
|
buffer[index ] = (byte) ((value >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLong(int index, long value) {
|
||||||
|
requestCapacity(index + 8);
|
||||||
|
|
||||||
|
int i = (int) value;
|
||||||
|
buffer[index++] = (byte) ((i) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 8) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 16) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 24) & 0xff);
|
||||||
|
i = (int) (value >> 32);
|
||||||
|
buffer[index++] = (byte) ((i) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 8) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 16) & 0xff);
|
||||||
|
buffer[index ] = (byte) ((i >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFloat(int index, float value) {
|
||||||
|
requestCapacity(index + 4);
|
||||||
|
|
||||||
|
int iValue = Float.floatToRawIntBits(value);
|
||||||
|
buffer[index++] = (byte) ((iValue) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((iValue >> 8) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((iValue >> 16) & 0xff);
|
||||||
|
buffer[index ] = (byte) ((iValue >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDouble(int index, double value) {
|
||||||
|
requestCapacity(index + 8);
|
||||||
|
|
||||||
|
long lValue = Double.doubleToRawLongBits(value);
|
||||||
|
int i = (int) lValue;
|
||||||
|
buffer[index++] = (byte) ((i) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 8) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 16) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 24) & 0xff);
|
||||||
|
i = (int) (lValue >> 32);
|
||||||
|
buffer[index++] = (byte) ((i) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 8) & 0xff);
|
||||||
|
buffer[index++] = (byte) ((i >> 16) & 0xff);
|
||||||
|
buffer[index ] = (byte) ((i >> 24) & 0xff);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int limit() {
|
||||||
|
return writePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int writePosition() {
|
||||||
|
return writePos;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requestCapacity(int capacity) {
|
||||||
|
if (buffer.length > capacity) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// implemented in the same growing fashion as ArrayList
|
||||||
|
int oldCapacity = buffer.length;
|
||||||
|
int newCapacity = oldCapacity + (oldCapacity >> 1);
|
||||||
|
buffer = Arrays.copyOf(buffer, newCapacity);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
96
java/com/google/flatbuffers/BaseVector.java
Normal file
96
java/com/google/flatbuffers/BaseVector.java
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
|
||||||
|
/**
|
||||||
|
* All vector access objects derive from this class, and add their own accessors.
|
||||||
|
*/
|
||||||
|
public class BaseVector {
|
||||||
|
/** Used to hold the vector data position. */
|
||||||
|
private int vector;
|
||||||
|
/** Used to hold the vector size. */
|
||||||
|
private int length;
|
||||||
|
/** Used to hold the vector element size in table. */
|
||||||
|
private int element_size;
|
||||||
|
/** The underlying ByteBuffer to hold the data of the vector. */
|
||||||
|
protected ByteBuffer bb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the start data of a vector.
|
||||||
|
*
|
||||||
|
* @return Returns the start of the vector data.
|
||||||
|
*/
|
||||||
|
protected int __vector() {
|
||||||
|
return vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the element position in vector's ByteBuffer.
|
||||||
|
*
|
||||||
|
* @param j An `int` index of element into a vector.
|
||||||
|
* @return Returns the position of the vector element in a ByteBuffer.
|
||||||
|
*/
|
||||||
|
protected int __element(int j) {
|
||||||
|
return vector + j * element_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-init the internal state with an external buffer {@code ByteBuffer}, an offset within and
|
||||||
|
* element size.
|
||||||
|
*
|
||||||
|
* This method exists primarily to allow recycling vector instances without risking memory leaks
|
||||||
|
* due to {@code ByteBuffer} references.
|
||||||
|
*/
|
||||||
|
protected void __reset(int _vector, int _element_size, ByteBuffer _bb) {
|
||||||
|
bb = _bb;
|
||||||
|
if (bb != null) {
|
||||||
|
vector = _vector;
|
||||||
|
length = bb.getInt(_vector - Constants.SIZEOF_INT);
|
||||||
|
element_size = _element_size;
|
||||||
|
} else {
|
||||||
|
vector = 0;
|
||||||
|
length = 0;
|
||||||
|
element_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
|
||||||
|
*
|
||||||
|
* This method exists primarily to allow recycling vector instances without risking memory leaks
|
||||||
|
* due to {@code ByteBuffer} references. The instance will be unusable until it is assigned
|
||||||
|
* again to a {@code ByteBuffer}.
|
||||||
|
*/
|
||||||
|
public void reset() {
|
||||||
|
__reset(0, 0, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the length of a vector.
|
||||||
|
*
|
||||||
|
* @return Returns the length of the vector.
|
||||||
|
*/
|
||||||
|
public int length() {
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @endcond
|
||||||
49
java/com/google/flatbuffers/BooleanVector.java
Normal file
49
java/com/google/flatbuffers/BooleanVector.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of booleans.
|
||||||
|
*/
|
||||||
|
public final class BooleanVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public BooleanVector __assign(int _vector, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, Constants.SIZEOF_BYTE, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the boolean at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the boolean will be read.
|
||||||
|
* @return the boolean value at the given index.
|
||||||
|
*/
|
||||||
|
public boolean get(int j) {
|
||||||
|
return 0 != bb.get(__element(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
165
java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
Normal file
165
java/com/google/flatbuffers/ByteBufferReadWriteBuf.java
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
|
public class ByteBufferReadWriteBuf implements ReadWriteBuf {
|
||||||
|
|
||||||
|
private final ByteBuffer buffer;
|
||||||
|
|
||||||
|
public ByteBufferReadWriteBuf(ByteBuffer bb) {
|
||||||
|
this.buffer = bb;
|
||||||
|
this.buffer.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getBoolean(int index) {
|
||||||
|
return get(index) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte get(int index) {
|
||||||
|
return buffer.get(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public short getShort(int index) {
|
||||||
|
return buffer.getShort(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getInt(int index) {
|
||||||
|
return buffer.getInt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getLong(int index) {
|
||||||
|
return buffer.getLong(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getFloat(int index) {
|
||||||
|
return buffer.getFloat(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public double getDouble(int index) {
|
||||||
|
return buffer.getDouble(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getString(int start, int size) {
|
||||||
|
return Utf8Safe.decodeUtf8Buffer(buffer, start, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] data() {
|
||||||
|
return buffer.array();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putBoolean(boolean value) {
|
||||||
|
buffer.put(value ? (byte)1 : (byte)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(byte[] value, int start, int length) {
|
||||||
|
buffer.put(value, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void put(byte value) {
|
||||||
|
buffer.put(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putShort(short value) {
|
||||||
|
buffer.putShort(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putInt(int value) {
|
||||||
|
buffer.putInt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putLong(long value) {
|
||||||
|
buffer.putLong(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putFloat(float value) {
|
||||||
|
buffer.putFloat(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void putDouble(double value) {
|
||||||
|
buffer.putDouble(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setBoolean(int index, boolean value) {
|
||||||
|
set(index, value ? (byte)1 : (byte)0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int index, byte value) {
|
||||||
|
requestCapacity(index + 1);
|
||||||
|
buffer.put(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void set(int index, byte[] value, int start, int length) {
|
||||||
|
requestCapacity(index + (length - start));
|
||||||
|
int curPos = buffer.position();
|
||||||
|
buffer.position(index);
|
||||||
|
buffer.put(value, start, length);
|
||||||
|
buffer.position(curPos);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setShort(int index, short value) {
|
||||||
|
requestCapacity(index + 2);
|
||||||
|
buffer.putShort(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setInt(int index, int value) {
|
||||||
|
requestCapacity(index + 4);
|
||||||
|
buffer.putInt(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setLong(int index, long value) {
|
||||||
|
requestCapacity(index + 8);
|
||||||
|
buffer.putLong(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setFloat(int index, float value) {
|
||||||
|
requestCapacity(index + 4);
|
||||||
|
buffer.putFloat(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDouble(int index, double value) {
|
||||||
|
requestCapacity(index + 8);
|
||||||
|
buffer.putDouble(index, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int writePosition() {
|
||||||
|
return buffer.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int limit() {
|
||||||
|
return buffer.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requestCapacity(int capacity) {
|
||||||
|
return capacity <= buffer.limit();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
60
java/com/google/flatbuffers/ByteVector.java
Normal file
60
java/com/google/flatbuffers/ByteVector.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of signed or unsigned 8-bit values.
|
||||||
|
*/
|
||||||
|
public final class ByteVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param vector Start data of a vector.
|
||||||
|
* @param bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public ByteVector __assign(int vector, ByteBuffer bb) {
|
||||||
|
__reset(vector, Constants.SIZEOF_BYTE, bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the byte at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the byte will be read.
|
||||||
|
* @return the 8-bit value at the given index.
|
||||||
|
*/
|
||||||
|
public byte get(int j) {
|
||||||
|
return bb.get(__element(j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the byte at the given index, zero-extends it to type int, and returns the result,
|
||||||
|
* which is therefore in the range 0 through 255.
|
||||||
|
*
|
||||||
|
* @param j The index from which the byte will be read.
|
||||||
|
* @return the unsigned 8-bit at the given index.
|
||||||
|
*/
|
||||||
|
public int getAsUnsigned(int j) {
|
||||||
|
return (int) get(j) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -39,6 +39,14 @@ public class Constants {
|
|||||||
static final int FILE_IDENTIFIER_LENGTH = 4;
|
static final int FILE_IDENTIFIER_LENGTH = 4;
|
||||||
/** The number of bytes in a size prefix. */
|
/** The number of bytes in a size prefix. */
|
||||||
public static final int SIZE_PREFIX_LENGTH = 4;
|
public static final int SIZE_PREFIX_LENGTH = 4;
|
||||||
|
/** A version identifier to force a compile error if someone
|
||||||
|
accidentally tries to build generated code with a runtime of
|
||||||
|
two mismatched version. Versions need to always match, as
|
||||||
|
the runtime and generated code are modified in sync.
|
||||||
|
Changes to the Java implementation need to be sure to change
|
||||||
|
the version here and in the code generator on every possible
|
||||||
|
incompatible change */
|
||||||
|
public static void FLATBUFFERS_1_12_0() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|||||||
49
java/com/google/flatbuffers/DoubleVector.java
Normal file
49
java/com/google/flatbuffers/DoubleVector.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of double values.
|
||||||
|
*/
|
||||||
|
public final class DoubleVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public DoubleVector __assign(int _vector, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, Constants.SIZEOF_DOUBLE, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the double value at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the double value will be read.
|
||||||
|
* @return the double value at the given index.
|
||||||
|
*/
|
||||||
|
public double get(int j) {
|
||||||
|
return bb.getDouble(__element(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -72,7 +72,6 @@ public class FlatBufferBuilder {
|
|||||||
if (initial_size <= 0) {
|
if (initial_size <= 0) {
|
||||||
initial_size = 1;
|
initial_size = 1;
|
||||||
}
|
}
|
||||||
space = initial_size;
|
|
||||||
this.bb_factory = bb_factory;
|
this.bb_factory = bb_factory;
|
||||||
if (existing_bb != null) {
|
if (existing_bb != null) {
|
||||||
bb = existing_bb;
|
bb = existing_bb;
|
||||||
@@ -82,6 +81,7 @@ public class FlatBufferBuilder {
|
|||||||
bb = bb_factory.newByteBuffer(initial_size);
|
bb = bb_factory.newByteBuffer(initial_size);
|
||||||
}
|
}
|
||||||
this.utf8 = utf8;
|
this.utf8 = utf8;
|
||||||
|
space = bb.capacity();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -199,6 +199,17 @@ public class FlatBufferBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function to test if a field is present in the table
|
||||||
|
*
|
||||||
|
* @param table Flatbuffer table
|
||||||
|
* @param offset virtual table offset
|
||||||
|
* @return true if the filed is present
|
||||||
|
*/
|
||||||
|
public static boolean isFieldPresent(Table table, int offset) {
|
||||||
|
return table.__offset(offset) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the FlatBufferBuilder by purging all data that it holds.
|
* Reset the FlatBufferBuilder by purging all data that it holds.
|
||||||
*/
|
*/
|
||||||
@@ -231,6 +242,7 @@ public class FlatBufferBuilder {
|
|||||||
int new_buf_size = old_buf_size == 0 ? 1 : old_buf_size << 1;
|
int new_buf_size = old_buf_size == 0 ? 1 : old_buf_size << 1;
|
||||||
bb.position(0);
|
bb.position(0);
|
||||||
ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
|
ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
|
||||||
|
new_buf_size = nbb.clear().capacity(); // Ensure the returned buffer is treated as empty
|
||||||
nbb.position(new_buf_size - old_buf_size);
|
nbb.position(new_buf_size - old_buf_size);
|
||||||
nbb.put(bb);
|
nbb.put(bb);
|
||||||
return nbb;
|
return nbb;
|
||||||
@@ -560,6 +572,38 @@ public class FlatBufferBuilder {
|
|||||||
return endVector();
|
return endVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a byte array in the buffer.
|
||||||
|
*
|
||||||
|
* @param arr a source array with data.
|
||||||
|
* @param offset the offset in the source array to start copying from.
|
||||||
|
* @param length the number of bytes to copy from the source array.
|
||||||
|
* @return The offset in the buffer where the encoded array starts.
|
||||||
|
*/
|
||||||
|
public int createByteVector(byte[] arr, int offset, int length) {
|
||||||
|
startVector(1, length, 1);
|
||||||
|
bb.position(space -= length);
|
||||||
|
bb.put(arr, offset, length);
|
||||||
|
return endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a byte array in the buffer.
|
||||||
|
*
|
||||||
|
* The source {@link ByteBuffer} position is advanced by {@link ByteBuffer#remaining()} places
|
||||||
|
* after this call.
|
||||||
|
*
|
||||||
|
* @param byteBuffer A source {@link ByteBuffer} with data.
|
||||||
|
* @return The offset in the buffer where the encoded array starts.
|
||||||
|
*/
|
||||||
|
public int createByteVector(ByteBuffer byteBuffer) {
|
||||||
|
int length = byteBuffer.remaining();
|
||||||
|
startVector(1, length, 1);
|
||||||
|
bb.position(space -= length);
|
||||||
|
bb.put(byteBuffer);
|
||||||
|
return endVector();
|
||||||
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
/**
|
/**
|
||||||
* Should not be accessing the final buffer before it is finished.
|
* Should not be accessing the final buffer before it is finished.
|
||||||
@@ -632,7 +676,7 @@ public class FlatBufferBuilder {
|
|||||||
*
|
*
|
||||||
* @param numfields The number of fields found in this object.
|
* @param numfields The number of fields found in this object.
|
||||||
*/
|
*/
|
||||||
public void startObject(int numfields) {
|
public void startTable(int numfields) {
|
||||||
notNested();
|
notNested();
|
||||||
if (vtable == null || vtable.length < numfields) vtable = new int[numfields];
|
if (vtable == null || vtable.length < numfields) vtable = new int[numfields];
|
||||||
vtable_in_use = numfields;
|
vtable_in_use = numfields;
|
||||||
@@ -757,11 +801,11 @@ public class FlatBufferBuilder {
|
|||||||
* Finish off writing the object that is under construction.
|
* Finish off writing the object that is under construction.
|
||||||
*
|
*
|
||||||
* @return The offset to the object inside {@link #dataBuffer()}.
|
* @return The offset to the object inside {@link #dataBuffer()}.
|
||||||
* @see #startObject(int)
|
* @see #startTable(int)
|
||||||
*/
|
*/
|
||||||
public int endObject() {
|
public int endTable() {
|
||||||
if (vtable == null || !nested)
|
if (vtable == null || !nested)
|
||||||
throw new AssertionError("FlatBuffers: endObject called without startObject");
|
throw new AssertionError("FlatBuffers: endTable called without startTable");
|
||||||
addInt(0);
|
addInt(0);
|
||||||
int vtableloc = offset();
|
int vtableloc = offset();
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
|
|||||||
1102
java/com/google/flatbuffers/FlexBuffers.java
Normal file
1102
java/com/google/flatbuffers/FlexBuffers.java
Normal file
File diff suppressed because it is too large
Load Diff
770
java/com/google/flatbuffers/FlexBuffersBuilder.java
Normal file
770
java/com/google/flatbuffers/FlexBuffersBuilder.java
Normal file
@@ -0,0 +1,770 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.FlexBuffers.*;
|
||||||
|
import static com.google.flatbuffers.FlexBuffers.Unsigned.byteToUnsignedInt;
|
||||||
|
import static com.google.flatbuffers.FlexBuffers.Unsigned.intToUnsignedLong;
|
||||||
|
import static com.google.flatbuffers.FlexBuffers.Unsigned.shortToUnsignedInt;
|
||||||
|
|
||||||
|
/// @file
|
||||||
|
/// @addtogroup flatbuffers_java_api
|
||||||
|
/// @{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class that builds FlexBuffers
|
||||||
|
* <p> This class presents all necessary APIs to create FlexBuffers. A `ByteBuffer` will be used to store the
|
||||||
|
* data. It can be created internally, or passed down in the constructor.</p>
|
||||||
|
*
|
||||||
|
* <p>There are some limitations when compared to original implementation in C++. Most notably:
|
||||||
|
* <ul>
|
||||||
|
* <li><p> No support for mutations (might change in the future).</p></li>
|
||||||
|
* <li><p> Buffer size limited to {@link Integer#MAX_VALUE}</p></li>
|
||||||
|
* <li><p> Since Java does not support unsigned type, all unsigned operations accepts an immediate higher representation
|
||||||
|
* of similar type.</p></li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class FlexBuffersBuilder {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* No keys or strings will be shared
|
||||||
|
*/
|
||||||
|
public static final int BUILDER_FLAG_NONE = 0;
|
||||||
|
/**
|
||||||
|
* Keys will be shared between elements. Identical keys will only be serialized once, thus possibly saving space.
|
||||||
|
* But serialization performance might be slower and consumes more memory.
|
||||||
|
*/
|
||||||
|
public static final int BUILDER_FLAG_SHARE_KEYS = 1;
|
||||||
|
/**
|
||||||
|
* Strings will be shared between elements. Identical strings will only be serialized once, thus possibly saving space.
|
||||||
|
* But serialization performance might be slower and consumes more memory. This is ideal if you expect many repeated
|
||||||
|
* strings on the message.
|
||||||
|
*/
|
||||||
|
public static final int BUILDER_FLAG_SHARE_STRINGS = 2;
|
||||||
|
/**
|
||||||
|
* Strings and keys will be shared between elements.
|
||||||
|
*/
|
||||||
|
public static final int BUILDER_FLAG_SHARE_KEYS_AND_STRINGS = 3;
|
||||||
|
/**
|
||||||
|
* Reserved for the future.
|
||||||
|
*/
|
||||||
|
public static final int BUILDER_FLAG_SHARE_KEY_VECTORS = 4;
|
||||||
|
/**
|
||||||
|
* Reserved for the future.
|
||||||
|
*/
|
||||||
|
public static final int BUILDER_FLAG_SHARE_ALL = 7;
|
||||||
|
|
||||||
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
private static final int WIDTH_8 = 0;
|
||||||
|
private static final int WIDTH_16 = 1;
|
||||||
|
private static final int WIDTH_32 = 2;
|
||||||
|
private static final int WIDTH_64 = 3;
|
||||||
|
private final ReadWriteBuf bb;
|
||||||
|
private final ArrayList<Value> stack = new ArrayList<>();
|
||||||
|
private final HashMap<String, Integer> keyPool = new HashMap<>();
|
||||||
|
private final HashMap<String, Integer> stringPool = new HashMap<>();
|
||||||
|
private final int flags;
|
||||||
|
private boolean finished = false;
|
||||||
|
|
||||||
|
// A lambda to sort map keys
|
||||||
|
private Comparator<Value> keyComparator = new Comparator<Value>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Value o1, Value o2) {
|
||||||
|
int ia = o1.key;
|
||||||
|
int io = o2.key;
|
||||||
|
byte c1, c2;
|
||||||
|
do {
|
||||||
|
c1 = bb.get(ia);
|
||||||
|
c2 = bb.get(io);
|
||||||
|
if (c1 == 0)
|
||||||
|
return c1 - c2;
|
||||||
|
ia++;
|
||||||
|
io++;
|
||||||
|
}
|
||||||
|
while (c1 == c2);
|
||||||
|
return c1 - c2;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
|
||||||
|
* @param bufSize size of buffer in bytes.
|
||||||
|
*/
|
||||||
|
public FlexBuffersBuilder(int bufSize) {
|
||||||
|
this(new ArrayReadWriteBuf(bufSize), BUILDER_FLAG_SHARE_KEYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a newly allocated {@code FlexBuffersBuilder} with {@link #BUILDER_FLAG_SHARE_KEYS} set.
|
||||||
|
*/
|
||||||
|
public FlexBuffersBuilder() {
|
||||||
|
this(256);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a newly allocated {@code FlexBuffersBuilder}.
|
||||||
|
*
|
||||||
|
* @param bb `ByteBuffer` that will hold the message
|
||||||
|
* @param flags Share flags
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public FlexBuffersBuilder(ByteBuffer bb, int flags) {
|
||||||
|
this(new ArrayReadWriteBuf(bb.array()), flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlexBuffersBuilder(ReadWriteBuf bb, int flags) {
|
||||||
|
this.bb = bb;
|
||||||
|
this.flags = flags;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a newly allocated {@code FlexBuffersBuilder}.
|
||||||
|
* By default same keys will be serialized only once
|
||||||
|
* @param bb `ByteBuffer` that will hold the message
|
||||||
|
*/
|
||||||
|
public FlexBuffersBuilder(ByteBuffer bb) {
|
||||||
|
this(bb, BUILDER_FLAG_SHARE_KEYS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return `ByteBuffer` containing FlexBuffer message. {@code #finish()} must be called before calling this
|
||||||
|
* function otherwise an assert will trigger.
|
||||||
|
*
|
||||||
|
* @return `ByteBuffer` with finished message
|
||||||
|
*/
|
||||||
|
public ReadWriteBuf getBuffer() {
|
||||||
|
assert (finished);
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a single boolean into the buffer
|
||||||
|
* @param val true or false
|
||||||
|
*/
|
||||||
|
public void putBoolean(boolean val) {
|
||||||
|
putBoolean(null, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Insert a single boolean into the buffer
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param val true or false
|
||||||
|
*/
|
||||||
|
public void putBoolean(String key, boolean val) {
|
||||||
|
stack.add(Value.bool(putKey(key), val));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int putKey(String key) {
|
||||||
|
if (key == null) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int pos = bb.writePosition();
|
||||||
|
if ((flags & BUILDER_FLAG_SHARE_KEYS) != 0) {
|
||||||
|
Integer keyFromPool = keyPool.get(key);
|
||||||
|
if (keyFromPool == null) {
|
||||||
|
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||||
|
bb.put(keyBytes, 0, keyBytes.length);
|
||||||
|
bb.put((byte) 0);
|
||||||
|
keyPool.put(key, pos);
|
||||||
|
} else {
|
||||||
|
pos = keyFromPool;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
byte[] keyBytes = key.getBytes(StandardCharsets.UTF_8);
|
||||||
|
bb.put(keyBytes, 0, keyBytes.length);
|
||||||
|
bb.put((byte) 0);
|
||||||
|
keyPool.put(key, pos);
|
||||||
|
}
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a integer into the buff
|
||||||
|
* @param val integer
|
||||||
|
*/
|
||||||
|
public void putInt(int val) {
|
||||||
|
putInt(null, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a integer into the buff
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param val integer
|
||||||
|
*/
|
||||||
|
public void putInt(String key, int val) {
|
||||||
|
putInt(key, (long) val);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a integer into the buff
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param val 64-bit integer
|
||||||
|
*/
|
||||||
|
public void putInt(String key, long val) {
|
||||||
|
int iKey = putKey(key);
|
||||||
|
if (Byte.MIN_VALUE <= val && val <= Byte.MAX_VALUE) {
|
||||||
|
stack.add(Value.int8(iKey, (int) val));
|
||||||
|
} else if (Short.MIN_VALUE <= val && val <= Short.MAX_VALUE) {
|
||||||
|
stack.add(Value.int16(iKey, (int) val));
|
||||||
|
} else if (Integer.MIN_VALUE <= val && val <= Integer.MAX_VALUE) {
|
||||||
|
stack.add(Value.int32(iKey, (int) val));
|
||||||
|
} else {
|
||||||
|
stack.add(Value.int64(iKey, val));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a 64-bit integer into the buff
|
||||||
|
* @param value integer
|
||||||
|
*/
|
||||||
|
public void putInt(long value) {
|
||||||
|
putInt(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a unsigned integer into the buff.
|
||||||
|
* @param value integer representing unsigned value
|
||||||
|
*/
|
||||||
|
public void putUInt(int value) {
|
||||||
|
putUInt(null, (long) value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a unsigned integer (stored in a signed 64-bit integer) into the buff.
|
||||||
|
* @param value integer representing unsigned value
|
||||||
|
*/
|
||||||
|
public void putUInt(long value) {
|
||||||
|
putUInt(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a 64-bit unsigned integer (stored as {@link BigInteger}) into the buff.
|
||||||
|
* Warning: This operation might be very slow.
|
||||||
|
* @param value integer representing unsigned value
|
||||||
|
*/
|
||||||
|
public void putUInt64(BigInteger value) {
|
||||||
|
putUInt64(null, value.longValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putUInt64(String key, long value) {
|
||||||
|
stack.add(Value.uInt64(putKey(key), value));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void putUInt(String key, long value) {
|
||||||
|
int iKey = putKey(key);
|
||||||
|
Value vVal;
|
||||||
|
|
||||||
|
int width = widthUInBits(value);
|
||||||
|
|
||||||
|
if (width == WIDTH_8) {
|
||||||
|
vVal = Value.uInt8(iKey, (int)value);
|
||||||
|
} else if (width == WIDTH_16) {
|
||||||
|
vVal = Value.uInt16(iKey, (int)value);
|
||||||
|
} else if (width == WIDTH_32) {
|
||||||
|
vVal = Value.uInt32(iKey, (int)value);
|
||||||
|
} else {
|
||||||
|
vVal = Value.uInt64(iKey, value);
|
||||||
|
}
|
||||||
|
stack.add(vVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a 32-bit float into the buff.
|
||||||
|
* @param value float representing value
|
||||||
|
*/
|
||||||
|
public void putFloat(float value) {
|
||||||
|
putFloat(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a 32-bit float into the buff.
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param value float representing value
|
||||||
|
*/
|
||||||
|
public void putFloat(String key, float val) {
|
||||||
|
stack.add(Value.float32(putKey(key), val));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a 64-bit float into the buff.
|
||||||
|
* @param value float representing value
|
||||||
|
*/
|
||||||
|
public void putFloat(double value) {
|
||||||
|
putFloat(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a 64-bit float into the buff.
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param value float representing value
|
||||||
|
*/
|
||||||
|
public void putFloat(String key, double val) {
|
||||||
|
stack.add(Value.float64(putKey(key), val));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a String into the buffer
|
||||||
|
* @param value string
|
||||||
|
* @return start position of string in the buffer
|
||||||
|
*/
|
||||||
|
public int putString(String value) {
|
||||||
|
return putString(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a String into the buffer
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param value string
|
||||||
|
* @return start position of string in the buffer
|
||||||
|
*/
|
||||||
|
public int putString(String key, String val) {
|
||||||
|
int iKey = putKey(key);
|
||||||
|
if ((flags & FlexBuffersBuilder.BUILDER_FLAG_SHARE_STRINGS) != 0) {
|
||||||
|
Integer i = stringPool.get(val);
|
||||||
|
if (i == null) {
|
||||||
|
Value value = writeString(iKey, val);
|
||||||
|
stringPool.put(val, (int) value.iValue);
|
||||||
|
stack.add(value);
|
||||||
|
return (int) value.iValue;
|
||||||
|
} else {
|
||||||
|
int bitWidth = widthUInBits(val.length());
|
||||||
|
stack.add(Value.blob(iKey, i, FBT_STRING, bitWidth));
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Value value = writeString(iKey, val);
|
||||||
|
stack.add(value);
|
||||||
|
return (int) value.iValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value writeString(int key, String s) {
|
||||||
|
return writeBlob(key, s.getBytes(StandardCharsets.UTF_8), FBT_STRING, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// in bits to fit a unsigned int
|
||||||
|
static int widthUInBits(long len) {
|
||||||
|
if (len <= byteToUnsignedInt((byte)0xff)) return WIDTH_8;
|
||||||
|
if (len <= shortToUnsignedInt((short)0xffff)) return WIDTH_16;
|
||||||
|
if (len <= intToUnsignedLong(0xffff_ffff)) return WIDTH_32;
|
||||||
|
return WIDTH_64;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value writeBlob(int key, byte[] blob, int type, boolean trailing) {
|
||||||
|
int bitWidth = widthUInBits(blob.length);
|
||||||
|
int byteWidth = align(bitWidth);
|
||||||
|
writeInt(blob.length, byteWidth);
|
||||||
|
int sloc = bb.writePosition();
|
||||||
|
bb.put(blob, 0, blob.length);
|
||||||
|
if (trailing) {
|
||||||
|
bb.put((byte) 0);
|
||||||
|
}
|
||||||
|
return Value.blob(key, sloc, type, bitWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Align to prepare for writing a scalar with a certain size.
|
||||||
|
private int align(int alignment) {
|
||||||
|
int byteWidth = 1 << alignment;
|
||||||
|
int padBytes = Value.paddingBytes(bb.writePosition(), byteWidth);
|
||||||
|
while (padBytes-- != 0) {
|
||||||
|
bb.put((byte) 0);
|
||||||
|
}
|
||||||
|
return byteWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeInt(long value, int byteWidth) {
|
||||||
|
switch (byteWidth) {
|
||||||
|
case 1: bb.put((byte) value); break;
|
||||||
|
case 2: bb.putShort((short) value); break;
|
||||||
|
case 4: bb.putInt((int) value); break;
|
||||||
|
case 8: bb.putLong(value); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a byte array into the message
|
||||||
|
* @param value byte array
|
||||||
|
* @return position in buffer as the start of byte array
|
||||||
|
*/
|
||||||
|
public int putBlob(byte[] value) {
|
||||||
|
return putBlob(null, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a byte array into the message
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param value byte array
|
||||||
|
* @return position in buffer as the start of byte array
|
||||||
|
*/
|
||||||
|
public int putBlob(String key, byte[] val) {
|
||||||
|
int iKey = putKey(key);
|
||||||
|
Value value = writeBlob(iKey, val, FBT_BLOB, false);
|
||||||
|
stack.add(value);
|
||||||
|
return (int) value.iValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a new vector in the buffer.
|
||||||
|
* @return a reference indicating position of the vector in buffer. This
|
||||||
|
* reference must be passed along when the vector is finished using endVector()
|
||||||
|
*/
|
||||||
|
public int startVector() {
|
||||||
|
return stack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes a vector, but writing the information in the buffer
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param start reference for begining of the vector. Returned by {@link startVector()}
|
||||||
|
* @param typed boolean indicating wether vector is typed
|
||||||
|
* @param fixed boolean indicating wether vector is fixed
|
||||||
|
* @return Reference to the vector
|
||||||
|
*/
|
||||||
|
public int endVector(String key, int start, boolean typed, boolean fixed) {
|
||||||
|
int iKey = putKey(key);
|
||||||
|
Value vec = createVector(iKey, start, stack.size() - start, typed, fixed, null);
|
||||||
|
// Remove temp elements and return vector.
|
||||||
|
while (stack.size() > start) {
|
||||||
|
stack.remove(stack.size() - 1);
|
||||||
|
}
|
||||||
|
stack.add(vec);
|
||||||
|
return (int) vec.iValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish writing the message into the buffer. After that no other element must
|
||||||
|
* be inserted into the buffer. Also, you must call this function before start using the
|
||||||
|
* FlexBuffer message
|
||||||
|
* @return `ByteBuffer` containing the FlexBuffer message
|
||||||
|
*/
|
||||||
|
public ByteBuffer finish() {
|
||||||
|
// If you hit this assert, you likely have objects that were never included
|
||||||
|
// in a parent. You need to have exactly one root to finish a buffer.
|
||||||
|
// Check your Start/End calls are matched, and all objects are inside
|
||||||
|
// some other object.
|
||||||
|
assert (stack.size() == 1);
|
||||||
|
// Write root value.
|
||||||
|
int byteWidth = align(stack.get(0).elemWidth(bb.writePosition(), 0));
|
||||||
|
writeAny(stack.get(0), byteWidth);
|
||||||
|
// Write root type.
|
||||||
|
bb.put(stack.get(0).storedPackedType());
|
||||||
|
// Write root size. Normally determined by parent, but root has no parent :)
|
||||||
|
bb.put((byte) byteWidth);
|
||||||
|
this.finished = true;
|
||||||
|
return ByteBuffer.wrap(bb.data(), 0, bb.writePosition());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a vector based on the elements stored in the stack
|
||||||
|
*
|
||||||
|
* @param key reference to its key
|
||||||
|
* @param start element in the stack
|
||||||
|
* @param length size of the vector
|
||||||
|
* @param typed whether is TypedVector or not
|
||||||
|
* @param fixed whether is Fixed vector or not
|
||||||
|
* @param keys Value representing key vector
|
||||||
|
* @return Value representing the created vector
|
||||||
|
*/
|
||||||
|
private Value createVector(int key, int start, int length, boolean typed, boolean fixed, Value keys) {
|
||||||
|
assert (!fixed || typed); // typed=false, fixed=true combination is not supported.
|
||||||
|
// Figure out smallest bit width we can store this vector with.
|
||||||
|
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
|
||||||
|
int prefixElems = 1;
|
||||||
|
if (keys != null) {
|
||||||
|
// If this vector is part of a map, we will pre-fix an offset to the keys
|
||||||
|
// to this vector.
|
||||||
|
bitWidth = Math.max(bitWidth, keys.elemWidth(bb.writePosition(), 0));
|
||||||
|
prefixElems += 2;
|
||||||
|
}
|
||||||
|
int vectorType = FBT_KEY;
|
||||||
|
// Check bit widths and types for all elements.
|
||||||
|
for (int i = start; i < stack.size(); i++) {
|
||||||
|
int elemWidth = stack.get(i).elemWidth(bb.writePosition(), i + prefixElems);
|
||||||
|
bitWidth = Math.max(bitWidth, elemWidth);
|
||||||
|
if (typed) {
|
||||||
|
if (i == start) {
|
||||||
|
vectorType = stack.get(i).type;
|
||||||
|
if (!FlexBuffers.isTypedVectorElementType(vectorType)) {
|
||||||
|
throw new FlexBufferException("TypedVector does not support this element type");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// If you get this assert, you are writing a typed vector with
|
||||||
|
// elements that are not all the same type.
|
||||||
|
assert (vectorType == stack.get(i).type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If you get this assert, your fixed types are not one of:
|
||||||
|
// Int / UInt / Float / Key.
|
||||||
|
assert (!fixed || FlexBuffers.isTypedVectorElementType(vectorType));
|
||||||
|
|
||||||
|
int byteWidth = align(bitWidth);
|
||||||
|
// Write vector. First the keys width/offset if available, and size.
|
||||||
|
if (keys != null) {
|
||||||
|
writeOffset(keys.iValue, byteWidth);
|
||||||
|
writeInt(1L << keys.minBitWidth, byteWidth);
|
||||||
|
}
|
||||||
|
if (!fixed) {
|
||||||
|
writeInt(length, byteWidth);
|
||||||
|
}
|
||||||
|
// Then the actual data.
|
||||||
|
int vloc = bb.writePosition();
|
||||||
|
for (int i = start; i < stack.size(); i++) {
|
||||||
|
writeAny(stack.get(i), byteWidth);
|
||||||
|
}
|
||||||
|
// Then the types.
|
||||||
|
if (!typed) {
|
||||||
|
for (int i = start; i < stack.size(); i++) {
|
||||||
|
bb.put(stack.get(i).storedPackedType(bitWidth));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Value(key, keys != null ? FBT_MAP
|
||||||
|
: (typed ? FlexBuffers.toTypedVector(vectorType, fixed ? length : 0)
|
||||||
|
: FBT_VECTOR), bitWidth, vloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeOffset(long val, int byteWidth) {
|
||||||
|
int reloff = (int) (bb.writePosition() - val);
|
||||||
|
assert (byteWidth == 8 || reloff < 1L << (byteWidth * 8));
|
||||||
|
writeInt(reloff, byteWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeAny(final Value val, int byteWidth) {
|
||||||
|
switch (val.type) {
|
||||||
|
case FBT_NULL:
|
||||||
|
case FBT_BOOL:
|
||||||
|
case FBT_INT:
|
||||||
|
case FBT_UINT:
|
||||||
|
writeInt(val.iValue, byteWidth);
|
||||||
|
break;
|
||||||
|
case FBT_FLOAT:
|
||||||
|
writeDouble(val.dValue, byteWidth);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
writeOffset(val.iValue, byteWidth);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeDouble(double val, int byteWidth) {
|
||||||
|
if (byteWidth == 4) {
|
||||||
|
bb.putFloat((float) val);
|
||||||
|
} else if (byteWidth == 8) {
|
||||||
|
bb.putDouble(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start a new map in the buffer.
|
||||||
|
* @return a reference indicating position of the map in buffer. This
|
||||||
|
* reference must be passed along when the map is finished using endMap()
|
||||||
|
*/
|
||||||
|
public int startMap() {
|
||||||
|
return stack.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finishes a map, but writing the information in the buffer
|
||||||
|
* @param key key used to store element in map
|
||||||
|
* @param start reference for begining of the map. Returned by {@link startMap()}
|
||||||
|
* @return Reference to the map
|
||||||
|
*/
|
||||||
|
public int endMap(String key, int start) {
|
||||||
|
int iKey = putKey(key);
|
||||||
|
|
||||||
|
Collections.sort(stack.subList(start, stack.size()), keyComparator);
|
||||||
|
|
||||||
|
Value keys = createKeyVector(start, stack.size() - start);
|
||||||
|
Value vec = createVector(iKey, start, stack.size() - start, false, false, keys);
|
||||||
|
// Remove temp elements and return map.
|
||||||
|
while (stack.size() > start) {
|
||||||
|
stack.remove(stack.size() - 1);
|
||||||
|
}
|
||||||
|
stack.add(vec);
|
||||||
|
return (int) vec.iValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Value createKeyVector(int start, int length) {
|
||||||
|
// Figure out smallest bit width we can store this vector with.
|
||||||
|
int bitWidth = Math.max(WIDTH_8, widthUInBits(length));
|
||||||
|
int prefixElems = 1;
|
||||||
|
// Check bit widths and types for all elements.
|
||||||
|
for (int i = start; i < stack.size(); i++) {
|
||||||
|
int elemWidth = Value.elemWidth(FBT_KEY, WIDTH_8, stack.get(i).key, bb.writePosition(), i + prefixElems);
|
||||||
|
bitWidth = Math.max(bitWidth, elemWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
int byteWidth = align(bitWidth);
|
||||||
|
// Write vector. First the keys width/offset if available, and size.
|
||||||
|
writeInt(length, byteWidth);
|
||||||
|
// Then the actual data.
|
||||||
|
int vloc = bb.writePosition();
|
||||||
|
for (int i = start; i < stack.size(); i++) {
|
||||||
|
int pos = stack.get(i).key;
|
||||||
|
assert(pos != -1);
|
||||||
|
writeOffset(stack.get(i).key, byteWidth);
|
||||||
|
}
|
||||||
|
// Then the types.
|
||||||
|
return new Value(-1, FlexBuffers.toTypedVector(FBT_KEY,0), bitWidth, vloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Value {
|
||||||
|
final int type;
|
||||||
|
// for scalars, represents scalar size in bytes
|
||||||
|
// for vectors, represents the size
|
||||||
|
// for string, length
|
||||||
|
final int minBitWidth;
|
||||||
|
// float value
|
||||||
|
final double dValue;
|
||||||
|
// integer value
|
||||||
|
long iValue;
|
||||||
|
// position of the key associated with this value in buffer
|
||||||
|
int key;
|
||||||
|
|
||||||
|
Value(int key, int type, int bitWidth, long iValue) {
|
||||||
|
this.key = key;
|
||||||
|
this.type = type;
|
||||||
|
this.minBitWidth = bitWidth;
|
||||||
|
this.iValue = iValue;
|
||||||
|
this.dValue = Double.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value(int key, int type, int bitWidth, double dValue) {
|
||||||
|
this.key = key;
|
||||||
|
this.type = type;
|
||||||
|
this.minBitWidth = bitWidth;
|
||||||
|
this.dValue = dValue;
|
||||||
|
this.iValue = Long.MIN_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value bool(int key, boolean b) {
|
||||||
|
return new Value(key, FBT_BOOL, WIDTH_8, b ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value blob(int key, int position, int type, int bitWidth) {
|
||||||
|
return new Value(key, type, bitWidth, position);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value int8(int key, int value) {
|
||||||
|
return new Value(key, FBT_INT, WIDTH_8, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value int16(int key, int value) {
|
||||||
|
return new Value(key, FBT_INT, WIDTH_16, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value int32(int key, int value) {
|
||||||
|
return new Value(key, FBT_INT, WIDTH_32, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value int64(int key, long value) {
|
||||||
|
return new Value(key, FBT_INT, WIDTH_64, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value uInt8(int key, int value) {
|
||||||
|
return new Value(key, FBT_UINT, WIDTH_8, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value uInt16(int key, int value) {
|
||||||
|
return new Value(key, FBT_UINT, WIDTH_16, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value uInt32(int key, int value) {
|
||||||
|
return new Value(key, FBT_UINT, WIDTH_32, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value uInt64(int key, long value) {
|
||||||
|
return new Value(key, FBT_UINT, WIDTH_64, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value float32(int key, float value) {
|
||||||
|
return new Value(key, FBT_FLOAT, WIDTH_32, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Value float64(int key, double value) {
|
||||||
|
return new Value(key, FBT_FLOAT, WIDTH_64, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte storedPackedType() {
|
||||||
|
return storedPackedType(WIDTH_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
private byte storedPackedType(int parentBitWidth) {
|
||||||
|
return packedType(storedWidth(parentBitWidth), type);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static byte packedType(int bitWidth, int type) {
|
||||||
|
return (byte) (bitWidth | (type << 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private int storedWidth(int parentBitWidth) {
|
||||||
|
if (FlexBuffers.isTypeInline(type)) {
|
||||||
|
return Math.max(minBitWidth, parentBitWidth);
|
||||||
|
} else {
|
||||||
|
return minBitWidth;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int elemWidth(int bufSize, int elemIndex) {
|
||||||
|
return elemWidth(type, minBitWidth, iValue, bufSize, elemIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int elemWidth(int type, int minBitWidth, long iValue, int bufSize, int elemIndex) {
|
||||||
|
if (FlexBuffers.isTypeInline(type)) {
|
||||||
|
return minBitWidth;
|
||||||
|
} else {
|
||||||
|
// We have an absolute offset, but want to store a relative offset
|
||||||
|
// elem_index elements beyond the current buffer end. Since whether
|
||||||
|
// the relative offset fits in a certain byte_width depends on
|
||||||
|
// the size of the elements before it (and their alignment), we have
|
||||||
|
// to test for each size in turn.
|
||||||
|
|
||||||
|
// Original implementation checks for largest scalar
|
||||||
|
// which is long unsigned int
|
||||||
|
for (int byteWidth = 1; byteWidth <= 32; byteWidth *= 2) {
|
||||||
|
// Where are we going to write this offset?
|
||||||
|
int offsetLoc = bufSize + paddingBytes(bufSize, byteWidth) + (elemIndex * byteWidth);
|
||||||
|
// Compute relative offset.
|
||||||
|
long offset = offsetLoc - iValue;
|
||||||
|
// Does it fit?
|
||||||
|
int bitWidth = widthUInBits((int) offset);
|
||||||
|
if (((1L) << bitWidth) == byteWidth)
|
||||||
|
return bitWidth;
|
||||||
|
}
|
||||||
|
assert (false); // Must match one of the sizes above.
|
||||||
|
return WIDTH_64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int paddingBytes(int bufSize, int scalarSize) {
|
||||||
|
return ((~bufSize) + 1) & (scalarSize - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @}
|
||||||
49
java/com/google/flatbuffers/FloatVector.java
Normal file
49
java/com/google/flatbuffers/FloatVector.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of float values.
|
||||||
|
*/
|
||||||
|
public final class FloatVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public FloatVector __assign(int _vector, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, Constants.SIZEOF_FLOAT, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the float value at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the float value will be read.
|
||||||
|
* @return the float value at the given index.
|
||||||
|
*/
|
||||||
|
public float get(int j) {
|
||||||
|
return bb.getFloat(__element(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
60
java/com/google/flatbuffers/IntVector.java
Normal file
60
java/com/google/flatbuffers/IntVector.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of signed or unsigned 32-bit values.
|
||||||
|
*/
|
||||||
|
public final class IntVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public IntVector __assign(int _vector, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, Constants.SIZEOF_INT, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the integer at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the integer will be read.
|
||||||
|
* @return the 32-bit value at the given index.
|
||||||
|
*/
|
||||||
|
public int get(int j) {
|
||||||
|
return bb.getInt(__element(j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the integer at the given index, zero-extends it to type long, and returns the result,
|
||||||
|
* which is therefore in the range 0 through 4294967295.
|
||||||
|
*
|
||||||
|
* @param j The index from which the integer will be read.
|
||||||
|
* @return the unsigned 32-bit at the given index.
|
||||||
|
*/
|
||||||
|
public long getAsUnsigned(int j) {
|
||||||
|
return (long) get(j) & 0xFFFFFFFFL;
|
||||||
|
}
|
||||||
|
}
|
||||||
49
java/com/google/flatbuffers/LongVector.java
Normal file
49
java/com/google/flatbuffers/LongVector.java
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of long values.
|
||||||
|
*/
|
||||||
|
public final class LongVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public LongVector __assign(int _vector, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, Constants.SIZEOF_LONG, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the long value at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the long value will be read.
|
||||||
|
* @return the signed 64-bit value at the given index.
|
||||||
|
*/
|
||||||
|
public long get(int j) {
|
||||||
|
return bb.getLong(__element(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
81
java/com/google/flatbuffers/ReadBuf.java
Normal file
81
java/com/google/flatbuffers/ReadBuf.java
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represent a chunk of data, where FlexBuffers will read from.
|
||||||
|
*/
|
||||||
|
interface ReadBuf {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read boolean from data. Booleans as stored as single byte
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return boolean element
|
||||||
|
*/
|
||||||
|
boolean getBoolean(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a byte from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a byte
|
||||||
|
*/
|
||||||
|
byte get(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a short from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a short
|
||||||
|
*/
|
||||||
|
short getShort(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 32-bit int from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return an int
|
||||||
|
*/
|
||||||
|
int getInt(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 64-bit long from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a long
|
||||||
|
*/
|
||||||
|
long getLong(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 32-bit float from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a float
|
||||||
|
*/
|
||||||
|
float getFloat(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 64-bit float from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a double
|
||||||
|
*/
|
||||||
|
double getDouble(int index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an UTF-8 string from data.
|
||||||
|
* @param start initial element of the string
|
||||||
|
* @param size size of the string in bytes.
|
||||||
|
* @return a {@code String}
|
||||||
|
*/
|
||||||
|
String getString(int start, int size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Expose ReadBuf as an array of bytes.
|
||||||
|
* This method is meant to be as efficient as possible, so for a array-backed ReadBuf, it should
|
||||||
|
* return its own internal data. In case access to internal data is not possible,
|
||||||
|
* a copy of the data into an array of bytes might occur.
|
||||||
|
* @return ReadBuf as an array of bytes
|
||||||
|
*/
|
||||||
|
byte[] data();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the size of the message in the buffer. It also determines last position that buffer
|
||||||
|
* can be read. Last byte to be accessed is in position {@code limit() -1}.
|
||||||
|
* @return indicate last position
|
||||||
|
*/
|
||||||
|
int limit();
|
||||||
|
|
||||||
|
}
|
||||||
135
java/com/google/flatbuffers/ReadWriteBuf.java
Normal file
135
java/com/google/flatbuffers/ReadWriteBuf.java
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface to represent a read-write buffer. This interface will be used to access and write
|
||||||
|
* FlexBuffers message.
|
||||||
|
*/
|
||||||
|
interface ReadWriteBuf extends ReadBuf {
|
||||||
|
/**
|
||||||
|
* Put a boolean into the buffer at {@code writePosition()} . Booleans as stored as single
|
||||||
|
* byte. Write position will be incremented.
|
||||||
|
* @return boolean element
|
||||||
|
*/
|
||||||
|
void putBoolean(boolean value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put an array of bytes into the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
* @param value the data to be copied
|
||||||
|
* @param start initial position on value to be copied
|
||||||
|
* @param length amount of bytes to be copied
|
||||||
|
*/
|
||||||
|
void put (byte[] value, int start, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a byte into the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
*/
|
||||||
|
void put(byte value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a 16-bit into in the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
*/
|
||||||
|
void putShort(short value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a 32-bit into in the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
*/
|
||||||
|
void putInt(int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a 64-bit into in the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
*/
|
||||||
|
void putLong(long value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a 32-bit float into the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
*/
|
||||||
|
void putFloat(float value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a 64-bit float into the buffer at {@code writePosition()}. Write position will be
|
||||||
|
* incremented.
|
||||||
|
*/
|
||||||
|
void putDouble(double value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write boolean into a given position on the buffer. Booleans as stored as single byte.
|
||||||
|
* @param index position of the element in buffer
|
||||||
|
*/
|
||||||
|
void setBoolean(int index, boolean value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a byte from data.
|
||||||
|
* @param index position of the element in the buffer
|
||||||
|
* @return a byte
|
||||||
|
*/
|
||||||
|
void set(int index, byte value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an array of bytes into the buffer.
|
||||||
|
* @param index initial position of the buffer to be written
|
||||||
|
* @param value the data to be copied
|
||||||
|
* @param start initial position on value to be copied
|
||||||
|
* @param length amount of bytes to be copied
|
||||||
|
*/
|
||||||
|
void set(int index, byte[] value, int start, int length);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a short from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a short
|
||||||
|
*/
|
||||||
|
void setShort(int index, short value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 32-bit int from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return an int
|
||||||
|
*/
|
||||||
|
void setInt(int index, int value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 64-bit long from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a long
|
||||||
|
*/
|
||||||
|
void setLong(int index, long value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 32-bit float from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a float
|
||||||
|
*/
|
||||||
|
void setFloat(int index, float value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read a 64-bit float from data.
|
||||||
|
* @param index position of the element in ReadBuf
|
||||||
|
* @return a double
|
||||||
|
*/
|
||||||
|
void setDouble(int index, double value);
|
||||||
|
|
||||||
|
|
||||||
|
int writePosition();
|
||||||
|
/**
|
||||||
|
* Defines the size of the message in the buffer. It also determines last position that buffer
|
||||||
|
* can be read or write. Last byte to be accessed is in position {@code limit() -1}.
|
||||||
|
* @return indicate last position
|
||||||
|
*/
|
||||||
|
int limit();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request capacity of the buffer. In case buffer is already larger
|
||||||
|
* than the requested, this method will just return true. Otherwise
|
||||||
|
* It might try to resize the buffer.
|
||||||
|
*
|
||||||
|
* @return true if buffer is able to offer
|
||||||
|
* the requested capacity
|
||||||
|
*/
|
||||||
|
boolean requestCapacity(int capacity);
|
||||||
|
}
|
||||||
60
java/com/google/flatbuffers/ShortVector.java
Normal file
60
java/com/google/flatbuffers/ShortVector.java
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of signed or unsigned 16-bit values.
|
||||||
|
*/
|
||||||
|
public final class ShortVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public ShortVector __assign(int _vector, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, Constants.SIZEOF_SHORT, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the short value at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the short value will be read.
|
||||||
|
* @return the 16-bit value at the given index.
|
||||||
|
*/
|
||||||
|
public short get(int j) {
|
||||||
|
return bb.getShort(__element(j));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the short at the given index, zero-extends it to type int, and returns the result,
|
||||||
|
* which is therefore in the range 0 through 65535.
|
||||||
|
*
|
||||||
|
* @param j The index from which the short value will be read.
|
||||||
|
* @return the unsigned 16-bit at the given index.
|
||||||
|
*/
|
||||||
|
public int getAsUnsigned(int j) {
|
||||||
|
return (int) get(j) & 0xFFFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
52
java/com/google/flatbuffers/StringVector.java
Normal file
52
java/com/google/flatbuffers/StringVector.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of String.
|
||||||
|
*/
|
||||||
|
public final class StringVector extends BaseVector {
|
||||||
|
private Utf8 utf8 = Utf8.getDefault();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _element_size Size of a vector element.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public StringVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, _element_size, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the String at the given index.
|
||||||
|
*
|
||||||
|
* @param j The index from which the String value will be read.
|
||||||
|
* @return the String at the given index.
|
||||||
|
*/
|
||||||
|
public String get(int j) {
|
||||||
|
return Table.__string(__element(j), bb, utf8);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,6 +29,21 @@ public class Struct {
|
|||||||
/** The underlying ByteBuffer to hold the data of the Struct. */
|
/** The underlying ByteBuffer to hold the data of the Struct. */
|
||||||
protected ByteBuffer bb;
|
protected ByteBuffer bb;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
|
||||||
|
*
|
||||||
|
* This method exists primarily to allow recycling Table instances without risking memory leaks
|
||||||
|
* due to {@code ByteBuffer} references.
|
||||||
|
*/
|
||||||
|
protected void __reset(int _i, ByteBuffer _bb) {
|
||||||
|
bb = _bb;
|
||||||
|
if (bb != null) {
|
||||||
|
bb_pos = _i;
|
||||||
|
} else {
|
||||||
|
bb_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets internal state with a null {@code ByteBuffer} and a zero position.
|
* Resets internal state with a null {@code ByteBuffer} and a zero position.
|
||||||
*
|
*
|
||||||
@@ -39,8 +54,7 @@ public class Struct {
|
|||||||
* @param struct the instance to reset to initial state
|
* @param struct the instance to reset to initial state
|
||||||
*/
|
*/
|
||||||
public void __reset() {
|
public void __reset() {
|
||||||
bb = null;
|
__reset(0, null);
|
||||||
bb_pos = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package com.google.flatbuffers;
|
|||||||
import static com.google.flatbuffers.Constants.*;
|
import static com.google.flatbuffers.Constants.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.ByteOrder;
|
import java.nio.ByteOrder;
|
||||||
import java.nio.charset.Charset;
|
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
|
|
||||||
@@ -27,20 +26,14 @@ import java.nio.charset.Charset;
|
|||||||
* All tables in the generated code derive from this class, and add their own accessors.
|
* All tables in the generated code derive from this class, and add their own accessors.
|
||||||
*/
|
*/
|
||||||
public class Table {
|
public class Table {
|
||||||
public final static ThreadLocal<Charset> UTF8_CHARSET = new ThreadLocal<Charset>() {
|
|
||||||
@Override
|
|
||||||
protected Charset initialValue() {
|
|
||||||
return Charset.forName("UTF-8");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
/** Used to hold the position of the `bb` buffer. */
|
/** Used to hold the position of the `bb` buffer. */
|
||||||
protected int bb_pos;
|
protected int bb_pos;
|
||||||
/** The underlying ByteBuffer to hold the data of the Table. */
|
/** The underlying ByteBuffer to hold the data of the Table. */
|
||||||
protected ByteBuffer bb;
|
protected ByteBuffer bb;
|
||||||
/** Used to hold the vtable position. */
|
/** Used to hold the vtable position. */
|
||||||
protected int vtable_start;
|
private int vtable_start;
|
||||||
/** Used to hold the vtable size. */
|
/** Used to hold the vtable size. */
|
||||||
protected int vtable_size;
|
private int vtable_size;
|
||||||
Utf8 utf8 = Utf8.getDefault();
|
Utf8 utf8 = Utf8.getDefault();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -75,6 +68,13 @@ public class Table {
|
|||||||
return offset + bb.getInt(offset);
|
return offset + bb.getInt(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve a relative offset.
|
||||||
|
*
|
||||||
|
* @param offset An `int` index into a ByteBuffer containing the relative offset.
|
||||||
|
* @param bb from which the relative offset will be retrieved.
|
||||||
|
* @return Returns the relative offset stored at `offset`.
|
||||||
|
*/
|
||||||
protected static int __indirect(int offset, ByteBuffer bb) {
|
protected static int __indirect(int offset, ByteBuffer bb) {
|
||||||
return offset + bb.getInt(offset);
|
return offset + bb.getInt(offset);
|
||||||
}
|
}
|
||||||
@@ -91,6 +91,23 @@ public class Table {
|
|||||||
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
|
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
|
||||||
*/
|
*/
|
||||||
protected String __string(int offset) {
|
protected String __string(int offset) {
|
||||||
|
return __string(offset, bb, utf8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a Java `String` from UTF-8 data stored inside the FlatBuffer.
|
||||||
|
*
|
||||||
|
* This allocates a new string and converts to wide chars upon each access,
|
||||||
|
* which is not very efficient. Instead, each FlatBuffer string also comes with an
|
||||||
|
* accessor based on __vector_as_bytebuffer below, which is much more efficient,
|
||||||
|
* assuming your Java program can handle UTF-8 data directly.
|
||||||
|
*
|
||||||
|
* @param offset An `int` index into the Table's ByteBuffer.
|
||||||
|
* @param bb Table ByteBuffer used to read a string at given offset.
|
||||||
|
* @param utf8 decoder that creates a Java `String` from UTF-8 characters.
|
||||||
|
* @return Returns a `String` from the data stored inside the FlatBuffer at `offset`.
|
||||||
|
*/
|
||||||
|
protected static String __string(int offset, ByteBuffer bb, Utf8 utf8) {
|
||||||
offset += bb.getInt(offset);
|
offset += bb.getInt(offset);
|
||||||
int length = bb.getInt(offset);
|
int length = bb.getInt(offset);
|
||||||
return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
|
return utf8.decodeUtf8(bb, offset + SIZEOF_INT, length);
|
||||||
@@ -169,11 +186,19 @@ public class Table {
|
|||||||
* @return Returns the Table that points to the union at `offset`.
|
* @return Returns the Table that points to the union at `offset`.
|
||||||
*/
|
*/
|
||||||
protected Table __union(Table t, int offset) {
|
protected Table __union(Table t, int offset) {
|
||||||
offset += bb_pos;
|
return __union(t, offset, bb);
|
||||||
t.bb_pos = offset + bb.getInt(offset);
|
}
|
||||||
t.bb = bb;
|
|
||||||
t.vtable_start = t.bb_pos - bb.getInt(t.bb_pos);
|
/**
|
||||||
t.vtable_size = bb.getShort(t.vtable_start);
|
* Initialize any Table-derived type to point to the union at the given `offset`.
|
||||||
|
*
|
||||||
|
* @param t A `Table`-derived type that should point to the union at `offset`.
|
||||||
|
* @param offset An `int` index into the Table's ByteBuffer.
|
||||||
|
* @param bb Table ByteBuffer used to initialize the object Table-derived type.
|
||||||
|
* @return Returns the Table that points to the union at `offset`.
|
||||||
|
*/
|
||||||
|
protected static Table __union(Table t, int offset, ByteBuffer bb) {
|
||||||
|
t.__reset(__indirect(offset, bb), bb);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,6 +288,25 @@ public class Table {
|
|||||||
return len_1 - len_2;
|
return len_1 - len_2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
|
||||||
|
*
|
||||||
|
* This method exists primarily to allow recycling Table instances without risking memory leaks
|
||||||
|
* due to {@code ByteBuffer} references.
|
||||||
|
*/
|
||||||
|
protected void __reset(int _i, ByteBuffer _bb) {
|
||||||
|
bb = _bb;
|
||||||
|
if (bb != null) {
|
||||||
|
bb_pos = _i;
|
||||||
|
vtable_start = bb_pos - bb.getInt(bb_pos);
|
||||||
|
vtable_size = bb.getShort(vtable_start);
|
||||||
|
} else {
|
||||||
|
bb_pos = 0;
|
||||||
|
vtable_start = 0;
|
||||||
|
vtable_size = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
|
* Resets the internal state with a null {@code ByteBuffer} and a zero position.
|
||||||
*
|
*
|
||||||
@@ -271,10 +315,7 @@ public class Table {
|
|||||||
* again to a {@code ByteBuffer}.
|
* again to a {@code ByteBuffer}.
|
||||||
*/
|
*/
|
||||||
public void __reset() {
|
public void __reset() {
|
||||||
bb = null;
|
__reset(0, null);
|
||||||
bb_pos = 0;
|
|
||||||
vtable_start = 0;
|
|
||||||
vtable_size = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
52
java/com/google/flatbuffers/UnionVector.java
Normal file
52
java/com/google/flatbuffers/UnionVector.java
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.flatbuffers;
|
||||||
|
|
||||||
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper type for accessing vector of unions.
|
||||||
|
*/
|
||||||
|
public final class UnionVector extends BaseVector {
|
||||||
|
/**
|
||||||
|
* Assigns vector access object to vector data.
|
||||||
|
*
|
||||||
|
* @param _vector Start data of a vector.
|
||||||
|
* @param _element_size Size of a vector element.
|
||||||
|
* @param _bb Table's ByteBuffer.
|
||||||
|
* @return Returns current vector access object assigned to vector data whose offset is stored at
|
||||||
|
* `vector`.
|
||||||
|
*/
|
||||||
|
public UnionVector __assign(int _vector, int _element_size, ByteBuffer _bb) {
|
||||||
|
__reset(_vector, _element_size, _bb); return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize any Table-derived type to point to the union at the given `index`.
|
||||||
|
*
|
||||||
|
* @param obj A `Table`-derived type that should point to the union at `index`.
|
||||||
|
* @param j An `int` index into the union vector.
|
||||||
|
* @return Returns the Table that points to the union at `index`.
|
||||||
|
*/
|
||||||
|
public Table get(Table obj, int j) {
|
||||||
|
return Table.__union(obj, __element(j), bb);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -110,9 +110,11 @@ public abstract class Utf8 {
|
|||||||
throws IllegalArgumentException {
|
throws IllegalArgumentException {
|
||||||
// Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
|
// Simultaneously checks for illegal trailing-byte in leading position (<= '11000000') and
|
||||||
// overlong 2-byte, '11000001'.
|
// overlong 2-byte, '11000001'.
|
||||||
if (byte1 < (byte) 0xC2
|
if (byte1 < (byte) 0xC2) {
|
||||||
|| isNotTrailingByte(byte2)) {
|
throw new IllegalArgumentException("Invalid UTF-8: Illegal leading byte in 2 bytes utf");
|
||||||
throw new IllegalArgumentException("Invalid UTF-8");
|
}
|
||||||
|
if (isNotTrailingByte(byte2)) {
|
||||||
|
throw new IllegalArgumentException("Invalid UTF-8: Illegal trailing byte in 2 bytes utf");
|
||||||
}
|
}
|
||||||
resultArr[resultPos] = (char) (((byte1 & 0x1F) << 6) | trailingByteValue(byte2));
|
resultArr[resultPos] = (char) (((byte1 & 0x1F) << 6) | trailingByteValue(byte2));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public class Utf8Old extends Utf8 {
|
|||||||
throw new IllegalArgumentException("bad character encoding", e);
|
throw new IllegalArgumentException("bad character encoding", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
cache.lastOutput.flip();
|
||||||
return cache.lastOutput.remaining();
|
return cache.lastOutput.remaining();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +91,6 @@ public class Utf8Old extends Utf8 {
|
|||||||
buffer.limit(offset + length);
|
buffer.limit(offset + length);
|
||||||
try {
|
try {
|
||||||
CharBuffer result = decoder.decode(buffer);
|
CharBuffer result = decoder.decode(buffer);
|
||||||
result.flip();
|
|
||||||
return result.toString();
|
return result.toString();
|
||||||
} catch (CharacterCodingException e) {
|
} catch (CharacterCodingException e) {
|
||||||
throw new IllegalArgumentException("Bad encoding", e);
|
throw new IllegalArgumentException("Bad encoding", e);
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ final public class Utf8Safe extends Utf8 {
|
|||||||
return utf8Length;
|
return utf8Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String decodeUtf8Array(byte[] bytes, int index, int size) {
|
public static String decodeUtf8Array(byte[] bytes, int index, int size) {
|
||||||
// Bitwise OR combines the sign bits so any negative value fails the check.
|
// Bitwise OR combines the sign bits so any negative value fails the check.
|
||||||
if ((index | size | bytes.length - index - size) < 0) {
|
if ((index | size | bytes.length - index - size) < 0) {
|
||||||
throw new ArrayIndexOutOfBoundsException(
|
throw new ArrayIndexOutOfBoundsException(
|
||||||
@@ -197,7 +197,7 @@ final public class Utf8Safe extends Utf8 {
|
|||||||
return new String(resultArr, 0, resultPos);
|
return new String(resultArr, 0, resultPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
|
public static String decodeUtf8Buffer(ByteBuffer buffer, int offset,
|
||||||
int length) {
|
int length) {
|
||||||
// Bitwise OR combines the sign bits so any negative value fails the check.
|
// Bitwise OR combines the sign bits so any negative value fails the check.
|
||||||
if ((offset | length | buffer.limit() - offset - length) < 0) {
|
if ((offset | length | buffer.limit() - offset - length) < 0) {
|
||||||
|
|||||||
@@ -48,6 +48,12 @@ flatbuffers.SIZEOF_INT = 4;
|
|||||||
*/
|
*/
|
||||||
flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
|
flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {number}
|
||||||
|
* @const
|
||||||
|
*/
|
||||||
|
flatbuffers.SIZE_PREFIX_LENGTH = 4;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @enum {number}
|
* @enum {number}
|
||||||
*/
|
*/
|
||||||
@@ -104,7 +110,7 @@ flatbuffers.Long = function(low, high) {
|
|||||||
/**
|
/**
|
||||||
* @param {number} low
|
* @param {number} low
|
||||||
* @param {number} high
|
* @param {number} high
|
||||||
* @returns {flatbuffers.Long}
|
* @returns {!flatbuffers.Long}
|
||||||
*/
|
*/
|
||||||
flatbuffers.Long.create = function(low, high) {
|
flatbuffers.Long.create = function(low, high) {
|
||||||
// Special-case zero to avoid GC overhead for default values
|
// Special-case zero to avoid GC overhead for default values
|
||||||
@@ -127,7 +133,7 @@ flatbuffers.Long.prototype.equals = function(other) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {flatbuffers.Long}
|
* @type {!flatbuffers.Long}
|
||||||
* @const
|
* @const
|
||||||
*/
|
*/
|
||||||
flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
|
flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
|
||||||
@@ -265,7 +271,7 @@ flatbuffers.Builder.prototype.dataBuffer = function() {
|
|||||||
* Get the bytes representing the FlatBuffer. Only call this after you've
|
* Get the bytes representing the FlatBuffer. Only call this after you've
|
||||||
* called finish().
|
* called finish().
|
||||||
*
|
*
|
||||||
* @returns {Uint8Array}
|
* @returns {!Uint8Array}
|
||||||
*/
|
*/
|
||||||
flatbuffers.Builder.prototype.asUint8Array = function() {
|
flatbuffers.Builder.prototype.asUint8Array = function() {
|
||||||
return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
|
return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
|
||||||
@@ -550,7 +556,7 @@ flatbuffers.Builder.prototype.offset = function() {
|
|||||||
* the end of the new buffer (since we build the buffer backwards).
|
* the end of the new buffer (since we build the buffer backwards).
|
||||||
*
|
*
|
||||||
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
|
* @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
|
||||||
* @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
|
* @returns {!flatbuffers.ByteBuffer} A new byte buffer with the old data copied
|
||||||
* to it. The data is located at the end of the buffer.
|
* to it. The data is located at the end of the buffer.
|
||||||
*
|
*
|
||||||
* uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
|
* uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
|
||||||
@@ -676,12 +682,14 @@ outer_loop:
|
|||||||
*
|
*
|
||||||
* @param {flatbuffers.Offset} root_table
|
* @param {flatbuffers.Offset} root_table
|
||||||
* @param {string=} opt_file_identifier
|
* @param {string=} opt_file_identifier
|
||||||
|
* @param {boolean=} opt_size_prefix
|
||||||
*/
|
*/
|
||||||
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
|
flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier, opt_size_prefix) {
|
||||||
|
var size_prefix = opt_size_prefix ? flatbuffers.SIZE_PREFIX_LENGTH : 0;
|
||||||
if (opt_file_identifier) {
|
if (opt_file_identifier) {
|
||||||
var file_identifier = opt_file_identifier;
|
var file_identifier = opt_file_identifier;
|
||||||
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
|
this.prep(this.minalign, flatbuffers.SIZEOF_INT +
|
||||||
flatbuffers.FILE_IDENTIFIER_LENGTH);
|
flatbuffers.FILE_IDENTIFIER_LENGTH + size_prefix);
|
||||||
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
|
if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
|
||||||
throw new Error('FlatBuffers: file identifier must be length ' +
|
throw new Error('FlatBuffers: file identifier must be length ' +
|
||||||
flatbuffers.FILE_IDENTIFIER_LENGTH);
|
flatbuffers.FILE_IDENTIFIER_LENGTH);
|
||||||
@@ -690,11 +698,24 @@ flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier)
|
|||||||
this.writeInt8(file_identifier.charCodeAt(i));
|
this.writeInt8(file_identifier.charCodeAt(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.prep(this.minalign, flatbuffers.SIZEOF_INT);
|
this.prep(this.minalign, flatbuffers.SIZEOF_INT + size_prefix);
|
||||||
this.addOffset(root_table);
|
this.addOffset(root_table);
|
||||||
|
if (size_prefix) {
|
||||||
|
this.addInt32(this.bb.capacity() - this.space);
|
||||||
|
}
|
||||||
this.bb.setPosition(this.space);
|
this.bb.setPosition(this.space);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finalize a size prefixed buffer, pointing to the given `root_table`.
|
||||||
|
*
|
||||||
|
* @param {flatbuffers.Offset} root_table
|
||||||
|
* @param {string=} opt_file_identifier
|
||||||
|
*/
|
||||||
|
flatbuffers.Builder.prototype.finishSizePrefixed = function (root_table, opt_file_identifier) {
|
||||||
|
this.finish(root_table, opt_file_identifier, true);
|
||||||
|
};
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
/**
|
/**
|
||||||
* This checks a required field has been set in a given table that has
|
* This checks a required field has been set in a given table that has
|
||||||
@@ -804,7 +825,7 @@ flatbuffers.Builder.prototype.createString = function(s) {
|
|||||||
*
|
*
|
||||||
* @param {number} low
|
* @param {number} low
|
||||||
* @param {number} high
|
* @param {number} high
|
||||||
* @returns {flatbuffers.Long}
|
* @returns {!flatbuffers.Long}
|
||||||
*/
|
*/
|
||||||
flatbuffers.Builder.prototype.createLong = function(low, high) {
|
flatbuffers.Builder.prototype.createLong = function(low, high) {
|
||||||
return flatbuffers.Long.create(low, high);
|
return flatbuffers.Long.create(low, high);
|
||||||
@@ -835,7 +856,7 @@ flatbuffers.ByteBuffer = function(bytes) {
|
|||||||
* Create and allocate a new ByteBuffer with a given size.
|
* Create and allocate a new ByteBuffer with a given size.
|
||||||
*
|
*
|
||||||
* @param {number} byte_size
|
* @param {number} byte_size
|
||||||
* @returns {flatbuffers.ByteBuffer}
|
* @returns {!flatbuffers.ByteBuffer}
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.allocate = function(byte_size) {
|
flatbuffers.ByteBuffer.allocate = function(byte_size) {
|
||||||
return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
|
return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
|
||||||
@@ -931,7 +952,7 @@ flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @returns {flatbuffers.Long}
|
* @returns {!flatbuffers.Long}
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
|
flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
|
||||||
return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
|
return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
|
||||||
@@ -939,7 +960,7 @@ flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @returns {flatbuffers.Long}
|
* @returns {!flatbuffers.Long}
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
|
flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
|
||||||
return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
|
return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
|
||||||
@@ -1114,7 +1135,7 @@ flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
|
|||||||
*
|
*
|
||||||
* @param {number} offset
|
* @param {number} offset
|
||||||
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
|
* @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
|
||||||
* @returns {string|Uint8Array}
|
* @returns {string|!Uint8Array}
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
|
flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
|
||||||
offset += this.readInt32(offset);
|
offset += this.readInt32(offset);
|
||||||
@@ -1225,7 +1246,7 @@ flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
|
|||||||
*
|
*
|
||||||
* @param {number} low
|
* @param {number} low
|
||||||
* @param {number} high
|
* @param {number} high
|
||||||
* @returns {flatbuffers.Long}
|
* @returns {!flatbuffers.Long}
|
||||||
*/
|
*/
|
||||||
flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
|
flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
|
||||||
return flatbuffers.Long.create(low, high);
|
return flatbuffers.Long.create(low, high);
|
||||||
|
|||||||
@@ -12,32 +12,37 @@
|
|||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
include "std.lobster"
|
import std
|
||||||
|
|
||||||
namespace flatbuffers
|
namespace flatbuffers
|
||||||
|
|
||||||
struct handle:
|
class handle:
|
||||||
buf_:string
|
buf_:string
|
||||||
pos_:int
|
pos_:int
|
||||||
|
|
||||||
enum + sz_8 = 1,
|
// More strongly typed than a naked int, at no cost.
|
||||||
sz_16 = 2,
|
struct offset:
|
||||||
sz_32 = 4,
|
o:int
|
||||||
sz_64 = 8,
|
|
||||||
sz_voffset = 2,
|
|
||||||
sz_uoffset = 4,
|
|
||||||
sz_soffset = 4,
|
|
||||||
sz_metadata_fields = 2
|
|
||||||
|
|
||||||
struct builder:
|
enum sizeof:
|
||||||
buf:string = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
sz_8 = 1
|
||||||
|
sz_16 = 2
|
||||||
|
sz_32 = 4
|
||||||
|
sz_64 = 8
|
||||||
|
sz_voffset = 2
|
||||||
|
sz_uoffset = 4
|
||||||
|
sz_soffset = 4
|
||||||
|
sz_metadata_fields = 2
|
||||||
|
|
||||||
|
class builder:
|
||||||
|
buf = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
|
||||||
current_vtable:[int] = []
|
current_vtable:[int] = []
|
||||||
head:int = 0
|
head = 0
|
||||||
minalign:int = 1
|
minalign = 1
|
||||||
object_end:int = 0
|
object_end = 0
|
||||||
vtables:[int] = []
|
vtables:[int] = []
|
||||||
nested:int = false
|
nested = false
|
||||||
finished:int = false
|
finished = false
|
||||||
|
|
||||||
// Optionally call this right after creating the builder for a larger initial buffer.
|
// Optionally call this right after creating the builder for a larger initial buffer.
|
||||||
def Initial(initial_size:int):
|
def Initial(initial_size:int):
|
||||||
@@ -49,7 +54,7 @@ struct builder:
|
|||||||
|
|
||||||
def Offset():
|
def Offset():
|
||||||
// Offset relative to the end of the buffer.
|
// Offset relative to the end of the buffer.
|
||||||
return head
|
return offset { head }
|
||||||
|
|
||||||
// Returns a copy of the part of the buffer containing only the finished FlatBuffer
|
// Returns a copy of the part of the buffer containing only the finished FlatBuffer
|
||||||
def SizedCopy():
|
def SizedCopy():
|
||||||
@@ -75,11 +80,11 @@ struct builder:
|
|||||||
// Prepend a zero scalar to the object. Later in this function we'll
|
// Prepend a zero scalar to the object. Later in this function we'll
|
||||||
// write an offset here that points to the object's vtable:
|
// write an offset here that points to the object's vtable:
|
||||||
PrependInt32(0)
|
PrependInt32(0)
|
||||||
object_offset := head
|
let object_offset = head
|
||||||
// Write out new vtable speculatively.
|
// Write out new vtable speculatively.
|
||||||
vtable_size := (current_vtable.length + sz_metadata_fields) * sz_voffset
|
let vtable_size = (current_vtable.length + sz_metadata_fields) * sz_voffset
|
||||||
while current_vtable.length:
|
while current_vtable.length:
|
||||||
o := current_vtable.pop()
|
let o = current_vtable.pop()
|
||||||
PrependVOffsetT(if o: object_offset - o else: 0)
|
PrependVOffsetT(if o: object_offset - o else: 0)
|
||||||
// The two metadata fields are written last.
|
// The two metadata fields are written last.
|
||||||
// First, store the object bytesize:
|
// First, store the object bytesize:
|
||||||
@@ -91,17 +96,18 @@ struct builder:
|
|||||||
// BenchmarkVtableDeduplication for a case in which this heuristic
|
// BenchmarkVtableDeduplication for a case in which this heuristic
|
||||||
// saves about 30% of the time used in writing objects with duplicate
|
// saves about 30% of the time used in writing objects with duplicate
|
||||||
// tables.
|
// tables.
|
||||||
existing_vtable := do():
|
def find_existing_table():
|
||||||
reverse(vtables) vt2_offset:
|
reverse(vtables) vt2_offset:
|
||||||
// Find the other vtable:
|
// Find the other vtable:
|
||||||
vt2_start := buf.length - vt2_offset
|
let vt2_start = buf.length - vt2_offset
|
||||||
vt2_len := buf.read_int16_le(vt2_start)
|
let vt2_len = buf.read_int16_le(vt2_start)
|
||||||
// Compare the other vtable to the one under consideration.
|
// Compare the other vtable to the one under consideration.
|
||||||
// If they are equal, return the offset:
|
// If they are equal, return the offset:
|
||||||
if vtable_size == vt2_len and
|
if vtable_size == vt2_len and
|
||||||
not compare_substring(buf, Start(), buf, vt2_start, vtable_size):
|
not compare_substring(buf, Start(), buf, vt2_start, vtable_size):
|
||||||
return vt2_offset from do
|
return vt2_offset
|
||||||
0
|
return 0
|
||||||
|
let existing_vtable = find_existing_table()
|
||||||
if existing_vtable:
|
if existing_vtable:
|
||||||
// Found a duplicate vtable, remove the one we wrote.
|
// Found a duplicate vtable, remove the one we wrote.
|
||||||
head = object_offset
|
head = object_offset
|
||||||
@@ -116,10 +122,11 @@ struct builder:
|
|||||||
// Finally, store this vtable in memory for future
|
// Finally, store this vtable in memory for future
|
||||||
// deduplication:
|
// deduplication:
|
||||||
vtables.push(head)
|
vtables.push(head)
|
||||||
return object_offset
|
return offset { object_offset }
|
||||||
|
|
||||||
def Pad(n):
|
def Pad(n):
|
||||||
for(n): buf, head = buf.write_int8_le_back(head, 0)
|
for(n):
|
||||||
|
buf, head = buf.write_int8_le_back(head, 0)
|
||||||
|
|
||||||
def Prep(size, additional_bytes):
|
def Prep(size, additional_bytes):
|
||||||
// Track the biggest thing we've ever aligned to.
|
// Track the biggest thing we've ever aligned to.
|
||||||
@@ -127,27 +134,27 @@ struct builder:
|
|||||||
minalign = size
|
minalign = size
|
||||||
// Find the amount of alignment needed such that `size` is properly
|
// Find the amount of alignment needed such that `size` is properly
|
||||||
// aligned after `additionalBytes`:
|
// aligned after `additionalBytes`:
|
||||||
align_size := ((~(head + additional_bytes)) + 1) & (size - 1)
|
let align_size = ((~(head + additional_bytes)) + 1) & (size - 1)
|
||||||
Pad(align_size)
|
Pad(align_size)
|
||||||
|
|
||||||
def PrependUOffsetTRelative(off):
|
def PrependUOffsetTRelative(off:offset):
|
||||||
// Prepends an unsigned offset into vector data, relative to where it will be written.
|
// Prepends an unsigned offset into vector data, relative to where it will be written.
|
||||||
Prep(sz_uoffset, 0)
|
Prep(sz_uoffset, 0)
|
||||||
assert off <= head
|
assert off.o <= head
|
||||||
PlaceUOffsetT(head - off + sz_uoffset)
|
PlaceUOffsetT(head - off.o + sz_uoffset)
|
||||||
|
|
||||||
def StartVector(elem_size, num_elems, alignment):
|
def StartVector(elem_size, num_elems, alignment):
|
||||||
// Initializes bookkeeping for writing a new vector.
|
// Initializes bookkeeping for writing a new vector.
|
||||||
StartNesting()
|
StartNesting()
|
||||||
Prep(sz_32, elem_size * num_elems)
|
Prep(sz_32, elem_size * num_elems)
|
||||||
Prep(alignment, elem_size * num_elems) // In case alignment > int.
|
Prep(alignment, elem_size * num_elems) // In case alignment > int.
|
||||||
return head
|
return Offset()
|
||||||
|
|
||||||
def EndVector(vector_num_elems):
|
def EndVector(vector_num_elems):
|
||||||
EndNesting()
|
EndNesting()
|
||||||
// we already made space for this, so write without PrependUint32
|
// we already made space for this, so write without PrependUint32
|
||||||
PlaceUOffsetT(vector_num_elems)
|
PlaceUOffsetT(vector_num_elems)
|
||||||
return head
|
return Offset()
|
||||||
|
|
||||||
def CreateString(s:string):
|
def CreateString(s:string):
|
||||||
// writes a null-terminated byte string.
|
// writes a null-terminated byte string.
|
||||||
@@ -168,11 +175,11 @@ struct builder:
|
|||||||
while current_vtable.length <= slotnum: current_vtable.push(0)
|
while current_vtable.length <= slotnum: current_vtable.push(0)
|
||||||
current_vtable[slotnum] = head
|
current_vtable[slotnum] = head
|
||||||
|
|
||||||
def __Finish(root_table:int, size_prefix:int):
|
def __Finish(root_table:offset, size_prefix:int):
|
||||||
// Finish finalizes a buffer, pointing to the given root_table
|
// Finish finalizes a buffer, pointing to the given root_table
|
||||||
assert not finished
|
assert not finished
|
||||||
assert not nested
|
assert not nested
|
||||||
prep_size := sz_32
|
var prep_size = sz_32
|
||||||
if size_prefix:
|
if size_prefix:
|
||||||
prep_size += sz_32
|
prep_size += sz_32
|
||||||
Prep(minalign, prep_size)
|
Prep(minalign, prep_size)
|
||||||
@@ -182,10 +189,10 @@ struct builder:
|
|||||||
finished = true
|
finished = true
|
||||||
return Start()
|
return Start()
|
||||||
|
|
||||||
def Finish(root_table:int):
|
def Finish(root_table:offset):
|
||||||
return __Finish(root_table, false)
|
return __Finish(root_table, false)
|
||||||
|
|
||||||
def FinishSizePrefixed(root_table:int):
|
def FinishSizePrefixed(root_table:offset):
|
||||||
return __Finish(root_table, true)
|
return __Finish(root_table, true)
|
||||||
|
|
||||||
def PrependBool(x):
|
def PrependBool(x):
|
||||||
@@ -263,16 +270,15 @@ struct builder:
|
|||||||
def PrependFloat32Slot(o, x, d): PrependSlot(o, x, d): PrependFloat32(_)
|
def PrependFloat32Slot(o, x, d): PrependSlot(o, x, d): PrependFloat32(_)
|
||||||
def PrependFloat64Slot(o, x, d): PrependSlot(o, x, d): PrependFloat64(_)
|
def PrependFloat64Slot(o, x, d): PrependSlot(o, x, d): PrependFloat64(_)
|
||||||
|
|
||||||
def PrependUOffsetTRelativeSlot(o, x, d):
|
def PrependUOffsetTRelativeSlot(o:int, x:offset):
|
||||||
if x != d:
|
if x.o:
|
||||||
PrependUOffsetTRelative(x)
|
PrependUOffsetTRelative(x)
|
||||||
Slot(o)
|
Slot(o)
|
||||||
|
|
||||||
def PrependStructSlot(v, x, d):
|
def PrependStructSlot(v:int, x:offset):
|
||||||
if x != d:
|
if x.o:
|
||||||
// Structs are always stored inline, so need to be created right
|
// Structs are always stored inline, so need to be created right
|
||||||
// where they are used. You'll get this error if you created it
|
// where they are used. You'll get this error if you created it
|
||||||
//elsewhere.
|
// elsewhere.
|
||||||
assert x == head
|
assert x.o == head
|
||||||
Slot(v)
|
Slot(v)
|
||||||
|
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ local getAlignSize = compat.GetAlignSize
|
|||||||
|
|
||||||
local function vtableEqual(a, objectStart, b)
|
local function vtableEqual(a, objectStart, b)
|
||||||
UOffsetT:EnforceNumber(objectStart)
|
UOffsetT:EnforceNumber(objectStart)
|
||||||
if (#a * VOffsetT.bytewidth) ~= #b then
|
if (#a * 2) ~= #b then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, elem in ipairs(a) do
|
for i, elem in ipairs(a) do
|
||||||
local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * VOffsetT.bytewidth)
|
local x = string.unpack(VOffsetT.packFmt, b, 1 + (i - 1) * 2)
|
||||||
if x ~= 0 or elem ~= 0 then
|
if x ~= 0 or elem ~= 0 then
|
||||||
local y = objectStart - elem
|
local y = objectStart - elem
|
||||||
if x ~= y then
|
if x ~= y then
|
||||||
@@ -60,6 +60,23 @@ function m.New(initialSize)
|
|||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Clears the builder and resets the state. It does not actually clear the backing binary array, it just reuses it as
|
||||||
|
-- needed. This is a performant way to use the builder for multiple constructions without the overhead of multiple
|
||||||
|
-- builder allocations.
|
||||||
|
function mt:Clear()
|
||||||
|
self.finished = false
|
||||||
|
self.nested = false
|
||||||
|
self.minalign = 1
|
||||||
|
self.currentVTable = nil
|
||||||
|
self.objectEnd = nil
|
||||||
|
self.head = #self.bytes -- place the head at the end of the binary array
|
||||||
|
|
||||||
|
-- clear vtables instead of making a new table
|
||||||
|
local vtable = self.vtables
|
||||||
|
local vtableCount = #vtable
|
||||||
|
for i=1,vtableCount do vtable[i] = nil end
|
||||||
|
end
|
||||||
|
|
||||||
function mt:Output(full)
|
function mt:Output(full)
|
||||||
assert(self.finished, "Builder Not Finished")
|
assert(self.finished, "Builder Not Finished")
|
||||||
if full then
|
if full then
|
||||||
@@ -104,7 +121,7 @@ function mt:WriteVtable()
|
|||||||
local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1)
|
local vt2lenstr = self.bytes:Slice(vt2Start, vt2Start+1)
|
||||||
local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1)
|
local vt2Len = string.unpack(VOffsetT.packFmt, vt2lenstr, 1)
|
||||||
|
|
||||||
local metadata = VtableMetadataFields * VOffsetT.bytewidth
|
local metadata = VtableMetadataFields * 2
|
||||||
local vt2End = vt2Start + vt2Len
|
local vt2End = vt2Start + vt2Len
|
||||||
local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End)
|
local vt2 = self.bytes:Slice(vt2Start+metadata,vt2End)
|
||||||
|
|
||||||
@@ -133,7 +150,7 @@ function mt:WriteVtable()
|
|||||||
self:PrependVOffsetT(objectSize)
|
self:PrependVOffsetT(objectSize)
|
||||||
|
|
||||||
local vBytes = #self.currentVTable + VtableMetadataFields
|
local vBytes = #self.currentVTable + VtableMetadataFields
|
||||||
vBytes = vBytes * VOffsetT.bytewidth
|
vBytes = vBytes * 2
|
||||||
self:PrependVOffsetT(vBytes)
|
self:PrependVOffsetT(vBytes)
|
||||||
|
|
||||||
local objectStart = #self.bytes - objectOffset
|
local objectStart = #self.bytes - objectOffset
|
||||||
@@ -208,17 +225,17 @@ function mt:Prep(size, additionalBytes)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mt:PrependSOffsetTRelative(off)
|
function mt:PrependSOffsetTRelative(off)
|
||||||
self:Prep(SOffsetT.bytewidth, 0)
|
self:Prep(4, 0)
|
||||||
assert(off <= self:Offset(), "Offset arithmetic error")
|
assert(off <= self:Offset(), "Offset arithmetic error")
|
||||||
local off2 = self:Offset() - off + SOffsetT.bytewidth
|
local off2 = self:Offset() - off + 4
|
||||||
self:Place(off2, SOffsetT)
|
self:Place(off2, SOffsetT)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:PrependUOffsetTRelative(off)
|
function mt:PrependUOffsetTRelative(off)
|
||||||
self:Prep(UOffsetT.bytewidth, 0)
|
self:Prep(4, 0)
|
||||||
local soffset = self:Offset()
|
local soffset = self:Offset()
|
||||||
if off <= soffset then
|
if off <= soffset then
|
||||||
local off2 = soffset - off + UOffsetT.bytewidth
|
local off2 = soffset - off + 4
|
||||||
self:Place(off2, UOffsetT)
|
self:Place(off2, UOffsetT)
|
||||||
else
|
else
|
||||||
error("Offset arithmetic error")
|
error("Offset arithmetic error")
|
||||||
@@ -228,8 +245,9 @@ end
|
|||||||
function mt:StartVector(elemSize, numElements, alignment)
|
function mt:StartVector(elemSize, numElements, alignment)
|
||||||
assert(not self.nested)
|
assert(not self.nested)
|
||||||
self.nested = true
|
self.nested = true
|
||||||
self:Prep(Uint32.bytewidth, elemSize * numElements)
|
local elementSize = elemSize * numElements
|
||||||
self:Prep(alignment, elemSize * numElements)
|
self:Prep(4, elementSize) -- Uint32 length
|
||||||
|
self:Prep(alignment, elementSize)
|
||||||
return self:Offset()
|
return self:Offset()
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -246,7 +264,7 @@ function mt:CreateString(s)
|
|||||||
|
|
||||||
assert(type(s) == "string")
|
assert(type(s) == "string")
|
||||||
|
|
||||||
self:Prep(UOffsetT.bytewidth, (#s + 1)*Uint8.bytewidth)
|
self:Prep(4, #s + 1)
|
||||||
self:Place(0, Uint8)
|
self:Place(0, Uint8)
|
||||||
|
|
||||||
local l = #s
|
local l = #s
|
||||||
@@ -254,20 +272,21 @@ function mt:CreateString(s)
|
|||||||
|
|
||||||
self.bytes:Set(s, self.head, self.head + l)
|
self.bytes:Set(s, self.head, self.head + l)
|
||||||
|
|
||||||
return self:EndVector(#s)
|
return self:EndVector(l)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:CreateByteVector(x)
|
function mt:CreateByteVector(x)
|
||||||
assert(not self.nested)
|
assert(not self.nested)
|
||||||
self.nested = true
|
self.nested = true
|
||||||
self:Prep(UOffsetT.bytewidth, #x*Uint8.bytewidth)
|
|
||||||
|
|
||||||
local l = #x
|
local l = #x
|
||||||
|
self:Prep(4, l)
|
||||||
|
|
||||||
self.head = self.head - l
|
self.head = self.head - l
|
||||||
|
|
||||||
self.bytes:Set(x, self.head, self.head + l)
|
self.bytes:Set(x, self.head, self.head + l)
|
||||||
|
|
||||||
return self:EndVector(#x)
|
return self:EndVector(l)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Slot(slotnum)
|
function mt:Slot(slotnum)
|
||||||
@@ -278,12 +297,7 @@ end
|
|||||||
|
|
||||||
local function finish(self, rootTable, sizePrefix)
|
local function finish(self, rootTable, sizePrefix)
|
||||||
UOffsetT:EnforceNumber(rootTable)
|
UOffsetT:EnforceNumber(rootTable)
|
||||||
local prepSize = UOffsetT.bytewidth
|
self:Prep(self.minalign, sizePrefix and 8 or 4)
|
||||||
if sizePrefix then
|
|
||||||
prepSize = prepSize + Int32.bytewidth
|
|
||||||
end
|
|
||||||
|
|
||||||
self:Prep(self.minalign, prepSize)
|
|
||||||
self:PrependUOffsetTRelative(rootTable)
|
self:PrependUOffsetTRelative(rootTable)
|
||||||
if sizePrefix then
|
if sizePrefix then
|
||||||
local size = #self.bytes - self.head
|
local size = #self.bytes - self.head
|
||||||
@@ -308,8 +322,9 @@ function mt:Prepend(flags, off)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mt:PrependSlot(flags, o, x, d)
|
function mt:PrependSlot(flags, o, x, d)
|
||||||
flags:EnforceNumber(x)
|
flags:EnforceNumbers(x,d)
|
||||||
flags:EnforceNumber(d)
|
-- flags:EnforceNumber(x)
|
||||||
|
-- flags:EnforceNumber(d)
|
||||||
if x ~= d then
|
if x ~= d then
|
||||||
self:Prepend(flags, x)
|
self:Prepend(flags, x)
|
||||||
self:Slot(o)
|
self:Slot(o)
|
||||||
|
|||||||
@@ -34,6 +34,20 @@ function type_mt:EnforceNumber(n)
|
|||||||
error("Number is not in the valid range")
|
error("Number is not in the valid range")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function type_mt:EnforceNumbers(a,b)
|
||||||
|
-- duplicate code since the overhead of function calls
|
||||||
|
-- for such a popular method is time consuming
|
||||||
|
if not self.min_value and not self.max_value then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.min_value <= a and a <= self.max_value and self.min_value <= b and b <= self.max_value then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
error("Number is not in the valid range")
|
||||||
|
end
|
||||||
|
|
||||||
function type_mt:EnforceNumberAndPack(n)
|
function type_mt:EnforceNumberAndPack(n)
|
||||||
return bpack(self.packFmt, n)
|
return bpack(self.packFmt, n)
|
||||||
end
|
end
|
||||||
@@ -53,7 +67,13 @@ local bool_mt =
|
|||||||
max_value = true,
|
max_value = true,
|
||||||
lua_type = type(true),
|
lua_type = type(true),
|
||||||
name = "bool",
|
name = "bool",
|
||||||
packFmt = "<b"
|
packFmt = "<I1",
|
||||||
|
Pack = function(self, value) return value and "1" or "0" end,
|
||||||
|
Unpack = function(self, buf, pos) return buf[pos] == "1" end,
|
||||||
|
ValidNumber = function(self, n) return true end, -- anything is a valid boolean in Lua
|
||||||
|
EnforceNumber = function(self, n) end, -- anything is a valid boolean in Lua
|
||||||
|
EnforceNumbers = function(self, a, b) end, -- anything is a valid boolean in Lua
|
||||||
|
EnforceNumberAndPack = function(self, n) return self:Pack(value) end,
|
||||||
}
|
}
|
||||||
|
|
||||||
local uint8_mt =
|
local uint8_mt =
|
||||||
@@ -170,7 +190,6 @@ setmetatable(float32_mt, {__index = type_mt})
|
|||||||
setmetatable(float64_mt, {__index = type_mt})
|
setmetatable(float64_mt, {__index = type_mt})
|
||||||
|
|
||||||
|
|
||||||
m.Bool = bool_mt
|
|
||||||
m.Uint8 = uint8_mt
|
m.Uint8 = uint8_mt
|
||||||
m.Uint16 = uint16_mt
|
m.Uint16 = uint16_mt
|
||||||
m.Uint32 = uint32_mt
|
m.Uint32 = uint32_mt
|
||||||
@@ -186,7 +205,7 @@ m.UOffsetT = uint32_mt
|
|||||||
m.VOffsetT = uint16_mt
|
m.VOffsetT = uint16_mt
|
||||||
m.SOffsetT = int32_mt
|
m.SOffsetT = int32_mt
|
||||||
|
|
||||||
function GenerateTypes(listOfTypes)
|
local GenerateTypes = function(listOfTypes)
|
||||||
for _,t in pairs(listOfTypes) do
|
for _,t in pairs(listOfTypes) do
|
||||||
t.Pack = function(self, value) return bpack(self.packFmt, value) end
|
t.Pack = function(self, value) return bpack(self.packFmt, value) end
|
||||||
t.Unpack = function(self, buf, pos) return bunpack(self.packFmt, buf, pos) end
|
t.Unpack = function(self, buf, pos) return bunpack(self.packFmt, buf, pos) end
|
||||||
@@ -195,4 +214,6 @@ end
|
|||||||
|
|
||||||
GenerateTypes(m)
|
GenerateTypes(m)
|
||||||
|
|
||||||
|
-- explicitly execute after GenerateTypes call, as we don't want to define a Pack/Unpack function for it.
|
||||||
|
m.Bool = bool_mt
|
||||||
return m
|
return m
|
||||||
|
|||||||
@@ -6,69 +6,83 @@ local mt_name = "flatbuffers.view.mt"
|
|||||||
local N = require("flatbuffers.numTypes")
|
local N = require("flatbuffers.numTypes")
|
||||||
local binaryarray = require("flatbuffers.binaryarray")
|
local binaryarray = require("flatbuffers.binaryarray")
|
||||||
|
|
||||||
function m.New(buf, pos)
|
local function enforceOffset(off)
|
||||||
N.UOffsetT:EnforceNumber(pos)
|
if off < 0 or off > 42949672951 then
|
||||||
|
error("Offset is not valid")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local unpack = string.unpack
|
||||||
|
local function unPackUoffset(bytes, off)
|
||||||
|
return unpack("<I4", bytes.str, off + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function unPackVoffset(bytes, off)
|
||||||
|
return unpack("<I2", bytes.str, off + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
function m.New(buf, pos)
|
||||||
|
enforceOffset(pos)
|
||||||
-- need to convert from a string buffer into
|
-- need to convert from a string buffer into
|
||||||
-- a binary array
|
-- a binary array
|
||||||
|
|
||||||
local o = {
|
local o = {
|
||||||
bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
|
bytes = type(buf) == "string" and binaryarray.New(buf) or buf,
|
||||||
pos = pos
|
pos = pos,
|
||||||
}
|
}
|
||||||
setmetatable(o, {__index = mt, __metatable = mt_name})
|
setmetatable(o, {__index = mt, __metatable = mt_name})
|
||||||
return o
|
return o
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Offset(vtableOffset)
|
function mt:Offset(vtableOffset)
|
||||||
local vtable = self.pos - self:Get(N.SOffsetT, self.pos)
|
local vtable = self.vtable
|
||||||
local vtableEnd = self:Get(N.VOffsetT, vtable)
|
if not vtable then
|
||||||
if vtableOffset < vtableEnd then
|
vtable = self.pos - self:Get(N.SOffsetT, self.pos)
|
||||||
return self:Get(N.VOffsetT, vtable + vtableOffset)
|
self.vtable = vtable
|
||||||
|
self.vtableEnd = self:Get(N.VOffsetT, vtable)
|
||||||
|
end
|
||||||
|
if vtableOffset < self.vtableEnd then
|
||||||
|
return unPackVoffset(self.bytes, vtable + vtableOffset)
|
||||||
end
|
end
|
||||||
return 0
|
return 0
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Indirect(off)
|
function mt:Indirect(off)
|
||||||
N.UOffsetT:EnforceNumber(off)
|
enforceOffset(off)
|
||||||
return off + N.UOffsetT:Unpack(self.bytes, off)
|
return off + unPackUoffset(self.bytes, off)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:String(off)
|
function mt:String(off)
|
||||||
N.UOffsetT:EnforceNumber(off)
|
enforceOffset(off)
|
||||||
off = off + N.UOffsetT:Unpack(self.bytes, off)
|
off = off + unPackUoffset(self.bytes, off)
|
||||||
local start = off + N.UOffsetT.bytewidth
|
local start = off + 4
|
||||||
local length = N.UOffsetT:Unpack(self.bytes, off)
|
local length = unPackUoffset(self.bytes, off)
|
||||||
return self.bytes:Slice(start, start+length)
|
return self.bytes:Slice(start, start+length)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:VectorLen(off)
|
function mt:VectorLen(off)
|
||||||
N.UOffsetT:EnforceNumber(off)
|
enforceOffset(off)
|
||||||
off = off + self.pos
|
off = off + self.pos
|
||||||
off = off + N.UOffsetT:Unpack(self.bytes, off)
|
off = off + unPackUoffset(self.bytes, off)
|
||||||
return N.UOffsetT:Unpack(self.bytes, off)
|
return unPackUoffset(self.bytes, off)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Vector(off)
|
function mt:Vector(off)
|
||||||
N.UOffsetT:EnforceNumber(off)
|
enforceOffset(off)
|
||||||
|
|
||||||
off = off + self.pos
|
off = off + self.pos
|
||||||
local x = off + self:Get(N.UOffsetT, off)
|
return off + self:Get(N.UOffsetT, off) + 4
|
||||||
x = x + N.UOffsetT.bytewidth
|
|
||||||
return x
|
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Union(t2, off)
|
function mt:Union(t2, off)
|
||||||
assert(getmetatable(t2) == mt_name)
|
assert(getmetatable(t2) == mt_name)
|
||||||
N.UOffsetT:EnforceNumber(off)
|
enforceOffset(off)
|
||||||
|
|
||||||
off = off + self.pos
|
off = off + self.pos
|
||||||
t2.pos = off + self:Get(N.UOffsetT, off)
|
t2.pos = off + self:Get(N.UOffsetT, off)
|
||||||
t2.bytes = self.bytes
|
t2.bytes = self.bytes
|
||||||
end
|
end
|
||||||
|
|
||||||
function mt:Get(flags, off)
|
function mt:Get(flags, off)
|
||||||
N.UOffsetT:EnforceNumber(off)
|
enforceOffset(off)
|
||||||
return flags:Unpack(self.bytes, off)
|
return flags:Unpack(self.bytes, off)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -85,8 +99,7 @@ function mt:GetSlot(slot, d, validatorFlags)
|
|||||||
end
|
end
|
||||||
|
|
||||||
function mt:GetVOffsetTSlot(slot, d)
|
function mt:GetVOffsetTSlot(slot, d)
|
||||||
N.VOffsetT:EnforceNumber(slot)
|
N.VOffsetT:EnforceNumbers(slot, d)
|
||||||
N.VOffsetT:EnforceNumber(d)
|
|
||||||
local off = self:Offset(slot)
|
local off = self:Offset(slot)
|
||||||
if off == 0 then
|
if off == 0 then
|
||||||
return d
|
return d
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
@@ -47,6 +48,9 @@ namespace FlatBuffers
|
|||||||
// For the current vector being built.
|
// For the current vector being built.
|
||||||
private int _vectorNumElems = 0;
|
private int _vectorNumElems = 0;
|
||||||
|
|
||||||
|
// For CreateSharedString
|
||||||
|
private Dictionary<string, StringOffset> _sharedStringMap = null;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create a FlatBufferBuilder with a given initial size.
|
/// Create a FlatBufferBuilder with a given initial size.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -407,7 +411,7 @@ namespace FlatBuffers
|
|||||||
"FlatBuffers: object serialization must not be nested.");
|
"FlatBuffers: object serialization must not be nested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartObject(int numfields)
|
public void StartTable(int numfields)
|
||||||
{
|
{
|
||||||
if (numfields < 0)
|
if (numfields < 0)
|
||||||
throw new ArgumentOutOfRangeException("Flatbuffers: invalid numfields");
|
throw new ArgumentOutOfRangeException("Flatbuffers: invalid numfields");
|
||||||
@@ -536,9 +540,9 @@ namespace FlatBuffers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="o">The index into the vtable</param>
|
/// <param name="o">The index into the vtable</param>
|
||||||
/// <param name="x">The value to put into the buffer. If the value is equal to the default
|
/// <param name="x">The value to put into the buffer. If the value is equal to the default
|
||||||
/// and <see cref="ForceDefaults"/> is false, the value will be skipped.</param>
|
/// the value will be skipped.</param>
|
||||||
/// <param name="d">The default value to compare the value against</param>
|
/// <param name="d">The default value to compare the value against</param>
|
||||||
public void AddOffset(int o, int x, int d) { if (ForceDefaults || x != d) { AddOffset(x); Slot(o); } }
|
public void AddOffset(int o, int x, int d) { if (x != d) { AddOffset(x); Slot(o); } }
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -579,6 +583,32 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Store a string in the buffer, which can contain any binary data.
|
||||||
|
/// If a string with this exact contents has already been serialized before,
|
||||||
|
/// instead simply returns the offset of the existing string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="s">The string to encode.</param>
|
||||||
|
/// <returns>
|
||||||
|
/// The offset in the buffer where the encoded string starts.
|
||||||
|
/// </returns>
|
||||||
|
public StringOffset CreateSharedString(string s)
|
||||||
|
{
|
||||||
|
if (_sharedStringMap == null)
|
||||||
|
{
|
||||||
|
_sharedStringMap = new Dictionary<string, StringOffset>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_sharedStringMap.ContainsKey(s))
|
||||||
|
{
|
||||||
|
return _sharedStringMap[s];
|
||||||
|
}
|
||||||
|
|
||||||
|
var stringOffset = CreateString(s);
|
||||||
|
_sharedStringMap.Add(s, stringOffset);
|
||||||
|
return stringOffset;
|
||||||
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
// Structs are stored inline, so nothing additional is being added.
|
// Structs are stored inline, so nothing additional is being added.
|
||||||
// `d` is always 0.
|
// `d` is always 0.
|
||||||
@@ -591,11 +621,11 @@ namespace FlatBuffers
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int EndObject()
|
public int EndTable()
|
||||||
{
|
{
|
||||||
if (_vtableSize < 0)
|
if (_vtableSize < 0)
|
||||||
throw new InvalidOperationException(
|
throw new InvalidOperationException(
|
||||||
"Flatbuffers: calling endObject without a startObject");
|
"Flatbuffers: calling EndTable without a StartTable");
|
||||||
|
|
||||||
AddInt((int)0);
|
AddInt((int)0);
|
||||||
var vtableloc = Offset;
|
var vtableloc = Offset;
|
||||||
|
|||||||
@@ -25,5 +25,13 @@ namespace FlatBuffers
|
|||||||
{
|
{
|
||||||
public const int FileIdentifierLength = 4;
|
public const int FileIdentifierLength = 4;
|
||||||
public const int SizePrefixLength = 4;
|
public const int SizePrefixLength = 4;
|
||||||
|
/** A version identifier to force a compile error if someone
|
||||||
|
accidentally tries to build generated code with a runtime of
|
||||||
|
two mismatched version. Versions need to always match, as
|
||||||
|
the runtime and generated code are modified in sync.
|
||||||
|
Changes to the C# implementation need to be sure to change
|
||||||
|
the version here and in the code generator on every possible
|
||||||
|
incompatible change */
|
||||||
|
public static void FLATBUFFERS_1_12_0() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,14 @@ namespace FlatBuffers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Struct
|
public struct Struct
|
||||||
{
|
{
|
||||||
public int bb_pos;
|
public int bb_pos { get; private set; }
|
||||||
public ByteBuffer bb;
|
public ByteBuffer bb { get; private set; }
|
||||||
|
|
||||||
|
// Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
|
||||||
|
public Struct(int _i, ByteBuffer _bb) : this()
|
||||||
|
{
|
||||||
|
bb = _bb;
|
||||||
|
bb_pos = _i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
namespace FlatBuffers
|
namespace FlatBuffers
|
||||||
{
|
{
|
||||||
@@ -24,11 +25,18 @@ namespace FlatBuffers
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public struct Table
|
public struct Table
|
||||||
{
|
{
|
||||||
public int bb_pos;
|
public int bb_pos { get; private set; }
|
||||||
public ByteBuffer bb;
|
public ByteBuffer bb { get; private set; }
|
||||||
|
|
||||||
public ByteBuffer ByteBuffer { get { return bb; } }
|
public ByteBuffer ByteBuffer { get { return bb; } }
|
||||||
|
|
||||||
|
// Re-init the internal state with an external buffer {@code ByteBuffer} and an offset within.
|
||||||
|
public Table(int _i, ByteBuffer _bb) : this()
|
||||||
|
{
|
||||||
|
bb = _bb;
|
||||||
|
bb_pos = _i;
|
||||||
|
}
|
||||||
|
|
||||||
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
|
// Look up a field in the vtable, return an offset into the object, or 0 if the field is not
|
||||||
// present.
|
// present.
|
||||||
public int __offset(int vtableOffset)
|
public int __offset(int vtableOffset)
|
||||||
@@ -82,17 +90,23 @@ namespace FlatBuffers
|
|||||||
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
||||||
// Spant<byte>. If the vector is not present in the ByteBuffer,
|
// Spant<byte>. If the vector is not present in the ByteBuffer,
|
||||||
// then an empty span will be returned.
|
// then an empty span will be returned.
|
||||||
public Span<byte> __vector_as_span(int offset)
|
public Span<T> __vector_as_span<T>(int offset, int elementSize) where T : struct
|
||||||
{
|
{
|
||||||
|
if (!BitConverter.IsLittleEndian)
|
||||||
|
{
|
||||||
|
throw new NotSupportedException("Getting typed span on a Big Endian " +
|
||||||
|
"system is not support");
|
||||||
|
}
|
||||||
|
|
||||||
var o = this.__offset(offset);
|
var o = this.__offset(offset);
|
||||||
if (0 == o)
|
if (0 == o)
|
||||||
{
|
{
|
||||||
return new Span<byte>();
|
return new Span<T>();
|
||||||
}
|
}
|
||||||
|
|
||||||
var pos = this.__vector(o);
|
var pos = this.__vector(o);
|
||||||
var len = this.__vector_len(o);
|
var len = this.__vector_len(o);
|
||||||
return bb.ToSpan(pos, len);
|
return MemoryMarshal.Cast<byte, T>(bb.ToSpan(pos, len * elementSize));
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
// Get the data of a vector whoses offset is stored at "offset" in this object as an
|
||||||
@@ -138,9 +152,8 @@ namespace FlatBuffers
|
|||||||
// Initialize any Table-derived type to point to the union at the given offset.
|
// Initialize any Table-derived type to point to the union at the given offset.
|
||||||
public T __union<T>(int offset) where T : struct, IFlatbufferObject
|
public T __union<T>(int offset) where T : struct, IFlatbufferObject
|
||||||
{
|
{
|
||||||
offset += bb_pos;
|
|
||||||
T t = new T();
|
T t = new T();
|
||||||
t.__init(offset + bb.GetInt(offset), bb);
|
t.__init(__indirect(offset), bb);
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "flatbuffers",
|
"name": "flatbuffers",
|
||||||
"version": "1.11.0",
|
"version": "1.12.0",
|
||||||
"description": "Memory Efficient Serialization Library",
|
"description": "Memory Efficient Serialization Library",
|
||||||
"files": [
|
"files": [
|
||||||
"js/flatbuffers.js",
|
"js/flatbuffers.js",
|
||||||
|
|||||||
4
pom.xml
4
pom.xml
@@ -3,7 +3,7 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-java</artifactId>
|
<artifactId>flatbuffers-java</artifactId>
|
||||||
<version>1.11.0</version>
|
<version>1.12.0</version>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
<name>FlatBuffers Java API</name>
|
<name>FlatBuffers Java API</name>
|
||||||
<description>
|
<description>
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
<connection>
|
<connection>
|
||||||
scm:git:https://github.com/google/flatbuffers.git
|
scm:git:https://github.com/google/flatbuffers.git
|
||||||
</connection>
|
</connection>
|
||||||
<tag>1.11.0</tag>
|
<tag>HEAD</tag>
|
||||||
</scm>
|
</scm>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user