mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-24 06:51:47 +00:00
Compare commits
315 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c0698cc33f | ||
|
|
ea8a4296e7 | ||
|
|
f85af46262 | ||
|
|
7a43775661 | ||
|
|
062dcf7007 | ||
|
|
ebb410062b | ||
|
|
4b864fd172 | ||
|
|
7e711f80d7 | ||
|
|
bf871ffd7f | ||
|
|
a89be8739c | ||
|
|
0bffce5aef | ||
|
|
d48f08acfe | ||
|
|
43132560f9 | ||
|
|
c56fff88a2 | ||
|
|
49fed8c4f6 | ||
|
|
b1a925dfc2 | ||
|
|
33791dc7b0 | ||
|
|
873a60b0d8 | ||
|
|
4b10656f9b | ||
|
|
e317b148dc | ||
|
|
ed03faaf07 | ||
|
|
02a7807dd8 | ||
|
|
615885e889 | ||
|
|
528ccdd458 | ||
|
|
c23ba6756f | ||
|
|
10e1d1a69e | ||
|
|
660c491265 | ||
|
|
c504a45404 | ||
|
|
919c929d30 | ||
|
|
ba4a02b46a | ||
|
|
be3d0b9c64 | ||
|
|
872fad049e | ||
|
|
9e648c392b | ||
|
|
d4f65bb8a3 | ||
|
|
3c54fd964b | ||
|
|
e7578548a5 | ||
|
|
99acd0bcd7 | ||
|
|
d0321df8cf | ||
|
|
e1f48ad35a | ||
|
|
d8f49e18d7 | ||
|
|
1f5eae5d6a | ||
|
|
ea9d60bbdf | ||
|
|
c2c3a84aaf | ||
|
|
1f03becd24 | ||
|
|
c721009491 | ||
|
|
55289c55bf | ||
|
|
ed2415eb72 | ||
|
|
aaa89429d3 | ||
|
|
12e5cf0b29 | ||
|
|
75601b81cc | ||
|
|
e203882d54 | ||
|
|
b9f1103b8a | ||
|
|
fd40cc61a4 | ||
|
|
38a6623f34 | ||
|
|
27e4f43b77 | ||
|
|
42515cfd33 | ||
|
|
5d3648b88a | ||
|
|
fc3ce7d1ab | ||
|
|
4898809eca | ||
|
|
ca5aaf62d3 | ||
|
|
c80f8d18c1 | ||
|
|
0d1559bdd4 | ||
|
|
8b39a0ee53 | ||
|
|
f675f6433c | ||
|
|
118093b613 | ||
|
|
1bb2a3bd08 | ||
|
|
2361dfb66a | ||
|
|
7b50004ec9 | ||
|
|
6e185d06a7 | ||
|
|
c949229395 | ||
|
|
e1d5fda5d4 | ||
|
|
a2603ec27e | ||
|
|
5f1b1ad42c | ||
|
|
4235a25640 | ||
|
|
88cd182349 | ||
|
|
7c824ef690 | ||
|
|
6bfa107f4e | ||
|
|
0cd8daf14e | ||
|
|
79f2adc50a | ||
|
|
dcfe38c58f | ||
|
|
51d9641de6 | ||
|
|
af6c0e6839 | ||
|
|
7c3cb5caa1 | ||
|
|
8f1bebba05 | ||
|
|
cda1525f84 | ||
|
|
72b05bc865 | ||
|
|
b3e4d9169b | ||
|
|
e2eb6af3e3 | ||
|
|
b188fde27e | ||
|
|
ba5eb3b5cf | ||
|
|
8ea293b988 | ||
|
|
f19803d364 | ||
|
|
b2d69aacf4 | ||
|
|
3331805a1c | ||
|
|
ea06768ad1 | ||
|
|
741c63052d | ||
|
|
e9912e9298 | ||
|
|
7dbc8f564a | ||
|
|
a2fe49b498 | ||
|
|
7dd5cfb510 | ||
|
|
00b741e5fb | ||
|
|
bb321fbe19 | ||
|
|
7330436713 | ||
|
|
f9c64891dd | ||
|
|
b752e4a9bb | ||
|
|
3e3c770c4e | ||
|
|
5a3f18d17d | ||
|
|
10bdcefa4a | ||
|
|
9bab626cbf | ||
|
|
effb608027 | ||
|
|
a96f2bd6ca | ||
|
|
ab3b721a54 | ||
|
|
4cfe36ae8e | ||
|
|
c7a797b966 | ||
|
|
ecc07e7793 | ||
|
|
43944a0ab1 | ||
|
|
27ce09860a | ||
|
|
3a2f6d5300 | ||
|
|
06d3229dc3 | ||
|
|
348fcb5b88 | ||
|
|
b4ca4d3cde | ||
|
|
0848f58cdd | ||
|
|
8e42f44807 | ||
|
|
88912640d0 | ||
|
|
c43a0beff0 | ||
|
|
a9640bd9e1 | ||
|
|
f11ffedb2b | ||
|
|
5d42c8352e | ||
|
|
7c1203d44c | ||
|
|
a0a33d94a7 | ||
|
|
b10123ff63 | ||
|
|
3a2c535592 | ||
|
|
6621424308 | ||
|
|
d215852f52 | ||
|
|
12c4c2238c | ||
|
|
85faa46fb3 | ||
|
|
cc354ea368 | ||
|
|
bed19a5340 | ||
|
|
9bb88a026a | ||
|
|
34cb163e38 | ||
|
|
a66f9e769b | ||
|
|
86153fd740 | ||
|
|
7eb4c6098e | ||
|
|
af3c598189 | ||
|
|
eac0bc6490 | ||
|
|
20a400e940 | ||
|
|
676f0248aa | ||
|
|
34b8b80f15 | ||
|
|
0998861e0f | ||
|
|
2e3d3cbcb5 | ||
|
|
d3a00f7730 | ||
|
|
cc54963830 | ||
|
|
79f62ee353 | ||
|
|
c0a6e5120d | ||
|
|
08cf50c54a | ||
|
|
6b3f057bdc | ||
|
|
60de374486 | ||
|
|
e78825e7a0 | ||
|
|
cc158e7009 | ||
|
|
5377957b14 | ||
|
|
4bc6de9a88 | ||
|
|
3a62813f0e | ||
|
|
fb94af8899 | ||
|
|
77b458bee5 | ||
|
|
9ce98dd77d | ||
|
|
4ea1be53d4 | ||
|
|
0068b25132 | ||
|
|
ec74f58b94 | ||
|
|
48d8232584 | ||
|
|
55ddb84eb2 | ||
|
|
6e2e909b5c | ||
|
|
b24c0b07a3 | ||
|
|
59e26017cb | ||
|
|
132e6a8220 | ||
|
|
19c81b11b3 | ||
|
|
36f8564846 | ||
|
|
daf0a420be | ||
|
|
474ba68bba | ||
|
|
9de0861104 | ||
|
|
b513db86c7 | ||
|
|
6a1acdc23b | ||
|
|
c696422558 | ||
|
|
e93d2bda07 | ||
|
|
bbf4dac6a3 | ||
|
|
8df2d9a3ef | ||
|
|
462ce03ebe | ||
|
|
020012e69c | ||
|
|
f431a96523 | ||
|
|
3694ae0817 | ||
|
|
2265129e14 | ||
|
|
4bddc6cc0c | ||
|
|
e162366b3f | ||
|
|
fee9afd80b | ||
|
|
98f681deb0 | ||
|
|
5cee340ad3 | ||
|
|
f0769b60ab | ||
|
|
79b80f84df | ||
|
|
dfe68566e4 | ||
|
|
0aa36101f4 | ||
|
|
70f345012d | ||
|
|
a056402f56 | ||
|
|
d7b1d418ee | ||
|
|
9dae3eac60 | ||
|
|
99a8a68a80 | ||
|
|
0c86929e39 | ||
|
|
b24f2016a1 | ||
|
|
1d73b3b9fc | ||
|
|
a4dbe13486 | ||
|
|
89711c9c47 | ||
|
|
5d9930aa0d | ||
|
|
8518b3fb4e | ||
|
|
61f4a46c43 | ||
|
|
dd73b53e28 | ||
|
|
c1901f2c01 | ||
|
|
4071b6f68b | ||
|
|
142401f50a | ||
|
|
7799642270 | ||
|
|
67b29d4e43 | ||
|
|
85b131a719 | ||
|
|
0e8a21854c | ||
|
|
53a897731e | ||
|
|
ba08b0ec02 | ||
|
|
da0bda6be3 | ||
|
|
617bbc9b0c | ||
|
|
0c8b4c7614 | ||
|
|
34aea4361f | ||
|
|
be1ad33910 | ||
|
|
0cf04ad9d5 | ||
|
|
fe483fa380 | ||
|
|
8a8dc4e111 | ||
|
|
7e803c410c | ||
|
|
1336d26252 | ||
|
|
853f7033e0 | ||
|
|
e2c7196ea8 | ||
|
|
61fe2a4fac | ||
|
|
d233b38008 | ||
|
|
ca52bfefc0 | ||
|
|
2edb1dcdda | ||
|
|
6eb031de9a | ||
|
|
5f2af34e02 | ||
|
|
f3f113b24a | ||
|
|
6bb0a728d3 | ||
|
|
97face1527 | ||
|
|
f2627e16ac | ||
|
|
01bac38c84 | ||
|
|
a1b5f565d9 | ||
|
|
0780a7db24 | ||
|
|
9234ddcf11 | ||
|
|
6d9a226f75 | ||
|
|
b0fd1a8c66 | ||
|
|
a0e5d78353 | ||
|
|
bc8a1608a8 | ||
|
|
30e7d16104 | ||
|
|
9c3920d0ab | ||
|
|
5b4acf809e | ||
|
|
86fb05d320 | ||
|
|
5e4739184f | ||
|
|
971a68110e | ||
|
|
7a6b2bf521 | ||
|
|
03e2899985 | ||
|
|
72a99abfb7 | ||
|
|
21a8121982 | ||
|
|
28920aff8f | ||
|
|
77b22aed5a | ||
|
|
cc25516d3e | ||
|
|
1d444f63d3 | ||
|
|
5fa00630af | ||
|
|
97af3d798b | ||
|
|
bb736091f3 | ||
|
|
d5b4db0692 | ||
|
|
5808f7fb03 | ||
|
|
42611f9a83 | ||
|
|
1f0bd12851 | ||
|
|
321a1c9dc0 | ||
|
|
ac1015e3c4 | ||
|
|
513958ea72 | ||
|
|
2f2e4cced4 | ||
|
|
f779962e3e | ||
|
|
69776b9e7e | ||
|
|
00d726fc4c | ||
|
|
ad0f48d7e7 | ||
|
|
801e1b7699 | ||
|
|
432e7582c6 | ||
|
|
d76113100a | ||
|
|
dca33ddb75 | ||
|
|
76744a4345 | ||
|
|
b4e91091ec | ||
|
|
d5f5d382eb | ||
|
|
ffddbdc7ab | ||
|
|
46bb05d952 | ||
|
|
7cc72e4b11 | ||
|
|
a6a3f59253 | ||
|
|
8a58aafda1 | ||
|
|
8dc1641c8a | ||
|
|
4b27c92910 | ||
|
|
7fe281295f | ||
|
|
917ff81b46 | ||
|
|
8a2cc7cc4e | ||
|
|
a64d968473 | ||
|
|
a2b1bfc107 | ||
|
|
f2b3705c2c | ||
|
|
3282a84e30 | ||
|
|
89a68942ac | ||
|
|
360c34467c | ||
|
|
265e43faf0 | ||
|
|
f064a6cc60 | ||
|
|
7fead0f140 | ||
|
|
d6f14b704f | ||
|
|
a892322203 | ||
|
|
2e2063cbeb | ||
|
|
625c989875 | ||
|
|
f20204180d | ||
|
|
0e85eeef2c | ||
|
|
b0fa5e0f42 | ||
|
|
25a15950f5 |
13
.clang-format
Normal file
13
.clang-format
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
BasedOnStyle: Google
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
PointerAlignment: Right
|
||||||
|
IndentPPDirectives: AfterHash
|
||||||
|
Cpp11BracedListStyle: false
|
||||||
|
AlwaysBreakTemplateDeclarations: false
|
||||||
|
AllowShortCaseLabelsOnASingleLine: true
|
||||||
|
SpaceAfterTemplateKeyword: false
|
||||||
|
AllowShortBlocksOnASingleLine: true
|
||||||
|
...
|
||||||
|
|
||||||
7
.editorconfig
Normal file
7
.editorconfig
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
root = true
|
||||||
|
[*.{cpp,cc,h}]
|
||||||
|
end_of_line = LF
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
0
.gitattributes
vendored
Executable file → Normal file
0
.gitattributes
vendored
Executable file → Normal file
37
.gitignore
vendored
Executable file → Normal file
37
.gitignore
vendored
Executable file → Normal file
@@ -5,14 +5,18 @@
|
|||||||
*.o.d
|
*.o.d
|
||||||
*.class
|
*.class
|
||||||
*.a
|
*.a
|
||||||
|
*.swp
|
||||||
*~
|
*~
|
||||||
*.vcxproj
|
*.vcxproj
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
*.vcxproj.user
|
*.vcxproj.user
|
||||||
*.sln
|
*.sln
|
||||||
*.suo
|
*.suo
|
||||||
|
*.opendb
|
||||||
*.keystore
|
*.keystore
|
||||||
|
**/.vs/**
|
||||||
**/bin/**
|
**/bin/**
|
||||||
|
!tests/rust_usage_test/bin/**
|
||||||
**/gen/**
|
**/gen/**
|
||||||
**/libs/**
|
**/libs/**
|
||||||
**/obj/**
|
**/obj/**
|
||||||
@@ -24,6 +28,8 @@
|
|||||||
**/CMakeTestfile.cmake
|
**/CMakeTestfile.cmake
|
||||||
**/Debug/**
|
**/Debug/**
|
||||||
**/Release/**
|
**/Release/**
|
||||||
|
**/RelWithDebInfo/**
|
||||||
|
**/x64/ #build artifacts from VS
|
||||||
build.xml
|
build.xml
|
||||||
local.properties
|
local.properties
|
||||||
project.properties
|
project.properties
|
||||||
@@ -43,15 +49,22 @@ flatsampletext.exe
|
|||||||
grpctest
|
grpctest
|
||||||
grpctest.exe
|
grpctest.exe
|
||||||
snapshot.sh
|
snapshot.sh
|
||||||
|
tags
|
||||||
|
tests/dart_gen
|
||||||
tests/go_gen
|
tests/go_gen
|
||||||
tests/monsterdata_java_wire.mon
|
tests/monsterdata_java_wire.mon
|
||||||
|
tests/monsterdata_java_wire_sp.mon
|
||||||
tests/monsterdata_go_wire.mon
|
tests/monsterdata_go_wire.mon
|
||||||
tests/monsterdata_javascript_wire.mon
|
tests/monsterdata_javascript_wire.mon
|
||||||
|
tests/monsterdata_lobster_wire.mon
|
||||||
|
tests/monsterdata_rust_wire.mon
|
||||||
tests/unicode_test.mon
|
tests/unicode_test.mon
|
||||||
tests/ts/
|
tests/ts/
|
||||||
|
tests/php/
|
||||||
CMakeLists.txt.user
|
CMakeLists.txt.user
|
||||||
CMakeScripts/**
|
CMakeScripts/**
|
||||||
CTestTestfile.cmake
|
CTestTestfile.cmake
|
||||||
|
FlatbuffersConfigVersion.cmake
|
||||||
FlatBuffers.cbp
|
FlatBuffers.cbp
|
||||||
build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
|
build/Xcode/FlatBuffers.xcodeproj/project.xcworkspace/**
|
||||||
build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
|
build/Xcode/FlatBuffers.xcodeproj/xcuserdata/**
|
||||||
@@ -72,3 +85,27 @@ Testing/Temporary
|
|||||||
.project
|
.project
|
||||||
net/**/obj
|
net/**/obj
|
||||||
node_modules/
|
node_modules/
|
||||||
|
android/.externalNativeBuild/
|
||||||
|
android/.gradle/
|
||||||
|
android/build/
|
||||||
|
samples/android/.externalNativeBuild/
|
||||||
|
samples/android/.gradle/
|
||||||
|
samples/android/build/
|
||||||
|
js/flatbuffers.mjs
|
||||||
|
/bazel-bin
|
||||||
|
/bazel-flatbuffers
|
||||||
|
/bazel-genfiles
|
||||||
|
/bazel-out
|
||||||
|
/bazel-testlogs
|
||||||
|
.ninja_deps
|
||||||
|
.ninja_log
|
||||||
|
build.ninja
|
||||||
|
rules.ninja
|
||||||
|
.vscode
|
||||||
|
dart/.pub/
|
||||||
|
dart/.packages
|
||||||
|
dart/pubspec.lock
|
||||||
|
dart/.dart_tool/
|
||||||
|
dart/build/
|
||||||
|
dart/doc/api/
|
||||||
|
Cargo.lock
|
||||||
|
|||||||
139
.travis.yml
139
.travis.yml
@@ -1,22 +1,67 @@
|
|||||||
language: cpp
|
env:
|
||||||
|
global:
|
||||||
|
# Set at the root level as this is ignored when set under matrix.env.
|
||||||
|
- GCC_VERSION="4.9"
|
||||||
|
|
||||||
|
conan-linux: &conan-linux
|
||||||
|
os: linux
|
||||||
|
sudo: required
|
||||||
|
language: python
|
||||||
|
python: "3.6"
|
||||||
|
services:
|
||||||
|
- docker
|
||||||
|
install:
|
||||||
|
- ./conan/travis/install.sh
|
||||||
|
script:
|
||||||
|
- ./conan/travis/build.sh
|
||||||
|
if: tag IS present
|
||||||
|
|
||||||
|
conan-osx: &conan-osx
|
||||||
|
os: osx
|
||||||
|
language: generic
|
||||||
|
install:
|
||||||
|
- ./conan/travis/install.sh
|
||||||
|
script:
|
||||||
|
- ./conan/travis/build.sh
|
||||||
|
if: tag IS present
|
||||||
|
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
#- language: python
|
||||||
|
# python: "2.7"
|
||||||
|
# install:
|
||||||
|
# - "pip install wheel twine"
|
||||||
|
# script:
|
||||||
|
# - "cd python/"
|
||||||
|
# - 'VERSION="$TRAVIS_TAG" python setup.py sdist bdist_wheel'
|
||||||
|
# - "cd ../"
|
||||||
|
# deploy:
|
||||||
|
# # Checkpointed release builds.
|
||||||
|
# - provider: script
|
||||||
|
# script: .travis/deploy-python.sh
|
||||||
|
# skip_cleanup: true
|
||||||
|
# on:
|
||||||
|
# tags: true
|
||||||
|
# # all_branches must be set with tags: true. See below post:
|
||||||
|
# # https://stackoverflow.com/a/27775257/1076585
|
||||||
|
# all_branches: true
|
||||||
|
# # Produce a new build for the cutting edge when master changes.
|
||||||
|
# - provider: script
|
||||||
|
# script: .travis/deploy-python.sh
|
||||||
|
# skip_cleanup: true
|
||||||
|
# on:
|
||||||
|
# branch: master
|
||||||
|
- language: cpp
|
||||||
os:
|
os:
|
||||||
- linux
|
- linux
|
||||||
- osx
|
|
||||||
|
|
||||||
compiler:
|
compiler:
|
||||||
- gcc
|
- gcc
|
||||||
#- clang
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
matrix:
|
||||||
- BUILD_TYPE=Debug BIICODE=false
|
- BUILD_TYPE=Debug
|
||||||
- BUILD_TYPE=Release BIICODE=false
|
- BUILD_TYPE=Release CONAN=true
|
||||||
# biicode .deb files no longer available.
|
|
||||||
# - BUILD_TYPE=Release BIICODE=true
|
|
||||||
# - BUILD_TYPE=Debug BIICODE=true
|
|
||||||
global:
|
|
||||||
- GCC_VERSION="4.9"
|
|
||||||
|
|
||||||
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
|
||||||
@@ -27,5 +72,75 @@ before_install:
|
|||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
|
- bash grpc/build_grpc.sh
|
||||||
- if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
|
- cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install -DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf . && make
|
||||||
|
- LD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib make test ARGS=-V
|
||||||
|
- if [ "$CONAN" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo pip install conan && conan create . google/testing -s build_type=$BUILD_TYPE -tf conan/test_package; fi
|
||||||
|
|
||||||
|
- language: cpp
|
||||||
|
os: osx
|
||||||
|
osx_image: xcode9.3
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- BUILD_TYPE=Debug
|
||||||
|
- BUILD_TYPE=Release
|
||||||
|
script:
|
||||||
|
- bash grpc/build_grpc.sh
|
||||||
|
- cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=$TRAVIS_BUILD_DIR/google/grpc/install -DPROTOBUF_DOWNLOAD_PATH=$TRAVIS_BUILD_DIR/google/grpc/third_party/protobuf . && make
|
||||||
|
- ./flattests
|
||||||
|
- DYLD_LIBRARY_PATH=$TRAVIS_BUILD_DIR/google/grpc/install/lib ./grpctest
|
||||||
|
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_GCC_VERSIONS=4.9 CONAN_DOCKER_IMAGE=lasote/conangcc49
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_GCC_VERSIONS=5 CONAN_DOCKER_IMAGE=lasote/conangcc5
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_GCC_VERSIONS=6 CONAN_DOCKER_IMAGE=lasote/conangcc6
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_GCC_VERSIONS=7 CONAN_DOCKER_IMAGE=lasote/conangcc7
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_GCC_VERSIONS=8 CONAN_DOCKER_IMAGE=lasote/conangcc8
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_CLANG_VERSIONS=3.9 CONAN_DOCKER_IMAGE=lasote/conanclang39
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_CLANG_VERSIONS=4.0 CONAN_DOCKER_IMAGE=lasote/conanclang40
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_CLANG_VERSIONS=5.0 CONAN_DOCKER_IMAGE=lasote/conanclang50
|
||||||
|
- <<: *conan-linux
|
||||||
|
env: CONAN_CLANG_VERSIONS=6.0 CONAN_DOCKER_IMAGE=lasote/conanclang60
|
||||||
|
- <<: *conan-osx
|
||||||
|
osx_image: xcode7.3
|
||||||
|
env: CONAN_APPLE_CLANG_VERSIONS=7.3
|
||||||
|
- <<: *conan-osx
|
||||||
|
osx_image: xcode8.3
|
||||||
|
env: CONAN_APPLE_CLANG_VERSIONS=8.1
|
||||||
|
- <<: *conan-osx
|
||||||
|
osx_image: xcode9
|
||||||
|
env: CONAN_APPLE_CLANG_VERSIONS=9.0
|
||||||
|
- <<: *conan-osx
|
||||||
|
osx_image: xcode9.3
|
||||||
|
env: CONAN_APPLE_CLANG_VERSIONS=9.1
|
||||||
|
|
||||||
|
#- language: android
|
||||||
|
# sudo: true
|
||||||
|
# android:
|
||||||
|
# components:
|
||||||
|
# - tools
|
||||||
|
# - platform-tools
|
||||||
|
# - build-tools-25.0.2
|
||||||
|
# - android-25
|
||||||
|
# - extra-android-m2repository
|
||||||
|
# compiler:
|
||||||
|
# - gcc
|
||||||
|
# before_install:
|
||||||
|
# - git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
|
||||||
|
# - export ANDROID_NDK_HOME=$HOME/android-ndk-root
|
||||||
|
# # 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 apt-get update -qq; fi
|
||||||
|
# - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
||||||
|
# - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
||||||
|
# - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
||||||
|
# - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
||||||
|
# script:
|
||||||
|
# - failed=0; for build_gradle in $(git ls-files | grep build.gradle); do ( cd "$(dirname "${build_gradle}")" && ./gradlew build ) || failed=1; done; exit $((failed))
|
||||||
|
|||||||
12
.travis/deploy-python.sh
Executable file
12
.travis/deploy-python.sh
Executable file
@@ -0,0 +1,12 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
PROD_REPOSITORY="https://upload.pypi.org/legacy/"
|
||||||
|
TEST_REPOSITORY="https://test.pypi.org/legacy/"
|
||||||
|
|
||||||
|
twine upload \
|
||||||
|
--username "$PYPI_USERNAME" \
|
||||||
|
--password "$PYPI_PASSWORD" \
|
||||||
|
--repository-url "$PROD_REPOSITORY" \
|
||||||
|
"$DIR/../python/dist/"*
|
||||||
|
|
||||||
148
BUILD
Normal file
148
BUILD
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
licenses(["notice"])
|
||||||
|
|
||||||
|
package(
|
||||||
|
default_visibility = ["//visibility:public"],
|
||||||
|
features = [
|
||||||
|
"-layering_check",
|
||||||
|
"-parse_headers",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
exports_files([
|
||||||
|
"LICENSE",
|
||||||
|
])
|
||||||
|
|
||||||
|
# Public flatc library to compile flatbuffer files at runtime.
|
||||||
|
cc_library(
|
||||||
|
name = "flatbuffers",
|
||||||
|
srcs = [
|
||||||
|
"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,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Public C++ headers for the Flatbuffers library.
|
||||||
|
filegroup(
|
||||||
|
name = "public_headers",
|
||||||
|
srcs = [
|
||||||
|
"include/flatbuffers/base.h",
|
||||||
|
"include/flatbuffers/code_generators.h",
|
||||||
|
"include/flatbuffers/flatbuffers.h",
|
||||||
|
"include/flatbuffers/flexbuffers.h",
|
||||||
|
"include/flatbuffers/hash.h",
|
||||||
|
"include/flatbuffers/idl.h",
|
||||||
|
"include/flatbuffers/minireflect.h",
|
||||||
|
"include/flatbuffers/reflection.h",
|
||||||
|
"include/flatbuffers/reflection_generated.h",
|
||||||
|
"include/flatbuffers/stl_emulation.h",
|
||||||
|
"include/flatbuffers/util.h",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# Public flatc compiler library.
|
||||||
|
cc_library(
|
||||||
|
name = "flatc_library",
|
||||||
|
srcs = [
|
||||||
|
"src/code_generators.cpp",
|
||||||
|
"src/flatc.cpp",
|
||||||
|
"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.
|
||||||
|
cc_binary(
|
||||||
|
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.cpp",
|
||||||
|
"src/idl_gen_json_schema.cpp",
|
||||||
|
"src/idl_gen_lua.cpp",
|
||||||
|
"src/idl_gen_lobster.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 = [
|
||||||
|
":flatc_library",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
# 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/monster_test_generated.h",
|
||||||
|
"tests/namespace_test/namespace_test1_generated.h",
|
||||||
|
"tests/namespace_test/namespace_test2_generated.h",
|
||||||
|
"tests/test.cpp",
|
||||||
|
"tests/test_builder.h",
|
||||||
|
"tests/test_assert.h",
|
||||||
|
"tests/test_builder.cpp",
|
||||||
|
"tests/test_assert.cpp",
|
||||||
|
"tests/union_vector/union_vector_generated.h",
|
||||||
|
":public_headers",
|
||||||
|
],
|
||||||
|
copts = [
|
||||||
|
"-DFLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE",
|
||||||
|
],
|
||||||
|
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/union_vector/union_vector.fbs",
|
||||||
|
],
|
||||||
|
includes = ["include/"],
|
||||||
|
)
|
||||||
@@ -71,6 +71,8 @@ function(build_flatbuffers flatbuffers_schemas
|
|||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
set(working_dir "${CMAKE_CURRENT_SOURCE_DIR}")
|
||||||
|
|
||||||
set(schema_glob "*.fbs")
|
set(schema_glob "*.fbs")
|
||||||
# Generate the include files parameters.
|
# Generate the include files parameters.
|
||||||
set(include_params "")
|
set(include_params "")
|
||||||
@@ -97,7 +99,8 @@ function(build_flatbuffers flatbuffers_schemas
|
|||||||
-o ${generated_includes_dir}
|
-o ${generated_includes_dir}
|
||||||
${include_params}
|
${include_params}
|
||||||
-c ${schema}
|
-c ${schema}
|
||||||
DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies})
|
DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies}
|
||||||
|
WORKING_DIRECTORY "${working_dir}")
|
||||||
list(APPEND all_generated_files ${generated_include})
|
list(APPEND all_generated_files ${generated_include})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -109,7 +112,8 @@ function(build_flatbuffers flatbuffers_schemas
|
|||||||
-o ${binary_schemas_dir}
|
-o ${binary_schemas_dir}
|
||||||
${include_params}
|
${include_params}
|
||||||
${schema}
|
${schema}
|
||||||
DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies})
|
DEPENDS ${FLATC_TARGET} ${schema} ${additional_dependencies}
|
||||||
|
WORKING_DIRECTORY "${working_dir}")
|
||||||
list(APPEND all_generated_files ${binary_schema})
|
list(APPEND all_generated_files ${binary_schema})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
4
CMake/FlatbuffersConfig.cmake
Normal file
4
CMake/FlatbuffersConfig.cmake
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/FlatbuffersTargets.cmake" OPTIONAL)
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/FlatcTargets.cmake" OPTIONAL)
|
||||||
|
include("${CMAKE_CURRENT_LIST_DIR}/FlatbuffersSharedTargets.cmake" OPTIONAL)
|
||||||
|
|
||||||
11
CMake/FlatbuffersConfigVersion.cmake.in
Normal file
11
CMake/FlatbuffersConfigVersion.cmake.in
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
set(PACKAGE_VERSION "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@")
|
||||||
|
|
||||||
|
# Check whether the requested PACKAGE_FIND_VERSION is compatible
|
||||||
|
if("${PACKAGE_VERSION}" VERSION_LESS "${PACKAGE_FIND_VERSION}")
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE FALSE)
|
||||||
|
else()
|
||||||
|
set(PACKAGE_VERSION_COMPATIBLE TRUE)
|
||||||
|
if ("${PACKAGE_VERSION}" VERSION_EQUAL "${PACKAGE_FIND_VERSION}")
|
||||||
|
set(PACKAGE_VERSION_EXACT TRUE)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
@@ -11,22 +11,6 @@ if (UNIX)
|
|||||||
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
|
SET(CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/google/flatbuffers")
|
||||||
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vitaly Isaev <vitalyisaev2@gmail.com>")
|
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "Vitaly Isaev <vitalyisaev2@gmail.com>")
|
||||||
|
|
||||||
# Derive package version from git
|
|
||||||
EXECUTE_PROCESS(
|
|
||||||
COMMAND date +%Y%m%d
|
|
||||||
OUTPUT_VARIABLE DATE
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
EXECUTE_PROCESS(
|
|
||||||
COMMAND git describe
|
|
||||||
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
|
|
||||||
OUTPUT_VARIABLE GIT_DESCRIBE_DIRTY
|
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
|
||||||
)
|
|
||||||
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESCRIBE_DIRTY}")
|
|
||||||
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_DESCRIBE_DIRTY}")
|
|
||||||
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GIT_DESCRIBE_DIRTY}")
|
|
||||||
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_DESCRIBE_DIRTY}")
|
|
||||||
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
SET(CPACK_PACKAGE_VERSION_MAJOR ${VERSION_MAJOR})
|
||||||
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
SET(CPACK_PACKAGE_VERSION_MINOR ${VERSION_MINOR})
|
||||||
SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
|
SET(CPACK_PACKAGE_VERSION_PATCH ${VERSION_PATCH})
|
||||||
|
|||||||
11
CMake/Version.cmake
Normal file
11
CMake/Version.cmake
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
find_program(GIT git)
|
||||||
|
execute_process(
|
||||||
|
COMMAND ${GIT} describe
|
||||||
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
OUTPUT_VARIABLE GIT_DESCRIBE_DIRTY
|
||||||
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
|
)
|
||||||
|
string(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${GIT_DESCRIBE_DIRTY}")
|
||||||
|
string(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.[0-9]+\\-([0-9]+).*" "\\1" VERSION_COMMIT "${GIT_DESCRIBE_DIRTY}")
|
||||||
139
CMakeLists.txt
139
CMakeLists.txt
@@ -15,6 +15,7 @@ option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
|||||||
option(FLATBUFFERS_BUILD_SHAREDLIB
|
option(FLATBUFFERS_BUILD_SHAREDLIB
|
||||||
"Enable the build of the flatbuffers shared library"
|
"Enable the build of the flatbuffers shared library"
|
||||||
OFF)
|
OFF)
|
||||||
|
option(FLATBUFFERS_LIBCXX_WITH_CLANG "Force libc++ when using Clang" ON)
|
||||||
|
|
||||||
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
if(NOT FLATBUFFERS_BUILD_FLATC AND FLATBUFFERS_BUILD_TESTS)
|
||||||
message(WARNING
|
message(WARNING
|
||||||
@@ -31,8 +32,10 @@ set(FlatBuffers_Library_SRCS
|
|||||||
include/flatbuffers/util.h
|
include/flatbuffers/util.h
|
||||||
include/flatbuffers/reflection.h
|
include/flatbuffers/reflection.h
|
||||||
include/flatbuffers/reflection_generated.h
|
include/flatbuffers/reflection_generated.h
|
||||||
|
include/flatbuffers/stl_emulation.h
|
||||||
include/flatbuffers/flexbuffers.h
|
include/flatbuffers/flexbuffers.h
|
||||||
include/flatbuffers/registry.h
|
include/flatbuffers/registry.h
|
||||||
|
include/flatbuffers/minireflect.h
|
||||||
src/code_generators.cpp
|
src/code_generators.cpp
|
||||||
src/idl_parser.cpp
|
src/idl_parser.cpp
|
||||||
src/idl_gen_text.cpp
|
src/idl_gen_text.cpp
|
||||||
@@ -43,13 +46,18 @@ 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_dart.cpp
|
||||||
src/idl_gen_general.cpp
|
src/idl_gen_general.cpp
|
||||||
src/idl_gen_go.cpp
|
src/idl_gen_go.cpp
|
||||||
src/idl_gen_js.cpp
|
src/idl_gen_js.cpp
|
||||||
src/idl_gen_php.cpp
|
src/idl_gen_php.cpp
|
||||||
src/idl_gen_python.cpp
|
src/idl_gen_python.cpp
|
||||||
|
src/idl_gen_lobster.cpp
|
||||||
|
src/idl_gen_lua.cpp
|
||||||
|
src/idl_gen_rust.cpp
|
||||||
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/flatc.cpp
|
src/flatc.cpp
|
||||||
src/flatc_main.cpp
|
src/flatc_main.cpp
|
||||||
grpc/src/compiler/schema_interface.h
|
grpc/src/compiler/schema_interface.h
|
||||||
@@ -57,6 +65,8 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
grpc/src/compiler/cpp_generator.cc
|
grpc/src/compiler/cpp_generator.cc
|
||||||
grpc/src/compiler/go_generator.h
|
grpc/src/compiler/go_generator.h
|
||||||
grpc/src/compiler/go_generator.cc
|
grpc/src/compiler/go_generator.cc
|
||||||
|
grpc/src/compiler/java_generator.h
|
||||||
|
grpc/src/compiler/java_generator.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
set(FlatHash_SRCS
|
set(FlatHash_SRCS
|
||||||
@@ -68,6 +78,10 @@ set(FlatBuffers_Tests_SRCS
|
|||||||
${FlatBuffers_Library_SRCS}
|
${FlatBuffers_Library_SRCS}
|
||||||
src/idl_gen_fbs.cpp
|
src/idl_gen_fbs.cpp
|
||||||
tests/test.cpp
|
tests/test.cpp
|
||||||
|
tests/test_assert.h
|
||||||
|
tests/test_assert.cpp
|
||||||
|
tests/test_builder.h
|
||||||
|
tests/test_builder.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
|
||||||
)
|
)
|
||||||
@@ -90,8 +104,13 @@ set(FlatBuffers_GRPCTest_SRCS
|
|||||||
include/flatbuffers/flatbuffers.h
|
include/flatbuffers/flatbuffers.h
|
||||||
include/flatbuffers/grpc.h
|
include/flatbuffers/grpc.h
|
||||||
tests/monster_test.grpc.fb.h
|
tests/monster_test.grpc.fb.h
|
||||||
|
tests/test_assert.h
|
||||||
|
tests/test_builder.h
|
||||||
tests/monster_test.grpc.fb.cc
|
tests/monster_test.grpc.fb.cc
|
||||||
|
tests/test_assert.cpp
|
||||||
|
tests/test_builder.cpp
|
||||||
grpc/tests/grpctest.cpp
|
grpc/tests/grpctest.cpp
|
||||||
|
grpc/tests/message_builder_test.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
|
||||||
)
|
)
|
||||||
@@ -115,10 +134,13 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
endif(CYGWIN)
|
endif(CYGWIN)
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Werror=shadow")
|
"${CMAKE_CXX_FLAGS} -Wall -pedantic -Werror -Wextra -Werror=shadow")
|
||||||
if (GCC_VERSION VERSION_GREATER 4.4)
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.4)
|
||||||
|
if (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 7.0)
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result \
|
"${CMAKE_CXX_FLAGS} -faligned-new")
|
||||||
-Wunused-parameter -Werror=unused-parameter")
|
endif()
|
||||||
|
set(CMAKE_CXX_FLAGS
|
||||||
|
"${CMAKE_CXX_FLAGS} -Wunused-result -Werror=unused-result -Wunused-parameter -Werror=unused-parameter")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Certain platforms such as ARM do not use signed chars by default
|
# Certain platforms such as ARM do not use signed chars by default
|
||||||
@@ -128,8 +150,8 @@ elseif(CMAKE_COMPILER_IS_GNUCXX)
|
|||||||
|
|
||||||
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -std=c++0x -Wall -pedantic -Werror \
|
"${CMAKE_CXX_FLAGS} -std=c++0x -Wall -pedantic -Werror -Wextra -Wno-unused-parameter")
|
||||||
-Wextra -Wno-unused-parameter")
|
if(FLATBUFFERS_LIBCXX_WITH_CLANG)
|
||||||
if(NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
if(NOT "${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||||
set(CMAKE_CXX_FLAGS
|
set(CMAKE_CXX_FLAGS
|
||||||
"${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
"${CMAKE_CXX_FLAGS} -stdlib=libc++")
|
||||||
@@ -139,6 +161,7 @@ elseif(${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")
|
|||||||
set(CMAKE_EXE_LINKER_FLAGS
|
set(CMAKE_EXE_LINKER_FLAGS
|
||||||
"${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
|
"${CMAKE_EXE_LINKER_FLAGS} -lc++abi")
|
||||||
endif()
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
# Certain platforms such as ARM do not use signed chars by default
|
# Certain platforms such as ARM do not use signed chars by default
|
||||||
# which causes issues with certain bounds checks.
|
# which causes issues with certain bounds checks.
|
||||||
@@ -168,6 +191,9 @@ 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().
|
||||||
|
target_include_directories(flatbuffers INTERFACE
|
||||||
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATC)
|
if(FLATBUFFERS_BUILD_FLATC)
|
||||||
@@ -187,7 +213,16 @@ endif()
|
|||||||
|
|
||||||
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||||
add_library(flatbuffers_shared SHARED ${FlatBuffers_Library_SRCS})
|
add_library(flatbuffers_shared SHARED ${FlatBuffers_Library_SRCS})
|
||||||
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers)
|
|
||||||
|
# Shared object version: "major.minor.micro"
|
||||||
|
# - micro updated every release when there is no API/ABI changes
|
||||||
|
# - minor updated when there are additions in API/ABI
|
||||||
|
# - major (ABI number) updated when there are changes in ABI (or removals)
|
||||||
|
set(FlatBuffers_Library_SONAME_MAJOR "1")
|
||||||
|
set(FlatBuffers_Library_SONAME_FULL "${FlatBuffers_Library_SONAME_MAJOR}.10.0")
|
||||||
|
set_target_properties(flatbuffers_shared PROPERTIES OUTPUT_NAME flatbuffers
|
||||||
|
SOVERSION "${FlatBuffers_Library_SONAME_MAJOR}"
|
||||||
|
VERSION "${FlatBuffers_Library_SONAME_FULL}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
||||||
@@ -196,7 +231,9 @@ function(compile_flatbuffers_schema_to_cpp 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}" -c --no-includes --gen-mutable
|
||||||
--gen-object-api -o "${SRC_FBS_DIR}"
|
--gen-object-api --gen-compare -o "${SRC_FBS_DIR}"
|
||||||
|
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||||
|
--reflect-names
|
||||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||||
DEPENDS flatc)
|
DEPENDS flatc)
|
||||||
@@ -230,20 +267,95 @@ if(FLATBUFFERS_BUILD_GRPCTEST)
|
|||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-shadow")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter -Wno-shadow")
|
||||||
endif()
|
endif()
|
||||||
|
if(NOT GRPC_INSTALL_PATH)
|
||||||
|
message(SEND_ERROR "GRPC_INSTALL_PATH variable is not defined. See grpc/README.md")
|
||||||
|
endif()
|
||||||
|
if(NOT PROTOBUF_DOWNLOAD_PATH)
|
||||||
|
message(SEND_ERROR "PROTOBUF_DOWNLOAD_PATH variable is not defined. See grpc/README.md")
|
||||||
|
endif()
|
||||||
|
INCLUDE_DIRECTORIES(${GRPC_INSTALL_PATH}/include)
|
||||||
|
INCLUDE_DIRECTORIES(${PROTOBUF_DOWNLOAD_PATH}/src)
|
||||||
|
LINK_DIRECTORIES(${GRPC_INSTALL_PATH}/lib)
|
||||||
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
||||||
target_link_libraries(grpctest grpc++_unsecure pthread dl)
|
target_link_libraries(grpctest grpc++_unsecure grpc_unsecure gpr pthread dl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
include(CMake/Version.cmake)
|
||||||
|
|
||||||
if(FLATBUFFERS_INSTALL)
|
if(FLATBUFFERS_INSTALL)
|
||||||
install(DIRECTORY include/flatbuffers DESTINATION include)
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
install(DIRECTORY include/flatbuffers DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
|
|
||||||
|
set(FB_CMAKE_DIR "${CMAKE_INSTALL_LIBDIR}/cmake/flatbuffers")
|
||||||
|
|
||||||
|
configure_file(CMake/FlatbuffersConfigVersion.cmake.in FlatbuffersConfigVersion.cmake @ONLY)
|
||||||
|
install(
|
||||||
|
FILES "CMake/FlatbuffersConfig.cmake" "${CMAKE_CURRENT_BINARY_DIR}/FlatbuffersConfigVersion.cmake"
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||||
install(TARGETS flatbuffers DESTINATION lib)
|
if(CMAKE_VERSION VERSION_LESS 3.0)
|
||||||
|
install(
|
||||||
|
TARGETS flatbuffers EXPORT FlatbuffersTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
install(
|
||||||
|
TARGETS flatbuffers EXPORT FlatbuffersTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
install(EXPORT FlatbuffersTargets
|
||||||
|
FILE FlatbuffersTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATC)
|
if(FLATBUFFERS_BUILD_FLATC)
|
||||||
install(TARGETS flatc DESTINATION bin)
|
install(
|
||||||
|
TARGETS flatc EXPORT FlatcTargets
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
|
||||||
|
CONFIGURATIONS Release
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT FlatcTargets
|
||||||
|
FILE FlatcTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
CONFIGURATIONS Release
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||||
install(TARGETS flatbuffers_shared DESTINATION lib)
|
if(CMAKE_VERSION VERSION_LESS 3.0)
|
||||||
|
install(
|
||||||
|
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
else()
|
||||||
|
install(
|
||||||
|
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT FlatbuffersSharedTargets
|
||||||
|
FILE FlatbuffersSharedTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
@@ -253,6 +365,9 @@ if(FLATBUFFERS_BUILD_TESTS)
|
|||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION
|
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}")
|
"${CMAKE_CURRENT_BINARY_DIR}")
|
||||||
add_test(NAME flattests COMMAND flattests)
|
add_test(NAME flattests COMMAND flattests)
|
||||||
|
if(FLATBUFFERS_BUILD_GRPCTEST)
|
||||||
|
add_test(NAME grpctest COMMAND grpctest)
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include(CMake/BuildFlatBuffers.cmake)
|
include(CMake/BuildFlatBuffers.cmake)
|
||||||
|
|||||||
0
android/.project
Executable file → Normal file
0
android/.project
Executable file → Normal file
11
android/AndroidManifest.xml
Executable file → Normal file
11
android/AndroidManifest.xml
Executable file → Normal file
@@ -17,17 +17,14 @@
|
|||||||
-->
|
-->
|
||||||
<!-- BEGIN_INCLUDE(manifest) -->
|
<!-- BEGIN_INCLUDE(manifest) -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="com.example.FlatBufferTest"
|
package="com.example.FlatBufferTest">
|
||||||
android:versionCode="1"
|
|
||||||
android:versionName="1.0">
|
|
||||||
|
|
||||||
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
<uses-feature android:glEsVersion="0x00020000"></uses-feature>
|
||||||
<!-- This is the platform API where NativeActivity was introduced. -->
|
|
||||||
<uses-sdk android:minSdkVersion="9" />
|
|
||||||
|
|
||||||
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
<!-- This .apk has no Java code itself, so set hasCode to false. -->
|
||||||
<application android:label="@string/app_name" android:hasCode="false">
|
<application android:label="@string/app_name"
|
||||||
|
android:hasCode="false"
|
||||||
|
android:allowBackup="false">
|
||||||
<!-- Our activity is the built-in NativeActivity framework class.
|
<!-- Our activity is the built-in NativeActivity framework class.
|
||||||
This will take care of integrating with our NDK code. -->
|
This will take care of integrating with our NDK code. -->
|
||||||
<activity android:name="android.app.NativeActivity"
|
<activity android:name="android.app.NativeActivity"
|
||||||
|
|||||||
108
android/build.gradle
Normal file
108
android/build.gradle
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
// Copyright (c) 2017 Google, Inc.
|
||||||
|
//
|
||||||
|
// This software is provided 'as-is', without any express or implied
|
||||||
|
// warranty. In no event will the authors be held liable for any damages
|
||||||
|
// arising from the use of this software.
|
||||||
|
// Permission is granted to anyone to use this software for any purpose,
|
||||||
|
// including commercial applications, and to alter it and redistribute it
|
||||||
|
// freely, subject to the following restrictions:
|
||||||
|
// 1. The origin of this software must not be misrepresented; you must not
|
||||||
|
// claim that you wrote the original software. If you use this software
|
||||||
|
// in a product, an acknowledgment in the product documentation would be
|
||||||
|
// appreciated but is not required.
|
||||||
|
// 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
// misrepresented as being the original software.
|
||||||
|
// 3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
buildscript {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
dependencies {
|
||||||
|
classpath 'com.android.tools.build:gradle:2.3.0'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
allprojects {
|
||||||
|
repositories {
|
||||||
|
jcenter()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
|
android {
|
||||||
|
compileSdkVersion 25
|
||||||
|
buildToolsVersion '25.0.2'
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
manifest.srcFile 'AndroidManifest.xml'
|
||||||
|
res.srcDirs = ['res']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
path "jni/Android.mk"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultConfig {
|
||||||
|
applicationId 'com.example.FlatBufferTest'
|
||||||
|
// This is the platform API where NativeActivity was introduced.
|
||||||
|
minSdkVersion 9
|
||||||
|
targetSdkVersion 25
|
||||||
|
versionCode 1
|
||||||
|
versionName "1.0"
|
||||||
|
|
||||||
|
buildTypes {
|
||||||
|
release {
|
||||||
|
minifyEnabled false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
targets "FlatBufferTest"
|
||||||
|
arguments "-j" + Runtime.getRuntime().availableProcessors()
|
||||||
|
abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86", "x86_64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lintOptions {
|
||||||
|
abortOnError false
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build with each STL variant.
|
||||||
|
productFlavors {
|
||||||
|
stlport {
|
||||||
|
applicationIdSuffix ".stlport"
|
||||||
|
versionNameSuffix "-stlport"
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_STL=stlport_static"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
gnustl {
|
||||||
|
applicationIdSuffix ".gnustl"
|
||||||
|
versionNameSuffix "-gnustl"
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_STL=gnustl_static"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
libcpp {
|
||||||
|
applicationIdSuffix ".libcpp"
|
||||||
|
versionNameSuffix "-libcpp"
|
||||||
|
externalNativeBuild {
|
||||||
|
ndkBuild {
|
||||||
|
arguments "APP_STL=c++_static"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,511 +0,0 @@
|
|||||||
#!/bin/bash -eu
|
|
||||||
#
|
|
||||||
# Copyright (c) 2013 Google, Inc.
|
|
||||||
#
|
|
||||||
# This software is provided 'as-is', without any express or implied
|
|
||||||
# warranty. In no event will the authors be held liable for any damages
|
|
||||||
# arising from the use of this software.
|
|
||||||
# Permission is granted to anyone to use this software for any purpose,
|
|
||||||
# including commercial applications, and to alter it and redistribute it
|
|
||||||
# freely, subject to the following restrictions:
|
|
||||||
# 1. The origin of this software must not be misrepresented; you must not
|
|
||||||
# claim that you wrote the original software. If you use this software
|
|
||||||
# in a product, an acknowledgment in the product documentation would be
|
|
||||||
# appreciated but is not required.
|
|
||||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
|
||||||
# misrepresented as being the original software.
|
|
||||||
# 3. This notice may not be removed or altered from any source distribution.
|
|
||||||
#
|
|
||||||
# Build, deploy, debug / execute a native Android package based upon
|
|
||||||
# NativeActivity.
|
|
||||||
|
|
||||||
declare -r script_directory=$(dirname $0)
|
|
||||||
declare -r android_root=${script_directory}/../../../../../../
|
|
||||||
declare -r script_name=$(basename $0)
|
|
||||||
declare -r android_manifest=AndroidManifest.xml
|
|
||||||
declare -r os_name=$(uname -s)
|
|
||||||
|
|
||||||
# Minimum Android target version supported by this project.
|
|
||||||
: ${BUILDAPK_ANDROID_TARGET_MINVERSION:=10}
|
|
||||||
# Directory containing the Android SDK
|
|
||||||
# (http://developer.android.com/sdk/index.html).
|
|
||||||
: ${ANDROID_SDK_HOME:=}
|
|
||||||
# Directory containing the Android NDK
|
|
||||||
# (http://developer.android.com/tools/sdk/ndk/index.html).
|
|
||||||
: ${NDK_HOME:=}
|
|
||||||
|
|
||||||
# Display script help and exit.
|
|
||||||
usage() {
|
|
||||||
echo "
|
|
||||||
Build the Android package in the current directory and deploy it to a
|
|
||||||
connected device.
|
|
||||||
|
|
||||||
Usage: ${script_name} \\
|
|
||||||
[ADB_DEVICE=serial_number] [BUILD=0] [DEPLOY=0] [RUN_DEBUGGER=1] \
|
|
||||||
[LAUNCH=0] [SWIG_BIN=swig_binary_directory] [SWIG_LIB=swig_include_directory] [ndk-build arguments ...]
|
|
||||||
|
|
||||||
ADB_DEVICE=serial_number:
|
|
||||||
serial_number specifies the device to deploy the built apk to if multiple
|
|
||||||
Android devices are connected to the host.
|
|
||||||
BUILD=0:
|
|
||||||
Disables the build of the package.
|
|
||||||
DEPLOY=0:
|
|
||||||
Disables the deployment of the built apk to the Android device.
|
|
||||||
RUN_DEBUGGER=1:
|
|
||||||
Launches the application in gdb after it has been deployed. To debug in
|
|
||||||
gdb, NDK_DEBUG=1 must also be specified on the command line to build a
|
|
||||||
debug apk.
|
|
||||||
LAUNCH=0:
|
|
||||||
Disable the launch of the apk on the Android device.
|
|
||||||
SWIG_BIN=swig_binary_directory:
|
|
||||||
The directory where the SWIG binary lives. No need to set this if SWIG is
|
|
||||||
installed and point to from your PATH variable.
|
|
||||||
SWIG_LIB=swig_include_directory:
|
|
||||||
The directory where SWIG shared include files are, usually obtainable from
|
|
||||||
commandline with \"swig -swiglib\". No need to set this if SWIG is installed
|
|
||||||
and point to from your PATH variable.
|
|
||||||
ndk-build arguments...:
|
|
||||||
Additional arguments for ndk-build. See ndk-build -h for more information.
|
|
||||||
" >&2
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the number of CPU cores present on the host.
|
|
||||||
get_number_of_cores() {
|
|
||||||
case ${os_name} in
|
|
||||||
Darwin)
|
|
||||||
sysctl hw.ncpu | awk '{ print $2 }'
|
|
||||||
;;
|
|
||||||
CYGWIN*|Linux)
|
|
||||||
awk '/^processor/ { n=$3 } END { print n + 1 }' /proc/cpuinfo
|
|
||||||
;;
|
|
||||||
*)
|
|
||||||
echo 1
|
|
||||||
;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the package name from an AndroidManifest.xml file.
|
|
||||||
get_package_name_from_manifest() {
|
|
||||||
xmllint --xpath 'string(/manifest/@package)' "${1}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the library name from an AndroidManifest.xml file.
|
|
||||||
get_library_name_from_manifest() {
|
|
||||||
echo "\
|
|
||||||
setns android=http://schemas.android.com/apk/res/android
|
|
||||||
xpath string(/manifest/application/activity\
|
|
||||||
[@android:name=\"android.app.NativeActivity\"]/meta-data\
|
|
||||||
[@android:name=\"android.app.lib_name\"]/@android:value)" |
|
|
||||||
xmllint --shell "${1}" | awk '/Object is a string/ { print $NF }'
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get the number of Android devices connected to the system.
|
|
||||||
get_number_of_devices_connected() {
|
|
||||||
adb devices -l | \
|
|
||||||
awk '/^..*$/ { if (p) { print $0 } }
|
|
||||||
/List of devices attached/ { p = 1 }' | \
|
|
||||||
wc -l
|
|
||||||
return ${PIPESTATUS[0]}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Kill a process and its' children. This is provided for cygwin which
|
|
||||||
# doesn't ship with pkill.
|
|
||||||
kill_process_group() {
|
|
||||||
local parent_pid="${1}"
|
|
||||||
local child_pid=
|
|
||||||
for child_pid in $(ps -f | \
|
|
||||||
awk '{ if ($3 == '"${parent_pid}"') { print $2 } }'); do
|
|
||||||
kill_process_group "${child_pid}"
|
|
||||||
done
|
|
||||||
kill "${parent_pid}" 2>/dev/null
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and run "adb".
|
|
||||||
adb() {
|
|
||||||
local adb_path=
|
|
||||||
for path in "$(which adb 2>/dev/null)" \
|
|
||||||
"${ANDROID_SDK_HOME}/sdk/platform-tools/adb" \
|
|
||||||
"${android_root}/prebuilts/sdk/platform-tools/adb"; do
|
|
||||||
if [[ -e "${path}" ]]; then
|
|
||||||
adb_path="${path}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${adb_path}" == "" ]]; then
|
|
||||||
echo -e "Unable to find adb." \
|
|
||||||
"\nAdd the Android ADT sdk/platform-tools directory to the" \
|
|
||||||
"PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
"${adb_path}" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and run "android".
|
|
||||||
android() {
|
|
||||||
local android_executable=android
|
|
||||||
if echo "${os_name}" | grep -q CYGWIN; then
|
|
||||||
android_executable=android.bat
|
|
||||||
fi
|
|
||||||
local android_path=
|
|
||||||
for path in "$(which ${android_executable})" \
|
|
||||||
"${ANDROID_SDK_HOME}/sdk/tools/${android_executable}" \
|
|
||||||
"${android_root}/prebuilts/sdk/tools/${android_executable}"; do
|
|
||||||
if [[ -e "${path}" ]]; then
|
|
||||||
android_path="${path}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${android_path}" == "" ]]; then
|
|
||||||
echo -e "Unable to find android tool." \
|
|
||||||
"\nAdd the Android ADT sdk/tools directory to the PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Make sure ant is installed.
|
|
||||||
if [[ "$(which ant)" == "" ]]; then
|
|
||||||
echo -e "Unable to find ant." \
|
|
||||||
"\nPlease install ant and add to the PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
"${android_path}" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Find and run "ndk-build"
|
|
||||||
ndkbuild() {
|
|
||||||
local ndkbuild_path=
|
|
||||||
for path in "$(which ndk-build 2>/dev/null)" \
|
|
||||||
"${NDK_HOME}/ndk-build" \
|
|
||||||
"${android_root}/prebuilts/ndk/current/ndk-build"; do
|
|
||||||
if [[ -e "${path}" ]]; then
|
|
||||||
ndkbuild_path="${path}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${ndkbuild_path}" == "" ]]; then
|
|
||||||
echo -e "Unable to find ndk-build." \
|
|
||||||
"\nAdd the Android NDK directory to the PATH." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
"${ndkbuild_path}" "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get file modification time of $1 in seconds since the epoch.
|
|
||||||
stat_mtime() {
|
|
||||||
local filename="${1}"
|
|
||||||
case ${os_name} in
|
|
||||||
Darwin) stat -f%m "${filename}" 2>/dev/null || echo 0 ;;
|
|
||||||
*) stat -c%Y "${filename}" 2>/dev/null || echo 0 ;;
|
|
||||||
esac
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build the native (C/C++) build targets in the current directory.
|
|
||||||
build_native_targets() {
|
|
||||||
# Save the list of output modules in the install directory so that it's
|
|
||||||
# possible to restore their timestamps after the build is complete. This
|
|
||||||
# works around a bug in ndk/build/core/setup-app.mk which results in the
|
|
||||||
# unconditional execution of the clean-installed-binaries rule.
|
|
||||||
restore_libraries="$(find libs -type f 2>/dev/null | \
|
|
||||||
sed -E 's@^libs/(.*)@\1@')"
|
|
||||||
|
|
||||||
# Build native code.
|
|
||||||
ndkbuild -j$(get_number_of_cores) "$@"
|
|
||||||
|
|
||||||
# Restore installed libraries.
|
|
||||||
# Obviously this is a nasty hack (along with ${restore_libraries} above) as
|
|
||||||
# it assumes it knows where the NDK will be placing output files.
|
|
||||||
(
|
|
||||||
IFS=$'\n'
|
|
||||||
for libpath in ${restore_libraries}; do
|
|
||||||
source_library="obj/local/${libpath}"
|
|
||||||
target_library="libs/${libpath}"
|
|
||||||
if [[ -e "${source_library}" ]]; then
|
|
||||||
cp -a "${source_library}" "${target_library}"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
# Select the oldest installed android build target that is at least as new as
|
|
||||||
# BUILDAPK_ANDROID_TARGET_MINVERSION. If a suitable build target isn't found,
|
|
||||||
# this function prints an error message and exits with an error.
|
|
||||||
select_android_build_target() {
|
|
||||||
local -r android_targets_installed=$( \
|
|
||||||
android list targets | \
|
|
||||||
awk -F'"' '/^id:.*android/ { print $2 }')
|
|
||||||
local android_build_target=
|
|
||||||
for android_target in $(echo "${android_targets_installed}" | \
|
|
||||||
awk -F- '{ print $2 }' | sort -n); do
|
|
||||||
local isNumber='^[0-9]+$'
|
|
||||||
# skip preview API releases e.g. 'android-L'
|
|
||||||
if [[ $android_target =~ $isNumber ]]; then
|
|
||||||
if [[ $((android_target)) -ge \
|
|
||||||
$((BUILDAPK_ANDROID_TARGET_MINVERSION)) ]]; then
|
|
||||||
android_build_target="android-${android_target}"
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
# else
|
|
||||||
# The API version is a letter, so skip it.
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
if [[ "${android_build_target}" == "" ]]; then
|
|
||||||
echo -e \
|
|
||||||
"Found installed Android targets:" \
|
|
||||||
"$(echo ${android_targets_installed} | sed 's/ /\n /g;s/^/\n /;')" \
|
|
||||||
"\nAndroid SDK platform" \
|
|
||||||
"android-$((BUILDAPK_ANDROID_TARGET_MINVERSION))" \
|
|
||||||
"must be installed to build this project." \
|
|
||||||
"\nUse the \"android\" application to install API" \
|
|
||||||
"$((BUILDAPK_ANDROID_TARGET_MINVERSION)) or newer." >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "${android_build_target}"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Sign unsigned apk $1 and write the result to $2 with key store file $3 and
|
|
||||||
# password $4.
|
|
||||||
# If a key store file $3 and password $4 aren't specified, a temporary
|
|
||||||
# (60 day) key is generated and used to sign the package.
|
|
||||||
sign_apk() {
|
|
||||||
local unsigned_apk="${1}"
|
|
||||||
local signed_apk="${2}"
|
|
||||||
if [[ $(stat_mtime "${unsigned_apk}") -gt \
|
|
||||||
$(stat_mtime "${signed_apk}") ]]; then
|
|
||||||
local -r key_alias=$(basename ${signed_apk} .apk)
|
|
||||||
local keystore="${3}"
|
|
||||||
local key_password="${4}"
|
|
||||||
[[ "${keystore}" == "" ]] && keystore="${unsigned_apk}.keystore"
|
|
||||||
[[ "${key_password}" == "" ]] && \
|
|
||||||
key_password="${key_alias}123456"
|
|
||||||
if [[ ! -e ${keystore} ]]; then
|
|
||||||
keytool -genkey -v -dname "cn=, ou=${key_alias}, o=fpl" \
|
|
||||||
-storepass ${key_password} \
|
|
||||||
-keypass ${key_password} -keystore ${keystore} \
|
|
||||||
-alias ${key_alias} -keyalg RSA -keysize 2048 -validity 60
|
|
||||||
fi
|
|
||||||
cp "${unsigned_apk}" "${signed_apk}"
|
|
||||||
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 \
|
|
||||||
-keystore ${keystore} -storepass ${key_password} \
|
|
||||||
-keypass ${key_password} "${signed_apk}" ${key_alias}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Build the apk $1 for package filename $2 in the current directory using the
|
|
||||||
# ant build target $3.
|
|
||||||
build_apk() {
|
|
||||||
local -r output_apk="${1}"
|
|
||||||
local -r package_filename="${2}"
|
|
||||||
local -r ant_target="${3}"
|
|
||||||
# Get the list of installed android targets and select the oldest target
|
|
||||||
# that is at least as new as BUILDAPK_ANDROID_TARGET_MINVERSION.
|
|
||||||
local -r android_build_target=$(select_android_build_target)
|
|
||||||
[[ "${android_build_target}" == "" ]] && exit 1
|
|
||||||
echo "Building ${output_apk} for target ${android_build_target}" >&2
|
|
||||||
|
|
||||||
# Create / update build.xml and local.properties files.
|
|
||||||
if [[ $(stat_mtime "${android_manifest}") -gt \
|
|
||||||
$(stat_mtime build.xml) ]]; then
|
|
||||||
android update project --target "${android_build_target}" \
|
|
||||||
-n ${package_filename} --path .
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use ant to build the apk.
|
|
||||||
ant -quiet ${ant_target}
|
|
||||||
|
|
||||||
# Sign release apks with a temporary key as these packages will not be
|
|
||||||
# redistributed.
|
|
||||||
local unsigned_apk="bin/${package_filename}-${ant_target}-unsigned.apk"
|
|
||||||
if [[ "${ant_target}" == "release" ]]; then
|
|
||||||
sign_apk "${unsigned_apk}" "${output_apk}" "" ""
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Uninstall package $1 and install apk $2 on device $3 where $3 is "-s device"
|
|
||||||
# or an empty string. If $3 is an empty string adb will fail when multiple
|
|
||||||
# devices are connected to the host system.
|
|
||||||
install_apk() {
|
|
||||||
local -r uninstall_package_name="${1}"
|
|
||||||
local -r install_apk="${2}"
|
|
||||||
local -r adb_device="${3}"
|
|
||||||
# Uninstall the package if it's already installed.
|
|
||||||
adb ${adb_device} uninstall "${uninstall_package_name}" 1>&2 > /dev/null || \
|
|
||||||
true # no error check
|
|
||||||
|
|
||||||
# Install the apk.
|
|
||||||
# NOTE: The following works around adb not returning an error code when
|
|
||||||
# it fails to install an apk.
|
|
||||||
echo "Install ${install_apk}" >&2
|
|
||||||
local -r adb_install_result=$(adb ${adb_device} install "${install_apk}")
|
|
||||||
echo "${adb_install_result}"
|
|
||||||
if echo "${adb_install_result}" | grep -qF 'Failure ['; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Launch previously installed package $1 on device $2.
|
|
||||||
# If $2 is an empty string adb will fail when multiple devices are connected
|
|
||||||
# to the host system.
|
|
||||||
launch_package() {
|
|
||||||
(
|
|
||||||
# Determine the SDK version of Android on the device.
|
|
||||||
local -r android_sdk_version=$(
|
|
||||||
adb ${adb_device} shell cat system/build.prop | \
|
|
||||||
awk -F= '/ro.build.version.sdk/ {
|
|
||||||
v=$2; sub(/[ \r\n]/, "", v); print v
|
|
||||||
}')
|
|
||||||
|
|
||||||
# Clear logs from previous runs.
|
|
||||||
# Note that logcat does not just 'tail' the logs, it dumps the entire log
|
|
||||||
# history.
|
|
||||||
adb ${adb_device} logcat -c
|
|
||||||
|
|
||||||
local finished_msg='Displayed '"${package_name}"
|
|
||||||
local timeout_msg='Activity destroy timeout.*'"${package_name}"
|
|
||||||
# Maximum time to wait before stopping log monitoring. 0 = infinity.
|
|
||||||
local launch_timeout=0
|
|
||||||
# If this is a Gingerbread device, kill log monitoring after 10 seconds.
|
|
||||||
if [[ $((android_sdk_version)) -le 10 ]]; then
|
|
||||||
launch_timeout=10
|
|
||||||
fi
|
|
||||||
# Display logcat in the background.
|
|
||||||
# Stop displaying the log when the app launch / execution completes or the
|
|
||||||
# logcat
|
|
||||||
(
|
|
||||||
adb ${adb_device} logcat | \
|
|
||||||
awk "
|
|
||||||
{
|
|
||||||
print \$0
|
|
||||||
}
|
|
||||||
|
|
||||||
/ActivityManager.*: ${finished_msg}/ {
|
|
||||||
exit 0
|
|
||||||
}
|
|
||||||
|
|
||||||
/ActivityManager.*: ${timeout_msg}/ {
|
|
||||||
exit 0
|
|
||||||
}" &
|
|
||||||
adb_logcat_pid=$!;
|
|
||||||
if [[ $((launch_timeout)) -gt 0 ]]; then
|
|
||||||
sleep $((launch_timeout));
|
|
||||||
kill ${adb_logcat_pid};
|
|
||||||
else
|
|
||||||
wait ${adb_logcat_pid};
|
|
||||||
fi
|
|
||||||
) &
|
|
||||||
logcat_pid=$!
|
|
||||||
# Kill adb logcat if this shell exits.
|
|
||||||
trap "kill_process_group ${logcat_pid}" SIGINT SIGTERM EXIT
|
|
||||||
|
|
||||||
# If the SDK is newer than 10, "am" supports stopping an activity.
|
|
||||||
adb_stop_activity=
|
|
||||||
if [[ $((android_sdk_version)) -gt 10 ]]; then
|
|
||||||
adb_stop_activity=-S
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Launch the activity and wait for it to complete.
|
|
||||||
adb ${adb_device} shell am start ${adb_stop_activity} -n \
|
|
||||||
${package_name}/android.app.NativeActivity
|
|
||||||
|
|
||||||
wait "${logcat_pid}"
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
# See usage().
|
|
||||||
main() {
|
|
||||||
# Parse arguments for this script.
|
|
||||||
local adb_device=
|
|
||||||
local ant_target=release
|
|
||||||
local disable_deploy=0
|
|
||||||
local disable_build=0
|
|
||||||
local run_debugger=0
|
|
||||||
local launch=1
|
|
||||||
local build_package=1
|
|
||||||
for opt; do
|
|
||||||
case ${opt} in
|
|
||||||
# NDK_DEBUG=0 tells ndk-build to build this as debuggable but to not
|
|
||||||
# modify the underlying code whereas NDK_DEBUG=1 also builds as debuggable
|
|
||||||
# but does modify the code
|
|
||||||
NDK_DEBUG=1) ant_target=debug ;;
|
|
||||||
NDK_DEBUG=0) ant_target=debug ;;
|
|
||||||
ADB_DEVICE*) adb_device="$(\
|
|
||||||
echo "${opt}" | sed -E 's/^ADB_DEVICE=([^ ]+)$/-s \1/;t;s/.*//')" ;;
|
|
||||||
BUILD=0) disable_build=1 ;;
|
|
||||||
DEPLOY=0) disable_deploy=1 ;;
|
|
||||||
RUN_DEBUGGER=1) run_debugger=1 ;;
|
|
||||||
LAUNCH=0) launch=0 ;;
|
|
||||||
clean) build_package=0 disable_deploy=1 launch=0 ;;
|
|
||||||
-h|--help|help) usage ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
# If a target device hasn't been specified and multiple devices are connected
|
|
||||||
# to the host machine, display an error.
|
|
||||||
local -r devices_connected=$(get_number_of_devices_connected)
|
|
||||||
if [[ "${adb_device}" == "" && $((devices_connected)) -gt 1 && \
|
|
||||||
($((disable_deploy)) -eq 0 || $((launch)) -ne 0 || \
|
|
||||||
$((run_debugger)) -ne 0) ]]; then
|
|
||||||
if [[ $((disable_deploy)) -ne 0 ]]; then
|
|
||||||
echo "Deployment enabled, disable using DEPLOY=0" >&2
|
|
||||||
fi
|
|
||||||
if [[ $((launch)) -ne 0 ]]; then
|
|
||||||
echo "Launch enabled." >&2
|
|
||||||
fi
|
|
||||||
if [[ $((disable_deploy)) -eq 0 ]]; then
|
|
||||||
echo "Deployment enabled." >&2
|
|
||||||
fi
|
|
||||||
if [[ $((run_debugger)) -ne 0 ]]; then
|
|
||||||
echo "Debugger launch enabled." >&2
|
|
||||||
fi
|
|
||||||
echo "
|
|
||||||
Multiple Android devices are connected to this host. Either disable deployment
|
|
||||||
and execution of the built .apk using:
|
|
||||||
\"${script_name} DEPLOY=0 LAUNCH=0\"
|
|
||||||
|
|
||||||
or specify a device to deploy to using:
|
|
||||||
\"${script_name} ADB_DEVICE=\${device_serial}\".
|
|
||||||
|
|
||||||
The Android devices connected to this machine are:
|
|
||||||
$(adb devices -l)
|
|
||||||
" >&2
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ $((disable_build)) -eq 0 ]]; then
|
|
||||||
# Build the native target.
|
|
||||||
build_native_targets "$@"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Get the package name from the manifest.
|
|
||||||
local -r package_name=$(get_package_name_from_manifest "${android_manifest}")
|
|
||||||
if [[ "${package_name}" == "" ]]; then
|
|
||||||
echo -e "No package name specified in ${android_manifest},"\
|
|
||||||
"skipping apk build, deploy"
|
|
||||||
"\nand launch steps." >&2
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
local -r package_basename=${package_name/*./}
|
|
||||||
local package_filename=$(get_library_name_from_manifest ${android_manifest})
|
|
||||||
[[ "${package_filename}" == "" ]] && package_filename="${package_basename}"
|
|
||||||
|
|
||||||
# Output apk name.
|
|
||||||
local -r output_apk="bin/${package_filename}-${ant_target}.apk"
|
|
||||||
|
|
||||||
if [[ $((disable_build)) -eq 0 && $((build_package)) -eq 1 ]]; then
|
|
||||||
# Build the apk.
|
|
||||||
build_apk "${output_apk}" "${package_filename}" "${ant_target}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Deploy to the device.
|
|
||||||
if [[ $((disable_deploy)) -eq 0 ]]; then
|
|
||||||
install_apk "${package_name}" "${output_apk}" "${adb_device}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ "${ant_target}" == "debug" && $((run_debugger)) -eq 1 ]]; then
|
|
||||||
# Start debugging.
|
|
||||||
ndk-gdb ${adb_device} --start
|
|
||||||
elif [[ $((launch)) -eq 1 ]]; then
|
|
||||||
launch_package "${package_name}" "${adb_device}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
main "$@"
|
|
||||||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#Mon Jun 19 11:54:59 PDT 2017
|
||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-4.0-all.zip
|
||||||
172
android/gradlew
vendored
Executable file
172
android/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
|||||||
|
#!/usr/bin/env sh
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
##
|
||||||
|
## Gradle start up script for UN*X
|
||||||
|
##
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
PRG="$0"
|
||||||
|
# Need this for relative symlinks.
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG=`dirname "$PRG"`"/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
SAVED="`pwd`"
|
||||||
|
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||||
|
APP_HOME="`pwd -P`"
|
||||||
|
cd "$SAVED" >/dev/null
|
||||||
|
|
||||||
|
APP_NAME="Gradle"
|
||||||
|
APP_BASE_NAME=`basename "$0"`
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS=""
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD="maximum"
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
}
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN* )
|
||||||
|
cygwin=true
|
||||||
|
;;
|
||||||
|
Darwin* )
|
||||||
|
darwin=true
|
||||||
|
;;
|
||||||
|
MINGW* )
|
||||||
|
msys=true
|
||||||
|
;;
|
||||||
|
NONSTOP* )
|
||||||
|
nonstop=true
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="java"
|
||||||
|
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||||
|
MAX_FD_LIMIT=`ulimit -H -n`
|
||||||
|
if [ $? -eq 0 ] ; then
|
||||||
|
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||||
|
MAX_FD="$MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
ulimit -n $MAX_FD
|
||||||
|
if [ $? -ne 0 ] ; then
|
||||||
|
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Darwin, add options to specify how the application appears in the dock
|
||||||
|
if $darwin; then
|
||||||
|
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin ; then
|
||||||
|
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||||
|
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||||
|
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||||
|
|
||||||
|
# We build the pattern for arguments to be converted via cygpath
|
||||||
|
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||||
|
SEP=""
|
||||||
|
for dir in $ROOTDIRSRAW ; do
|
||||||
|
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||||
|
SEP="|"
|
||||||
|
done
|
||||||
|
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||||
|
# Add a user-defined pattern to the cygpath arguments
|
||||||
|
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||||
|
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||||
|
fi
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
i=0
|
||||||
|
for arg in "$@" ; do
|
||||||
|
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||||
|
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||||
|
|
||||||
|
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||||
|
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||||
|
else
|
||||||
|
eval `echo args$i`="\"$arg\""
|
||||||
|
fi
|
||||||
|
i=$((i+1))
|
||||||
|
done
|
||||||
|
case $i in
|
||||||
|
(0) set -- ;;
|
||||||
|
(1) set -- "$args0" ;;
|
||||||
|
(2) set -- "$args0" "$args1" ;;
|
||||||
|
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||||
|
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||||
|
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||||
|
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||||
|
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||||
|
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||||
|
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Escape application args
|
||||||
|
save () {
|
||||||
|
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||||
|
echo " "
|
||||||
|
}
|
||||||
|
APP_ARGS=$(save "$@")
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||||
|
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||||
|
|
||||||
|
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||||
|
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
||||||
84
android/gradlew.bat
vendored
Normal file
84
android/gradlew.bat
vendored
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
@if "%DEBUG%" == "" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%" == "" set DIRNAME=.
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS=
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if "%ERRORLEVEL%" == "0" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||||
|
echo.
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
echo location of your Java installation.
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:init
|
||||||
|
@rem Get command-line arguments, handling Windows variants
|
||||||
|
|
||||||
|
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||||
|
|
||||||
|
:win9xME_args
|
||||||
|
@rem Slurp the command line arguments.
|
||||||
|
set CMD_LINE_ARGS=
|
||||||
|
set _SKIP=2
|
||||||
|
|
||||||
|
:win9xME_args_slurp
|
||||||
|
if "x%~1" == "x" goto execute
|
||||||
|
|
||||||
|
set CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
||||||
7
android/jni/Android.mk
Executable file → Normal file
7
android/jni/Android.mk
Executable file → Normal file
@@ -39,6 +39,7 @@ LOCAL_SRC_FILES := src/idl_parser.cpp \
|
|||||||
src/util.cpp \
|
src/util.cpp \
|
||||||
src/code_generators.cpp
|
src/code_generators.cpp
|
||||||
LOCAL_STATIC_LIBRARIES := flatbuffers
|
LOCAL_STATIC_LIBRARIES := flatbuffers
|
||||||
|
LOCAL_ARM_MODE := arm
|
||||||
include $(BUILD_STATIC_LIBRARY)
|
include $(BUILD_STATIC_LIBRARY)
|
||||||
|
|
||||||
# FlatBuffers test
|
# FlatBuffers test
|
||||||
@@ -46,9 +47,13 @@ include $(CLEAR_VARS)
|
|||||||
LOCAL_MODULE := FlatBufferTest
|
LOCAL_MODULE := FlatBufferTest
|
||||||
LOCAL_SRC_FILES := android/jni/main.cpp \
|
LOCAL_SRC_FILES := android/jni/main.cpp \
|
||||||
tests/test.cpp \
|
tests/test.cpp \
|
||||||
|
tests/test_assert.h \
|
||||||
|
tests/test_builder.h \
|
||||||
|
tests/test_assert.cpp \
|
||||||
|
tests/test_builder.cpp \
|
||||||
src/idl_gen_fbs.cpp \
|
src/idl_gen_fbs.cpp \
|
||||||
src/idl_gen_general.cpp
|
src/idl_gen_general.cpp
|
||||||
LOCAL_LDLIBS := -llog -landroid
|
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
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|||||||
6
android/jni/Application.mk
Executable file → Normal file
6
android/jni/Application.mk
Executable file → Normal file
@@ -13,10 +13,8 @@
|
|||||||
# 2. Altered source versions must be plainly marked as such, and must not be
|
# 2. Altered source versions must be plainly marked as such, and must not be
|
||||||
# misrepresented as being the original software.
|
# misrepresented as being the original software.
|
||||||
# 3. This notice may not be removed or altered from any source distribution.
|
# 3. This notice may not be removed or altered from any source distribution.
|
||||||
APP_PLATFORM := android-10
|
APP_PLATFORM := android-9
|
||||||
APP_PROJECT_PATH := $(call my-dir)/..
|
APP_PROJECT_PATH := $(call my-dir)/..
|
||||||
APP_STL := gnustl_static
|
APP_STL ?= stlport_static
|
||||||
|
|
||||||
APP_ABI := armeabi-v7a
|
APP_ABI := armeabi-v7a
|
||||||
|
|
||||||
APP_CPPFLAGS += -std=c++11
|
APP_CPPFLAGS += -std=c++11
|
||||||
|
|||||||
0
android/jni/build_flatc.bat
Executable file → Normal file
0
android/jni/build_flatc.bat
Executable file → Normal file
0
android/res/values/strings.xml
Executable file → Normal file
0
android/res/values/strings.xml
Executable file → Normal file
52
appveyor.yml
52
appveyor.yml
@@ -5,8 +5,15 @@ branches:
|
|||||||
os: Visual Studio 2015
|
os: Visual Studio 2015
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|
||||||
|
global:
|
||||||
|
# Workaround for https://github.com/conda/conda-build/issues/636
|
||||||
|
PYTHONIOENCODING: UTF-8
|
||||||
|
CONDA_INSTALL_LOCN: "C:\\Miniconda35-x64"
|
||||||
|
|
||||||
matrix:
|
matrix:
|
||||||
- CMAKE_VS_VERSION: "10 2010"
|
- CMAKE_VS_VERSION: "10 2010"
|
||||||
|
- CMAKE_VS_VERSION: "12 2013"
|
||||||
- CMAKE_VS_VERSION: "14 2015"
|
- CMAKE_VS_VERSION: "14 2015"
|
||||||
|
|
||||||
platform:
|
platform:
|
||||||
@@ -26,17 +33,52 @@ build:
|
|||||||
project: ALL_BUILD.vcxproj
|
project: ALL_BUILD.vcxproj
|
||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
|
|
||||||
|
after_build:
|
||||||
|
- python conan/appveyor/install.py
|
||||||
|
- python conan/appveyor/build.py
|
||||||
|
|
||||||
|
install:
|
||||||
|
- set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%;
|
||||||
|
- curl -sSf -o rustup-init.exe https://win.rustup.rs/
|
||||||
|
- rustup-init.exe -y
|
||||||
|
- set PATH=%PATH%;C:\Users\appveyor\.cargo\bin
|
||||||
|
- rustc -V
|
||||||
|
- cargo -V
|
||||||
|
|
||||||
test_script:
|
test_script:
|
||||||
- rem "---------------- C++ -----------------"
|
|
||||||
- "%CONFIGURATION%\\flattests.exe"
|
|
||||||
- rem "---------------- Java -----------------"
|
|
||||||
- "cd tests"
|
- "cd tests"
|
||||||
|
- rem "Building all code"
|
||||||
|
- generate_code.bat -b %CONFIGURATION%
|
||||||
|
- 7z a GeneratedMyGameCode.zip MyGame\
|
||||||
|
- rem "---------------- C++ -----------------"
|
||||||
|
- "cd .."
|
||||||
|
- "%CONFIGURATION%\\flattests.exe"
|
||||||
|
- "cd tests"
|
||||||
|
- rem "---------------- Java -----------------"
|
||||||
- "java -version"
|
- "java -version"
|
||||||
- "JavaTest.bat"
|
- "JavaTest.bat"
|
||||||
|
- rem "---------------- Rust ----------------"
|
||||||
|
- "RustTest.bat"
|
||||||
- rem "---------------- JS -----------------"
|
- rem "---------------- JS -----------------"
|
||||||
- "node --version"
|
- "node --version"
|
||||||
- "..\\%CONFIGURATION%\\flatc -b -I include_test monster_test.fbs unicode_test.json"
|
- "..\\%CONFIGURATION%\\flatc -b -I include_test monster_test.fbs unicode_test.json"
|
||||||
- "node JavaScriptTest ./monster_test_generated"
|
- "node JavaScriptTest ./monster_test_generated"
|
||||||
|
- rem "-------------- Python ---------------"
|
||||||
|
- where python
|
||||||
|
- python --version
|
||||||
|
- where pip
|
||||||
|
- pip --version
|
||||||
|
- where conda
|
||||||
|
- conda --version
|
||||||
|
- rem "installing flatbuffers python library"
|
||||||
|
- pip install ../python
|
||||||
|
- rem "testing without installing Numpy"
|
||||||
|
- python py_test.py 0 0 0
|
||||||
|
- rem "testing after installing Numpy - disabled"
|
||||||
|
# FIXME: This has a LOT of unnecessary dependencies and makes the tests fail
|
||||||
|
# with timeouts.
|
||||||
|
# - conda install --yes numpy
|
||||||
|
# - python py_test.py 0 0 0
|
||||||
- rem "---------------- C# -----------------"
|
- rem "---------------- C# -----------------"
|
||||||
# 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??
|
||||||
@@ -47,5 +89,7 @@ test_script:
|
|||||||
- "cd ..\\.."
|
- "cd ..\\.."
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: $(CONFIGURATION)\\flatc.exe
|
- path: $(CONFIGURATION)\flatc.exe
|
||||||
name: flatc.exe
|
name: flatc.exe
|
||||||
|
- path: tests\GeneratedMyGameCode.zip
|
||||||
|
name: GeneratedMyGameCode.zip
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
# Biicode configuration file
|
|
||||||
[paths]
|
|
||||||
include
|
|
||||||
[mains]
|
|
||||||
!android/*
|
|
||||||
[tests]
|
|
||||||
tests/*
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
Biicode C/C++ dependency manager
|
|
||||||
=================================
|
|
||||||
|
|
||||||
[](https://www.biicode.com/fenix/flatbuffers)
|
|
||||||
|
|
||||||
New with biicode? Check the [Getting Started Guide](http://docs.biicode.com/c++/gettingstarted.html).
|
|
||||||
|
|
||||||
How to build it?
|
|
||||||
------------------
|
|
||||||
Building it is too easy:
|
|
||||||
|
|
||||||
$ git clone git@github.com:google/flatbuffers.git
|
|
||||||
$ cd flatbuffers
|
|
||||||
$ bii init -L && bii build
|
|
||||||
$ ./bin/any_executable
|
|
||||||
|
|
||||||
Or run its tests:
|
|
||||||
|
|
||||||
$ bii test
|
|
||||||
|
|
||||||
You can check [the examples/flatbuffers block](https://www.biicode.com/examples/flatbuffers).
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
set(BII_TESTS_WORKING_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
# Copying data files to project/bin folder
|
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/samples")
|
|
||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples/monster.fbs"
|
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/samples/monsterdata.json"
|
|
||||||
DESTINATION
|
|
||||||
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/samples")
|
|
||||||
endif()
|
|
||||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/tests")
|
|
||||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests"
|
|
||||||
DESTINATION
|
|
||||||
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
ADD_BIICODE_TARGETS()
|
|
||||||
|
|
||||||
string(REPLACE " " ";" REPLACED_FLAGS ${CMAKE_CXX_FLAGS})
|
|
||||||
target_compile_options(${BII_BLOCK_TARGET} INTERFACE ${REPLACED_FLAGS})
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#
|
|
||||||
# Copyright 2016 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.
|
|
||||||
|
|
||||||
sudo apt-get update -qq
|
|
||||||
sudo apt-get install libglu1-mesa-dev xorg-dev
|
|
||||||
wget http://www.biicode.com/downloads/latest/ubuntu64
|
|
||||||
mv ubuntu64 bii-ubuntu64.deb
|
|
||||||
(sudo dpkg -i bii-ubuntu64.deb) && sudo apt-get -f install
|
|
||||||
rm bii-ubuntu64.deb
|
|
||||||
wget https://s3.amazonaws.com/biibinaries/thirdparty/cmake-3.0.2-Linux-64.tar.gz
|
|
||||||
tar -xzf cmake-3.0.2-Linux-64.tar.gz
|
|
||||||
sudo cp -fR cmake-3.0.2-Linux-64/* /usr
|
|
||||||
rm -rf cmake-3.0.2-Linux-64
|
|
||||||
rm cmake-3.0.2-Linux-64.tar.gz
|
|
||||||
|
|
||||||
cmake --version
|
|
||||||
bii init -l && bii configure -DCMAKE_BUILD_TYPE=$1 && bii test
|
|
||||||
12
conan/CMakeLists.txt
Normal file
12
conan/CMakeLists.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
message(STATUS "Conan FlatBuffers Wrapper")
|
||||||
|
|
||||||
|
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||||
|
conan_basic_setup()
|
||||||
|
|
||||||
|
if (WIN32 AND MSVC AND FLATBUFFERS_BUILD_SHAREDLIB)
|
||||||
|
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
|
||||||
|
endif(WIN32 AND MSVC AND FLATBUFFERS_BUILD_SHAREDLIB)
|
||||||
|
|
||||||
|
include(${CMAKE_SOURCE_DIR}/CMakeListsOriginal.txt)
|
||||||
8
conan/appveyor/build.py
Normal file
8
conan/appveyor/build.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
|
||||||
|
if os.getenv("APPVEYOR_REPO_TAG") != "true":
|
||||||
|
print("Skip build step. It's not TAG")
|
||||||
|
else:
|
||||||
|
os.system("python conan/build.py")
|
||||||
8
conan/appveyor/install.py
Normal file
8
conan/appveyor/install.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import os
|
||||||
|
|
||||||
|
if os.getenv("APPVEYOR_REPO_TAG") != "true":
|
||||||
|
print("Skip step. It's not TAG")
|
||||||
|
else:
|
||||||
|
os.system("pip install conan conan-package-tools")
|
||||||
32
conan/build.py
Normal file
32
conan/build.py
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from cpt.packager import ConanMultiPackager
|
||||||
|
import os
|
||||||
|
|
||||||
|
def set_appveyor_environment():
|
||||||
|
if os.getenv("APPVEYOR") is not None:
|
||||||
|
compiler_version = os.getenv("CMAKE_VS_VERSION").split(" ")[0].replace('"', '')
|
||||||
|
os.environ["CONAN_VISUAL_VERSIONS"] = compiler_version
|
||||||
|
os.environ["CONAN_STABLE_BRANCH_PATTERN"] = "master"
|
||||||
|
ci_platform = os.getenv("Platform").replace('"', '')
|
||||||
|
ci_platform = "x86" if ci_platform == "x86" else "x86_64"
|
||||||
|
os.environ["CONAN_ARCHS"] = ci_platform
|
||||||
|
os.environ["CONAN_BUILD_TYPES"] = os.getenv("Configuration").replace('"', '')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
login_username = os.getenv("CONAN_LOGIN_USERNAME", "aardappel")
|
||||||
|
username = os.getenv("CONAN_USERNAME", "google")
|
||||||
|
upload = os.getenv("CONAN_UPLOAD", "https://api.bintray.com/conan/aardappel/flatbuffers")
|
||||||
|
stable_branch_pattern = os.getenv("CONAN_STABLE_BRANCH_PATTERN", r"v\d+\.\d+\.\d+.*")
|
||||||
|
test_folder = os.getenv("CPT_TEST_FOLDER", os.path.join("conan", "test_package"))
|
||||||
|
upload_only_when_stable = os.getenv("CONAN_UPLOAD_ONLY_WHEN_STABLE", True)
|
||||||
|
set_appveyor_environment()
|
||||||
|
|
||||||
|
builder = ConanMultiPackager(username=username,
|
||||||
|
login_username=login_username,
|
||||||
|
upload=upload,
|
||||||
|
stable_branch_pattern=stable_branch_pattern,
|
||||||
|
upload_only_when_stable=upload_only_when_stable,
|
||||||
|
test_folder=test_folder)
|
||||||
|
builder.add_common_builds(pure_c=False)
|
||||||
|
builder.run()
|
||||||
9
conan/test_package/CMakeLists.txt
Normal file
9
conan/test_package/CMakeLists.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
project(test_package CXX)
|
||||||
|
cmake_minimum_required(VERSION 2.8.11)
|
||||||
|
|
||||||
|
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
|
||||||
|
conan_basic_setup()
|
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} test_package.cpp)
|
||||||
|
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
|
||||||
|
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
|
||||||
21
conan/test_package/conanfile.py
Normal file
21
conan/test_package/conanfile.py
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from conans import ConanFile, CMake
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
class TestPackageConan(ConanFile):
|
||||||
|
settings = "os", "compiler", "build_type", "arch"
|
||||||
|
generators = "cmake"
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.configure()
|
||||||
|
cmake.build()
|
||||||
|
|
||||||
|
def test(self):
|
||||||
|
bin_path = os.path.join("bin", "test_package")
|
||||||
|
self.run(bin_path, run_environment=True)
|
||||||
|
self.run("flatc --version", run_environment=True)
|
||||||
|
self.run("flathash fnv1_16 conan", run_environment=True)
|
||||||
35
conan/test_package/test_package.cpp
Normal file
35
conan/test_package/test_package.cpp
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
|
// Test to validate Conan package generated
|
||||||
|
|
||||||
|
int main(int /*argc*/, const char * /*argv*/ []) {
|
||||||
|
|
||||||
|
const std::string filename("conanbuildinfo.cmake");
|
||||||
|
|
||||||
|
if (flatbuffers::FileExists(filename.c_str())) {
|
||||||
|
std::cout << "File " << filename << " exists.\n";
|
||||||
|
} else {
|
||||||
|
std::cout << "File " << filename << " does not exist.\n";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
14
conan/travis/build.sh
Executable file
14
conan/travis/build.sh
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ "$(uname -s)" == 'Darwin' ]]; then
|
||||||
|
if which pyenv > /dev/null; then
|
||||||
|
eval "$(pyenv init -)"
|
||||||
|
fi
|
||||||
|
pyenv activate conan
|
||||||
|
fi
|
||||||
|
|
||||||
|
conan user
|
||||||
|
python conan/build.py
|
||||||
22
conan/travis/install.sh
Executable file
22
conan/travis/install.sh
Executable file
@@ -0,0 +1,22 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
set -x
|
||||||
|
|
||||||
|
if [[ "$(uname -s)" == 'Darwin' ]]; then
|
||||||
|
brew update || brew update
|
||||||
|
brew outdated pyenv || brew upgrade pyenv
|
||||||
|
brew install pyenv-virtualenv
|
||||||
|
brew install cmake || true
|
||||||
|
|
||||||
|
if which pyenv > /dev/null; then
|
||||||
|
eval "$(pyenv init -)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pyenv install 2.7.10
|
||||||
|
pyenv virtualenv 2.7.10 conan
|
||||||
|
pyenv rehash
|
||||||
|
pyenv activate conan
|
||||||
|
fi
|
||||||
|
|
||||||
|
pip install -U conan_package_tools conan
|
||||||
74
conanfile.py
Normal file
74
conanfile.py
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
"""Conan recipe package for Google FlatBuffers
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
from conans import ConanFile, CMake, tools
|
||||||
|
|
||||||
|
|
||||||
|
class FlatbuffersConan(ConanFile):
|
||||||
|
name = "flatbuffers"
|
||||||
|
version = "1.10.0"
|
||||||
|
license = "Apache-2.0"
|
||||||
|
url = "https://github.com/google/flatbuffers"
|
||||||
|
homepage = "http://google.github.io/flatbuffers/"
|
||||||
|
author = "Wouter van Oortmerssen"
|
||||||
|
description = "Memory Efficient Serialization Library"
|
||||||
|
settings = "os", "compiler", "build_type", "arch"
|
||||||
|
options = {"shared": [True, False], "fPIC": [True, False]}
|
||||||
|
default_options = "shared=False", "fPIC=True"
|
||||||
|
generators = "cmake"
|
||||||
|
exports = "LICENSE.txt"
|
||||||
|
exports_sources = ["CMake/*", "include/*", "src/*", "grpc/*", "CMakeLists.txt", "conan/CMakeLists.txt"]
|
||||||
|
|
||||||
|
def source(self):
|
||||||
|
"""Wrap the original CMake file to call conan_basic_setup
|
||||||
|
"""
|
||||||
|
shutil.move("CMakeLists.txt", "CMakeListsOriginal.txt")
|
||||||
|
shutil.move(os.path.join("conan", "CMakeLists.txt"), "CMakeLists.txt")
|
||||||
|
|
||||||
|
def config_options(self):
|
||||||
|
"""Remove fPIC option on Windows platform
|
||||||
|
"""
|
||||||
|
if self.settings.os == "Windows":
|
||||||
|
self.options.remove("fPIC")
|
||||||
|
|
||||||
|
def configure_cmake(self):
|
||||||
|
"""Create CMake instance and execute configure step
|
||||||
|
"""
|
||||||
|
cmake = CMake(self)
|
||||||
|
cmake.definitions["FLATBUFFERS_BUILD_TESTS"] = False
|
||||||
|
cmake.definitions["FLATBUFFERS_BUILD_SHAREDLIB"] = self.options.shared
|
||||||
|
cmake.definitions["FLATBUFFERS_BUILD_FLATLIB"] = not self.options.shared
|
||||||
|
cmake.configure()
|
||||||
|
return cmake
|
||||||
|
|
||||||
|
def build(self):
|
||||||
|
"""Configure, build and install FlatBuffers using CMake.
|
||||||
|
"""
|
||||||
|
cmake = self.configure_cmake()
|
||||||
|
cmake.build()
|
||||||
|
|
||||||
|
def package(self):
|
||||||
|
"""Copy Flatbuffers' artifacts to package folder
|
||||||
|
"""
|
||||||
|
cmake = self.configure_cmake()
|
||||||
|
cmake.install()
|
||||||
|
self.copy(pattern="LICENSE.txt", dst="licenses")
|
||||||
|
self.copy(pattern="flathash*", dst="bin", src="bin")
|
||||||
|
self.copy(pattern="flatc*", dst="bin", src="bin")
|
||||||
|
if self.settings.os == "Windows" and self.options.shared:
|
||||||
|
if self.settings.compiler == "Visual Studio":
|
||||||
|
shutil.move(os.path.join(self.package_folder, "lib", "%s.dll" % self.name),
|
||||||
|
os.path.join(self.package_folder, "bin", "%s.dll" % self.name))
|
||||||
|
elif self.settings.compiler == "gcc":
|
||||||
|
shutil.move(os.path.join(self.package_folder, "lib", "lib%s.dll" % self.name),
|
||||||
|
os.path.join(self.package_folder, "bin", "lib%s.dll" % self.name))
|
||||||
|
|
||||||
|
def package_info(self):
|
||||||
|
"""Collect built libraries names and solve flatc path.
|
||||||
|
"""
|
||||||
|
self.cpp_info.libs = tools.collect_libs(self)
|
||||||
|
self.user_info.flatc = os.path.join(self.package_folder, "bin", "flatc")
|
||||||
14
dart/CHANGELOG.md
Normal file
14
dart/CHANGELOG.md
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 1.9.2
|
||||||
|
|
||||||
|
- Ensure `_writeString` adds enough padding to null terminate strings.
|
||||||
|
|
||||||
|
## 1.9.1
|
||||||
|
|
||||||
|
- Changed constant identifiers to be compatible with Dart 2.x
|
||||||
|
- No longer supports Dart 1.x
|
||||||
|
|
||||||
|
## 1.9.0
|
||||||
|
|
||||||
|
- Initial release, supports Dart 1.x and many dev versions of Dart 2.x
|
||||||
233
dart/LICENSE
Normal file
233
dart/LICENSE
Normal file
@@ -0,0 +1,233 @@
|
|||||||
|
The code in lib/flat_buffers.dart is based on code that was releases under the
|
||||||
|
following license:
|
||||||
|
|
||||||
|
Copyright 2012, the Dart project authors. 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.
|
||||||
|
|
||||||
|
To the extent permissible, the changes to that code and the other assets in
|
||||||
|
this package are licensed under the Apache2 license:
|
||||||
|
|
||||||
|
|
||||||
|
Apache License
|
||||||
|
Version 2.0, January 2004
|
||||||
|
http://www.apache.org/licenses/
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||||
|
|
||||||
|
1. Definitions.
|
||||||
|
|
||||||
|
"License" shall mean the terms and conditions for use, reproduction,
|
||||||
|
and distribution as defined by Sections 1 through 9 of this document.
|
||||||
|
|
||||||
|
"Licensor" shall mean the copyright owner or entity authorized by
|
||||||
|
the copyright owner that is granting the License.
|
||||||
|
|
||||||
|
"Legal Entity" shall mean the union of the acting entity and all
|
||||||
|
other entities that control, are controlled by, or are under common
|
||||||
|
control with that entity. For the purposes of this definition,
|
||||||
|
"control" means (i) the power, direct or indirect, to cause the
|
||||||
|
direction or management of such entity, whether by contract or
|
||||||
|
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||||
|
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||||
|
|
||||||
|
"You" (or "Your") shall mean an individual or Legal Entity
|
||||||
|
exercising permissions granted by this License.
|
||||||
|
|
||||||
|
"Source" form shall mean the preferred form for making modifications,
|
||||||
|
including but not limited to software source code, documentation
|
||||||
|
source, and configuration files.
|
||||||
|
|
||||||
|
"Object" form shall mean any form resulting from mechanical
|
||||||
|
transformation or translation of a Source form, including but
|
||||||
|
not limited to compiled object code, generated documentation,
|
||||||
|
and conversions to other media types.
|
||||||
|
|
||||||
|
"Work" shall mean the work of authorship, whether in Source or
|
||||||
|
Object form, made available under the License, as indicated by a
|
||||||
|
copyright notice that is included in or attached to the work
|
||||||
|
(an example is provided in the Appendix below).
|
||||||
|
|
||||||
|
"Derivative Works" shall mean any work, whether in Source or Object
|
||||||
|
form, that is based on (or derived from) the Work and for which the
|
||||||
|
editorial revisions, annotations, elaborations, or other modifications
|
||||||
|
represent, as a whole, an original work of authorship. For the purposes
|
||||||
|
of this License, Derivative Works shall not include works that remain
|
||||||
|
separable from, or merely link (or bind by name) to the interfaces of,
|
||||||
|
the Work and Derivative Works thereof.
|
||||||
|
|
||||||
|
"Contribution" shall mean any work of authorship, including
|
||||||
|
the original version of the Work and any modifications or additions
|
||||||
|
to that Work or Derivative Works thereof, that is intentionally
|
||||||
|
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||||
|
or by an individual or Legal Entity authorized to submit on behalf of
|
||||||
|
the copyright owner. For the purposes of this definition, "submitted"
|
||||||
|
means any form of electronic, verbal, or written communication sent
|
||||||
|
to the Licensor or its representatives, including but not limited to
|
||||||
|
communication on electronic mailing lists, source code control systems,
|
||||||
|
and issue tracking systems that are managed by, or on behalf of, the
|
||||||
|
Licensor for the purpose of discussing and improving the Work, but
|
||||||
|
excluding communication that is conspicuously marked or otherwise
|
||||||
|
designated in writing by the copyright owner as "Not a Contribution."
|
||||||
|
|
||||||
|
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||||
|
on behalf of whom a Contribution has been received by Licensor and
|
||||||
|
subsequently incorporated within the Work.
|
||||||
|
|
||||||
|
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
copyright license to reproduce, prepare Derivative Works of,
|
||||||
|
publicly display, publicly perform, sublicense, and distribute the
|
||||||
|
Work and such Derivative Works in Source or Object form.
|
||||||
|
|
||||||
|
3. Grant of Patent License. Subject to the terms and conditions of
|
||||||
|
this License, each Contributor hereby grants to You a perpetual,
|
||||||
|
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||||
|
(except as stated in this section) patent license to make, have made,
|
||||||
|
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||||
|
where such license applies only to those patent claims licensable
|
||||||
|
by such Contributor that are necessarily infringed by their
|
||||||
|
Contribution(s) alone or by combination of their Contribution(s)
|
||||||
|
with the Work to which such Contribution(s) was submitted. If You
|
||||||
|
institute patent litigation against any entity (including a
|
||||||
|
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||||
|
or a Contribution incorporated within the Work constitutes direct
|
||||||
|
or contributory patent infringement, then any patent licenses
|
||||||
|
granted to You under this License for that Work shall terminate
|
||||||
|
as of the date such litigation is filed.
|
||||||
|
|
||||||
|
4. Redistribution. You may reproduce and distribute copies of the
|
||||||
|
Work or Derivative Works thereof in any medium, with or without
|
||||||
|
modifications, and in Source or Object form, provided that You
|
||||||
|
meet the following conditions:
|
||||||
|
|
||||||
|
(a) You must give any other recipients of the Work or
|
||||||
|
Derivative Works a copy of this License; and
|
||||||
|
|
||||||
|
(b) You must cause any modified files to carry prominent notices
|
||||||
|
stating that You changed the files; and
|
||||||
|
|
||||||
|
(c) You must retain, in the Source form of any Derivative Works
|
||||||
|
that You distribute, all copyright, patent, trademark, and
|
||||||
|
attribution notices from the Source form of the Work,
|
||||||
|
excluding those notices that do not pertain to any part of
|
||||||
|
the Derivative Works; and
|
||||||
|
|
||||||
|
(d) If the Work includes a "NOTICE" text file as part of its
|
||||||
|
distribution, then any Derivative Works that You distribute must
|
||||||
|
include a readable copy of the attribution notices contained
|
||||||
|
within such NOTICE file, excluding those notices that do not
|
||||||
|
pertain to any part of the Derivative Works, in at least one
|
||||||
|
of the following places: within a NOTICE text file distributed
|
||||||
|
as part of the Derivative Works; within the Source form or
|
||||||
|
documentation, if provided along with the Derivative Works; or,
|
||||||
|
within a display generated by the Derivative Works, if and
|
||||||
|
wherever such third-party notices normally appear. The contents
|
||||||
|
of the NOTICE file are for informational purposes only and
|
||||||
|
do not modify the License. You may add Your own attribution
|
||||||
|
notices within Derivative Works that You distribute, alongside
|
||||||
|
or as an addendum to the NOTICE text from the Work, provided
|
||||||
|
that such additional attribution notices cannot be construed
|
||||||
|
as modifying the License.
|
||||||
|
|
||||||
|
You may add Your own copyright statement to Your modifications and
|
||||||
|
may provide additional or different license terms and conditions
|
||||||
|
for use, reproduction, or distribution of Your modifications, or
|
||||||
|
for any such Derivative Works as a whole, provided Your use,
|
||||||
|
reproduction, and distribution of the Work otherwise complies with
|
||||||
|
the conditions stated in this License.
|
||||||
|
|
||||||
|
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||||
|
any Contribution intentionally submitted for inclusion in the Work
|
||||||
|
by You to the Licensor shall be under the terms and conditions of
|
||||||
|
this License, without any additional terms or conditions.
|
||||||
|
Notwithstanding the above, nothing herein shall supersede or modify
|
||||||
|
the terms of any separate license agreement you may have executed
|
||||||
|
with Licensor regarding such Contributions.
|
||||||
|
|
||||||
|
6. Trademarks. This License does not grant permission to use the trade
|
||||||
|
names, trademarks, service marks, or product names of the Licensor,
|
||||||
|
except as required for reasonable and customary use in describing the
|
||||||
|
origin of the Work and reproducing the content of the NOTICE file.
|
||||||
|
|
||||||
|
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||||
|
agreed to in writing, Licensor provides the Work (and each
|
||||||
|
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||||
|
implied, including, without limitation, any warranties or conditions
|
||||||
|
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||||
|
appropriateness of using or redistributing the Work and assume any
|
||||||
|
risks associated with Your exercise of permissions under this License.
|
||||||
|
|
||||||
|
8. Limitation of Liability. In no event and under no legal theory,
|
||||||
|
whether in tort (including negligence), contract, or otherwise,
|
||||||
|
unless required by applicable law (such as deliberate and grossly
|
||||||
|
negligent acts) or agreed to in writing, shall any Contributor be
|
||||||
|
liable to You for damages, including any direct, indirect, special,
|
||||||
|
incidental, or consequential damages of any character arising as a
|
||||||
|
result of this License or out of the use or inability to use the
|
||||||
|
Work (including but not limited to damages for loss of goodwill,
|
||||||
|
work stoppage, computer failure or malfunction, or any and all
|
||||||
|
other commercial damages or losses), even if such Contributor
|
||||||
|
has been advised of the possibility of such damages.
|
||||||
|
|
||||||
|
9. Accepting Warranty or Additional Liability. While redistributing
|
||||||
|
the Work or Derivative Works thereof, You may choose to offer,
|
||||||
|
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||||
|
or other liability obligations and/or rights consistent with this
|
||||||
|
License. However, in accepting such obligations, You may act only
|
||||||
|
on Your own behalf and on Your sole responsibility, not on behalf
|
||||||
|
of any other Contributor, and only if You agree to indemnify,
|
||||||
|
defend, and hold each Contributor harmless for any liability
|
||||||
|
incurred by, or claims asserted against, such Contributor by reason
|
||||||
|
of your accepting any such warranty or additional liability.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
APPENDIX: How to apply the Apache License to your work.
|
||||||
|
|
||||||
|
To apply the Apache License to your work, attach the following
|
||||||
|
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||||
|
replaced with your own identifying information. (Don't include
|
||||||
|
the brackets!) The text should be enclosed in the appropriate
|
||||||
|
comment syntax for the file format. We also recommend that a
|
||||||
|
file or class name and description of purpose be included on the
|
||||||
|
same "printed page" as the copyright notice for easier
|
||||||
|
identification within third-party archives.
|
||||||
|
|
||||||
|
Copyright 2014 Google Inc.
|
||||||
|
|
||||||
|
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.
|
||||||
13
dart/README.md
Normal file
13
dart/README.md
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# FlatBuffers for Dart
|
||||||
|
|
||||||
|
This package is used to read and write FlatBuffer files in Dart.
|
||||||
|
|
||||||
|
Most consumers will want to use the [`flatc`](https://github.com/google/flatbuffers)
|
||||||
|
compiler to generate Dart code from a FlatBuffers IDL schema. For example, the
|
||||||
|
`monster_my_game.sample_generated.dart` was generated with `flatc` from
|
||||||
|
`monster.fbs` in the example folder. The generated classes can be used to read
|
||||||
|
or write binary files that are interoperable with other languages and platforms
|
||||||
|
supported by FlatBuffers, as illustrated in the `example.dart` in the
|
||||||
|
examples folder.
|
||||||
|
|
||||||
|
Additional documentation and examples are available [at the FlatBuffers site](https://google.github.io/flatbuffers/index.html)
|
||||||
155
dart/example/example.dart
Normal file
155
dart/example/example.dart
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 Dan Field. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import 'package:flat_buffers/flat_buffers.dart' as fb;
|
||||||
|
import './monster_my_game.sample_generated.dart' as myGame;
|
||||||
|
|
||||||
|
// Example how to use FlatBuffers to create and read binary buffers.
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
builderTest();
|
||||||
|
objectBuilderTest();
|
||||||
|
}
|
||||||
|
|
||||||
|
void builderTest() {
|
||||||
|
final builder = new fb.Builder(initialSize: 1024);
|
||||||
|
final int weaponOneName = builder.writeString("Sword");
|
||||||
|
final int weaponOneDamage = 3;
|
||||||
|
|
||||||
|
final int weaponTwoName = builder.writeString("Axe");
|
||||||
|
final int weaponTwoDamage = 5;
|
||||||
|
|
||||||
|
final swordBuilder = new myGame.WeaponBuilder(builder)
|
||||||
|
..begin()
|
||||||
|
..addNameOffset(weaponOneName)
|
||||||
|
..addDamage(weaponOneDamage);
|
||||||
|
final int sword = swordBuilder.finish();
|
||||||
|
|
||||||
|
final axeBuilder = new myGame.WeaponBuilder(builder)
|
||||||
|
..begin()
|
||||||
|
..addNameOffset(weaponTwoName)
|
||||||
|
..addDamage(weaponTwoDamage);
|
||||||
|
final int axe = axeBuilder.finish();
|
||||||
|
|
||||||
|
// Serialize a name for our monster, called "Orc".
|
||||||
|
final int name = builder.writeString('Orc');
|
||||||
|
|
||||||
|
// Create a list representing the inventory of the Orc. Each number
|
||||||
|
// could correspond to an item that can be claimed after he is slain.
|
||||||
|
final List<int> treasure = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
|
||||||
|
final inventory = builder.writeListUint8(treasure);
|
||||||
|
final weapons = builder.writeList([sword, axe]);
|
||||||
|
|
||||||
|
// Struct builders are very easy to reuse.
|
||||||
|
final vec3Builder = new myGame.Vec3Builder(builder);
|
||||||
|
|
||||||
|
vec3Builder.finish(4.0, 5.0, 6.0);
|
||||||
|
vec3Builder.finish(1.0, 2.0, 3.0);
|
||||||
|
// Set his hit points to 300 and his mana to 150.
|
||||||
|
final int hp = 300;
|
||||||
|
final int mana = 150;
|
||||||
|
|
||||||
|
final monster = new myGame.MonsterBuilder(builder)
|
||||||
|
..begin()
|
||||||
|
..addNameOffset(name)
|
||||||
|
..addInventoryOffset(inventory)
|
||||||
|
..addWeaponsOffset(weapons)
|
||||||
|
..addEquippedType(myGame.EquipmentTypeId.Weapon)
|
||||||
|
..addEquippedOffset(axe)
|
||||||
|
..addHp(hp)
|
||||||
|
..addMana(mana)
|
||||||
|
..addPos(vec3Builder.finish(1.0, 2.0, 3.0))
|
||||||
|
..addColor(myGame.Color.Red);
|
||||||
|
|
||||||
|
final int monsteroff = monster.finish();
|
||||||
|
final buffer = builder.finish(monsteroff);
|
||||||
|
if (verify(buffer)) {
|
||||||
|
print(
|
||||||
|
"The FlatBuffer was successfully created with a builder and verified!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void objectBuilderTest() {
|
||||||
|
// Create the builder here so we can use it for both weapons and equipped
|
||||||
|
// the actual data will only be written to the buffer once.
|
||||||
|
var axe = new myGame.WeaponObjectBuilder(name: 'Axe', damage: 5);
|
||||||
|
|
||||||
|
var monsterBuilder = new myGame.MonsterObjectBuilder(
|
||||||
|
pos: new myGame.Vec3ObjectBuilder(x: 1.0, y: 2.0, z: 3.0),
|
||||||
|
mana: 150,
|
||||||
|
hp: 300,
|
||||||
|
name: 'Orc',
|
||||||
|
inventory: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
|
||||||
|
color: myGame.Color.Red,
|
||||||
|
weapons: [new myGame.WeaponObjectBuilder(name: 'Sword', damage: 3), axe],
|
||||||
|
equippedType: myGame.EquipmentTypeId.Weapon,
|
||||||
|
equipped: axe,
|
||||||
|
);
|
||||||
|
|
||||||
|
var buffer = monsterBuilder.toBytes();
|
||||||
|
|
||||||
|
// We now have a FlatBuffer we can store on disk or send over a network.
|
||||||
|
|
||||||
|
// ** file/network code goes here :) **
|
||||||
|
|
||||||
|
// Instead, we're going to access it right away (as if we just received it).
|
||||||
|
if (verify(buffer)) {
|
||||||
|
print(
|
||||||
|
"The FlatBuffer was successfully created with an object builder and verified!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool verify(List<int> buffer) {
|
||||||
|
// Get access to the root:
|
||||||
|
var monster = new myGame.Monster(buffer);
|
||||||
|
|
||||||
|
// Get and test some scalar types from the FlatBuffer.
|
||||||
|
assert(monster.hp == 80);
|
||||||
|
assert(monster.mana == 150); // default
|
||||||
|
assert(monster.name == "MyMonster");
|
||||||
|
|
||||||
|
// Get and test a field of the FlatBuffer's `struct`.
|
||||||
|
var pos = monster.pos;
|
||||||
|
assert(pos != null);
|
||||||
|
assert(pos.z == 3.0);
|
||||||
|
|
||||||
|
// Get a test an element from the `inventory` FlatBuffer's `vector`.
|
||||||
|
var inv = monster.inventory;
|
||||||
|
assert(inv != null);
|
||||||
|
assert(inv.length == 10);
|
||||||
|
assert(inv[9] == 9);
|
||||||
|
|
||||||
|
// Get and test the `weapons` FlatBuffers's `vector`.
|
||||||
|
var expected_weapon_names = ["Sword", "Axe"];
|
||||||
|
var expected_weapon_damages = [3, 5];
|
||||||
|
var weps = monster.weapons;
|
||||||
|
for (int i = 0; i < weps.length; i++) {
|
||||||
|
assert(weps[i].name == expected_weapon_names[i]);
|
||||||
|
assert(weps[i].damage == expected_weapon_damages[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get and test the `Equipment` union (`equipped` field).
|
||||||
|
assert(monster.equippedType.value == myGame.EquipmentTypeId.Weapon.value);
|
||||||
|
assert(monster.equippedType == myGame.EquipmentTypeId.Weapon);
|
||||||
|
|
||||||
|
assert(monster.equipped is myGame.Weapon);
|
||||||
|
var equipped = monster.equipped as myGame.Weapon;
|
||||||
|
assert(equipped.name == "Axe");
|
||||||
|
assert(equipped.damage == 5);
|
||||||
|
|
||||||
|
print(monster);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
440
dart/example/monster_my_game.sample_generated.dart
Normal file
440
dart/example/monster_my_game.sample_generated.dart
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
// ignore_for_file: unused_import, non_constant_identifier_names
|
||||||
|
|
||||||
|
library my_game.sample;
|
||||||
|
|
||||||
|
import 'dart:typed_data' show Uint8List;
|
||||||
|
import 'package:flat_buffers/flat_buffers.dart' as fb;
|
||||||
|
|
||||||
|
|
||||||
|
class Color {
|
||||||
|
final int value;
|
||||||
|
const Color._(this.value);
|
||||||
|
|
||||||
|
factory Color.fromValue(int value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (!values.containsKey(value)) {
|
||||||
|
throw new StateError('Invalid value $value for bit flag enum Color');
|
||||||
|
}
|
||||||
|
return values[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int minValue = 0;
|
||||||
|
static const int maxValue = 2;
|
||||||
|
static bool containsValue(int value) => values.containsKey(value);
|
||||||
|
|
||||||
|
static const Color Red = const Color._(0);
|
||||||
|
static const Color Green = const Color._(1);
|
||||||
|
static const Color Blue = const Color._(2);
|
||||||
|
static get values => {0: Red,1: Green,2: Blue,};
|
||||||
|
|
||||||
|
static const fb.Reader<Color> reader = const _ColorReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Color{value: $value}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _ColorReader extends fb.Reader<Color> {
|
||||||
|
const _ColorReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get size => 1;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Color read(fb.BufferContext bc, int offset) =>
|
||||||
|
new Color.fromValue(const fb.Int8Reader().read(bc, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
class EquipmentTypeId {
|
||||||
|
final int value;
|
||||||
|
const EquipmentTypeId._(this.value);
|
||||||
|
|
||||||
|
factory EquipmentTypeId.fromValue(int value) {
|
||||||
|
if (value == null) return null;
|
||||||
|
if (!values.containsKey(value)) {
|
||||||
|
throw new StateError('Invalid value $value for bit flag enum EquipmentTypeId');
|
||||||
|
}
|
||||||
|
return values[value];
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int minValue = 0;
|
||||||
|
static const int maxValue = 1;
|
||||||
|
static bool containsValue(int value) => values.containsKey(value);
|
||||||
|
|
||||||
|
static const EquipmentTypeId NONE = const EquipmentTypeId._(0);
|
||||||
|
static const EquipmentTypeId Weapon = const EquipmentTypeId._(1);
|
||||||
|
static get values => {0: NONE,1: Weapon,};
|
||||||
|
|
||||||
|
static const fb.Reader<EquipmentTypeId> reader = const _EquipmentTypeIdReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'EquipmentTypeId{value: $value}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _EquipmentTypeIdReader extends fb.Reader<EquipmentTypeId> {
|
||||||
|
const _EquipmentTypeIdReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get size => 1;
|
||||||
|
|
||||||
|
@override
|
||||||
|
EquipmentTypeId read(fb.BufferContext bc, int offset) =>
|
||||||
|
new EquipmentTypeId.fromValue(const fb.Uint8Reader().read(bc, offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vec3 {
|
||||||
|
Vec3._(this._bc, this._bcOffset);
|
||||||
|
|
||||||
|
static const fb.Reader<Vec3> reader = const _Vec3Reader();
|
||||||
|
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
double get x => const fb.Float32Reader().read(_bc, _bcOffset + 0);
|
||||||
|
double get y => const fb.Float32Reader().read(_bc, _bcOffset + 4);
|
||||||
|
double get z => const fb.Float32Reader().read(_bc, _bcOffset + 8);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Vec3{x: $x, y: $y, z: $z}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _Vec3Reader extends fb.StructReader<Vec3> {
|
||||||
|
const _Vec3Reader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get size => 12;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Vec3 createObject(fb.BufferContext bc, int offset) =>
|
||||||
|
new Vec3._(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vec3Builder {
|
||||||
|
Vec3Builder(this.fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
final fb.Builder fbBuilder;
|
||||||
|
|
||||||
|
int finish(double x, double y, double z) {
|
||||||
|
fbBuilder.putFloat32(z);
|
||||||
|
fbBuilder.putFloat32(y);
|
||||||
|
fbBuilder.putFloat32(x);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Vec3ObjectBuilder extends fb.ObjectBuilder {
|
||||||
|
final double _x;
|
||||||
|
final double _y;
|
||||||
|
final double _z;
|
||||||
|
|
||||||
|
Vec3ObjectBuilder({
|
||||||
|
double x,
|
||||||
|
double y,
|
||||||
|
double z,
|
||||||
|
})
|
||||||
|
: _x = x,
|
||||||
|
_y = y,
|
||||||
|
_z = z;
|
||||||
|
|
||||||
|
/// Finish building, and store into the [fbBuilder].
|
||||||
|
@override
|
||||||
|
int finish(
|
||||||
|
fb.Builder fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
|
||||||
|
fbBuilder.putFloat32(_z);
|
||||||
|
fbBuilder.putFloat32(_y);
|
||||||
|
fbBuilder.putFloat32(_x);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to serialize to byte list.
|
||||||
|
@override
|
||||||
|
Uint8List toBytes([String fileIdentifier]) {
|
||||||
|
fb.Builder fbBuilder = new fb.Builder();
|
||||||
|
int offset = finish(fbBuilder);
|
||||||
|
return fbBuilder.finish(offset, fileIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Monster {
|
||||||
|
Monster._(this._bc, this._bcOffset);
|
||||||
|
factory Monster(List<int> bytes) {
|
||||||
|
fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
|
||||||
|
return reader.read(rootRef, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const fb.Reader<Monster> reader = const _MonsterReader();
|
||||||
|
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
Vec3 get pos => Vec3.reader.vTableGet(_bc, _bcOffset, 4, null);
|
||||||
|
int get mana => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, 150);
|
||||||
|
int get hp => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 8, 100);
|
||||||
|
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);
|
||||||
|
Color get color => new Color.fromValue(const fb.Int8Reader().vTableGet(_bc, _bcOffset, 16, 2));
|
||||||
|
List<Weapon> get weapons => const fb.ListReader<Weapon>(Weapon.reader).vTableGet(_bc, _bcOffset, 18, null);
|
||||||
|
EquipmentTypeId get equippedType => new EquipmentTypeId.fromValue(const fb.Uint8Reader().vTableGet(_bc, _bcOffset, 20, null));
|
||||||
|
dynamic get equipped {
|
||||||
|
switch (equippedType?.value) {
|
||||||
|
case 1: return Weapon.reader.vTableGet(_bc, _bcOffset, 22, null);
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
List<Vec3> get path => const fb.ListReader<Vec3>(Vec3.reader).vTableGet(_bc, _bcOffset, 24, null);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Monster{pos: $pos, mana: $mana, hp: $hp, name: $name, inventory: $inventory, color: $color, weapons: $weapons, equippedType: $equippedType, equipped: $equipped, path: $path}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MonsterReader extends fb.TableReader<Monster> {
|
||||||
|
const _MonsterReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Monster createObject(fb.BufferContext bc, int offset) =>
|
||||||
|
new Monster._(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonsterBuilder {
|
||||||
|
MonsterBuilder(this.fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
final fb.Builder fbBuilder;
|
||||||
|
|
||||||
|
void begin() {
|
||||||
|
fbBuilder.startTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int addPos(int offset) {
|
||||||
|
fbBuilder.addStruct(0, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addMana(int mana) {
|
||||||
|
fbBuilder.addInt16(1, mana);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addHp(int hp) {
|
||||||
|
fbBuilder.addInt16(2, hp);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addNameOffset(int offset) {
|
||||||
|
fbBuilder.addOffset(3, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addInventoryOffset(int offset) {
|
||||||
|
fbBuilder.addOffset(5, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addColor(Color color) {
|
||||||
|
fbBuilder.addInt8(6, color?.value);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addWeaponsOffset(int offset) {
|
||||||
|
fbBuilder.addOffset(7, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addEquippedType(EquipmentTypeId equippedType) {
|
||||||
|
fbBuilder.addUint8(8, equippedType?.value);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addEquippedOffset(int offset) {
|
||||||
|
fbBuilder.addOffset(9, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addPathOffset(int offset) {
|
||||||
|
fbBuilder.addOffset(10, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finish() {
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonsterObjectBuilder extends fb.ObjectBuilder {
|
||||||
|
final Vec3ObjectBuilder _pos;
|
||||||
|
final int _mana;
|
||||||
|
final int _hp;
|
||||||
|
final String _name;
|
||||||
|
final List<int> _inventory;
|
||||||
|
final Color _color;
|
||||||
|
final List<WeaponObjectBuilder> _weapons;
|
||||||
|
final EquipmentTypeId _equippedType;
|
||||||
|
final dynamic _equipped;
|
||||||
|
final List<Vec3ObjectBuilder> _path;
|
||||||
|
|
||||||
|
MonsterObjectBuilder({
|
||||||
|
Vec3ObjectBuilder pos,
|
||||||
|
int mana,
|
||||||
|
int hp,
|
||||||
|
String name,
|
||||||
|
List<int> inventory,
|
||||||
|
Color color,
|
||||||
|
List<WeaponObjectBuilder> weapons,
|
||||||
|
EquipmentTypeId equippedType,
|
||||||
|
dynamic equipped,
|
||||||
|
List<Vec3ObjectBuilder> path,
|
||||||
|
})
|
||||||
|
: _pos = pos,
|
||||||
|
_mana = mana,
|
||||||
|
_hp = hp,
|
||||||
|
_name = name,
|
||||||
|
_inventory = inventory,
|
||||||
|
_color = color,
|
||||||
|
_weapons = weapons,
|
||||||
|
_equippedType = equippedType,
|
||||||
|
_equipped = equipped,
|
||||||
|
_path = path;
|
||||||
|
|
||||||
|
/// Finish building, and store into the [fbBuilder].
|
||||||
|
@override
|
||||||
|
int finish(
|
||||||
|
fb.Builder fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
final int nameOffset = fbBuilder.writeString(_name);
|
||||||
|
final int inventoryOffset = _inventory?.isNotEmpty == true
|
||||||
|
? fbBuilder.writeListUint8(_inventory)
|
||||||
|
: null;
|
||||||
|
final int weaponsOffset = _weapons?.isNotEmpty == true
|
||||||
|
? fbBuilder.writeList(_weapons.map((b) => b.getOrCreateOffset(fbBuilder)).toList())
|
||||||
|
: null;
|
||||||
|
final int equippedOffset = _equipped?.getOrCreateOffset(fbBuilder);
|
||||||
|
final int pathOffset = _path?.isNotEmpty == true
|
||||||
|
? fbBuilder.writeListOfStructs(_path)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
fbBuilder.startTable();
|
||||||
|
if (_pos != null) {
|
||||||
|
fbBuilder.addStruct(0, _pos.finish(fbBuilder));
|
||||||
|
}
|
||||||
|
fbBuilder.addInt16(1, _mana);
|
||||||
|
fbBuilder.addInt16(2, _hp);
|
||||||
|
if (nameOffset != null) {
|
||||||
|
fbBuilder.addOffset(3, nameOffset);
|
||||||
|
}
|
||||||
|
if (inventoryOffset != null) {
|
||||||
|
fbBuilder.addOffset(5, inventoryOffset);
|
||||||
|
}
|
||||||
|
fbBuilder.addInt8(6, _color?.value);
|
||||||
|
if (weaponsOffset != null) {
|
||||||
|
fbBuilder.addOffset(7, weaponsOffset);
|
||||||
|
}
|
||||||
|
fbBuilder.addUint8(8, _equippedType?.value);
|
||||||
|
if (equippedOffset != null) {
|
||||||
|
fbBuilder.addOffset(9, equippedOffset);
|
||||||
|
}
|
||||||
|
if (pathOffset != null) {
|
||||||
|
fbBuilder.addOffset(10, pathOffset);
|
||||||
|
}
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to serialize to byte list.
|
||||||
|
@override
|
||||||
|
Uint8List toBytes([String fileIdentifier]) {
|
||||||
|
fb.Builder fbBuilder = new fb.Builder();
|
||||||
|
int offset = finish(fbBuilder);
|
||||||
|
return fbBuilder.finish(offset, fileIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
class Weapon {
|
||||||
|
Weapon._(this._bc, this._bcOffset);
|
||||||
|
factory Weapon(List<int> bytes) {
|
||||||
|
fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
|
||||||
|
return reader.read(rootRef, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const fb.Reader<Weapon> reader = const _WeaponReader();
|
||||||
|
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
String get name => const fb.StringReader().vTableGet(_bc, _bcOffset, 4, null);
|
||||||
|
int get damage => const fb.Int16Reader().vTableGet(_bc, _bcOffset, 6, null);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Weapon{name: $name, damage: $damage}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _WeaponReader extends fb.TableReader<Weapon> {
|
||||||
|
const _WeaponReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Weapon createObject(fb.BufferContext bc, int offset) =>
|
||||||
|
new Weapon._(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeaponBuilder {
|
||||||
|
WeaponBuilder(this.fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
}
|
||||||
|
|
||||||
|
final fb.Builder fbBuilder;
|
||||||
|
|
||||||
|
void begin() {
|
||||||
|
fbBuilder.startTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
int addNameOffset(int offset) {
|
||||||
|
fbBuilder.addOffset(0, offset);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
int addDamage(int damage) {
|
||||||
|
fbBuilder.addInt16(1, damage);
|
||||||
|
return fbBuilder.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
int finish() {
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WeaponObjectBuilder extends fb.ObjectBuilder {
|
||||||
|
final String _name;
|
||||||
|
final int _damage;
|
||||||
|
|
||||||
|
WeaponObjectBuilder({
|
||||||
|
String name,
|
||||||
|
int damage,
|
||||||
|
})
|
||||||
|
: _name = name,
|
||||||
|
_damage = damage;
|
||||||
|
|
||||||
|
/// Finish building, and store into the [fbBuilder].
|
||||||
|
@override
|
||||||
|
int finish(
|
||||||
|
fb.Builder fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
final int nameOffset = fbBuilder.writeString(_name);
|
||||||
|
|
||||||
|
fbBuilder.startTable();
|
||||||
|
if (nameOffset != null) {
|
||||||
|
fbBuilder.addOffset(0, nameOffset);
|
||||||
|
}
|
||||||
|
fbBuilder.addInt16(1, _damage);
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to serialize to byte list.
|
||||||
|
@override
|
||||||
|
Uint8List toBytes([String fileIdentifier]) {
|
||||||
|
fb.Builder fbBuilder = new fb.Builder();
|
||||||
|
int offset = finish(fbBuilder);
|
||||||
|
return fbBuilder.finish(offset, fileIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
1241
dart/lib/flat_buffers.dart
Normal file
1241
dart/lib/flat_buffers.dart
Normal file
File diff suppressed because it is too large
Load Diff
28
dart/publish.sh
Executable file
28
dart/publish.sh
Executable file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
#
|
||||||
|
# Copyright 2018 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 to pub consumers: this file is used to assist with publishing the
|
||||||
|
# pub package from the flatbuffers repository and is not meant for general use.
|
||||||
|
# As pub does not currently provide a way to exclude files, it is included here.
|
||||||
|
|
||||||
|
command -v pub >/dev/null 2>&1 || { echo >&2 "Require `pub` but it's not installed. Aborting."; exit 1; }
|
||||||
|
|
||||||
|
cp ../samples/monster.fbs example/
|
||||||
|
cp ../tests/monster_test.fbs test/
|
||||||
|
pub publish
|
||||||
|
|
||||||
|
rm example/monster.fbs
|
||||||
|
rm test/monster_test.fbs
|
||||||
20
dart/pubspec.yaml
Normal file
20
dart/pubspec.yaml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
name: flat_buffers
|
||||||
|
version: 1.10.0
|
||||||
|
description: >
|
||||||
|
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
|
||||||
|
reading and writing the binary format.
|
||||||
|
|
||||||
|
Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
|
||||||
|
authors:
|
||||||
|
- Dan Field <dfield@gmail.com>
|
||||||
|
- Konstantin Scheglov
|
||||||
|
- Paul Berry
|
||||||
|
homepage: https://github.com/google/flatbuffers
|
||||||
|
documentation: https://google.github.io/flatbuffers/index.html
|
||||||
|
dev_dependencies:
|
||||||
|
test: ^1.3.0
|
||||||
|
test_reflective_loader: ^0.1.4
|
||||||
|
path: ^1.5.1
|
||||||
|
environment:
|
||||||
|
sdk: '>=2.0.0-dev.28.0 <3.0.0'
|
||||||
573
dart/test/flat_buffers_test.dart
Normal file
573
dart/test/flat_buffers_test.dart
Normal file
@@ -0,0 +1,573 @@
|
|||||||
|
// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
|
||||||
|
// for details. All rights reserved. Use of this source code is governed by a
|
||||||
|
// BSD-style license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'dart:typed_data';
|
||||||
|
import 'dart:io' as io;
|
||||||
|
|
||||||
|
import 'package:path/path.dart' as path;
|
||||||
|
|
||||||
|
import 'package:flat_buffers/flat_buffers.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||||
|
|
||||||
|
import './monster_test_my_game.example_generated.dart' as example;
|
||||||
|
|
||||||
|
main() {
|
||||||
|
defineReflectiveSuite(() {
|
||||||
|
defineReflectiveTests(BuilderTest);
|
||||||
|
defineReflectiveTests(CheckOtherLangaugesData);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
int indexToField(int index) {
|
||||||
|
return (1 + 1 + index) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
@reflectiveTest
|
||||||
|
class CheckOtherLangaugesData {
|
||||||
|
test_cppData() async {
|
||||||
|
List<int> data = await new io.File(path.join(
|
||||||
|
path.dirname(io.Platform.script.path),
|
||||||
|
'monsterdata_test.mon',
|
||||||
|
))
|
||||||
|
.readAsBytes();
|
||||||
|
example.Monster mon = new example.Monster(data);
|
||||||
|
expect(mon.hp, 80);
|
||||||
|
expect(mon.mana, 150);
|
||||||
|
expect(mon.name, 'MyMonster');
|
||||||
|
expect(mon.pos.x, 1.0);
|
||||||
|
expect(mon.pos.y, 2.0);
|
||||||
|
expect(mon.pos.z, 3.0);
|
||||||
|
expect(mon.pos.test1, 3.0);
|
||||||
|
expect(mon.pos.test2.value, 2.0);
|
||||||
|
expect(mon.pos.test3.a, 5);
|
||||||
|
expect(mon.pos.test3.b, 6);
|
||||||
|
expect(mon.testType.value, example.AnyTypeId.Monster.value);
|
||||||
|
expect(mon.test is example.Monster, true);
|
||||||
|
final monster2 = mon.test as example.Monster;
|
||||||
|
expect(monster2.name, "Fred");
|
||||||
|
|
||||||
|
expect(mon.inventory.length, 5);
|
||||||
|
expect(mon.inventory.reduce((cur, next) => cur + next), 10);
|
||||||
|
expect(mon.test4.length, 2);
|
||||||
|
expect(
|
||||||
|
mon.test4[0].a + mon.test4[0].b + mon.test4[1].a + mon.test4[1].b, 100);
|
||||||
|
expect(mon.testarrayofstring.length, 2);
|
||||||
|
expect(mon.testarrayofstring[0], "test1");
|
||||||
|
expect(mon.testarrayofstring[1], "test2");
|
||||||
|
|
||||||
|
// this will fail if accessing any field fails.
|
||||||
|
expect(mon.toString(),
|
||||||
|
'Monster{pos: Vec3{x: 1.0, y: 2.0, z: 3.0, test1: 3.0, test2: Color{value: 2}, test3: Test{a: 5, b: 6}}, mana: 150, hp: 80, name: MyMonster, inventory: [0, 1, 2, 3, 4], color: Color{value: 8}, testType: AnyTypeId{value: 1}, test: Monster{pos: null, mana: 150, hp: 100, name: Fred, inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, test: null, test4: null, testarrayofstring: null, testarrayoftables: null, enemy: null, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: 0, testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: null, vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}, test4: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], testarrayofstring: [test1, test2], testarrayoftables: null, enemy: Monster{pos: null, mana: 150, hp: 100, name: Fred, inventory: null, color: Color{value: 8}, testType: AnyTypeId{value: 0}, test: null, test4: null, testarrayofstring: null, testarrayoftables: null, enemy: null, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: 0, testhashu32Fnv1: 0, testhashs64Fnv1: 0, testhashu64Fnv1: 0, testhashs32Fnv1a: 0, testhashu32Fnv1a: 0, testhashs64Fnv1a: 0, testhashu64Fnv1a: 0, testarrayofbools: null, testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: null, vectorOfLongs: null, vectorOfDoubles: null, parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}, testnestedflatbuffer: null, testempty: null, testbool: false, testhashs32Fnv1: -579221183, testhashu32Fnv1: 3715746113, testhashs64Fnv1: 7930699090847568257, testhashu64Fnv1: 7930699090847568257, testhashs32Fnv1a: -1904106383, testhashu32Fnv1a: 2390860913, testhashs64Fnv1a: 4898026182817603057, testhashu64Fnv1a: 4898026182817603057, testarrayofbools: [true, false, true], testf: 3.14159, testf2: 3.0, testf3: 0.0, testarrayofstring2: null, testarrayofsortedstruct: null, flex: null, test5: [Test{a: 10, b: 20}, Test{a: 30, b: 40}], vectorOfLongs: [1, 100, 10000, 1000000, 100000000], vectorOfDoubles: [-1.7976931348623157e+308, 0.0, 1.7976931348623157e+308], parentNamespaceTest: null, vectorOfReferrables: null, singleWeakReference: 0, vectorOfWeakReferences: null, vectorOfStrongReferrables: null, coOwningReference: 0, vectorOfCoOwningReferences: null, nonOwningReference: 0, vectorOfNonOwningReferences: null}');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@reflectiveTest
|
||||||
|
class BuilderTest {
|
||||||
|
void test_monsterBuilder() {
|
||||||
|
final fbBuilder = new Builder();
|
||||||
|
final str = fbBuilder.writeString('MyMonster');
|
||||||
|
|
||||||
|
fbBuilder.writeString('test1');
|
||||||
|
fbBuilder.writeString('test2');
|
||||||
|
final testArrayOfString = fbBuilder.endStructVector(2);
|
||||||
|
|
||||||
|
final fred = fbBuilder.writeString('Fred');
|
||||||
|
|
||||||
|
final List<int> treasure = [0, 1, 2, 3, 4];
|
||||||
|
final inventory = fbBuilder.writeListUint8(treasure);
|
||||||
|
|
||||||
|
final monBuilder = new example.MonsterBuilder(fbBuilder)
|
||||||
|
..begin()
|
||||||
|
..addNameOffset(fred);
|
||||||
|
final mon2 = monBuilder.finish();
|
||||||
|
|
||||||
|
final testBuilder = new example.TestBuilder(fbBuilder);
|
||||||
|
testBuilder.finish(10, 20);
|
||||||
|
testBuilder.finish(30, 40);
|
||||||
|
final test4 = fbBuilder.endStructVector(2);
|
||||||
|
|
||||||
|
|
||||||
|
monBuilder
|
||||||
|
..begin()
|
||||||
|
..addPos(
|
||||||
|
new example.Vec3Builder(fbBuilder).finish(
|
||||||
|
1.0,
|
||||||
|
2.0,
|
||||||
|
3.0,
|
||||||
|
3.0,
|
||||||
|
example.Color.Green,
|
||||||
|
() => testBuilder.finish(5, 6),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
..addHp(80)
|
||||||
|
..addNameOffset(str)
|
||||||
|
..addInventoryOffset(inventory)
|
||||||
|
..addTestType(example.AnyTypeId.Monster)
|
||||||
|
..addTestOffset(mon2)
|
||||||
|
..addTest4Offset(test4)
|
||||||
|
..addTestarrayofstringOffset(testArrayOfString);
|
||||||
|
final mon = monBuilder.finish();
|
||||||
|
fbBuilder.finish(mon);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_error_addInt32_withoutStartTable() {
|
||||||
|
Builder builder = new Builder();
|
||||||
|
expect(() {
|
||||||
|
builder.addInt32(0, 0);
|
||||||
|
}, throwsStateError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_error_addOffset_withoutStartTable() {
|
||||||
|
Builder builder = new Builder();
|
||||||
|
expect(() {
|
||||||
|
builder.addOffset(0, 0);
|
||||||
|
}, throwsStateError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_error_endTable_withoutStartTable() {
|
||||||
|
Builder builder = new Builder();
|
||||||
|
expect(() {
|
||||||
|
builder.endTable();
|
||||||
|
}, throwsStateError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_error_startTable_duringTable() {
|
||||||
|
Builder builder = new Builder();
|
||||||
|
builder.startTable();
|
||||||
|
expect(() {
|
||||||
|
builder.startTable();
|
||||||
|
}, throwsStateError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_error_writeString_duringTable() {
|
||||||
|
Builder builder = new Builder();
|
||||||
|
builder.startTable();
|
||||||
|
expect(() {
|
||||||
|
builder.writeString('12345');
|
||||||
|
}, throwsStateError);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_file_identifier() {
|
||||||
|
Uint8List byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
builder.startTable();
|
||||||
|
int offset = builder.endTable();
|
||||||
|
byteList = builder.finish(offset, 'Az~ÿ');
|
||||||
|
}
|
||||||
|
// Convert byteList to a ByteData so that we can read data from it.
|
||||||
|
ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
|
||||||
|
// First 4 bytes are an offset to the table data.
|
||||||
|
int tableDataLoc = byteData.getUint32(0, Endian.little);
|
||||||
|
// Next 4 bytes are the file identifier.
|
||||||
|
expect(byteData.getUint8(4), 65); // 'a'
|
||||||
|
expect(byteData.getUint8(5), 122); // 'z'
|
||||||
|
expect(byteData.getUint8(6), 126); // '~'
|
||||||
|
expect(byteData.getUint8(7), 255); // 'ÿ'
|
||||||
|
// First 4 bytes of the table data are a backwards offset to the vtable.
|
||||||
|
int vTableLoc = tableDataLoc -
|
||||||
|
byteData.getInt32(tableDataLoc, Endian.little);
|
||||||
|
// First 2 bytes of the vtable are the size of the vtable in bytes, which
|
||||||
|
// should be 4.
|
||||||
|
expect(byteData.getUint16(vTableLoc, Endian.little), 4);
|
||||||
|
// Next 2 bytes are the size of the object in bytes (including the vtable
|
||||||
|
// pointer), which should be 4.
|
||||||
|
expect(byteData.getUint16(vTableLoc + 2, Endian.little), 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_low() {
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
expect((builder..putUint8(1)).lowFinish(), [1]);
|
||||||
|
expect((builder..putUint32(2)).lowFinish(), [2, 0, 0, 0, 0, 0, 0, 1]);
|
||||||
|
expect((builder..putUint8(3)).lowFinish(),
|
||||||
|
[0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
|
||||||
|
expect((builder..putUint8(4)).lowFinish(),
|
||||||
|
[0, 0, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
|
||||||
|
expect((builder..putUint8(5)).lowFinish(),
|
||||||
|
[0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
|
||||||
|
expect((builder..putUint32(6)).lowFinish(),
|
||||||
|
[6, 0, 0, 0, 0, 5, 4, 3, 2, 0, 0, 0, 0, 0, 0, 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_table_default() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
builder.startTable();
|
||||||
|
builder.addInt32(0, 10, 10);
|
||||||
|
builder.addInt32(1, 20, 10);
|
||||||
|
int offset = builder.endTable();
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buffer = new BufferContext.fromBytes(byteList);
|
||||||
|
int objectOffset = buffer.derefObject(0);
|
||||||
|
// was not written, so uses the new default value
|
||||||
|
expect(
|
||||||
|
const Int32Reader()
|
||||||
|
.vTableGet(buffer, objectOffset, indexToField(0), 15),
|
||||||
|
15);
|
||||||
|
// has the written value
|
||||||
|
expect(
|
||||||
|
const Int32Reader()
|
||||||
|
.vTableGet(buffer, objectOffset, indexToField(1), 15),
|
||||||
|
20);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_table_format() {
|
||||||
|
Uint8List byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
builder.startTable();
|
||||||
|
builder.addInt32(0, 10);
|
||||||
|
builder.addInt32(1, 20);
|
||||||
|
builder.addInt32(2, 30);
|
||||||
|
byteList = builder.finish(builder.endTable());
|
||||||
|
}
|
||||||
|
// Convert byteList to a ByteData so that we can read data from it.
|
||||||
|
ByteData byteData = byteList.buffer.asByteData(byteList.offsetInBytes);
|
||||||
|
// First 4 bytes are an offset to the table data.
|
||||||
|
int tableDataLoc = byteData.getUint32(0, Endian.little);
|
||||||
|
// First 4 bytes of the table data are a backwards offset to the vtable.
|
||||||
|
int vTableLoc = tableDataLoc -
|
||||||
|
byteData.getInt32(tableDataLoc, Endian.little);
|
||||||
|
// First 2 bytes of the vtable are the size of the vtable in bytes, which
|
||||||
|
// should be 10.
|
||||||
|
expect(byteData.getUint16(vTableLoc, Endian.little), 10);
|
||||||
|
// Next 2 bytes are the size of the object in bytes (including the vtable
|
||||||
|
// pointer), which should be 16.
|
||||||
|
expect(byteData.getUint16(vTableLoc + 2, Endian.little), 16);
|
||||||
|
// Remaining 6 bytes are the offsets within the object where the ints are
|
||||||
|
// located.
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
int offset =
|
||||||
|
byteData.getUint16(vTableLoc + 4 + 2 * i, Endian.little);
|
||||||
|
expect(byteData.getInt32(tableDataLoc + offset, Endian.little),
|
||||||
|
10 + 10 * i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_table_string() {
|
||||||
|
String latinString = 'test';
|
||||||
|
String unicodeString = 'Проба пера';
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int latinStringOffset = builder.writeString(latinString);
|
||||||
|
int unicodeStringOffset = builder.writeString(unicodeString);
|
||||||
|
builder.startTable();
|
||||||
|
builder.addOffset(0, latinStringOffset);
|
||||||
|
builder.addOffset(1, unicodeStringOffset);
|
||||||
|
int offset = builder.endTable();
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
int objectOffset = buf.derefObject(0);
|
||||||
|
expect(const StringReader().vTableGet(buf, objectOffset, indexToField(0)),
|
||||||
|
latinString);
|
||||||
|
expect(const StringReader().vTableGet(buf, objectOffset, indexToField(1)),
|
||||||
|
unicodeString);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_table_types() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int stringOffset = builder.writeString('12345');
|
||||||
|
builder.startTable();
|
||||||
|
builder.addBool(0, true);
|
||||||
|
builder.addInt8(1, 10);
|
||||||
|
builder.addInt32(2, 20);
|
||||||
|
builder.addOffset(3, stringOffset);
|
||||||
|
builder.addInt32(4, 40);
|
||||||
|
builder.addUint32(5, 0x9ABCDEF0);
|
||||||
|
builder.addUint8(6, 0x9A);
|
||||||
|
int offset = builder.endTable();
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
int objectOffset = buf.derefObject(0);
|
||||||
|
expect(
|
||||||
|
const BoolReader().vTableGet(buf, objectOffset, indexToField(0)), true);
|
||||||
|
expect(
|
||||||
|
const Int8Reader().vTableGet(buf, objectOffset, indexToField(1)), 10);
|
||||||
|
expect(
|
||||||
|
const Int32Reader().vTableGet(buf, objectOffset, indexToField(2)), 20);
|
||||||
|
expect(const StringReader().vTableGet(buf, objectOffset, indexToField(3)),
|
||||||
|
'12345');
|
||||||
|
expect(
|
||||||
|
const Int32Reader().vTableGet(buf, objectOffset, indexToField(4)), 40);
|
||||||
|
expect(const Uint32Reader().vTableGet(buf, objectOffset, indexToField(5)),
|
||||||
|
0x9ABCDEF0);
|
||||||
|
expect(const Uint8Reader().vTableGet(buf, objectOffset, indexToField(6)),
|
||||||
|
0x9A);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_of_Uint32() {
|
||||||
|
List<int> values = <int>[10, 100, 12345, 0x9abcdef0];
|
||||||
|
// write
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListUint32(values);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<int> items = const Uint32ListReader().read(buf, 0);
|
||||||
|
expect(items, hasLength(4));
|
||||||
|
expect(items, orderedEquals(values));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofBool() {
|
||||||
|
void verifyListBooleans(int len, List<int> trueBits) {
|
||||||
|
// write
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
List<bool> values = new List<bool>.filled(len, false);
|
||||||
|
for (int bit in trueBits) {
|
||||||
|
values[bit] = true;
|
||||||
|
}
|
||||||
|
int offset = builder.writeListBool(values);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<bool> items = const BoolListReader().read(buf, 0);
|
||||||
|
expect(items, hasLength(len));
|
||||||
|
for (int i = 0; i < items.length; i++) {
|
||||||
|
expect(items[i], trueBits.contains(i), reason: 'bit $i of $len');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
verifyListBooleans(0, <int>[]);
|
||||||
|
verifyListBooleans(1, <int>[]);
|
||||||
|
verifyListBooleans(1, <int>[0]);
|
||||||
|
verifyListBooleans(31, <int>[0, 1]);
|
||||||
|
verifyListBooleans(31, <int>[1, 2, 24, 25, 30]);
|
||||||
|
verifyListBooleans(31, <int>[0, 30]);
|
||||||
|
verifyListBooleans(32, <int>[1, 2, 24, 25, 31]);
|
||||||
|
verifyListBooleans(33, <int>[1, 2, 24, 25, 32]);
|
||||||
|
verifyListBooleans(33, <int>[1, 2, 24, 25, 31, 32]);
|
||||||
|
verifyListBooleans(63, <int>[]);
|
||||||
|
verifyListBooleans(63, <int>[0, 1, 2, 61, 62]);
|
||||||
|
verifyListBooleans(63, new List<int>.generate(63, (i) => i));
|
||||||
|
verifyListBooleans(64, <int>[]);
|
||||||
|
verifyListBooleans(64, <int>[0, 1, 2, 61, 62, 63]);
|
||||||
|
verifyListBooleans(64, <int>[1, 2, 62]);
|
||||||
|
verifyListBooleans(64, <int>[0, 1, 2, 63]);
|
||||||
|
verifyListBooleans(64, new List<int>.generate(64, (i) => i));
|
||||||
|
verifyListBooleans(100, <int>[0, 3, 30, 60, 90, 99]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofInt32() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListInt32(<int>[1, 2, 3, 4, 5]);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<int> items = const ListReader<int>(const Int32Reader()).read(buf, 0);
|
||||||
|
expect(items, hasLength(5));
|
||||||
|
expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofFloat64() {
|
||||||
|
List<double> values = <double>[-1.234567, 3.4E+9, -5.6E-13, 7.8, 12.13];
|
||||||
|
// write
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListFloat64(values);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<double> items = const Float64ListReader().read(buf, 0);
|
||||||
|
|
||||||
|
expect(items, hasLength(values.length));
|
||||||
|
for (int i = 0; i < values.length; i++) {
|
||||||
|
expect(values[i], closeTo(items[i], .001));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofFloat32() {
|
||||||
|
List<double> values = [1.0, 2.23, -3.213, 7.8, 12.13];
|
||||||
|
// write
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListFloat32(values);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<double> items = const Float32ListReader().read(buf, 0);
|
||||||
|
expect(items, hasLength(5));
|
||||||
|
for (int i = 0; i < values.length; i++) {
|
||||||
|
expect(values[i], closeTo(items[i], .001));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofObjects() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
// write the object #1
|
||||||
|
int object1;
|
||||||
|
{
|
||||||
|
builder.startTable();
|
||||||
|
builder.addInt32(0, 10);
|
||||||
|
builder.addInt32(1, 20);
|
||||||
|
object1 = builder.endTable();
|
||||||
|
}
|
||||||
|
// write the object #1
|
||||||
|
int object2;
|
||||||
|
{
|
||||||
|
builder.startTable();
|
||||||
|
builder.addInt32(0, 100);
|
||||||
|
builder.addInt32(1, 200);
|
||||||
|
object2 = builder.endTable();
|
||||||
|
}
|
||||||
|
// write the list
|
||||||
|
int offset = builder.writeList([object1, object2]);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<TestPointImpl> items =
|
||||||
|
const ListReader<TestPointImpl>(const TestPointReader()).read(buf, 0);
|
||||||
|
expect(items, hasLength(2));
|
||||||
|
expect(items[0].x, 10);
|
||||||
|
expect(items[0].y, 20);
|
||||||
|
expect(items[1].x, 100);
|
||||||
|
expect(items[1].y, 200);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofStrings_asRoot() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int str1 = builder.writeString('12345');
|
||||||
|
int str2 = builder.writeString('ABC');
|
||||||
|
int offset = builder.writeList([str1, str2]);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<String> items =
|
||||||
|
const ListReader<String>(const StringReader()).read(buf, 0);
|
||||||
|
expect(items, hasLength(2));
|
||||||
|
expect(items, contains('12345'));
|
||||||
|
expect(items, contains('ABC'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofStrings_inObject() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int listOffset = builder.writeList(
|
||||||
|
[builder.writeString('12345'), builder.writeString('ABC')]);
|
||||||
|
builder.startTable();
|
||||||
|
builder.addOffset(0, listOffset);
|
||||||
|
int offset = builder.endTable();
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
StringListWrapperImpl reader = new StringListWrapperReader().read(buf, 0);
|
||||||
|
List<String> items = reader.items;
|
||||||
|
expect(items, hasLength(2));
|
||||||
|
expect(items, contains('12345'));
|
||||||
|
expect(items, contains('ABC'));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofUint32() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListUint32(<int>[1, 2, 0x9ABCDEF0]);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<int> items = const Uint32ListReader().read(buf, 0);
|
||||||
|
expect(items, hasLength(3));
|
||||||
|
expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofUint16() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListUint16(<int>[1, 2, 60000]);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<int> items = const Uint16ListReader().read(buf, 0);
|
||||||
|
expect(items, hasLength(3));
|
||||||
|
expect(items, orderedEquals(<int>[1, 2, 60000]));
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_writeList_ofUint8() {
|
||||||
|
List<int> byteList;
|
||||||
|
{
|
||||||
|
Builder builder = new Builder(initialSize: 0);
|
||||||
|
int offset = builder.writeListUint8(<int>[1, 2, 3, 4, 0x9A]);
|
||||||
|
byteList = builder.finish(offset);
|
||||||
|
}
|
||||||
|
// read and verify
|
||||||
|
BufferContext buf = new BufferContext.fromBytes(byteList);
|
||||||
|
List<int> items = const Uint8ListReader().read(buf, 0);
|
||||||
|
expect(items, hasLength(5));
|
||||||
|
expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class StringListWrapperImpl {
|
||||||
|
final BufferContext bp;
|
||||||
|
final int offset;
|
||||||
|
|
||||||
|
StringListWrapperImpl(this.bp, this.offset);
|
||||||
|
|
||||||
|
List<String> get items => const ListReader<String>(const StringReader())
|
||||||
|
.vTableGet(bp, offset, indexToField(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
|
||||||
|
const StringListWrapperReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
StringListWrapperImpl createObject(BufferContext object, int offset) {
|
||||||
|
return new StringListWrapperImpl(object, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestPointImpl {
|
||||||
|
final BufferContext bp;
|
||||||
|
final int offset;
|
||||||
|
|
||||||
|
TestPointImpl(this.bp, this.offset);
|
||||||
|
|
||||||
|
int get x => const Int32Reader().vTableGet(bp, offset, indexToField(0), 0);
|
||||||
|
|
||||||
|
int get y => const Int32Reader().vTableGet(bp, offset, indexToField(1), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
class TestPointReader extends TableReader<TestPointImpl> {
|
||||||
|
const TestPointReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
TestPointImpl createObject(BufferContext object, int offset) {
|
||||||
|
return new TestPointImpl(object, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
dart/test/monster_test_my_game.example2_generated.dart
Normal file
62
dart/test/monster_test_my_game.example2_generated.dart
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
// ignore_for_file: unused_import, unused_field, unused_local_variable
|
||||||
|
|
||||||
|
library my_game.example2;
|
||||||
|
|
||||||
|
import 'dart:typed_data' show Uint8List;
|
||||||
|
import 'package:flat_buffers/flat_buffers.dart' as fb;
|
||||||
|
|
||||||
|
import 'include_test1_my_game.example2_generated.dart';
|
||||||
|
import 'include_test2_my_game.example2_generated.dart';
|
||||||
|
import './monster_test_my_game.example_generated.dart' as my_game_example;
|
||||||
|
import './monster_test_my_game_generated.dart' as my_game;
|
||||||
|
|
||||||
|
class Monster {
|
||||||
|
Monster._(this._bc, this._bcOffset);
|
||||||
|
factory Monster(List<int> bytes) {
|
||||||
|
fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
|
||||||
|
return reader.read(rootRef, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const fb.Reader<Monster> reader = const _MonsterReader();
|
||||||
|
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'Monster{}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _MonsterReader extends fb.TableReader<Monster> {
|
||||||
|
const _MonsterReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
Monster createObject(fb.BufferContext bc, int offset) =>
|
||||||
|
new Monster._(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class MonsterObjectBuilder extends fb.ObjectBuilder {
|
||||||
|
|
||||||
|
MonsterObjectBuilder();
|
||||||
|
|
||||||
|
/// Finish building, and store into the [fbBuilder].
|
||||||
|
@override
|
||||||
|
int finish(
|
||||||
|
fb.Builder fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
|
||||||
|
fbBuilder.startTable();
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to serialize to byte list.
|
||||||
|
@override
|
||||||
|
Uint8List toBytes([String fileIdentifier]) {
|
||||||
|
fb.Builder fbBuilder = new fb.Builder();
|
||||||
|
int offset = finish(fbBuilder);
|
||||||
|
return fbBuilder.finish(offset, fileIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
1334
dart/test/monster_test_my_game.example_generated.dart
Normal file
1334
dart/test/monster_test_my_game.example_generated.dart
Normal file
File diff suppressed because it is too large
Load Diff
62
dart/test/monster_test_my_game_generated.dart
Normal file
62
dart/test/monster_test_my_game_generated.dart
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
// automatically generated by the FlatBuffers compiler, do not modify
|
||||||
|
// ignore_for_file: unused_import, unused_field, unused_local_variable
|
||||||
|
|
||||||
|
library my_game;
|
||||||
|
|
||||||
|
import 'dart:typed_data' show Uint8List;
|
||||||
|
import 'package:flat_buffers/flat_buffers.dart' as fb;
|
||||||
|
|
||||||
|
import 'include_test1_my_game_generated.dart';
|
||||||
|
import 'include_test2_my_game_generated.dart';
|
||||||
|
import './monster_test_my_game.example_generated.dart' as my_game_example;
|
||||||
|
import './monster_test_my_game.example2_generated.dart' as my_game_example2;
|
||||||
|
|
||||||
|
class InParentNamespace {
|
||||||
|
InParentNamespace._(this._bc, this._bcOffset);
|
||||||
|
factory InParentNamespace(List<int> bytes) {
|
||||||
|
fb.BufferContext rootRef = new fb.BufferContext.fromBytes(bytes);
|
||||||
|
return reader.read(rootRef, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const fb.Reader<InParentNamespace> reader = const _InParentNamespaceReader();
|
||||||
|
|
||||||
|
final fb.BufferContext _bc;
|
||||||
|
final int _bcOffset;
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'InParentNamespace{}';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class _InParentNamespaceReader extends fb.TableReader<InParentNamespace> {
|
||||||
|
const _InParentNamespaceReader();
|
||||||
|
|
||||||
|
@override
|
||||||
|
InParentNamespace createObject(fb.BufferContext bc, int offset) =>
|
||||||
|
new InParentNamespace._(bc, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
class InParentNamespaceObjectBuilder extends fb.ObjectBuilder {
|
||||||
|
|
||||||
|
InParentNamespaceObjectBuilder();
|
||||||
|
|
||||||
|
/// Finish building, and store into the [fbBuilder].
|
||||||
|
@override
|
||||||
|
int finish(
|
||||||
|
fb.Builder fbBuilder) {
|
||||||
|
assert(fbBuilder != null);
|
||||||
|
|
||||||
|
fbBuilder.startTable();
|
||||||
|
return fbBuilder.endTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Convenience method to serialize to byte list.
|
||||||
|
@override
|
||||||
|
Uint8List toBytes([String fileIdentifier]) {
|
||||||
|
fb.Builder fbBuilder = new fb.Builder();
|
||||||
|
int offset = finish(fbBuilder);
|
||||||
|
return fbBuilder.finish(offset, fileIdentifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
0
docs/footer.html
Executable file → Normal file
0
docs/footer.html
Executable file → Normal file
2
docs/source/Benchmarks.md
Executable file → Normal file
2
docs/source/Benchmarks.md
Executable file → Normal file
@@ -1,4 +1,4 @@
|
|||||||
Benchmarks {#flatbuffers_benchmarks}
|
C++ Benchmarks {#flatbuffers_benchmarks}
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Comparing against other serialization solutions, running on Windows 7
|
Comparing against other serialization solutions, running on Windows 7
|
||||||
|
|||||||
35
docs/source/Building.md
Executable file → Normal file
35
docs/source/Building.md
Executable file → Normal file
@@ -5,12 +5,12 @@ Building {#flatbuffers_guide_building}
|
|||||||
|
|
||||||
The distribution comes with a `cmake` file that should allow
|
The distribution comes with a `cmake` file that should allow
|
||||||
you to build project/make files for any platform. For details on `cmake`, see
|
you to build project/make files for any platform. For details on `cmake`, see
|
||||||
<http://www.cmake.org>. In brief, depending on your platform, use one of
|
<https://www.cmake.org>. In brief, depending on your platform, use one of
|
||||||
e.g.:
|
e.g.:
|
||||||
|
|
||||||
cmake -G "Unix Makefiles"
|
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release
|
||||||
cmake -G "Visual Studio 10"
|
cmake -G "Visual Studio 10" -DCMAKE_BUILD_TYPE=Release
|
||||||
cmake -G "Xcode"
|
cmake -G "Xcode" -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
Then, build as normal for your platform. This should result in a `flatc`
|
Then, build as normal for your platform. This should result in a `flatc`
|
||||||
executable, essential for the next steps.
|
executable, essential for the next steps.
|
||||||
@@ -41,7 +41,7 @@ running the `android_sample.sh` script. Optionally, you may go to the
|
|||||||
`flatbuffers/samples/android` folder and build the sample with the
|
`flatbuffers/samples/android` folder and build the sample with the
|
||||||
`build_apk.sh` script or `ndk_build` / `adb` etc.
|
`build_apk.sh` script or `ndk_build` / `adb` etc.
|
||||||
|
|
||||||
## Using FlatBuffers in your own projects.
|
## Using FlatBuffers in your own projects
|
||||||
|
|
||||||
For C++, there is usually no runtime to compile, as the code consists of a
|
For C++, there is usually no runtime to compile, as the code consists of a
|
||||||
single header, `include/flatbuffers/flatbuffers.h`. You should add the
|
single header, `include/flatbuffers/flatbuffers.h`. You should add the
|
||||||
@@ -55,6 +55,31 @@ To see how to include FlatBuffers in any of our supported languages, please
|
|||||||
view the [Tutorial](@ref flatbuffers_guide_tutorial) and select your appropriate
|
view the [Tutorial](@ref flatbuffers_guide_tutorial) and select your appropriate
|
||||||
language using the radio buttons.
|
language using the radio buttons.
|
||||||
|
|
||||||
|
### Using in CMake-based projects
|
||||||
|
If you want to use FlatBuffers in a project which already uses CMake, then a more
|
||||||
|
robust and flexible approach is to build FlatBuffers as part of that project directly.
|
||||||
|
This is done by making the FlatBuffers source code available to the main build
|
||||||
|
and adding it using CMake's `add_subdirectory()` command. This has the
|
||||||
|
significant advantage that the same compiler and linker settings are used
|
||||||
|
between FlatBuffers and the rest of your project, so issues associated with using
|
||||||
|
incompatible libraries (eg debug/release), etc. are avoided. This is
|
||||||
|
particularly useful on Windows.
|
||||||
|
|
||||||
|
Suppose you put FlatBuffers source code in directory `${FLATBUFFERS_SRC_DIR}`.
|
||||||
|
To build it as part of your project, add following code to your `CMakeLists.txt` file:
|
||||||
|
```cmake
|
||||||
|
# Add FlatBuffers directly to our build. This defines the `flatbuffers` target.
|
||||||
|
add_subdirectory(${FLATBUFFERS_SRC_DIR}
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/flatbuffers-build
|
||||||
|
EXCLUDE_FROM_ALL)
|
||||||
|
|
||||||
|
# Now simply link against flatbuffers as needed to your already declared target.
|
||||||
|
# The flatbuffers target carry header search path automatically if CMake > 2.8.11.
|
||||||
|
target_link_libraries(own_project_target PRIVATE flatbuffers)
|
||||||
|
```
|
||||||
|
When build your project the `flatbuffers` library will be compiled and linked
|
||||||
|
to a target as part of your project.
|
||||||
|
|
||||||
#### For Google Play apps
|
#### For Google Play apps
|
||||||
|
|
||||||
For applications on Google Play that integrate this library, usage is tracked.
|
For applications on Google Play that integrate this library, usage is tracked.
|
||||||
|
|||||||
26
docs/source/Compiler.md
Executable file → Normal file
26
docs/source/Compiler.md
Executable file → Normal file
@@ -31,10 +31,20 @@ For any schema input files, one or more generators can be specified:
|
|||||||
|
|
||||||
- `--js`, `-s`: Generate JavaScript code.
|
- `--js`, `-s`: Generate JavaScript code.
|
||||||
|
|
||||||
|
- `--ts`: Generate TypeScript code.
|
||||||
|
|
||||||
- `--php`: Generate PHP code.
|
- `--php`: Generate PHP code.
|
||||||
|
|
||||||
- `--grpc`: Generate RPC stub code for GRPC.
|
- `--grpc`: Generate RPC stub code for GRPC.
|
||||||
|
|
||||||
|
- `--dart`: Generate Dart code.
|
||||||
|
|
||||||
|
- `--lua`: Generate Lua code.
|
||||||
|
|
||||||
|
- `--lobster`: Generate Lobster code.
|
||||||
|
|
||||||
|
- `--rust`, `-r` : Generate Rust 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
|
||||||
@@ -86,6 +96,8 @@ Additional options:
|
|||||||
at the cost of efficiency (object allocation). Recommended only to be used
|
at the cost of efficiency (object allocation). Recommended only to be used
|
||||||
if other options are insufficient.
|
if other options are insufficient.
|
||||||
|
|
||||||
|
- `--gen-compare` : Generate operator== for object-based API types.
|
||||||
|
|
||||||
- `--gen-onefile` : Generate single output file (useful for C#)
|
- `--gen-onefile` : Generate single output file (useful for C#)
|
||||||
|
|
||||||
- `--gen-all`: Generate not just code for the current schema files, but
|
- `--gen-all`: Generate not just code for the current schema files, but
|
||||||
@@ -99,6 +111,10 @@ Additional options:
|
|||||||
instead of Node.js style exporting. Needed for compatibility with the
|
instead of Node.js style exporting. Needed for compatibility with the
|
||||||
Google closure compiler (useful for JS).
|
Google closure compiler (useful for JS).
|
||||||
|
|
||||||
|
- `--es6-js-export` : Generates ECMAScript v6 style export definitions
|
||||||
|
instead of Node.js style exporting. Useful when integrating flatbuffers
|
||||||
|
with modern Javascript projects.
|
||||||
|
|
||||||
- `--raw-binary` : Allow binaries without a file_indentifier to be read.
|
- `--raw-binary` : Allow binaries without a file_indentifier to be read.
|
||||||
This may crash flatc given a mismatched schema.
|
This may crash flatc given a mismatched schema.
|
||||||
|
|
||||||
@@ -125,5 +141,15 @@ Additional options:
|
|||||||
|
|
||||||
- `--keep-prefix` : Keep original prefix of schema include statement.
|
- `--keep-prefix` : Keep original prefix of schema include statement.
|
||||||
|
|
||||||
|
- `--reflect-types` : Add minimal type reflection to code generation.
|
||||||
|
- `--reflect-names` : Add minimal type/name reflection.
|
||||||
|
|
||||||
|
- `--root-type T` : Select or override the default root_type.
|
||||||
|
|
||||||
|
- `--force-defaults` : Emit default values in binary output from JSON.
|
||||||
|
|
||||||
|
- `--force-empty` : When serializing from object API representation, force
|
||||||
|
strings and 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.
|
||||||
|
|||||||
88
docs/source/CppUsage.md
Executable file → Normal file
88
docs/source/CppUsage.md
Executable file → Normal file
@@ -59,15 +59,18 @@ a `char *` array, which you pass to `GetMonster()`.
|
|||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "monster_test_generate.h"
|
#include "monster_test_generate.h"
|
||||||
#include <cstdio> // For printing and file access.
|
#include <iostream> // C++ header file for printing
|
||||||
|
#include <fstream> // C++ header file for file access
|
||||||
|
|
||||||
FILE* file = fopen("monsterdata_test.mon", "rb");
|
|
||||||
fseek(file, 0L, SEEK_END);
|
std::ifstream infile;
|
||||||
int length = ftell(file);
|
infile.open("monsterdata_test.mon", std::ios::binary | std::ios::in);
|
||||||
fseek(file, 0L, SEEK_SET);
|
infile.seekg(0,std::ios::end);
|
||||||
|
int length = infile.tellg();
|
||||||
|
infile.seekg(0,std::ios::beg);
|
||||||
char *data = new char[length];
|
char *data = new char[length];
|
||||||
fread(data, sizeof(char), length, file);
|
infile.read(data, length);
|
||||||
fclose(file);
|
infile.close();
|
||||||
|
|
||||||
auto monster = GetMonster(data);
|
auto monster = GetMonster(data);
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
@@ -78,9 +81,9 @@ If you look in your generated header, you'll see it has
|
|||||||
convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
|
convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
|
||||||
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
|
||||||
printf("%d\n", monster->hp()); // `80`
|
std::cout << "hp : " << monster->hp() << std::endl; // `80`
|
||||||
printf("%d\n", monster->mana()); // default value of `150`
|
std::cout << "mana : " << monster->mana() << std::endl; // default value of `150`
|
||||||
printf("%s\n", monster->name()->c_str()); // "MyMonster"
|
std::cout << "name : " << monster->name()->c_str() << std::endl; // "MyMonster"
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
*Note: That we never stored a `mana` value, so it will return the default.*
|
*Note: That we never stored a `mana` value, so it will return the default.*
|
||||||
@@ -126,6 +129,45 @@ The following attributes are specific to the object-based API code generation:
|
|||||||
"native_inline", the value specified with this attribute will be included
|
"native_inline", the value specified with this attribute will be included
|
||||||
verbatim in the class constructor initializer list for this member.
|
verbatim in the class constructor initializer list for this member.
|
||||||
|
|
||||||
|
- `native_custom_alloc`:"custom_allocator" (on a table or struct): When using the
|
||||||
|
object-based API all generated NativeTables that are allocated when unpacking
|
||||||
|
your flatbuffer will use "custom allocator". The allocator is also used by
|
||||||
|
any std::vector that appears in a table defined with `native_custom_alloc`.
|
||||||
|
This can be used to provide allocation from a pool for example, for faster
|
||||||
|
unpacking when using the object-based API.
|
||||||
|
|
||||||
|
Minimal Example:
|
||||||
|
|
||||||
|
schema:
|
||||||
|
|
||||||
|
table mytable(native_custom_alloc:"custom_allocator") {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
with custom_allocator defined before flatbuffers.h is included, as:
|
||||||
|
|
||||||
|
template <typename T> struct custom_allocator : public std::allocator<T> {
|
||||||
|
|
||||||
|
typedef T *pointer;
|
||||||
|
|
||||||
|
template <class U>
|
||||||
|
struct rebind {
|
||||||
|
typedef custom_allocator<U> other;
|
||||||
|
};
|
||||||
|
|
||||||
|
pointer allocate(const std::size_t n) {
|
||||||
|
return std::allocator<T>::allocate(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
void deallocate(T* ptr, std::size_t n) {
|
||||||
|
return std::allocator<T>::deallocate(ptr,n);
|
||||||
|
}
|
||||||
|
|
||||||
|
custom_allocator() throw() {}
|
||||||
|
template <class U>
|
||||||
|
custom_allocator(const custom_allocator<U>&) throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
|
- `native_type`' "type" (on a struct): In some cases, a more optimal C++ data
|
||||||
type exists for a given struct. For example, the following schema:
|
type exists for a given struct. For example, the following schema:
|
||||||
|
|
||||||
@@ -231,6 +273,30 @@ schema, as well as a lot of helper functions.
|
|||||||
And example of usage, for the time being, can be found in
|
And example of usage, for the time being, can be found in
|
||||||
`test.cpp/ReflectionTest()`.
|
`test.cpp/ReflectionTest()`.
|
||||||
|
|
||||||
|
## Mini Reflection
|
||||||
|
|
||||||
|
A more limited form of reflection is available for direct inclusion in
|
||||||
|
generated code, which doesn't any (binary) schema access at all. It was designed
|
||||||
|
to keep the overhead of reflection as low as possible (on the order of 2-6
|
||||||
|
bytes per field added to your executable), but doesn't contain all the
|
||||||
|
information the (binary) schema contains.
|
||||||
|
|
||||||
|
You add this information to your generated code by specifying `--reflect-types`
|
||||||
|
(or instead `--reflect-names` if you also want field / enum names).
|
||||||
|
|
||||||
|
You can now use this information, for example to print a FlatBuffer to text:
|
||||||
|
|
||||||
|
auto s = flatbuffers::FlatBufferToString(flatbuf, MonsterTypeTable());
|
||||||
|
|
||||||
|
`MonsterTypeTable()` is declared in the generated code for each type. The
|
||||||
|
string produced is very similar to the JSON produced by the `Parser` based
|
||||||
|
text generator.
|
||||||
|
|
||||||
|
You'll need `flatbuffers/minireflect.h` for this functionality. In there is also
|
||||||
|
a convenient visitor/iterator so you can write your own output / functionality
|
||||||
|
based on the mini reflection tables without having to know the FlatBuffers or
|
||||||
|
reflection encoding.
|
||||||
|
|
||||||
## Storing maps / dictionaries in a FlatBuffer
|
## Storing maps / dictionaries in a FlatBuffer
|
||||||
|
|
||||||
FlatBuffers doesn't support maps natively, but there is support to
|
FlatBuffers doesn't support maps natively, but there is support to
|
||||||
@@ -266,7 +332,7 @@ performs a swap operation on big endian machines), and also because
|
|||||||
the layout of things is generally not known to the user.
|
the layout of things is generally not known to the user.
|
||||||
|
|
||||||
For structs, layout is deterministic and guaranteed to be the same
|
For structs, layout is deterministic and guaranteed to be the same
|
||||||
accross platforms (scalars are aligned to their
|
across platforms (scalars are aligned to their
|
||||||
own size, and structs themselves to their largest member), and you
|
own size, and structs themselves to their largest member), and you
|
||||||
are allowed to access this memory directly by using `sizeof()` and
|
are allowed to access this memory directly by using `sizeof()` and
|
||||||
`memcpy` on the pointer to a struct, or even an array of structs.
|
`memcpy` on the pointer to a struct, or even an array of structs.
|
||||||
|
|||||||
108
docs/source/DartUsage.md
Normal file
108
docs/source/DartUsage.md
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
Use in Dart {#flatbuffers_guide_use_dart}
|
||||||
|
===========
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in Dart, 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 Dart).
|
||||||
|
This page is designed to cover the nuances of FlatBuffers usage, specific to
|
||||||
|
Dart.
|
||||||
|
|
||||||
|
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 Dart library code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers Go library can be found at
|
||||||
|
`flatbuffers/dart`. You can browse the library code on the [FlatBuffers
|
||||||
|
GitHub page](https://github.com/google/flatbuffers/tree/master/dart).
|
||||||
|
|
||||||
|
## Testing the FlatBuffers Dart library
|
||||||
|
|
||||||
|
The code to test the Dart library can be found at `flatbuffers/tests`.
|
||||||
|
The test code itself is located in [dart_test.dart](https://github.com/google/
|
||||||
|
flatbuffers/blob/master/tests/dart_test.dart).
|
||||||
|
|
||||||
|
To run the tests, use the [DartTest.sh](https://github.com/google/flatbuffers/
|
||||||
|
blob/master/tests/DartTest.sh) shell script.
|
||||||
|
|
||||||
|
*Note: The shell script requires the [Dart SDK](https://www.dartlang.org/tools/sdk)
|
||||||
|
to be installed.*
|
||||||
|
|
||||||
|
## Using the FlatBuffers Dart library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in Dart.*
|
||||||
|
|
||||||
|
FlatBuffers supports reading and writing binary FlatBuffers in Dart.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate Dart classes from your
|
||||||
|
schema with the `--dart` 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 Dart: First,
|
||||||
|
include the library and generated code. Then read a FlatBuffer binary file into
|
||||||
|
a `List<int>`, which you pass to the factory constructor for `Monster`:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart}
|
||||||
|
import 'dart:io' as io;
|
||||||
|
|
||||||
|
import 'package:flat_buffers/flat_buffers.dart' as fb;
|
||||||
|
import './monster_my_game.sample_generated.dart' as myGame;
|
||||||
|
|
||||||
|
List<int> data = await new io.File('monster.dat').readAsBytes();
|
||||||
|
var monster = new myGame.Monster(data);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Now you can access values like this:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.dart}
|
||||||
|
var hp = monster.hp;
|
||||||
|
var pos = monster.pos;
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
## Differences from the Dart SDK Front End flat_buffers
|
||||||
|
|
||||||
|
The work in this repository is signfiicantly based on the implementation used
|
||||||
|
internally by the Dart SDK in the front end/analyzer package. Several
|
||||||
|
significant changes have been made.
|
||||||
|
|
||||||
|
1. Support for packed boolean lists has been removed. This is not standard
|
||||||
|
in other implementations and is not compatible with them. Do note that,
|
||||||
|
like in the JavaScript implementation, __null values in boolean lists
|
||||||
|
will be treated as false__. It is also still entirely possible to pack data
|
||||||
|
in a single scalar field, but that would have to be done on the application
|
||||||
|
side.
|
||||||
|
2. The SDK implementation supports enums with regular Dart enums, which
|
||||||
|
works if enums are always indexed at 1; however, FlatBuffers does not
|
||||||
|
require that. This implementation uses specialized enum-like classes to
|
||||||
|
ensure proper mapping from FlatBuffers to Dart and other platforms.
|
||||||
|
3. The SDK implementation does not appear to support FlatBuffer structs or
|
||||||
|
vectors of structs - it treated everything as a built-in scalar or a table.
|
||||||
|
This implementation treats structs in a way that is compatible with other
|
||||||
|
non-Dart implementations, and properly handles vectors of structs. Many of
|
||||||
|
the methods prefixed with 'low' have been prepurposed to support this.
|
||||||
|
4. The SDK implementation treats int64 and uint64 as float64s. This
|
||||||
|
implementation does not. This may cause problems with JavaScript
|
||||||
|
compatibility - however, it should be possible to use the JavaScript
|
||||||
|
implementation, or to do a customized implementation that treats all 64 bit
|
||||||
|
numbers as floats. Supporting the Dart VM and Flutter was a more important
|
||||||
|
goal of this implementation. Support for 16 bit integers was also added.
|
||||||
|
5. The code generation in this offers an "ObjectBuilder", which generates code
|
||||||
|
very similar to the SDK classes that consume FlatBuffers, as well as Builder
|
||||||
|
classes, which produces code which more closely resembles the builders in
|
||||||
|
other languages. The ObjectBuilder classes are easier to use, at the cost of
|
||||||
|
additional references allocated.
|
||||||
|
|
||||||
|
## Text Parsing
|
||||||
|
|
||||||
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
|
from Dart, though you could use the C++ parser through Dart Native Extensions.
|
||||||
|
Please see the C++ documentation for more on text parsing (note that this is
|
||||||
|
not currently an option in Flutter - follow [this issue](https://github.com/flutter/flutter/issues/7053)
|
||||||
|
for the latest).
|
||||||
|
|
||||||
|
<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, PHP, and Python.
|
serialization library for C++, C#, C, Go, Java, JavaScript, Lobster, Lua, TypeScript, PHP, Python, and Rust.
|
||||||
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.
|
||||||
|
|
||||||
@@ -134,8 +134,18 @@ sections provide a more in-depth usage guide.
|
|||||||
in your own programs.
|
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
|
||||||
|
own programs.
|
||||||
|
- How to [use the generated JavaScript code](@ref flatbuffers_guide_use_javascript) in your
|
||||||
|
own programs.
|
||||||
|
- How to [use the generated TypeScript code](@ref flatbuffers_guide_use_typescript) in your
|
||||||
|
own programs.
|
||||||
- How to [use FlatBuffers in C with `flatcc`](@ref flatbuffers_guide_use_c) in your
|
- How to [use FlatBuffers in C with `flatcc`](@ref flatbuffers_guide_use_c) in your
|
||||||
own programs.
|
own programs.
|
||||||
|
- How to [use the generated Lobster code](@ref flatbuffers_guide_use_lobster) in your
|
||||||
|
own programs.
|
||||||
|
- How to [use the generated Rust code](@ref flatbuffers_guide_use_rust) 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.
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ map["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
|
||||||
[internals](Internals.md#flexbuffers) document.
|
[internals](@ref flatbuffers_internals) document.
|
||||||
|
|
||||||
|
|
||||||
# Nesting inside a FlatBuffer
|
# Nesting inside a FlatBuffer
|
||||||
|
|||||||
27
docs/source/Grammar.md
Executable file → Normal file
27
docs/source/Grammar.md
Executable file → Normal file
@@ -4,26 +4,32 @@ Grammar of the schema language {#flatbuffers_grammar}
|
|||||||
schema = include*
|
schema = include*
|
||||||
( namespace\_decl | type\_decl | enum\_decl | root\_decl |
|
( namespace\_decl | type\_decl | enum\_decl | root\_decl |
|
||||||
file_extension_decl | file_identifier_decl |
|
file_extension_decl | file_identifier_decl |
|
||||||
attribute\_decl | object )*
|
attribute\_decl | rpc\_decl | object )*
|
||||||
|
|
||||||
include = `include` string\_constant `;`
|
include = `include` string\_constant `;`
|
||||||
|
|
||||||
namespace\_decl = `namespace` ident ( `.` ident )* `;`
|
namespace\_decl = `namespace` ident ( `.` ident )* `;`
|
||||||
|
|
||||||
attribute\_decl = `attribute` string\_constant `;`
|
attribute\_decl = `attribute` ident | `"`ident`"` `;`
|
||||||
|
|
||||||
type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
|
type\_decl = ( `table` | `struct` ) ident metadata `{` field\_decl+ `}`
|
||||||
|
|
||||||
enum\_decl = ( `enum` | `union` ) ident [ `:` type ] metadata `{` commasep(
|
enum\_decl = ( `enum` ident [ `:` type ] | `union` ident ) metadata `{`
|
||||||
enumval\_decl ) `}`
|
commasep( enumval\_decl ) `}`
|
||||||
|
|
||||||
root\_decl = `root_type` ident `;`
|
root\_decl = `root_type` ident `;`
|
||||||
|
|
||||||
field\_decl = ident `:` type [ `=` scalar ] metadata `;`
|
field\_decl = ident `:` type [ `=` scalar ] metadata `;`
|
||||||
|
|
||||||
|
rpc\_decl = `rpc_service` ident `{` rpc\_method+ `}`
|
||||||
|
|
||||||
|
rpc\_method = ident `(` ident `)` `:` ident metadata `;`
|
||||||
|
|
||||||
type = `bool` | `byte` | `ubyte` | `short` | `ushort` | `int` | `uint` |
|
type = `bool` | `byte` | `ubyte` | `short` | `ushort` | `int` | `uint` |
|
||||||
`float` | `long` | `ulong` | `double`
|
`float` | `long` | `ulong` | `double` |
|
||||||
| `string` | `[` type `]` | ident
|
`int8` | `uint8` | `int16` | `uint16` | `int32` | `uint32`| `int64` | `uint64` |
|
||||||
|
`float32` | `float64` |
|
||||||
|
`string` | `[` type `]` | ident
|
||||||
|
|
||||||
enumval\_decl = ident [ `=` integer\_constant ]
|
enumval\_decl = ident [ `=` integer\_constant ]
|
||||||
|
|
||||||
@@ -43,6 +49,11 @@ file_extension_decl = `file_extension` string\_constant `;`
|
|||||||
|
|
||||||
file_identifier_decl = `file_identifier` string\_constant `;`
|
file_identifier_decl = `file_identifier` string\_constant `;`
|
||||||
|
|
||||||
integer\_constant = -?[0-9]+ | `true` | `false`
|
integer\_constant = `-?[0-9]+` | `true` | `false`
|
||||||
|
|
||||||
|
float\_constant = `-?[0-9]+.[0-9]+((e|E)(+|-)?[0-9]+)?`
|
||||||
|
|
||||||
|
string\_constant = `\".*?\"`
|
||||||
|
|
||||||
|
ident = `[a-zA-Z_][a-zA-Z0-9_]*`
|
||||||
|
|
||||||
float\_constant = -?[0-9]+.[0-9]+((e|E)(+|-)?[0-9]+)?
|
|
||||||
|
|||||||
26
docs/source/Internals.md
Executable file → Normal file
26
docs/source/Internals.md
Executable file → Normal file
@@ -169,7 +169,7 @@ Unions share a lot with enums.
|
|||||||
Predeclare all data types since circular references between types are allowed
|
Predeclare all data types since circular references between types are allowed
|
||||||
(circular references between object are not, though).
|
(circular references between object are not, though).
|
||||||
|
|
||||||
MANUALLY_ALIGNED_STRUCT(4) Vec3 {
|
FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vec3 {
|
||||||
private:
|
private:
|
||||||
float x_;
|
float x_;
|
||||||
float y_;
|
float y_;
|
||||||
@@ -183,7 +183,7 @@ Predeclare all data types since circular references between types are allowed
|
|||||||
float y() const { return flatbuffers::EndianScalar(y_); }
|
float y() const { return flatbuffers::EndianScalar(y_); }
|
||||||
float z() const { return flatbuffers::EndianScalar(z_); }
|
float z() const { return flatbuffers::EndianScalar(z_); }
|
||||||
};
|
};
|
||||||
STRUCT_END(Vec3, 12);
|
FLATBUFFERS_STRUCT_END(Vec3, 12);
|
||||||
|
|
||||||
These ugly macros do a couple of things: they turn off any padding the compiler
|
These ugly macros do a couple of things: they turn off any padding the compiler
|
||||||
might normally do, since we add padding manually (though none in this example),
|
might normally do, since we add padding manually (though none in this example),
|
||||||
@@ -292,6 +292,12 @@ flexibility in which of the children of root object to write first (though in
|
|||||||
this case there's only one string), and what order to write the fields in.
|
this case there's only one string), and what order to write the fields in.
|
||||||
Different orders may also cause different alignments to happen.
|
Different orders may also cause different alignments to happen.
|
||||||
|
|
||||||
|
### Additional reading.
|
||||||
|
|
||||||
|
The author of the C language implementation has made a similar
|
||||||
|
[document](https://github.com/dvidelabs/flatcc/blob/master/doc/binary-format.md#flatbuffers-binary-format)
|
||||||
|
that may further help clarify the format.
|
||||||
|
|
||||||
# FlexBuffers
|
# FlexBuffers
|
||||||
|
|
||||||
The [schema-less](@ref flexbuffers) version of FlatBuffers have their
|
The [schema-less](@ref flexbuffers) version of FlatBuffers have their
|
||||||
@@ -368,6 +374,10 @@ The offset version is useful to encode costly 64bit (or even 32bit) quantities
|
|||||||
into vectors / maps of smaller sizes, and to share / repeat a value multiple
|
into vectors / maps of smaller sizes, and to share / repeat a value multiple
|
||||||
times.
|
times.
|
||||||
|
|
||||||
|
### Booleans and Nulls
|
||||||
|
|
||||||
|
Booleans (`TYPE_BOOL`) and nulls (`TYPE_NULL`) are encoded as inlined unsigned integers.
|
||||||
|
|
||||||
### Blobs, Strings and Keys.
|
### Blobs, Strings and Keys.
|
||||||
|
|
||||||
A blob (`TYPE_BLOB`) is encoded similar to a vector, with one difference: the
|
A blob (`TYPE_BLOB`) is encoded similar to a vector, with one difference: the
|
||||||
@@ -408,19 +418,19 @@ that lookups can be made using binary search.
|
|||||||
|
|
||||||
The reason the key vector is a seperate structure from the value vector is
|
The reason the key vector is a seperate structure from the value vector is
|
||||||
such that it can be shared between multiple value vectors, and also to
|
such that it can be shared between multiple value vectors, and also to
|
||||||
allow it to be treated as its own indivual vector in code.
|
allow it to be treated as its own individual vector in code.
|
||||||
|
|
||||||
An example map { foo: 13, bar: 14 } would be encoded as:
|
An example map { foo: 13, bar: 14 } would be encoded as:
|
||||||
|
|
||||||
0 : uint8_t 'f', 'o', 'o', 0
|
0 : uint8_t 'b', 'a', 'r', 0
|
||||||
4 : uint8_t 'b', 'a', 'r', 0
|
4 : uint8_t 'f', 'o', 'o', 0
|
||||||
8 : uint8_t 2 // key vector of size 2
|
8 : uint8_t 2 // key vector of size 2
|
||||||
// key vector offset points here
|
// key vector offset points here
|
||||||
9 : uint8_t 9, 6 // offsets to foo_key and bar_key
|
9 : uint8_t 9, 6 // offsets to bar_key and foo_key
|
||||||
11: uint8_t 3, 1 // offset to key vector, and its byte width
|
11: uint8_t 2, 1 // offset to key vector, and its byte width
|
||||||
13: uint8_t 2 // value vector of size
|
13: uint8_t 2 // value vector of size
|
||||||
// value vector offset points here
|
// value vector offset points here
|
||||||
14: uint8_t 13, 14 // values
|
14: uint8_t 14, 13 // values
|
||||||
16: uint8_t 4, 4 // types
|
16: uint8_t 4, 4 // types
|
||||||
|
|
||||||
### The root
|
### The root
|
||||||
|
|||||||
2
docs/source/JavaCsharpUsage.md
Executable file → Normal file
2
docs/source/JavaCsharpUsage.md
Executable file → Normal file
@@ -139,7 +139,7 @@ can have fast lookups directly from a FlatBuffer without having to unpack
|
|||||||
your data into a `Dictionary` or similar.
|
your data into a `Dictionary` or similar.
|
||||||
|
|
||||||
To use it:
|
To use it:
|
||||||
- Designate one of the fields in a table as they "key" field. You do this
|
- 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.
|
by setting the `key` attribute on this field, e.g.
|
||||||
`name:string (key)`.
|
`name:string (key)`.
|
||||||
You may only have one key field, and it must be of string or scalar type.
|
You may only have one key field, and it must be of string or scalar type.
|
||||||
|
|||||||
0
docs/source/JavaScriptUsage.md
Executable file → Normal file
0
docs/source/JavaScriptUsage.md
Executable file → Normal file
85
docs/source/LobsterUsage.md
Normal file
85
docs/source/LobsterUsage.md
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
Use in Lobster {#flatbuffers_guide_use_lobster}
|
||||||
|
==============
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in Lobster, 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 Lobster). This
|
||||||
|
page is designed to cover the nuances of FlatBuffers usage, specific to
|
||||||
|
Lobster.
|
||||||
|
|
||||||
|
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 Lobster library code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers Lobster library can be found at
|
||||||
|
`flatbuffers/lobster`. You can browse the library code on the
|
||||||
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/
|
||||||
|
lobster).
|
||||||
|
|
||||||
|
## Testing the FlatBuffers Lobster library
|
||||||
|
|
||||||
|
The code to test the Lobster library can be found at `flatbuffers/tests`.
|
||||||
|
The test code itself is located in [lobstertest.lobster](https://github.com/google/
|
||||||
|
flatbuffers/blob/master/tests/lobstertest.lobster).
|
||||||
|
|
||||||
|
To run the tests, run `lobster lobstertest.lobster`. To obtain Lobster itself,
|
||||||
|
go to the [Lobster homepage](http://strlen.com/lobster) or
|
||||||
|
[github](https://github.com/aardappel/lobster) to learn how to build it for your
|
||||||
|
platform.
|
||||||
|
|
||||||
|
## Using the FlatBuffers Lobster library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in Lobster.*
|
||||||
|
|
||||||
|
There is support for both reading and writing FlatBuffers in Lobster.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate Lobster classes from your
|
||||||
|
schema with the `--lobster` 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 Lobster:
|
||||||
|
First, import the library and the generated code. Then read a FlatBuffer binary
|
||||||
|
file into a string, which you pass to the `GetRootAsMonster` function:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lobster}
|
||||||
|
include "monster_generated.lobster"
|
||||||
|
|
||||||
|
let fb = read_file("monsterdata_test.mon")
|
||||||
|
assert fb
|
||||||
|
let monster = MyGame_Example_GetRootAsMonster(fb)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Now you can access values like this:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lobster}
|
||||||
|
let hp = monster.hp
|
||||||
|
let pos = monster.pos
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
As you can see, even though `hp` and `pos` are functions that access FlatBuffer
|
||||||
|
data in-place in the string buffer, they appear as field accesses.
|
||||||
|
|
||||||
|
## Speed
|
||||||
|
|
||||||
|
Using FlatBuffers in Lobster should be relatively fast, as the implementation
|
||||||
|
makes use of native support for writing binary values, and access of vtables.
|
||||||
|
Both generated code and the runtime library are therefore small and fast.
|
||||||
|
|
||||||
|
Actual speed will depend on wether you use Lobster as bytecode VM or compiled to
|
||||||
|
C++.
|
||||||
|
|
||||||
|
## Text Parsing
|
||||||
|
|
||||||
|
Lobster has full support for parsing JSON into FlatBuffers, or generating
|
||||||
|
JSON from FlatBuffers. See `samples/sample_test.lobster` for an example.
|
||||||
|
|
||||||
|
This uses the C++ parser and generator underneath, so should be both fast and
|
||||||
|
conformant.
|
||||||
|
|
||||||
|
<br>
|
||||||
81
docs/source/LuaUsage.md
Normal file
81
docs/source/LuaUsage.md
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
Use in Lua {#flatbuffers_guide_use_lua}
|
||||||
|
=============
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in Lua, 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 Lua). This
|
||||||
|
page is designed to cover the nuances of FlatBuffers usage, specific to
|
||||||
|
Lua.
|
||||||
|
|
||||||
|
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 Lua library code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers Lua library can be found at
|
||||||
|
`flatbuffers/lua`. You can browse the library code on the
|
||||||
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/lua).
|
||||||
|
|
||||||
|
## Testing the FlatBuffers Lua library
|
||||||
|
|
||||||
|
The code to test the Lua library can be found at `flatbuffers/tests`.
|
||||||
|
The test code itself is located in [luatest.lua](https://github.com/google/
|
||||||
|
flatbuffers/blob/master/tests/luatest.lua).
|
||||||
|
|
||||||
|
To run the tests, use the [LuaTest.sh](https://github.com/google/flatbuffers/
|
||||||
|
blob/master/tests/LuaTest.sh) shell script.
|
||||||
|
|
||||||
|
*Note: This script requires [Lua 5.3](https://www.lua.org/) to be
|
||||||
|
installed.*
|
||||||
|
|
||||||
|
## Using the FlatBuffers Lua library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in Lua.*
|
||||||
|
|
||||||
|
There is support for both reading and writing FlatBuffers in Lua.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate Lua classes from your
|
||||||
|
schema with the `--lua` 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 Lua:
|
||||||
|
First, require the module and the generated code. Then read a FlatBuffer binary
|
||||||
|
file into a `string`, which you pass to the `GetRootAsMonster` function:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lua}
|
||||||
|
-- require the library
|
||||||
|
local flatbuffers = require("flatbuffers")
|
||||||
|
|
||||||
|
-- require the generated code
|
||||||
|
local monster = require("MyGame.Sample.Monster")
|
||||||
|
|
||||||
|
-- read the flatbuffer from a file into a string
|
||||||
|
local f = io.open('monster.dat', 'rb')
|
||||||
|
local buf = f:read('*a')
|
||||||
|
f:close()
|
||||||
|
|
||||||
|
-- parse the flatbuffer to get an instance to the root monster
|
||||||
|
local monster1 = monster.GetRootAsMonster(buf, 0)
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Now you can access values like this:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.lua}
|
||||||
|
-- use the : notation to access member data
|
||||||
|
local hp = monster1:Hp()
|
||||||
|
local pos = monster1:Pos()
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
||||||
|
## Text Parsing
|
||||||
|
|
||||||
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
|
from Lua, though you could use the C++ parser through SWIG or ctypes. Please
|
||||||
|
see the C++ documentation for more on text parsing.
|
||||||
|
|
||||||
|
<br>
|
||||||
27
docs/source/PythonUsage.md
Executable file → Normal file
27
docs/source/PythonUsage.md
Executable file → Normal file
@@ -64,6 +64,33 @@ Now you can access values like this:
|
|||||||
pos = monster.Pos()
|
pos = monster.Pos()
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
## Support for Numpy arrays
|
||||||
|
|
||||||
|
The Flatbuffers python library also has support for accessing scalar
|
||||||
|
vectors as numpy arrays. This can be orders of magnitude faster than
|
||||||
|
iterating over the vector one element at a time, and is particularly
|
||||||
|
useful when unpacking large nested flatbuffers. The generated code for
|
||||||
|
a scalar vector will have a method `<vector name>AsNumpy()`. In the
|
||||||
|
case of the Monster example, you could access the inventory vector
|
||||||
|
like this:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
|
||||||
|
inventory = monster.InventoryAsNumpy()
|
||||||
|
# inventory is a numpy array of type np.dtype('uint8')
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
instead of
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.py}
|
||||||
|
inventory = []
|
||||||
|
for i in range(monster.InventoryLength()):
|
||||||
|
inventory.append(int(monster.Inventory(i)))
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Numpy is not a requirement. If numpy is not installed on your system,
|
||||||
|
then attempting to access one of the `*asNumpy()` methods will result
|
||||||
|
in a `NumpyRequiredForThisFeature` exception.
|
||||||
|
|
||||||
## 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
|
||||||
|
|||||||
166
docs/source/RustUsage.md
Normal file
166
docs/source/RustUsage.md
Normal file
@@ -0,0 +1,166 @@
|
|||||||
|
Use in Rust {#flatbuffers_guide_use_rust}
|
||||||
|
==========
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in Rust, 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 Rust).
|
||||||
|
This page is designed to cover the nuances of FlatBuffers usage, specific to
|
||||||
|
Rust.
|
||||||
|
|
||||||
|
#### Prerequisites
|
||||||
|
|
||||||
|
This page assumes you have written a FlatBuffers schema and compiled it
|
||||||
|
with the Schema Compiler. If you have not, please see
|
||||||
|
[Using the schema compiler](@ref flatbuffers_guide_using_schema_compiler)
|
||||||
|
and [Writing a schema](@ref flatbuffers_guide_writing_schema).
|
||||||
|
|
||||||
|
Assuming you wrote a schema, say `mygame.fbs` (though the extension doesn't
|
||||||
|
matter), you've generated a Rust file called `mygame_generated.rs` using the
|
||||||
|
compiler (e.g. `flatc --rust mygame.fbs`), you can now start using this in
|
||||||
|
your program by including the file. As noted, this header relies on the crate
|
||||||
|
`flatbuffers`, which should be in your include `Cargo.toml`.
|
||||||
|
|
||||||
|
## FlatBuffers Rust library code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers Rust library can be found at
|
||||||
|
`flatbuffers/rust`. You can browse the library code on the
|
||||||
|
[FlatBuffers GitHub page](https://github.com/google/flatbuffers/tree/master/rust).
|
||||||
|
|
||||||
|
## Testing the FlatBuffers Rust library
|
||||||
|
|
||||||
|
The code to test the Rust library can be found at `flatbuffers/tests/rust_usage_test`.
|
||||||
|
The test code itself is located in
|
||||||
|
[integration_test.rs](https://github.com/google/flatbuffers/blob/master/tests/rust_usage_test/tests/integration_test.rs)
|
||||||
|
|
||||||
|
This test file requires `flatc` to be present. To review how to build the project,
|
||||||
|
please read the [Building](@ref flatbuffers_guide_building) documenation.
|
||||||
|
|
||||||
|
To run the tests, execute `RustTest.sh` from the `flatbuffers/tests` directory.
|
||||||
|
For example, on [Linux](https://en.wikipedia.org/wiki/Linux), you would simply
|
||||||
|
run: `cd tests && ./RustTest.sh`.
|
||||||
|
|
||||||
|
*Note: The shell script requires [Rust](https://www.rust-lang.org) to
|
||||||
|
be installed.*
|
||||||
|
|
||||||
|
## Using the FlatBuffers Rust library
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in Rust.*
|
||||||
|
|
||||||
|
FlatBuffers supports both reading and writing FlatBuffers in Rust.
|
||||||
|
|
||||||
|
To use FlatBuffers in your code, first generate the Rust modules from your
|
||||||
|
schema with the `--rust` option to `flatc`. Then you can import both FlatBuffers
|
||||||
|
and the generated code to read or write FlatBuffers.
|
||||||
|
|
||||||
|
For example, here is how you would read a FlatBuffer binary file in Rust:
|
||||||
|
First, include the library and generated code. Then read the file into
|
||||||
|
a `u8` vector, which you pass, as a byte slice, to `get_root_as_monster()`.
|
||||||
|
|
||||||
|
This full example program is available in the Rust test suite:
|
||||||
|
[monster_example.rs](https://github.com/google/flatbuffers/blob/master/tests/rust_usage_test/bin/monster_example.rs)
|
||||||
|
|
||||||
|
It can be run by `cd`ing to the `rust_usage_test` directory and executing: `cargo run monster_example`.
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
|
||||||
|
extern crate flatbuffers;
|
||||||
|
|
||||||
|
#[path = "../../monster_test_generated.rs"]
|
||||||
|
mod monster_test_generated;
|
||||||
|
pub use monster_test_generated::my_game;
|
||||||
|
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let mut f = std::fs::File::open("../monsterdata_test.mon").unwrap();
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
f.read_to_end(&mut buf).expect("file reading failed");
|
||||||
|
|
||||||
|
let monster = my_game::example::get_root_as_monster(&buf[..]);
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
`monster` is of type `Monster`, and points to somewhere *inside* your
|
||||||
|
buffer (root object pointers are not the same as `buffer_pointer` !).
|
||||||
|
If you look in your generated header, you'll see it has
|
||||||
|
convenient accessors for all fields, e.g. `hp()`, `mana()`, etc:
|
||||||
|
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.rs}
|
||||||
|
println!("{}", monster.hp()); // `80`
|
||||||
|
println!("{}", monster.mana()); // default value of `150`
|
||||||
|
println!("{:?}", monster.name()); // Some("MyMonster")
|
||||||
|
}
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
*Note: That we never stored a `mana` value, so it will return the default.*
|
||||||
|
|
||||||
|
## Direct memory access
|
||||||
|
|
||||||
|
As you can see from the above examples, all elements in a buffer are
|
||||||
|
accessed through generated accessors. This is because everything is
|
||||||
|
stored in little endian format on all platforms (the accessor
|
||||||
|
performs a swap operation on big endian machines), and also because
|
||||||
|
the layout of things is generally not known to the user.
|
||||||
|
|
||||||
|
For structs, layout is deterministic and guaranteed to be the same
|
||||||
|
across platforms (scalars are aligned to their
|
||||||
|
own size, and structs themselves to their largest member), and you
|
||||||
|
are allowed to access this memory directly by using `safe_slice` and
|
||||||
|
on the reference to a struct, or even an array of structs.
|
||||||
|
|
||||||
|
To compute offsets to sub-elements of a struct, make sure they
|
||||||
|
are structs themselves, as then you can use the pointers to
|
||||||
|
figure out the offset without having to hardcode it. This is
|
||||||
|
handy for use of arrays of structs with calls like `glVertexAttribPointer`
|
||||||
|
in OpenGL or similar APIs.
|
||||||
|
|
||||||
|
It is important to note is that structs are still little endian on all
|
||||||
|
machines, so only use tricks like this if you can guarantee you're not
|
||||||
|
shipping on a big endian machine (using an `#[cfg(target_endian = "little")]`
|
||||||
|
attribute would be wise).
|
||||||
|
|
||||||
|
The special function `safe_slice` is implemented on Vector objects that are
|
||||||
|
represented in memory the same way as they are represented on the wire. This
|
||||||
|
function is always available on vectors of struct, bool, u8, and i8. It is
|
||||||
|
conditionally-compiled on little-endian systems for all the remaining scalar
|
||||||
|
types.
|
||||||
|
|
||||||
|
The FlatBufferBuilder function `create_vector_direct` is implemented for all
|
||||||
|
types that are endian-safe to write with a `memcpy`. It is the write-equivalent
|
||||||
|
of `safe_slice`.
|
||||||
|
|
||||||
|
## Access of untrusted buffers
|
||||||
|
|
||||||
|
The generated accessor functions access fields over offsets, which is
|
||||||
|
very quick. These offsets are used to index into Rust slices, so they are
|
||||||
|
bounds-checked by the Rust runtime. However, our Rust implementation may
|
||||||
|
change: we may convert access functions to use direct pointer dereferencing, to
|
||||||
|
improve lookup speed. As a result, users should not rely on the aforementioned
|
||||||
|
bounds-checking behavior.
|
||||||
|
|
||||||
|
When you're processing large amounts of data from a source you know (e.g.
|
||||||
|
your own generated data on disk), this is acceptable, but when reading
|
||||||
|
data from the network that can potentially have been modified by an
|
||||||
|
attacker, this is undesirable.
|
||||||
|
|
||||||
|
The C++ port provides a buffer verifier. At this time, Rust does not. Rust may
|
||||||
|
provide a verifier in a future version. In the meantime, Rust users can access
|
||||||
|
the buffer verifier generated by the C++ port through a foreign function
|
||||||
|
interface (FFI).
|
||||||
|
|
||||||
|
## Threading
|
||||||
|
|
||||||
|
Reading a FlatBuffer does not touch any memory outside the original buffer,
|
||||||
|
and is entirely read-only (all immutable), so is safe to access from multiple
|
||||||
|
threads even without synchronisation primitives.
|
||||||
|
|
||||||
|
Creating a FlatBuffer is not thread safe. All state related to building
|
||||||
|
a FlatBuffer is contained in a FlatBufferBuilder instance, and no memory
|
||||||
|
outside of it is touched. To make this thread safe, either do not
|
||||||
|
share instances of FlatBufferBuilder between threads (recommended), or
|
||||||
|
manually wrap it in synchronisation primitives. There's no automatic way to
|
||||||
|
accomplish this, by design, as we feel multithreaded construction
|
||||||
|
of a single buffer will be rare, and synchronisation overhead would be costly.
|
||||||
|
|
||||||
|
<br>
|
||||||
24
docs/source/Schemas.md
Executable file → Normal file
24
docs/source/Schemas.md
Executable file → Normal file
@@ -84,15 +84,19 @@ parent object, and use no virtual table).
|
|||||||
|
|
||||||
### Types
|
### Types
|
||||||
|
|
||||||
Built-in scalar types are:
|
Built-in scalar types are
|
||||||
|
|
||||||
- 8 bit: `byte`, `ubyte`, `bool`
|
- 8 bit: `byte` (`int8`), `ubyte` (`uint8`), `bool`
|
||||||
|
|
||||||
- 16 bit: `short`, `ushort`
|
- 16 bit: `short` (`int16`), `ushort` (`uint16`)
|
||||||
|
|
||||||
- 32 bit: `int`, `uint`, `float`
|
- 32 bit: `int` (`int32`), `uint` (`uint32`), `float` (`float32`)
|
||||||
|
|
||||||
- 64 bit: `long`, `ulong`, `double`
|
- 64 bit: `long` (`int64`), `ulong` (`uint64`), `double` (`float64`)
|
||||||
|
|
||||||
|
The type names in parentheses are alias names such that for example
|
||||||
|
`uint8` can be used in place of `ubyte`, and `int32` can be used in
|
||||||
|
place of `int` without affecting code generation.
|
||||||
|
|
||||||
Built-in non-scalar types:
|
Built-in non-scalar types:
|
||||||
|
|
||||||
@@ -278,7 +282,10 @@ Current understood attributes:
|
|||||||
IDs allow the fields to be placed in any order in the schema.
|
IDs allow the fields to be placed in any order in the schema.
|
||||||
When a new field is added to the schema it must use the next available ID.
|
When a new field is added to the schema it must use the next available ID.
|
||||||
- `deprecated` (on a field): do not generate accessors for this field
|
- `deprecated` (on a field): do not generate accessors for this field
|
||||||
anymore, code should stop using this data.
|
anymore, code should stop using this data. Old data may still contain this
|
||||||
|
field, but it won't be accessible anymore by newer code. Note that if you
|
||||||
|
deprecate a field that was previous required, old code may fail to validate
|
||||||
|
new data (when using the optional verifier).
|
||||||
- `required` (on a non-scalar table field): this field must always be set.
|
- `required` (on a non-scalar table field): this field must always be set.
|
||||||
By default, all fields are optional, i.e. may be left out. This is
|
By default, all fields are optional, i.e. may be left out. This is
|
||||||
desirable, as it helps with forwards/backwards compatibility, and
|
desirable, as it helps with forwards/backwards compatibility, and
|
||||||
@@ -288,7 +295,10 @@ Current understood attributes:
|
|||||||
constructs FlatBuffers to ensure this field is initialized, so the reading
|
constructs FlatBuffers to ensure this field is initialized, so the reading
|
||||||
code may access it directly, without checking for NULL. If the constructing
|
code may access it directly, without checking for NULL. If the constructing
|
||||||
code does not initialize this field, they will get an assert, and also
|
code does not initialize this field, they will get an assert, and also
|
||||||
the verifier will fail on buffers that have missing required fields.
|
the verifier will fail on buffers that have missing required fields. Note
|
||||||
|
that if you add this attribute to an existing field, this will only be
|
||||||
|
valid if existing data always contains this field / existing code always
|
||||||
|
writes this field.
|
||||||
- `force_align: size` (on a struct): force the alignment of this struct
|
- `force_align: size` (on a struct): force the alignment of this struct
|
||||||
to be something higher than what it is naturally aligned to. Causes
|
to be something higher than what it is naturally aligned to. Causes
|
||||||
these structs to be aligned to that amount inside a buffer, IF that
|
these structs to be aligned to that amount inside a buffer, IF that
|
||||||
|
|||||||
36
docs/source/Support.md
Executable file → Normal file
36
docs/source/Support.md
Executable file → Normal file
@@ -18,27 +18,29 @@ 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 | C | PHP | Ruby
|
Feature | C++ | Java | C# | Go | Python | JS | TS | C | PHP | Dart | Lobster | Rust
|
||||||
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | ------ | --- | ----
|
------------------------------ | ------ | ------ | ------ | ------ | ------ | --------- | --------- | ------ | --- | ------- | ------- | ----
|
||||||
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | WiP
|
Codegen for all basic features | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | WiP | Yes | Yes | Yes
|
||||||
JSON parsing | Yes | No | No | No | No | No | Yes | No | No
|
JSON parsing | Yes | No | No | No | No | No | No | Yes | No | No | Yes | No
|
||||||
Simple mutation | Yes | WIP | WIP | No | No | No | No | No | No
|
Simple mutation | Yes | Yes | Yes | Yes | No | No | No | No | No | No | No | No
|
||||||
Reflection | Yes | No | No | No | No | No | Basic | No | No
|
Reflection | Yes | No | No | No | No | No | No | Basic | No | No | No | No
|
||||||
Buffer verifier | Yes | No | No | No | No | No | Yes | No | No
|
Buffer verifier | Yes | No | No | No | No | No | No | Yes | No | No | No | No
|
||||||
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | ?
|
Testing: basic | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes | ? | Yes | Yes | Yes
|
||||||
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | ? | ?
|
Testing: fuzz | Yes | No | No | Yes | Yes | No | No | No | ? | No | No | Yes
|
||||||
Performance: | Superb | Great | Great | Great | Ok | ? | Superb | ? | ?
|
Performance: | Superb | Great | Great | Great | Ok | ? | ? | Superb | ? | ? | Great | Superb
|
||||||
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | VS2010 | ? | ?
|
Platform: Windows | VS2010 | Yes | Yes | ? | ? | ? | Yes | VS2010 | ? | Yes | Yes | Yes
|
||||||
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | ? | ?
|
Platform: Linux | GCC282 | Yes | ? | Yes | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
|
||||||
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | ? | ?
|
Platform: OS X | Xcode4 | ? | ? | ? | Yes | ? | Yes | Yes | ? | Yes | Yes | Yes
|
||||||
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ?
|
Platform: Android | NDK10d | Yes | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
|
||||||
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ?
|
Platform: iOS | ? | ? | ? | ? | ? | ? | ? | ? | ? | Flutter | Yes | ?
|
||||||
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ?
|
Engine: Unity | ? | ? | Yes | ? | ? | ? | ? | ? | ? | ? | No | ?
|
||||||
Primary authors (github) | gwvo | gwvo | ev*/js*| rw | rw | evanw/ev* | mik* | ch* | rw
|
Primary authors (github) | aard* | aard* | ev*/js*| rw | rw | evanw/ev* | kr* | mik* | ch* | dnfield | aard* | rw
|
||||||
|
|
||||||
|
* aard = aardappel (previously: gwvo)
|
||||||
* ev = evolutional
|
* ev = evolutional
|
||||||
* js = jonsimantov
|
* js = jonsimantov
|
||||||
* mik = mikkelfj
|
* mik = mikkelfj
|
||||||
* ch = chobie
|
* ch = chobie
|
||||||
|
* kr = krojew
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
66
docs/source/TypeScriptUsage.md
Normal file
66
docs/source/TypeScriptUsage.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
Use in TypeScript {#flatbuffers_guide_use_typescript}
|
||||||
|
=================
|
||||||
|
|
||||||
|
## Before you get started
|
||||||
|
|
||||||
|
Before diving into the FlatBuffers usage in TypeScript, 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 TypeScript). This page is specifically designed to cover the nuances
|
||||||
|
of FlatBuffers usage in TypeScript.
|
||||||
|
|
||||||
|
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 TypeScript library code location
|
||||||
|
|
||||||
|
The code for the FlatBuffers TypeScript library can be found at
|
||||||
|
`flatbuffers/js` with typings available at @types/flatubffers.
|
||||||
|
|
||||||
|
## Testing the FlatBuffers TypeScript library
|
||||||
|
|
||||||
|
To run the tests, use the [TypeScriptTest.sh](https://github.com/google/
|
||||||
|
flatbuffers/blob/master/tests/TypeScriptTest.sh) shell script.
|
||||||
|
|
||||||
|
*Note: The TypeScript test file requires [Node.js](https://nodejs.org/en/).*
|
||||||
|
|
||||||
|
## Using the FlatBuffers TypeScript libary
|
||||||
|
|
||||||
|
*Note: See [Tutorial](@ref flatbuffers_guide_tutorial) for a more in-depth
|
||||||
|
example of how to use FlatBuffers in TypeScript.*
|
||||||
|
|
||||||
|
FlatBuffers supports both reading and writing FlatBuffers in TypeScript.
|
||||||
|
|
||||||
|
To use FlatBuffers in your own code, first generate TypeScript classes from your
|
||||||
|
schema with the `--ts` 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 TypeScript:
|
||||||
|
First, include the library and generated code. Then read the file into an
|
||||||
|
`Uint8Array`. Make a `flatbuffers.ByteBuffer` out of the `Uint8Array`, and pass
|
||||||
|
the ByteBuffer to the `getRootAsMonster` function.
|
||||||
|
|
||||||
|
~~~{.ts}
|
||||||
|
// note: import flabuffers with your desired import method
|
||||||
|
|
||||||
|
import { MyGame } from './monster_generated';
|
||||||
|
|
||||||
|
let data = new Uint8Array(fs.readFileSync('monster.dat'));
|
||||||
|
let buf = new flatbuffers.ByteBuffer(data);
|
||||||
|
|
||||||
|
let monster = MyGame.Example.Monster.getRootAsMonster(buf);
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Now you can access values like this:
|
||||||
|
|
||||||
|
~~~{.ts}
|
||||||
|
let hp = monster.hp();
|
||||||
|
let pos = monster.pos();
|
||||||
|
~~~
|
||||||
|
|
||||||
|
## Text parsing FlatBuffers in TypeScript
|
||||||
|
|
||||||
|
There currently is no support for parsing text (Schema's and JSON) directly
|
||||||
|
from TypeScript.
|
||||||
0
docs/source/WhitePaper.md
Executable file → Normal file
0
docs/source/WhitePaper.md
Executable file → Normal file
6
docs/source/doxyfile
Executable file → Normal file
6
docs/source/doxyfile
Executable file → Normal file
@@ -751,11 +751,16 @@ INPUT = "FlatBuffers.md" \
|
|||||||
"Schemas.md" \
|
"Schemas.md" \
|
||||||
"CppUsage.md" \
|
"CppUsage.md" \
|
||||||
"CUsage.md" \
|
"CUsage.md" \
|
||||||
|
"DartUsage.md" \
|
||||||
"GoUsage.md" \
|
"GoUsage.md" \
|
||||||
"JavaCsharpUsage.md" \
|
"JavaCsharpUsage.md" \
|
||||||
"JavaScriptUsage.md" \
|
"JavaScriptUsage.md" \
|
||||||
|
"TypeScriptUsage.md" \
|
||||||
"PHPUsage.md" \
|
"PHPUsage.md" \
|
||||||
"PythonUsage.md" \
|
"PythonUsage.md" \
|
||||||
|
"LuaUsage.md" \
|
||||||
|
"LobsterUsage.md" \
|
||||||
|
"RustUsage.md" \
|
||||||
"Support.md" \
|
"Support.md" \
|
||||||
"Benchmarks.md" \
|
"Benchmarks.md" \
|
||||||
"WhitePaper.md" \
|
"WhitePaper.md" \
|
||||||
@@ -774,6 +779,7 @@ INPUT = "FlatBuffers.md" \
|
|||||||
"../../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"
|
||||||
|
|
||||||
# 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
|
||||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||||
|
|||||||
@@ -33,10 +33,18 @@
|
|||||||
title="Use in Java/C#"/>
|
title="Use in Java/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"
|
||||||
|
title="Use in TypeScript"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_php"
|
<tab type="user" url="@ref flatbuffers_guide_use_php"
|
||||||
title="Use in PHP"/>
|
title="Use in PHP"/>
|
||||||
<tab type="user" url="@ref flatbuffers_guide_use_python"
|
<tab type="user" url="@ref flatbuffers_guide_use_python"
|
||||||
title="Use in Python"/>
|
title="Use in Python"/>
|
||||||
|
<tab type="user" url="@ref flatbuffers_guide_use_dart"
|
||||||
|
title="Use in Dart"/>
|
||||||
|
<tab type="user" url="@ref flatbuffers_guide_use_lua"
|
||||||
|
title="Use in Lua"/>
|
||||||
|
<tab type="user" url="@ref flatbuffers_guide_use_lobster"
|
||||||
|
title="Use in Lobster"/>
|
||||||
<tab type="user" url="@ref flexbuffers"
|
<tab type="user" url="@ref flexbuffers"
|
||||||
title="Schema-less version"/>
|
title="Schema-less version"/>
|
||||||
<tab type="usergroup" url="" title="gRPC">
|
<tab type="usergroup" url="" title="gRPC">
|
||||||
|
|||||||
@@ -13,6 +13,9 @@
|
|||||||
/// @defgroup flatbuffers_javascript_api JavaScript API
|
/// @defgroup flatbuffers_javascript_api JavaScript API
|
||||||
/// @brief FlatBuffers API for JavaScript
|
/// @brief FlatBuffers API for JavaScript
|
||||||
|
|
||||||
|
/// @defgroup flatbuffers_typescript_api TypeScript API
|
||||||
|
/// @brief FlatBuffers API for TypeScript
|
||||||
|
|
||||||
/// @defgroup flatbuffers_php_api PHP API
|
/// @defgroup flatbuffers_php_api PHP API
|
||||||
/// @brief FlatBuffers API for PHP
|
/// @brief FlatBuffers API for PHP
|
||||||
|
|
||||||
|
|||||||
17
go/BUILD.bazel
Normal file
17
go/BUILD.bazel
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||||
|
|
||||||
|
go_library(
|
||||||
|
name = "go",
|
||||||
|
srcs = [
|
||||||
|
"builder.go",
|
||||||
|
"doc.go",
|
||||||
|
"encode.go",
|
||||||
|
"grpc.go",
|
||||||
|
"lib.go",
|
||||||
|
"sizes.go",
|
||||||
|
"struct.go",
|
||||||
|
"table.go",
|
||||||
|
],
|
||||||
|
importpath = "github.com/google/flatbuffers/go",
|
||||||
|
visibility = ["//visibility:public"],
|
||||||
|
)
|
||||||
@@ -19,6 +19,8 @@ type Builder struct {
|
|||||||
finished bool
|
finished bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const fileIdentifierLength = 4
|
||||||
|
|
||||||
// NewBuilder initializes a Builder of size `initial_size`.
|
// NewBuilder initializes a Builder of size `initial_size`.
|
||||||
// The internal buffer is grown as needed.
|
// The internal buffer is grown as needed.
|
||||||
func NewBuilder(initialSize int) *Builder {
|
func NewBuilder(initialSize int) *Builder {
|
||||||
@@ -80,7 +82,6 @@ func (b *Builder) StartObject(numfields int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
b.objectEnd = b.Offset()
|
b.objectEnd = b.Offset()
|
||||||
b.minalign = 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteVtable serializes the vtable for the current object, if applicable.
|
// WriteVtable serializes the vtable for the current object, if applicable.
|
||||||
@@ -110,6 +111,12 @@ func (b *Builder) WriteVtable() (n UOffsetT) {
|
|||||||
objectOffset := b.Offset()
|
objectOffset := b.Offset()
|
||||||
existingVtable := UOffsetT(0)
|
existingVtable := UOffsetT(0)
|
||||||
|
|
||||||
|
// Trim vtable of trailing zeroes.
|
||||||
|
i := len(b.vtable) - 1
|
||||||
|
for ; i >= 0 && b.vtable[i] == 0; i-- {
|
||||||
|
}
|
||||||
|
b.vtable = b.vtable[:i+1]
|
||||||
|
|
||||||
// Search backwards through existing vtables, because similar vtables
|
// Search backwards through existing vtables, because similar vtables
|
||||||
// are likely to have been recently appended. See
|
// are likely to have been recently appended. See
|
||||||
// BenchmarkVtableDeduplication for a case in which this heuristic
|
// BenchmarkVtableDeduplication for a case in which this heuristic
|
||||||
@@ -535,6 +542,23 @@ func (b *Builder) Slot(slotnum int) {
|
|||||||
b.vtable[slotnum] = UOffsetT(b.Offset())
|
b.vtable[slotnum] = UOffsetT(b.Offset())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FinishWithFileIdentifier finalizes a buffer, pointing to the given `rootTable`.
|
||||||
|
// as well as applys a file identifier
|
||||||
|
func (b *Builder) FinishWithFileIdentifier(rootTable UOffsetT, fid []byte) {
|
||||||
|
if fid == nil || len(fid) != fileIdentifierLength {
|
||||||
|
panic("incorrect file identifier length")
|
||||||
|
}
|
||||||
|
// In order to add a file identifier to the flatbuffer message, we need
|
||||||
|
// to prepare an alignment and file identifier length
|
||||||
|
b.Prep(b.minalign, SizeInt32+fileIdentifierLength)
|
||||||
|
for i := fileIdentifierLength - 1; i >= 0; i-- {
|
||||||
|
// place the file identifier
|
||||||
|
b.PlaceByte(fid[i])
|
||||||
|
}
|
||||||
|
// finish
|
||||||
|
b.Finish(rootTable)
|
||||||
|
}
|
||||||
|
|
||||||
// Finish finalizes a buffer, pointing to the given `rootTable`.
|
// Finish finalizes a buffer, pointing to the given `rootTable`.
|
||||||
func (b *Builder) Finish(rootTable UOffsetT) {
|
func (b *Builder) Finish(rootTable UOffsetT) {
|
||||||
b.assertNotNested()
|
b.assertNotNested()
|
||||||
|
|||||||
34
go/encode.go
34
go/encode.go
@@ -36,6 +36,7 @@ func GetUint8(buf []byte) (n uint8) {
|
|||||||
|
|
||||||
// GetUint16 decodes a little-endian uint16 from a byte slice.
|
// GetUint16 decodes a little-endian uint16 from a byte slice.
|
||||||
func GetUint16(buf []byte) (n uint16) {
|
func GetUint16(buf []byte) (n uint16) {
|
||||||
|
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||||
n |= uint16(buf[0])
|
n |= uint16(buf[0])
|
||||||
n |= uint16(buf[1]) << 8
|
n |= uint16(buf[1]) << 8
|
||||||
return
|
return
|
||||||
@@ -43,6 +44,7 @@ func GetUint16(buf []byte) (n uint16) {
|
|||||||
|
|
||||||
// GetUint32 decodes a little-endian uint32 from a byte slice.
|
// GetUint32 decodes a little-endian uint32 from a byte slice.
|
||||||
func GetUint32(buf []byte) (n uint32) {
|
func GetUint32(buf []byte) (n uint32) {
|
||||||
|
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||||
n |= uint32(buf[0])
|
n |= uint32(buf[0])
|
||||||
n |= uint32(buf[1]) << 8
|
n |= uint32(buf[1]) << 8
|
||||||
n |= uint32(buf[2]) << 16
|
n |= uint32(buf[2]) << 16
|
||||||
@@ -52,6 +54,7 @@ func GetUint32(buf []byte) (n uint32) {
|
|||||||
|
|
||||||
// GetUint64 decodes a little-endian uint64 from a byte slice.
|
// GetUint64 decodes a little-endian uint64 from a byte slice.
|
||||||
func GetUint64(buf []byte) (n uint64) {
|
func GetUint64(buf []byte) (n uint64) {
|
||||||
|
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||||
n |= uint64(buf[0])
|
n |= uint64(buf[0])
|
||||||
n |= uint64(buf[1]) << 8
|
n |= uint64(buf[1]) << 8
|
||||||
n |= uint64(buf[2]) << 16
|
n |= uint64(buf[2]) << 16
|
||||||
@@ -71,6 +74,7 @@ func GetInt8(buf []byte) (n int8) {
|
|||||||
|
|
||||||
// GetInt16 decodes a little-endian int16 from a byte slice.
|
// GetInt16 decodes a little-endian int16 from a byte slice.
|
||||||
func GetInt16(buf []byte) (n int16) {
|
func GetInt16(buf []byte) (n int16) {
|
||||||
|
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||||
n |= int16(buf[0])
|
n |= int16(buf[0])
|
||||||
n |= int16(buf[1]) << 8
|
n |= int16(buf[1]) << 8
|
||||||
return
|
return
|
||||||
@@ -78,6 +82,7 @@ func GetInt16(buf []byte) (n int16) {
|
|||||||
|
|
||||||
// GetInt32 decodes a little-endian int32 from a byte slice.
|
// GetInt32 decodes a little-endian int32 from a byte slice.
|
||||||
func GetInt32(buf []byte) (n int32) {
|
func GetInt32(buf []byte) (n int32) {
|
||||||
|
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||||
n |= int32(buf[0])
|
n |= int32(buf[0])
|
||||||
n |= int32(buf[1]) << 8
|
n |= int32(buf[1]) << 8
|
||||||
n |= int32(buf[2]) << 16
|
n |= int32(buf[2]) << 16
|
||||||
@@ -87,6 +92,7 @@ func GetInt32(buf []byte) (n int32) {
|
|||||||
|
|
||||||
// GetInt64 decodes a little-endian int64 from a byte slice.
|
// GetInt64 decodes a little-endian int64 from a byte slice.
|
||||||
func GetInt64(buf []byte) (n int64) {
|
func GetInt64(buf []byte) (n int64) {
|
||||||
|
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||||
n |= int64(buf[0])
|
n |= int64(buf[0])
|
||||||
n |= int64(buf[1]) << 8
|
n |= int64(buf[1]) << 8
|
||||||
n |= int64(buf[2]) << 16
|
n |= int64(buf[2]) << 16
|
||||||
@@ -145,12 +151,14 @@ func WriteUint8(buf []byte, n uint8) {
|
|||||||
|
|
||||||
// WriteUint16 encodes a little-endian uint16 into a byte slice.
|
// WriteUint16 encodes a little-endian uint16 into a byte slice.
|
||||||
func WriteUint16(buf []byte, n uint16) {
|
func WriteUint16(buf []byte, n uint16) {
|
||||||
|
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||||
buf[0] = byte(n)
|
buf[0] = byte(n)
|
||||||
buf[1] = byte(n >> 8)
|
buf[1] = byte(n >> 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteUint32 encodes a little-endian uint32 into a byte slice.
|
// WriteUint32 encodes a little-endian uint32 into a byte slice.
|
||||||
func WriteUint32(buf []byte, n uint32) {
|
func WriteUint32(buf []byte, n uint32) {
|
||||||
|
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||||
buf[0] = byte(n)
|
buf[0] = byte(n)
|
||||||
buf[1] = byte(n >> 8)
|
buf[1] = byte(n >> 8)
|
||||||
buf[2] = byte(n >> 16)
|
buf[2] = byte(n >> 16)
|
||||||
@@ -159,9 +167,15 @@ func WriteUint32(buf []byte, n uint32) {
|
|||||||
|
|
||||||
// WriteUint64 encodes a little-endian uint64 into a byte slice.
|
// WriteUint64 encodes a little-endian uint64 into a byte slice.
|
||||||
func WriteUint64(buf []byte, n uint64) {
|
func WriteUint64(buf []byte, n uint64) {
|
||||||
for i := uint(0); i < uint(SizeUint64); i++ {
|
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||||
buf[i] = byte(n >> (i * 8))
|
buf[0] = byte(n)
|
||||||
}
|
buf[1] = byte(n >> 8)
|
||||||
|
buf[2] = byte(n >> 16)
|
||||||
|
buf[3] = byte(n >> 24)
|
||||||
|
buf[4] = byte(n >> 32)
|
||||||
|
buf[5] = byte(n >> 40)
|
||||||
|
buf[6] = byte(n >> 48)
|
||||||
|
buf[7] = byte(n >> 56)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteInt8 encodes a little-endian int8 into a byte slice.
|
// WriteInt8 encodes a little-endian int8 into a byte slice.
|
||||||
@@ -171,12 +185,14 @@ func WriteInt8(buf []byte, n int8) {
|
|||||||
|
|
||||||
// WriteInt16 encodes a little-endian int16 into a byte slice.
|
// WriteInt16 encodes a little-endian int16 into a byte slice.
|
||||||
func WriteInt16(buf []byte, n int16) {
|
func WriteInt16(buf []byte, n int16) {
|
||||||
|
_ = buf[1] // Force one bounds check. See: golang.org/issue/14808
|
||||||
buf[0] = byte(n)
|
buf[0] = byte(n)
|
||||||
buf[1] = byte(n >> 8)
|
buf[1] = byte(n >> 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteInt32 encodes a little-endian int32 into a byte slice.
|
// WriteInt32 encodes a little-endian int32 into a byte slice.
|
||||||
func WriteInt32(buf []byte, n int32) {
|
func WriteInt32(buf []byte, n int32) {
|
||||||
|
_ = buf[3] // Force one bounds check. See: golang.org/issue/14808
|
||||||
buf[0] = byte(n)
|
buf[0] = byte(n)
|
||||||
buf[1] = byte(n >> 8)
|
buf[1] = byte(n >> 8)
|
||||||
buf[2] = byte(n >> 16)
|
buf[2] = byte(n >> 16)
|
||||||
@@ -185,9 +201,15 @@ func WriteInt32(buf []byte, n int32) {
|
|||||||
|
|
||||||
// WriteInt64 encodes a little-endian int64 into a byte slice.
|
// WriteInt64 encodes a little-endian int64 into a byte slice.
|
||||||
func WriteInt64(buf []byte, n int64) {
|
func WriteInt64(buf []byte, n int64) {
|
||||||
for i := uint(0); i < uint(SizeInt64); i++ {
|
_ = buf[7] // Force one bounds check. See: golang.org/issue/14808
|
||||||
buf[i] = byte(n >> (i * 8))
|
buf[0] = byte(n)
|
||||||
}
|
buf[1] = byte(n >> 8)
|
||||||
|
buf[2] = byte(n >> 16)
|
||||||
|
buf[3] = byte(n >> 24)
|
||||||
|
buf[4] = byte(n >> 32)
|
||||||
|
buf[5] = byte(n >> 40)
|
||||||
|
buf[6] = byte(n >> 48)
|
||||||
|
buf[7] = byte(n >> 56)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteFloat32 encodes a little-endian float32 into a byte slice.
|
// WriteFloat32 encodes a little-endian float32 into a byte slice.
|
||||||
|
|||||||
@@ -9,3 +9,23 @@ from GRPC, and work with both the Protobuf and FlatBuffers code generator.
|
|||||||
the GRPC libraries for this to compile. This test will build using the
|
the GRPC libraries for this to compile. This test will build using the
|
||||||
`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project.
|
`FLATBUFFERS_BUILD_GRPCTEST` option to the main FlatBuffers CMake project.
|
||||||
|
|
||||||
|
## Building Flatbuffers with gRPC
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
1. Download, build and install gRPC. See [instructions](https://github.com/grpc/grpc/tree/master/src/cpp).
|
||||||
|
* Lets say your gRPC clone is at `/your/path/to/grpc_repo`.
|
||||||
|
* Install gRPC in a custom directory by running `make install prefix=/your/path/to/grpc_repo/install`.
|
||||||
|
2. `export GRPC_INSTALL_PATH=/your/path/to/grpc_repo/install`
|
||||||
|
3. `export PROTOBUF_DOWNLOAD_PATH=/your/path/to/grpc_repo/third_party/protobuf`
|
||||||
|
4. `mkdir build ; cd build`
|
||||||
|
5. `cmake -DFLATBUFFERS_BUILD_GRPCTEST=ON -DGRPC_INSTALL_PATH=${GRPC_INSTALL_PATH} -DPROTOBUF_DOWNLOAD_PATH=${PROTOBUF_DOWNLOAD_PATH} ..`
|
||||||
|
6. `make`
|
||||||
|
|
||||||
|
## Running FlatBuffer gRPC tests
|
||||||
|
|
||||||
|
### Linux
|
||||||
|
|
||||||
|
1. `ln -s ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.6 ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1`
|
||||||
|
2. `export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${GRPC_INSTALL_PATH}/lib`
|
||||||
|
3. `make test ARGS=-V`
|
||||||
|
|||||||
21
grpc/build_grpc.sh
Executable file
21
grpc/build_grpc.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
grpc_1_15_1_githash=1a60e6971f428323245a930031ad267bb3142ba4
|
||||||
|
|
||||||
|
function build_grpc () {
|
||||||
|
git clone https://github.com/grpc/grpc.git google/grpc
|
||||||
|
cd google/grpc
|
||||||
|
git checkout ${grpc_1_15_1_githash}
|
||||||
|
git submodule update --init
|
||||||
|
make
|
||||||
|
make install prefix=`pwd`/install
|
||||||
|
if [ ! -f ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1 ]; then
|
||||||
|
ln -s ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.6 ${GRPC_INSTALL_PATH}/lib/libgrpc++_unsecure.so.1
|
||||||
|
fi
|
||||||
|
cd ../..
|
||||||
|
}
|
||||||
|
|
||||||
|
GRPC_INSTALL_PATH=`pwd`/google/grpc/install
|
||||||
|
PROTOBUF_DOWNLOAD_PATH=`pwd`/google/grpc/third_party/protobuf
|
||||||
|
|
||||||
|
build_grpc
|
||||||
42
grpc/flatbuffers-java-grpc/pom.xml
Normal file
42
grpc/flatbuffers-java-grpc/pom.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
|
<artifactId>flatbuffers-parent</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>flatbuffers-java-grpc</artifactId>
|
||||||
|
<name>${project.artifactId}</name>
|
||||||
|
<packaging>bundle</packaging>
|
||||||
|
<description>
|
||||||
|
Utilities supporting generated code for GRPC
|
||||||
|
</description>
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Wouter van Oortmerssen</name>
|
||||||
|
</developer>
|
||||||
|
<developer>
|
||||||
|
<name>Yuri Finkelstein</name>
|
||||||
|
<url>https://github.com/yfinkelstein</url>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
<properties>
|
||||||
|
<gRPC.version>1.9.0</gRPC.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
|
<artifactId>flatbuffers-java</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.grpc</groupId>
|
||||||
|
<artifactId>grpc-core</artifactId>
|
||||||
|
<version>${gRPC.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
||||||
|
|
||||||
@@ -0,0 +1,117 @@
|
|||||||
|
/*
|
||||||
|
* 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.grpc;
|
||||||
|
|
||||||
|
import com.google.flatbuffers.Table;
|
||||||
|
import io.grpc.Drainable;
|
||||||
|
import io.grpc.KnownLength;
|
||||||
|
import io.grpc.MethodDescriptor;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
public class FlatbuffersUtils {
|
||||||
|
abstract public static class FBExtactor <T extends Table> {
|
||||||
|
T extract (InputStream stream) throws IOException {
|
||||||
|
if (stream instanceof KnownLength) {
|
||||||
|
int size = stream.available();
|
||||||
|
ByteBuffer buffer = ByteBuffer.allocate(size);
|
||||||
|
stream.read(buffer.array());
|
||||||
|
return extract(buffer);
|
||||||
|
} else
|
||||||
|
throw new RuntimeException("The class " + stream.getClass().getCanonicalName() + " does not extend from KnownLength ");
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract T extract(ByteBuffer buffer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static class FBInputStream extends InputStream implements Drainable, KnownLength {
|
||||||
|
private final ByteBuffer buffer;
|
||||||
|
private final int size;
|
||||||
|
@Nullable private ByteArrayInputStream inputStream;
|
||||||
|
|
||||||
|
FBInputStream(ByteBuffer buffer) {
|
||||||
|
this.buffer = buffer;
|
||||||
|
this.size = buffer.remaining();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void makeStreamIfNotAlready() {
|
||||||
|
if (inputStream == null)
|
||||||
|
inputStream = new ByteArrayInputStream(buffer.array(), buffer.position(), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int drainTo(OutputStream target) throws IOException {
|
||||||
|
target.write(buffer.array(), buffer.position(), size);
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read() throws IOException {
|
||||||
|
makeStreamIfNotAlready();
|
||||||
|
return inputStream.read();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int read(byte[] b, int off, int len) throws IOException {
|
||||||
|
makeStreamIfNotAlready();
|
||||||
|
if (inputStream == null) {
|
||||||
|
if (len >= size) {
|
||||||
|
System.arraycopy(buffer.array(), buffer.position(), b, off, size);
|
||||||
|
return size;
|
||||||
|
} else {
|
||||||
|
makeStreamIfNotAlready();
|
||||||
|
return inputStream.read(b, off, len);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
return inputStream.read(b, off, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int available() throws IOException {
|
||||||
|
return inputStream == null ? size : inputStream.available();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T extends Table> MethodDescriptor.Marshaller<T> marshaller(final Class<T> clazz, final FBExtactor<T> extractor) {
|
||||||
|
return new MethodDescriptor.ReflectableMarshaller<T>() {
|
||||||
|
@Override
|
||||||
|
public Class<T> getMessageClass() {
|
||||||
|
return clazz;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream stream(T value) {
|
||||||
|
return new FBInputStream (value.getByteBuffer());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T parse(InputStream stream) {
|
||||||
|
try {
|
||||||
|
return extractor.extract(stream);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
213
grpc/pom.xml
Normal file
213
grpc/pom.xml
Normal file
@@ -0,0 +1,213 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
|
<artifactId>flatbuffers-parent</artifactId>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
<name>flatbuffers-parent</name>
|
||||||
|
<description>parent pom for flatbuffers java artifacts</description>
|
||||||
|
<properties>
|
||||||
|
<scm.url>https://github.com/google/flatbuffers</scm.url>
|
||||||
|
<scm.connection>scm:git:${scm.url}.git</scm.connection>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<licenses>
|
||||||
|
<license>
|
||||||
|
<name>The Apache Software License, Version 2.0</name>
|
||||||
|
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
|
||||||
|
<distribution>repo</distribution>
|
||||||
|
</license>
|
||||||
|
</licenses>
|
||||||
|
|
||||||
|
<issueManagement>
|
||||||
|
<system>GitHub</system>
|
||||||
|
<url>https://github.com/google/flatbuffers/issues</url>
|
||||||
|
</issueManagement>
|
||||||
|
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Wouter van Oortmerssen</name>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
|
|
||||||
|
<url>${scm.url}</url>
|
||||||
|
|
||||||
|
<scm>
|
||||||
|
<connection>${scm.connection}</connection>
|
||||||
|
<developerConnection>${scm.connection}</developerConnection>
|
||||||
|
<url>${scm.url}</url>
|
||||||
|
<tag>HEAD</tag>
|
||||||
|
</scm>
|
||||||
|
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
<build>
|
||||||
|
<extensions>
|
||||||
|
<extension>
|
||||||
|
<!--
|
||||||
|
os-maven-plugin is a Maven extension/plugin that generates various useful platform-dependent
|
||||||
|
project properties normalized from ${os.detected.name} and ${os.detected.arch}.
|
||||||
|
-->
|
||||||
|
<groupId>kr.motd.maven</groupId>
|
||||||
|
<artifactId>os-maven-plugin</artifactId>
|
||||||
|
<version>1.5.0.Final</version>
|
||||||
|
</extension>
|
||||||
|
</extensions>
|
||||||
|
<pluginManagement>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.6.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-jar-plugin</artifactId>
|
||||||
|
<version>3.0.2</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.19.1</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<version>2.10.4</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<version>1.12</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-dependency-plugin</artifactId>
|
||||||
|
<version>2.8</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-deploy-plugin</artifactId>
|
||||||
|
<version>2.7</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>1.5</version>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
|
<version>2.5.3</version>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>exec-maven-plugin</artifactId>
|
||||||
|
<version>1.5.0</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<source>1.6</source>
|
||||||
|
<target>1.6</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<includes>
|
||||||
|
<include>**/*Test.java</include>
|
||||||
|
</includes>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-source-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-sources</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-javadoc-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>attach-javadocs</id>
|
||||||
|
<goals>
|
||||||
|
<goal>jar</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.felix</groupId>
|
||||||
|
<artifactId>maven-bundle-plugin</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.sonatype.plugins</groupId>
|
||||||
|
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||||
|
<version>1.6.7</version>
|
||||||
|
<extensions>true</extensions>
|
||||||
|
<configuration>
|
||||||
|
<serverId>ossrh</serverId>
|
||||||
|
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||||
|
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||||
|
<useReleaseProfile>false</useReleaseProfile>
|
||||||
|
<releaseProfiles>release</releaseProfiles>
|
||||||
|
<goals>deploy</goals>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
<modules>
|
||||||
|
<!-- consider the benefits of publishing all maven artifacts in this project
|
||||||
|
|
||||||
|
<module>flatbuffers-compiler</module>
|
||||||
|
<module>flatbuffers-java</module>
|
||||||
|
|
||||||
|
-->
|
||||||
|
<module>flatbuffers-java-grpc</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "src/compiler/cpp_generator.h"
|
#include "src/compiler/cpp_generator.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@@ -127,8 +128,8 @@ grpc::string GetHeaderPrologue(grpc_generator::File *file,
|
|||||||
printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
|
printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n");
|
||||||
printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
|
printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n");
|
||||||
printer->Print(vars, "\n");
|
printer->Print(vars, "\n");
|
||||||
printer->Print(vars, file->additional_headers().c_str());
|
|
||||||
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
|
printer->Print(vars, "#include \"$filename_base$$message_header_ext$\"\n");
|
||||||
|
printer->Print(vars, file->additional_headers().c_str());
|
||||||
printer->Print(vars, "\n");
|
printer->Print(vars, "\n");
|
||||||
}
|
}
|
||||||
return output;
|
return output;
|
||||||
@@ -158,7 +159,6 @@ grpc::string GetHeaderIncludes(grpc_generator::File *file,
|
|||||||
printer->Print(vars, "namespace grpc {\n");
|
printer->Print(vars, "namespace grpc {\n");
|
||||||
printer->Print(vars, "class CompletionQueue;\n");
|
printer->Print(vars, "class CompletionQueue;\n");
|
||||||
printer->Print(vars, "class Channel;\n");
|
printer->Print(vars, "class Channel;\n");
|
||||||
printer->Print(vars, "class RpcService;\n");
|
|
||||||
printer->Print(vars, "class ServerCompletionQueue;\n");
|
printer->Print(vars, "class ServerCompletionQueue;\n");
|
||||||
printer->Print(vars, "class ServerContext;\n");
|
printer->Print(vars, "class ServerContext;\n");
|
||||||
printer->Print(vars, "} // namespace grpc\n\n");
|
printer->Print(vars, "} // namespace grpc\n\n");
|
||||||
@@ -183,25 +183,38 @@ void PrintHeaderClientMethodInterfaces(
|
|||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
(*vars)["Response"] = method->output_type_name();
|
(*vars)["Response"] = method->output_type_name();
|
||||||
|
|
||||||
|
struct {
|
||||||
|
grpc::string prefix;
|
||||||
|
grpc::string method_params; // extra arguments to method
|
||||||
|
grpc::string raw_args; // extra arguments to raw version of method
|
||||||
|
} async_prefixes[] = {{"Async", ", void* tag", ", tag"},
|
||||||
|
{"PrepareAsync", "", ""}};
|
||||||
|
|
||||||
if (is_public) {
|
if (is_public) {
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
|
"virtual ::grpc::Status $Method$(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, $Response$* response) = 0;\n");
|
"const $Request$& request, $Response$* response) = 0;\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"std::unique_ptr< "
|
"std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
|
"::grpc::ClientAsyncResponseReaderInterface< $Response$>> "
|
||||||
"Async$Method$(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, "
|
"const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq) {\n");
|
"::grpc::CompletionQueue* cq) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"return std::unique_ptr< "
|
"return std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
|
"::grpc::ClientAsyncResponseReaderInterface< $Response$>>("
|
||||||
"Async$Method$Raw(context, request, cq));\n");
|
"$AsyncPrefix$$Method$Raw(context, request, cq));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
} else if (ClientOnlyStreaming(method)) {
|
} else if (ClientOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
@@ -215,19 +228,27 @@ void PrintHeaderClientMethodInterfaces(
|
|||||||
"($Method$Raw(context, response));\n");
|
"($Method$Raw(context, response));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
|
"std::unique_ptr< ::grpc::ClientAsyncWriterInterface< $Request$>>"
|
||||||
" Async$Method$(::grpc::ClientContext* context, $Response$* "
|
" $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
|
||||||
|
"$Response$* "
|
||||||
"response, "
|
"response, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"return std::unique_ptr< "
|
"return std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncWriterInterface< $Request$>>("
|
"::grpc::ClientAsyncWriterInterface< $Request$>>("
|
||||||
"Async$Method$Raw(context, response, cq, tag));\n");
|
"$AsyncPrefix$$Method$Raw(context, response, "
|
||||||
|
"cq$AsyncRawArgs$));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
} else if (ServerOnlyStreaming(method)) {
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
@@ -241,19 +262,26 @@ void PrintHeaderClientMethodInterfaces(
|
|||||||
"($Method$Raw(context, request));\n");
|
"($Method$Raw(context, request));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
|
"std::unique_ptr< ::grpc::ClientAsyncReaderInterface< $Response$>> "
|
||||||
"Async$Method$("
|
"$AsyncPrefix$$Method$("
|
||||||
"::grpc::ClientContext* context, const $Request$& request, "
|
"::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"return std::unique_ptr< "
|
"return std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncReaderInterface< $Response$>>("
|
"::grpc::ClientAsyncReaderInterface< $Response$>>("
|
||||||
"Async$Method$Raw(context, request, cq, tag));\n");
|
"$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
|
"std::unique_ptr< ::grpc::ClientReaderWriterInterface< "
|
||||||
@@ -267,61 +295,89 @@ void PrintHeaderClientMethodInterfaces(
|
|||||||
"$Method$Raw(context));\n");
|
"$Method$Raw(context));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"std::unique_ptr< "
|
"std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
|
"::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>> "
|
||||||
"Async$Method$(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"return std::unique_ptr< "
|
"return std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
|
"::grpc::ClientAsyncReaderWriterInterface< $Request$, $Response$>>("
|
||||||
"Async$Method$Raw(context, cq, tag));\n");
|
"$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
|
"virtual ::grpc::ClientAsyncResponseReaderInterface< $Response$>* "
|
||||||
"Async$Method$Raw(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, "
|
"const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq) = 0;\n");
|
"::grpc::CompletionQueue* cq) = 0;\n");
|
||||||
|
}
|
||||||
} else if (ClientOnlyStreaming(method)) {
|
} else if (ClientOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"virtual ::grpc::ClientWriterInterface< $Request$>*"
|
"virtual ::grpc::ClientWriterInterface< $Request$>*"
|
||||||
" $Method$Raw("
|
" $Method$Raw("
|
||||||
"::grpc::ClientContext* context, $Response$* response) = 0;\n");
|
"::grpc::ClientContext* context, $Response$* response) = 0;\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
|
"virtual ::grpc::ClientAsyncWriterInterface< $Request$>*"
|
||||||
" Async$Method$Raw(::grpc::ClientContext* context, "
|
" $AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
|
||||||
"$Response$* response, "
|
"$Response$* response, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) = 0;\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
|
||||||
|
}
|
||||||
} else if (ServerOnlyStreaming(method)) {
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"virtual ::grpc::ClientReaderInterface< $Response$>* $Method$Raw("
|
"virtual ::grpc::ClientReaderInterface< $Response$>* "
|
||||||
|
"$Method$Raw("
|
||||||
"::grpc::ClientContext* context, const $Request$& request) = 0;\n");
|
"::grpc::ClientContext* context, const $Request$& request) = 0;\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
|
"virtual ::grpc::ClientAsyncReaderInterface< $Response$>* "
|
||||||
"Async$Method$Raw("
|
"$AsyncPrefix$$Method$Raw("
|
||||||
"::grpc::ClientContext* context, const $Request$& request, "
|
"::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) = 0;\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
|
||||||
|
}
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"virtual ::grpc::ClientReaderWriterInterface< $Request$, "
|
"virtual ::grpc::ClientReaderWriterInterface< $Request$, "
|
||||||
"$Response$>* "
|
"$Response$>* "
|
||||||
"$Method$Raw(::grpc::ClientContext* context) = 0;\n");
|
"$Method$Raw(::grpc::ClientContext* context) = 0;\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"virtual ::grpc::ClientAsyncReaderWriterInterface< "
|
"virtual ::grpc::ClientAsyncReaderWriterInterface< "
|
||||||
"$Request$, $Response$>* "
|
"$Request$, $Response$>* "
|
||||||
"Async$Method$Raw(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) = 0;\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) = 0;\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -333,25 +389,36 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
(*vars)["Response"] = method->output_type_name();
|
(*vars)["Response"] = method->output_type_name();
|
||||||
|
struct {
|
||||||
|
grpc::string prefix;
|
||||||
|
grpc::string method_params; // extra arguments to method
|
||||||
|
grpc::string raw_args; // extra arguments to raw version of method
|
||||||
|
} async_prefixes[] = {{"Async", ", void* tag", ", tag"},
|
||||||
|
{"PrepareAsync", "", ""}};
|
||||||
|
|
||||||
if (is_public) {
|
if (is_public) {
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"::grpc::Status $Method$(::grpc::ClientContext* context, "
|
"::grpc::Status $Method$(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, $Response$* response) override;\n");
|
"const $Request$& request, $Response$* response) override;\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
|
"std::unique_ptr< ::grpc::ClientAsyncResponseReader< $Response$>> "
|
||||||
"Async$Method$(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, "
|
"const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq) {\n");
|
"::grpc::CompletionQueue* cq) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"return std::unique_ptr< "
|
"return std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncResponseReader< $Response$>>("
|
"::grpc::ClientAsyncResponseReader< $Response$>>("
|
||||||
"Async$Method$Raw(context, request, cq));\n");
|
"$AsyncPrefix$$Method$Raw(context, request, cq));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
} else if (ClientOnlyStreaming(method)) {
|
} else if (ClientOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
@@ -364,18 +431,25 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||||||
"($Method$Raw(context, response));\n");
|
"($Method$Raw(context, response));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
|
"std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>"
|
||||||
" Async$Method$(::grpc::ClientContext* context, "
|
" $AsyncPrefix$$Method$(::grpc::ClientContext* context, "
|
||||||
"$Response$* response, "
|
"$Response$* response, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
|
"return std::unique_ptr< ::grpc::ClientAsyncWriter< $Request$>>("
|
||||||
"Async$Method$Raw(context, response, cq, tag));\n");
|
"$AsyncPrefix$$Method$Raw(context, response, "
|
||||||
|
"cq$AsyncRawArgs$));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
} else if (ServerOnlyStreaming(method)) {
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
@@ -389,19 +463,25 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||||||
"($Method$Raw(context, request));\n");
|
"($Method$Raw(context, request));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
|
"std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>> "
|
||||||
"Async$Method$("
|
"$AsyncPrefix$$Method$("
|
||||||
"::grpc::ClientContext* context, const $Request$& request, "
|
"::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
|
"return std::unique_ptr< ::grpc::ClientAsyncReader< $Response$>>("
|
||||||
"Async$Method$Raw(context, request, cq, tag));\n");
|
"$AsyncPrefix$$Method$Raw(context, request, cq$AsyncRawArgs$));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
}
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
@@ -414,53 +494,85 @@ void PrintHeaderClientMethod(grpc_generator::Printer *printer,
|
|||||||
"$Method$Raw(context));\n");
|
"$Method$Raw(context));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
|
"std::unique_ptr< ::grpc::ClientAsyncReaderWriter< "
|
||||||
"$Request$, $Response$>> "
|
"$Request$, $Response$>> "
|
||||||
"Async$Method$(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$(::grpc::ClientContext* context, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"return std::unique_ptr< "
|
"return std::unique_ptr< "
|
||||||
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
|
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>>("
|
||||||
"Async$Method$Raw(context, cq, tag));\n");
|
"$AsyncPrefix$$Method$Raw(context, cq$AsyncRawArgs$));\n");
|
||||||
printer->Outdent();
|
printer->Outdent();
|
||||||
printer->Print("}\n");
|
printer->Print("}\n");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"::grpc::ClientAsyncResponseReader< $Response$>* "
|
"::grpc::ClientAsyncResponseReader< $Response$>* "
|
||||||
"Async$Method$Raw(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, "
|
"const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq) override;\n");
|
"::grpc::CompletionQueue* cq) override;\n");
|
||||||
|
}
|
||||||
} else if (ClientOnlyStreaming(method)) {
|
} else if (ClientOnlyStreaming(method)) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"::grpc::ClientWriter< $Request$>* $Method$Raw("
|
"::grpc::ClientWriter< $Request$>* $Method$Raw("
|
||||||
"::grpc::ClientContext* context, $Response$* response) "
|
"::grpc::ClientContext* context, $Response$* response) "
|
||||||
"override;\n");
|
"override;\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
"::grpc::ClientAsyncWriter< $Request$>* Async$Method$Raw("
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
|
"::grpc::ClientAsyncWriter< $Request$>* $AsyncPrefix$$Method$Raw("
|
||||||
"::grpc::ClientContext* context, $Response$* response, "
|
"::grpc::ClientContext* context, $Response$* response, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) override;\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
|
||||||
|
}
|
||||||
} else if (ServerOnlyStreaming(method)) {
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"::grpc::ClientReader< $Response$>* $Method$Raw("
|
"::grpc::ClientReader< $Response$>* $Method$Raw("
|
||||||
"::grpc::ClientContext* context, const $Request$& request)"
|
"::grpc::ClientContext* context, const $Request$& request)"
|
||||||
" override;\n");
|
" override;\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"::grpc::ClientAsyncReader< $Response$>* Async$Method$Raw("
|
"::grpc::ClientAsyncReader< $Response$>* $AsyncPrefix$$Method$Raw("
|
||||||
"::grpc::ClientContext* context, const $Request$& request, "
|
"::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) override;\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
|
||||||
|
}
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
|
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
|
||||||
"$Method$Raw(::grpc::ClientContext* context) override;\n");
|
"$Method$Raw(::grpc::ClientContext* context) override;\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncRawArgs"] = async_prefix.raw_args;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
|
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
|
||||||
"Async$Method$Raw(::grpc::ClientContext* context, "
|
"$AsyncPrefix$$Method$Raw(::grpc::ClientContext* context, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) override;\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) override;\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -469,7 +581,8 @@ void PrintHeaderClientMethodData(grpc_generator::Printer *printer,
|
|||||||
const grpc_generator::Method *method,
|
const grpc_generator::Method *method,
|
||||||
std::map<grpc::string, grpc::string> *vars) {
|
std::map<grpc::string, grpc::string> *vars) {
|
||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
printer->Print(*vars, "const ::grpc::RpcMethod rpcmethod_$Method$_;\n");
|
printer->Print(*vars,
|
||||||
|
"const ::grpc::internal::RpcMethod rpcmethod_$Method$_;\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
|
void PrintHeaderServerMethodSync(grpc_generator::Printer *printer,
|
||||||
@@ -641,7 +754,7 @@ void PrintHeaderServerMethodStreamedUnary(
|
|||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"WithStreamedUnaryMethod_$Method$() {\n"
|
"WithStreamedUnaryMethod_$Method$() {\n"
|
||||||
" ::grpc::Service::MarkMethodStreamed($Idx$,\n"
|
" ::grpc::Service::MarkMethodStreamed($Idx$,\n"
|
||||||
" new ::grpc::StreamedUnaryHandler< $Request$, "
|
" new ::grpc::internal::StreamedUnaryHandler< $Request$, "
|
||||||
"$Response$>(std::bind"
|
"$Response$>(std::bind"
|
||||||
"(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
|
"(&WithStreamedUnaryMethod_$Method$<BaseClass>::"
|
||||||
"Streamed$Method$, this, std::placeholders::_1, "
|
"Streamed$Method$, this, std::placeholders::_1, "
|
||||||
@@ -689,10 +802,11 @@ void PrintHeaderServerMethodSplitStreaming(
|
|||||||
"{}\n");
|
"{}\n");
|
||||||
printer->Print(" public:\n");
|
printer->Print(" public:\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"WithSplitStreamingMethod_$Method$() {\n"
|
"WithSplitStreamingMethod_$Method$() {\n"
|
||||||
" ::grpc::Service::MarkMethodStreamed($Idx$,\n"
|
" ::grpc::Service::MarkMethodStreamed($Idx$,\n"
|
||||||
" new ::grpc::SplitServerStreamingHandler< $Request$, "
|
" new ::grpc::internal::SplitServerStreamingHandler< $Request$, "
|
||||||
"$Response$>(std::bind"
|
"$Response$>(std::bind"
|
||||||
"(&WithSplitStreamingMethod_$Method$<BaseClass>::"
|
"(&WithSplitStreamingMethod_$Method$<BaseClass>::"
|
||||||
"Streamed$Method$, this, std::placeholders::_1, "
|
"Streamed$Method$, this, std::placeholders::_1, "
|
||||||
@@ -837,7 +951,8 @@ void PrintHeaderService(grpc_generator::Printer *printer,
|
|||||||
" {\n public:\n");
|
" {\n public:\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(
|
printer->Print(
|
||||||
"Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel);\n");
|
"Stub(const std::shared_ptr< ::grpc::ChannelInterface>& "
|
||||||
|
"channel);\n");
|
||||||
for (int i = 0; i < service->method_count(); ++i) {
|
for (int i = 0; i < service->method_count(); ++i) {
|
||||||
PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
|
PrintHeaderClientMethod(printer, service->method(i).get(), vars, true);
|
||||||
}
|
}
|
||||||
@@ -1095,101 +1210,139 @@ void PrintSourceClientMethod(grpc_generator::Printer *printer,
|
|||||||
(*vars)["Method"] = method->name();
|
(*vars)["Method"] = method->name();
|
||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
(*vars)["Response"] = method->output_type_name();
|
(*vars)["Response"] = method->output_type_name();
|
||||||
|
struct {
|
||||||
|
grpc::string prefix;
|
||||||
|
grpc::string start; // bool literal expressed as string
|
||||||
|
grpc::string method_params; // extra arguments to method
|
||||||
|
grpc::string create_args; // extra arguments to creator
|
||||||
|
} async_prefixes[] = {{"Async", "true", ", void* tag", ", tag"},
|
||||||
|
{"PrepareAsync", "false", "", ", nullptr"}};
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"::grpc::Status $ns$$Service$::Stub::$Method$("
|
"::grpc::Status $ns$$Service$::Stub::$Method$("
|
||||||
"::grpc::ClientContext* context, "
|
"::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, $Response$* response) {\n");
|
"const $Request$& request, $Response$* response) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
" return ::grpc::BlockingUnaryCall(channel_.get(), "
|
" return ::grpc::internal::BlockingUnaryCall"
|
||||||
"rpcmethod_$Method$_, "
|
"(channel_.get(), rpcmethod_$Method$_, "
|
||||||
"context, request, response);\n"
|
"context, request, response);\n}\n\n");
|
||||||
"}\n\n");
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
printer->Print(
|
auto& async_prefix = async_prefixes[i];
|
||||||
*vars,
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncStart"] = async_prefix.start;
|
||||||
|
printer->Print(*vars,
|
||||||
"::grpc::ClientAsyncResponseReader< $Response$>* "
|
"::grpc::ClientAsyncResponseReader< $Response$>* "
|
||||||
"$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
|
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
|
||||||
|
"ClientContext* context, "
|
||||||
"const $Request$& request, "
|
"const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq) {\n");
|
"::grpc::CompletionQueue* cq) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
|
*vars,
|
||||||
" return "
|
" return "
|
||||||
"::grpc::ClientAsyncResponseReader< $Response$>::Create("
|
"::grpc::internal::ClientAsyncResponseReaderFactory< $Response$>"
|
||||||
"channel_.get(), cq, "
|
"::Create(channel_.get(), cq, "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context, request);\n"
|
"context, request, $AsyncStart$);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
|
}
|
||||||
} else if (ClientOnlyStreaming(method)) {
|
} else if (ClientOnlyStreaming(method)) {
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"::grpc::ClientWriter< $Request$>* "
|
"::grpc::ClientWriter< $Request$>* "
|
||||||
"$ns$$Service$::Stub::$Method$Raw("
|
"$ns$$Service$::Stub::$Method$Raw("
|
||||||
"::grpc::ClientContext* context, $Response$* response) {\n");
|
"::grpc::ClientContext* context, $Response$* response) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
" return new ::grpc::ClientWriter< $Request$>("
|
*vars,
|
||||||
|
" return ::grpc::internal::ClientWriterFactory< $Request$>::Create("
|
||||||
"channel_.get(), "
|
"channel_.get(), "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context, response);\n"
|
"context, response);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncStart"] = async_prefix.start;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncCreateArgs"] = async_prefix.create_args;
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"::grpc::ClientAsyncWriter< $Request$>* "
|
"::grpc::ClientAsyncWriter< $Request$>* "
|
||||||
"$ns$$Service$::Stub::Async$Method$Raw("
|
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
|
||||||
"::grpc::ClientContext* context, $Response$* response, "
|
"::grpc::ClientContext* context, $Response$* response, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
" return ::grpc::ClientAsyncWriter< $Request$>::Create("
|
*vars,
|
||||||
"channel_.get(), cq, "
|
" return ::grpc::internal::ClientAsyncWriterFactory< $Request$>"
|
||||||
|
"::Create(channel_.get(), cq, "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context, response, tag);\n"
|
"context, response, $AsyncStart$$AsyncCreateArgs$);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
|
}
|
||||||
} else if (ServerOnlyStreaming(method)) {
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"::grpc::ClientReader< $Response$>* "
|
"::grpc::ClientReader< $Response$>* "
|
||||||
"$ns$$Service$::Stub::$Method$Raw("
|
"$ns$$Service$::Stub::$Method$Raw("
|
||||||
"::grpc::ClientContext* context, const $Request$& request) {\n");
|
"::grpc::ClientContext* context, const $Request$& request) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
" return new ::grpc::ClientReader< $Response$>("
|
*vars,
|
||||||
|
" return ::grpc::internal::ClientReaderFactory< $Response$>::Create("
|
||||||
"channel_.get(), "
|
"channel_.get(), "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context, request);\n"
|
"context, request);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncStart"] = async_prefix.start;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncCreateArgs"] = async_prefix.create_args;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
"::grpc::ClientAsyncReader< $Response$>* "
|
"::grpc::ClientAsyncReader< $Response$>* "
|
||||||
"$ns$$Service$::Stub::Async$Method$Raw("
|
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw("
|
||||||
"::grpc::ClientContext* context, const $Request$& request, "
|
"::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(
|
||||||
" return ::grpc::ClientAsyncReader< $Response$>::Create("
|
*vars,
|
||||||
"channel_.get(), cq, "
|
" return ::grpc::internal::ClientAsyncReaderFactory< $Response$>"
|
||||||
|
"::Create(channel_.get(), cq, "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context, request, tag);\n"
|
"context, request, $AsyncStart$$AsyncCreateArgs$);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
|
}
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
|
"::grpc::ClientReaderWriter< $Request$, $Response$>* "
|
||||||
"$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
|
"$ns$$Service$::Stub::$Method$Raw(::grpc::ClientContext* context) {\n");
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
" return new ::grpc::ClientReaderWriter< "
|
" return ::grpc::internal::ClientReaderWriterFactory< "
|
||||||
"$Request$, $Response$>("
|
"$Request$, $Response$>::Create("
|
||||||
"channel_.get(), "
|
"channel_.get(), "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context);\n"
|
"context);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
printer->Print(
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
*vars,
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncStart"] = async_prefix.start;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["AsyncCreateArgs"] = async_prefix.create_args;
|
||||||
|
printer->Print(*vars,
|
||||||
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
|
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>* "
|
||||||
"$ns$$Service$::Stub::Async$Method$Raw(::grpc::ClientContext* context, "
|
"$ns$$Service$::Stub::$AsyncPrefix$$Method$Raw(::grpc::"
|
||||||
"::grpc::CompletionQueue* cq, void* tag) {\n");
|
"ClientContext* context, "
|
||||||
printer->Print(
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$) {\n");
|
||||||
*vars,
|
printer->Print(*vars,
|
||||||
" return "
|
" return "
|
||||||
"::grpc::ClientAsyncReaderWriter< $Request$, $Response$>::Create("
|
"::grpc::internal::ClientAsyncReaderWriterFactory< "
|
||||||
|
"$Request$, $Response$>::Create("
|
||||||
"channel_.get(), cq, "
|
"channel_.get(), cq, "
|
||||||
"rpcmethod_$Method$_, "
|
"rpcmethod_$Method$_, "
|
||||||
"context, tag);\n"
|
"context, $AsyncStart$$AsyncCreateArgs$);\n"
|
||||||
"}\n\n");
|
"}\n\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void PrintSourceServerMethod(grpc_generator::Printer *printer,
|
void PrintSourceServerMethod(grpc_generator::Printer *printer,
|
||||||
const grpc_generator::Method *method,
|
const grpc_generator::Method *method,
|
||||||
@@ -1297,7 +1450,7 @@ void PrintSourceService(grpc_generator::Printer *printer,
|
|||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
", rpcmethod_$Method$_("
|
", rpcmethod_$Method$_("
|
||||||
"$prefix$$Service$_method_names[$Idx$], "
|
"$prefix$$Service$_method_names[$Idx$], "
|
||||||
"::grpc::RpcMethod::$StreamingType$, "
|
"::grpc::internal::RpcMethod::$StreamingType$, "
|
||||||
"channel"
|
"channel"
|
||||||
")\n");
|
")\n");
|
||||||
}
|
}
|
||||||
@@ -1320,38 +1473,38 @@ void PrintSourceService(grpc_generator::Printer *printer,
|
|||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"AddMethod(new ::grpc::RpcServiceMethod(\n"
|
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
|
||||||
" $prefix$$Service$_method_names[$Idx$],\n"
|
" $prefix$$Service$_method_names[$Idx$],\n"
|
||||||
" ::grpc::RpcMethod::NORMAL_RPC,\n"
|
" ::grpc::internal::RpcMethod::NORMAL_RPC,\n"
|
||||||
" new ::grpc::RpcMethodHandler< $ns$$Service$::Service, "
|
" new ::grpc::internal::RpcMethodHandler< $ns$$Service$::Service, "
|
||||||
"$Request$, "
|
"$Request$, "
|
||||||
"$Response$>(\n"
|
"$Response$>(\n"
|
||||||
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
||||||
} else if (ClientOnlyStreaming(method.get())) {
|
} else if (ClientOnlyStreaming(method.get())) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"AddMethod(new ::grpc::RpcServiceMethod(\n"
|
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
|
||||||
" $prefix$$Service$_method_names[$Idx$],\n"
|
" $prefix$$Service$_method_names[$Idx$],\n"
|
||||||
" ::grpc::RpcMethod::CLIENT_STREAMING,\n"
|
" ::grpc::internal::RpcMethod::CLIENT_STREAMING,\n"
|
||||||
" new ::grpc::ClientStreamingHandler< "
|
" new ::grpc::internal::ClientStreamingHandler< "
|
||||||
"$ns$$Service$::Service, $Request$, $Response$>(\n"
|
"$ns$$Service$::Service, $Request$, $Response$>(\n"
|
||||||
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
||||||
} else if (ServerOnlyStreaming(method.get())) {
|
} else if (ServerOnlyStreaming(method.get())) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"AddMethod(new ::grpc::RpcServiceMethod(\n"
|
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
|
||||||
" $prefix$$Service$_method_names[$Idx$],\n"
|
" $prefix$$Service$_method_names[$Idx$],\n"
|
||||||
" ::grpc::RpcMethod::SERVER_STREAMING,\n"
|
" ::grpc::internal::RpcMethod::SERVER_STREAMING,\n"
|
||||||
" new ::grpc::ServerStreamingHandler< "
|
" new ::grpc::internal::ServerStreamingHandler< "
|
||||||
"$ns$$Service$::Service, $Request$, $Response$>(\n"
|
"$ns$$Service$::Service, $Request$, $Response$>(\n"
|
||||||
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"AddMethod(new ::grpc::RpcServiceMethod(\n"
|
"AddMethod(new ::grpc::internal::RpcServiceMethod(\n"
|
||||||
" $prefix$$Service$_method_names[$Idx$],\n"
|
" $prefix$$Service$_method_names[$Idx$],\n"
|
||||||
" ::grpc::RpcMethod::BIDI_STREAMING,\n"
|
" ::grpc::internal::RpcMethod::BIDI_STREAMING,\n"
|
||||||
" new ::grpc::BidiStreamingHandler< "
|
" new ::grpc::internal::BidiStreamingHandler< "
|
||||||
"$ns$$Service$::Service, $Request$, $Response$>(\n"
|
"$ns$$Service$::Service, $Request$, $Response$>(\n"
|
||||||
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
" std::mem_fn(&$ns$$Service$::Service::$Method$), this)));\n");
|
||||||
}
|
}
|
||||||
@@ -1452,7 +1605,8 @@ grpc::string GetMockIncludes(grpc_generator::File *file,
|
|||||||
|
|
||||||
static const char *headers_strs[] = {
|
static const char *headers_strs[] = {
|
||||||
"grpc++/impl/codegen/async_stream.h",
|
"grpc++/impl/codegen/async_stream.h",
|
||||||
"grpc++/impl/codegen/sync_stream.h", "gmock/gmock.h",
|
"grpc++/impl/codegen/sync_stream.h",
|
||||||
|
"gmock/gmock.h",
|
||||||
};
|
};
|
||||||
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
|
std::vector<grpc::string> headers(headers_strs, array_end(headers_strs));
|
||||||
PrintIncludes(printer.get(), headers, params);
|
PrintIncludes(printer.get(), headers, params);
|
||||||
@@ -1478,50 +1632,83 @@ void PrintMockClientMethods(grpc_generator::Printer *printer,
|
|||||||
(*vars)["Request"] = method->input_type_name();
|
(*vars)["Request"] = method->input_type_name();
|
||||||
(*vars)["Response"] = method->output_type_name();
|
(*vars)["Response"] = method->output_type_name();
|
||||||
|
|
||||||
|
struct {
|
||||||
|
grpc::string prefix;
|
||||||
|
grpc::string method_params; // extra arguments to method
|
||||||
|
int extra_method_param_count;
|
||||||
|
} async_prefixes[] = {{"Async", ", void* tag", 1}, {"PrepareAsync", "", 0}};
|
||||||
|
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
|
"MOCK_METHOD3($Method$, ::grpc::Status(::grpc::ClientContext* context, "
|
||||||
"const $Request$& request, $Response$* response));\n");
|
"const $Request$& request, $Response$* response));\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
"MOCK_METHOD3(Async$Method$Raw, "
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
|
"MOCK_METHOD3($AsyncPrefix$$Method$Raw, "
|
||||||
"::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
|
"::grpc::ClientAsyncResponseReaderInterface< $Response$>*"
|
||||||
"(::grpc::ClientContext* context, const $Request$& request, "
|
"(::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq));\n");
|
"::grpc::CompletionQueue* cq));\n");
|
||||||
|
}
|
||||||
} else if (ClientOnlyStreaming(method)) {
|
} else if (ClientOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"MOCK_METHOD2($Method$Raw, "
|
"MOCK_METHOD2($Method$Raw, "
|
||||||
"::grpc::ClientWriterInterface< $Request$>*"
|
"::grpc::ClientWriterInterface< $Request$>*"
|
||||||
"(::grpc::ClientContext* context, $Response$* response));\n");
|
"(::grpc::ClientContext* context, $Response$* response));\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["MockArgs"] =
|
||||||
|
flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
|
||||||
printer->Print(*vars,
|
printer->Print(*vars,
|
||||||
"MOCK_METHOD4(Async$Method$Raw, "
|
"MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
|
||||||
"::grpc::ClientAsyncWriterInterface< $Request$>*"
|
"::grpc::ClientAsyncWriterInterface< $Request$>*"
|
||||||
"(::grpc::ClientContext* context, $Response$* response, "
|
"(::grpc::ClientContext* context, $Response$* response, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag));\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
|
||||||
|
}
|
||||||
} else if (ServerOnlyStreaming(method)) {
|
} else if (ServerOnlyStreaming(method)) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"MOCK_METHOD2($Method$Raw, "
|
"MOCK_METHOD2($Method$Raw, "
|
||||||
"::grpc::ClientReaderInterface< $Response$>*"
|
"::grpc::ClientReaderInterface< $Response$>*"
|
||||||
"(::grpc::ClientContext* context, const $Request$& request));\n");
|
"(::grpc::ClientContext* context, const $Request$& request));\n");
|
||||||
printer->Print(*vars,
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
"MOCK_METHOD4(Async$Method$Raw, "
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["MockArgs"] =
|
||||||
|
flatbuffers::NumToString(3 + async_prefix.extra_method_param_count);
|
||||||
|
printer->Print(
|
||||||
|
*vars,
|
||||||
|
"MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
|
||||||
"::grpc::ClientAsyncReaderInterface< $Response$>*"
|
"::grpc::ClientAsyncReaderInterface< $Response$>*"
|
||||||
"(::grpc::ClientContext* context, const $Request$& request, "
|
"(::grpc::ClientContext* context, const $Request$& request, "
|
||||||
"::grpc::CompletionQueue* cq, void* tag));\n");
|
"::grpc::CompletionQueue* cq$AsyncMethodParams$));\n");
|
||||||
|
}
|
||||||
} else if (method->BidiStreaming()) {
|
} else if (method->BidiStreaming()) {
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"MOCK_METHOD1($Method$Raw, "
|
"MOCK_METHOD1($Method$Raw, "
|
||||||
"::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
|
"::grpc::ClientReaderWriterInterface< $Request$, $Response$>*"
|
||||||
"(::grpc::ClientContext* context));\n");
|
"(::grpc::ClientContext* context));\n");
|
||||||
|
for (size_t i = 0; i < sizeof(async_prefixes)/sizeof(async_prefixes[0]); i ++) {
|
||||||
|
auto& async_prefix = async_prefixes[i];
|
||||||
|
(*vars)["AsyncPrefix"] = async_prefix.prefix;
|
||||||
|
(*vars)["AsyncMethodParams"] = async_prefix.method_params;
|
||||||
|
(*vars)["MockArgs"] =
|
||||||
|
flatbuffers::NumToString(2 + async_prefix.extra_method_param_count);
|
||||||
printer->Print(
|
printer->Print(
|
||||||
*vars,
|
*vars,
|
||||||
"MOCK_METHOD3(Async$Method$Raw, "
|
"MOCK_METHOD$MockArgs$($AsyncPrefix$$Method$Raw, "
|
||||||
"::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
|
"::grpc::ClientAsyncReaderWriterInterface<$Request$, $Response$>*"
|
||||||
"(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq, "
|
"(::grpc::ClientContext* context, ::grpc::CompletionQueue* cq"
|
||||||
"void* tag));\n");
|
"$AsyncMethodParams$));\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ void GenerateServerMethod(const grpc_generator::Method *method, grpc_generator::
|
|||||||
vars["Method"] = exportName(method->name());
|
vars["Method"] = exportName(method->name());
|
||||||
vars["Request"] = method->get_input_type_name();
|
vars["Request"] = method->get_input_type_name();
|
||||||
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
|
vars["Response"] = (vars["CustomMethodIO"] == "") ? method->get_output_type_name() : vars["CustomMethodIO"];
|
||||||
vars["FullMethodName"] = "/" + vars["Package"] + "." + vars["Service"] + "/" + vars["Method"];
|
vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
|
||||||
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
vars["Handler"] = "_" + vars["Service"] + "_" + vars["Method"] + "_Handler";
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
|
printer->Print(vars, "func $Handler$(srv interface{}, ctx $context$.Context,\n\tdec func(interface{}) error, interceptor $grpc$.UnaryServerInterceptor) (interface{}, error) {\n");
|
||||||
@@ -223,7 +223,7 @@ void GenerateClientMethod(const grpc_generator::Method *method, grpc_generator::
|
|||||||
vars["Method"] = exportName(method->name());
|
vars["Method"] = exportName(method->name());
|
||||||
vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
|
vars["Request"] = (vars["CustomMethodIO"] == "") ? method->get_input_type_name() : vars["CustomMethodIO"];
|
||||||
vars["Response"] = method->get_output_type_name();
|
vars["Response"] = method->get_output_type_name();
|
||||||
vars["FullMethodName"] = "/" + vars["Package"] + "." + vars["Service"] + "/" + vars["Method"];
|
vars["FullMethodName"] = "/" + vars["ServicePrefix"] + "." + vars["Service"] + "/" + vars["Method"];
|
||||||
if (method->NoStreaming()) {
|
if (method->NoStreaming()) {
|
||||||
printer->Print(vars, "out := new($Response$)\n");
|
printer->Print(vars, "out := new($Response$)\n");
|
||||||
printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
|
printer->Print(vars, "err := $grpc$.Invoke(ctx, \"$FullMethodName$\", in, out, c.cc, opts...)\n");
|
||||||
@@ -374,7 +374,7 @@ void GenerateService(const grpc_generator::Service *service, grpc_generator::Pri
|
|||||||
//Service Descriptor
|
//Service Descriptor
|
||||||
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
|
printer->Print(vars, "var $ServiceDesc$ = $grpc$.ServiceDesc{\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
printer->Print(vars, "ServiceName: \"$Package$.$Service$\",\n");
|
printer->Print(vars, "ServiceName: \"$ServicePrefix$.$Service$\",\n");
|
||||||
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
|
printer->Print(vars, "HandlerType: (*$Service$Server)(nil),\n");
|
||||||
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
|
printer->Print(vars, "Methods: []$grpc$.MethodDesc{\n");
|
||||||
printer->Indent();
|
printer->Indent();
|
||||||
@@ -433,6 +433,7 @@ grpc::string GenerateServiceSource(grpc_generator::File *file,
|
|||||||
auto printer = p.get();
|
auto printer = p.get();
|
||||||
std::map<grpc::string, grpc::string> vars;
|
std::map<grpc::string, grpc::string> vars;
|
||||||
vars["Package"] = parameters->package_name;
|
vars["Package"] = parameters->package_name;
|
||||||
|
vars["ServicePrefix"] = parameters->service_prefix;
|
||||||
vars["grpc"] = "grpc";
|
vars["grpc"] = "grpc";
|
||||||
vars["context"] = "context";
|
vars["context"] = "context";
|
||||||
GenerateImports(file, printer, vars);
|
GenerateImports(file, printer, vars);
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ struct Parameters {
|
|||||||
|
|
||||||
//Package name for the service
|
//Package name for the service
|
||||||
grpc::string package_name;
|
grpc::string package_name;
|
||||||
|
|
||||||
|
//Prefix for RPC Calls
|
||||||
|
grpc::string service_prefix;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return the source of the generated service file.
|
// Return the source of the generated service file.
|
||||||
|
|||||||
1137
grpc/src/compiler/java_generator.cc
Normal file
1137
grpc/src/compiler/java_generator.cc
Normal file
File diff suppressed because it is too large
Load Diff
85
grpc/src/compiler/java_generator.h
Normal file
85
grpc/src/compiler/java_generator.h
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2016 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NET_GRPC_COMPILER_JAVA_GENERATOR_H_
|
||||||
|
#define NET_GRPC_COMPILER_JAVA_GENERATOR_H_
|
||||||
|
|
||||||
|
#include <stdlib.h> // for abort()
|
||||||
|
#include <iostream>
|
||||||
|
#include <map>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "src/compiler/schema_interface.h"
|
||||||
|
|
||||||
|
class LogMessageVoidify {
|
||||||
|
public:
|
||||||
|
LogMessageVoidify() {}
|
||||||
|
// This has to be an operator with a precedence lower than << but
|
||||||
|
// higher than ?:
|
||||||
|
void operator&(std::ostream&) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class LogHelper {
|
||||||
|
std::ostream* os_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
LogHelper(std::ostream* os) : os_(os) {}
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning( \
|
||||||
|
disable : 4722) // the flow of control terminates in a destructor
|
||||||
|
// (needed to compile ~LogHelper where destructor emits abort intentionally -
|
||||||
|
// inherited from grpc/java code generator).
|
||||||
|
#endif
|
||||||
|
~LogHelper() {
|
||||||
|
*os_ << std::endl;
|
||||||
|
::abort();
|
||||||
|
}
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
std::ostream& get_os() const { return *os_; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// Abort the program after logging the mesage if the given condition is not
|
||||||
|
// true. Otherwise, do nothing.
|
||||||
|
#define GRPC_CODEGEN_CHECK(x) \
|
||||||
|
(x) ? (void)0 \
|
||||||
|
: LogMessageVoidify() & LogHelper(&std::cerr).get_os() \
|
||||||
|
<< "CHECK FAILED: " << __FILE__ << ":" \
|
||||||
|
<< __LINE__ << ": "
|
||||||
|
|
||||||
|
// Abort the program after logging the mesage.
|
||||||
|
#define GRPC_CODEGEN_FAIL GRPC_CODEGEN_CHECK(false)
|
||||||
|
|
||||||
|
namespace grpc_java_generator {
|
||||||
|
struct Parameters {
|
||||||
|
// //Defines the custom parameter types for methods
|
||||||
|
// //eg: flatbuffers uses flatbuffers.Builder as input for the client
|
||||||
|
// and output for the server grpc::string custom_method_io_type;
|
||||||
|
|
||||||
|
// Package name for the service
|
||||||
|
grpc::string package_name;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Return the source of the generated service file.
|
||||||
|
grpc::string GenerateServiceSource(grpc_generator::File* file,
|
||||||
|
const grpc_generator::Service* service,
|
||||||
|
grpc_java_generator::Parameters* parameters);
|
||||||
|
|
||||||
|
} // namespace grpc_java_generator
|
||||||
|
|
||||||
|
#endif // NET_GRPC_COMPILER_JAVA_GENERATOR_H_
|
||||||
119
grpc/tests/JavaGrpcTest.java
Normal file
119
grpc/tests/JavaGrpcTest.java
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2014 Google Inc. All rights reserved.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import MyGame.Example.Monster;
|
||||||
|
import MyGame.Example.MonsterStorageGrpc;
|
||||||
|
import MyGame.Example.Stat;
|
||||||
|
import com.google.flatbuffers.FlatBufferBuilder;
|
||||||
|
import io.grpc.ManagedChannel;
|
||||||
|
import io.grpc.ManagedChannelBuilder;
|
||||||
|
import io.grpc.Server;
|
||||||
|
import io.grpc.ServerBuilder;
|
||||||
|
import org.junit.Assert;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrates basic client-server interaction using grpc-java over netty.
|
||||||
|
*/
|
||||||
|
public class JavaGrpcTest {
|
||||||
|
static final String BIG_MONSTER_NAME = "big-monster";
|
||||||
|
static final short nestedMonsterHp = 600;
|
||||||
|
static final short nestedMonsterMana = 1024;
|
||||||
|
static final int numStreamedMsgs = 10;
|
||||||
|
|
||||||
|
static class MyService extends MonsterStorageGrpc.MonsterStorageImplBase {
|
||||||
|
@Override
|
||||||
|
public void store(Monster request, io.grpc.stub.StreamObserver<Stat> responseObserver) {
|
||||||
|
Assert.assertEquals(request.name(), BIG_MONSTER_NAME);
|
||||||
|
Assert.assertEquals(request.hp(), nestedMonsterHp);
|
||||||
|
Assert.assertEquals(request.mana(), nestedMonsterMana);
|
||||||
|
System.out.println("Received store request from " + request.name());
|
||||||
|
// Create a response from the incoming request name.
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
int statOffset = Stat.createStat(builder, builder.createString("Hello " + request.name()), 100, 10);
|
||||||
|
builder.finish(statOffset);
|
||||||
|
Stat stat = Stat.getRootAsStat(builder.dataBuffer());
|
||||||
|
responseObserver.onNext(stat);
|
||||||
|
responseObserver.onCompleted();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void retrieve(Stat request, io.grpc.stub.StreamObserver<Monster> responseObserver) {
|
||||||
|
// Create 10 monsters for streaming response.
|
||||||
|
for (int i=0; i<numStreamedMsgs; i++) {
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
int i1 = builder.createString(request.id() + " No." + i);
|
||||||
|
Monster.startMonster(builder);
|
||||||
|
Monster.addName(builder, i1);
|
||||||
|
int i2 = Monster.endMonster(builder);
|
||||||
|
Monster.finishMonsterBuffer(builder, i2);
|
||||||
|
Monster monster = Monster.getRootAsMonster(builder.dataBuffer());
|
||||||
|
responseObserver.onNext(monster);
|
||||||
|
}
|
||||||
|
responseObserver.onCompleted();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static int startServer() throws IOException {
|
||||||
|
Server server = ServerBuilder.forPort(0).addService(new MyService()).build().start();
|
||||||
|
return server.getPort();
|
||||||
|
}
|
||||||
|
|
||||||
|
@org.junit.Test
|
||||||
|
public void testMonster() throws IOException {
|
||||||
|
int port = startServer();
|
||||||
|
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", port)
|
||||||
|
// Channels are secure by default (via SSL/TLS). For the example we disable TLS to avoid
|
||||||
|
// needing certificates.
|
||||||
|
.usePlaintext(true)
|
||||||
|
.directExecutor()
|
||||||
|
.build();
|
||||||
|
|
||||||
|
MonsterStorageGrpc.MonsterStorageBlockingStub stub = MonsterStorageGrpc.newBlockingStub(channel);
|
||||||
|
|
||||||
|
FlatBufferBuilder builder = new FlatBufferBuilder();
|
||||||
|
|
||||||
|
int o_string = builder.createString(BIG_MONSTER_NAME);
|
||||||
|
Monster.startMonster(builder);
|
||||||
|
Monster.addName(builder, o_string);
|
||||||
|
Monster.addHp(builder, nestedMonsterHp);
|
||||||
|
Monster.addMana(builder, nestedMonsterMana);
|
||||||
|
int monster1 = Monster.endMonster(builder);
|
||||||
|
Monster.finishMonsterBuffer(builder, monster1);
|
||||||
|
|
||||||
|
ByteBuffer buffer = builder.dataBuffer();
|
||||||
|
Monster monsterRequest = Monster.getRootAsMonster(buffer);
|
||||||
|
Stat stat = stub.store(monsterRequest);
|
||||||
|
Assert.assertEquals(stat.id(), "Hello " + BIG_MONSTER_NAME);
|
||||||
|
System.out.println("Received stat response from service: " + stat.id());
|
||||||
|
|
||||||
|
|
||||||
|
Iterator<Monster> iterator = stub.retrieve(stat);
|
||||||
|
int counter = 0;
|
||||||
|
while(iterator.hasNext()) {
|
||||||
|
Monster m = iterator.next();
|
||||||
|
System.out.println("Received monster " + m.name());
|
||||||
|
counter ++;
|
||||||
|
}
|
||||||
|
Assert.assertEquals(counter, numStreamedMsgs);
|
||||||
|
System.out.println("FlatBuffers GRPC client/server test: completed successfully");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,41 +18,45 @@
|
|||||||
|
|
||||||
#include <grpc++/grpc++.h>
|
#include <grpc++/grpc++.h>
|
||||||
|
|
||||||
#include "monster_test_generated.h"
|
|
||||||
#include "monster_test.grpc.fb.h"
|
#include "monster_test.grpc.fb.h"
|
||||||
|
#include "monster_test_generated.h"
|
||||||
|
#include "test_assert.h"
|
||||||
|
|
||||||
using namespace MyGame::Example;
|
using namespace MyGame::Example;
|
||||||
|
void message_builder_tests();
|
||||||
|
|
||||||
// The callback implementation of our server, that derives from the generated
|
// The callback implementation of our server, that derives from the generated
|
||||||
// code. It implements all rpcs specified in the FlatBuffers schema.
|
// code. It implements all rpcs specified in the FlatBuffers schema.
|
||||||
class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
class ServiceImpl final : public MyGame::Example::MonsterStorage::Service {
|
||||||
virtual ::grpc::Status Store(::grpc::ServerContext* context,
|
virtual ::grpc::Status Store(
|
||||||
|
::grpc::ServerContext *context,
|
||||||
const flatbuffers::grpc::Message<Monster> *request,
|
const flatbuffers::grpc::Message<Monster> *request,
|
||||||
flatbuffers::grpc::Message<Stat> *response)
|
flatbuffers::grpc::Message<Stat> *response) override {
|
||||||
override {
|
|
||||||
// Create a response from the incoming request name.
|
// Create a response from the incoming request name.
|
||||||
fbb_.Clear();
|
fbb_.Clear();
|
||||||
auto stat_offset = CreateStat(fbb_, fbb_.CreateString("Hello, " +
|
auto stat_offset = CreateStat(
|
||||||
request->GetRoot()->name()->str()));
|
fbb_, fbb_.CreateString("Hello, " + request->GetRoot()->name()->str()));
|
||||||
fbb_.Finish(stat_offset);
|
fbb_.Finish(stat_offset);
|
||||||
// Transfer ownership of the message to gRPC
|
// Transfer ownership of the message to gRPC
|
||||||
*response = fbb_.ReleaseMessage<Stat>();
|
*response = fbb_.ReleaseMessage<Stat>();
|
||||||
return grpc::Status::OK;
|
return grpc::Status::OK;
|
||||||
}
|
}
|
||||||
virtual ::grpc::Status Retrieve(::grpc::ServerContext *context,
|
virtual ::grpc::Status Retrieve(
|
||||||
|
::grpc::ServerContext *context,
|
||||||
const flatbuffers::grpc::Message<Stat> *request,
|
const flatbuffers::grpc::Message<Stat> *request,
|
||||||
::grpc::ServerWriter<flatbuffers::grpc::Message<Monster>> *writer)
|
::grpc::ServerWriter<flatbuffers::grpc::Message<Monster>> *writer)
|
||||||
override {
|
override {
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
fbb_.Clear();
|
fbb_.Clear();
|
||||||
// Create 10 monsters for resposne.
|
// Create 10 monsters for resposne.
|
||||||
auto monster_offset =
|
auto monster_offset =
|
||||||
CreateMonster(fbb_, 0, 0, 0, fbb_.CreateString(
|
CreateMonster(fbb_, 0, 0, 0,
|
||||||
request->GetRoot()->id()->str() + " No." + std::to_string(i)));
|
fbb_.CreateString(request->GetRoot()->id()->str() +
|
||||||
|
" No." + std::to_string(i)));
|
||||||
fbb_.Finish(monster_offset);
|
fbb_.Finish(monster_offset);
|
||||||
|
|
||||||
flatbuffers::grpc::Message<Monster> monster = fbb_.ReleaseMessage<Monster>();
|
flatbuffers::grpc::Message<Monster> monster =
|
||||||
|
fbb_.ReleaseMessage<Monster>();
|
||||||
|
|
||||||
// Send monster to client using streaming.
|
// Send monster to client using streaming.
|
||||||
writer->Write(monster);
|
writer->Write(monster);
|
||||||
@@ -90,7 +94,7 @@ void RunServer() {
|
|||||||
server_instance->Wait();
|
server_instance->Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int /*argc*/, const char * /*argv*/[]) {
|
int grpc_server_test() {
|
||||||
// Launch server.
|
// Launch server.
|
||||||
std::thread server_thread(RunServer);
|
std::thread server_thread(RunServer);
|
||||||
|
|
||||||
@@ -103,7 +107,6 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
grpc::InsecureChannelCredentials());
|
grpc::InsecureChannelCredentials());
|
||||||
auto stub = MyGame::Example::MonsterStorage::NewStub(channel);
|
auto stub = MyGame::Example::MonsterStorage::NewStub(channel);
|
||||||
|
|
||||||
|
|
||||||
flatbuffers::grpc::MessageBuilder fbb;
|
flatbuffers::grpc::MessageBuilder fbb;
|
||||||
{
|
{
|
||||||
grpc::ClientContext context;
|
grpc::ClientContext context;
|
||||||
@@ -149,7 +152,8 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
// matches the protobuf gRPC status code for an unparseable message.
|
// matches the protobuf gRPC status code for an unparseable message.
|
||||||
assert(!status.ok());
|
assert(!status.ok());
|
||||||
assert(status.error_code() == ::grpc::StatusCode::INTERNAL);
|
assert(status.error_code() == ::grpc::StatusCode::INTERNAL);
|
||||||
assert(strcmp(status.error_message().c_str(), "Message verification failed") == 0);
|
assert(strcmp(status.error_message().c_str(),
|
||||||
|
"Message verification failed") == 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -161,3 +165,17 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int main(int /*argc*/, const char * /*argv*/ []) {
|
||||||
|
message_builder_tests();
|
||||||
|
grpc_server_test();
|
||||||
|
|
||||||
|
if (!testing_fails) {
|
||||||
|
TEST_OUTPUT_LINE("ALL TESTS PASSED");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
TEST_OUTPUT_LINE("%d FAILED TESTS", testing_fails);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
4
grpc/tests/java-grpc-test.sh
Executable file
4
grpc/tests/java-grpc-test.sh
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# NOTE: make sure `mvn install` in /gprc is executed before running this test
|
||||||
|
mvn test
|
||||||
188
grpc/tests/message_builder_test.cpp
Normal file
188
grpc/tests/message_builder_test.cpp
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
#include "flatbuffers/grpc.h"
|
||||||
|
#include "monster_test_generated.h"
|
||||||
|
#include "test_assert.h"
|
||||||
|
#include "test_builder.h"
|
||||||
|
|
||||||
|
bool verify(flatbuffers::grpc::Message<Monster> &msg, const std::string &expected_name, Color color) {
|
||||||
|
const Monster *monster = msg.GetRoot();
|
||||||
|
return (monster->name()->str() == expected_name) && (monster->color() == color);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool release_n_verify(flatbuffers::grpc::MessageBuilder &mbb, const std::string &expected_name, Color color) {
|
||||||
|
flatbuffers::grpc::Message<Monster> msg = mbb.ReleaseMessage<Monster>();
|
||||||
|
const Monster *monster = msg.GetRoot();
|
||||||
|
return (monster->name()->str() == expected_name) && (monster->color() == color);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
struct BuilderReuseTests<flatbuffers::grpc::MessageBuilder> {
|
||||||
|
static void builder_reusable_after_release_message_test(TestSelector selector) {
|
||||||
|
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b1;
|
||||||
|
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
auto root_offset1 = populate1(b1);
|
||||||
|
b1.Finish(root_offset1);
|
||||||
|
buffers.push_back(b1.ReleaseMessage<Monster>());
|
||||||
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void builder_reusable_after_release_test(TestSelector selector) {
|
||||||
|
if (!selector.count(REUSABLE_AFTER_RELEASE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Populate-Release loop fails assert(GRPC_SLICE_IS_EMPTY(slice_)).
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b1;
|
||||||
|
std::vector<flatbuffers::DetachedBuffer> buffers;
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
auto root_offset1 = populate1(b1);
|
||||||
|
b1.Finish(root_offset1);
|
||||||
|
buffers.push_back(b1.Release());
|
||||||
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void builder_reusable_after_releaseraw_test(TestSelector selector) {
|
||||||
|
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b1;
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
auto root_offset1 = populate1(b1);
|
||||||
|
b1.Finish(root_offset1);
|
||||||
|
size_t size, offset;
|
||||||
|
grpc_slice slice;
|
||||||
|
const uint8_t *buf = b1.ReleaseRaw(size, offset, slice);
|
||||||
|
TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
|
||||||
|
grpc_slice_unref(slice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void builder_reusable_after_release_and_move_assign_test(TestSelector selector) {
|
||||||
|
if (!selector.count(REUSABLE_AFTER_RELEASE_AND_MOVE_ASSIGN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: Release-move_assign loop fails assert(p == GRPC_SLICE_START_PTR(slice_)).
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b1;
|
||||||
|
std::vector<flatbuffers::DetachedBuffer> buffers;
|
||||||
|
|
||||||
|
for (int i = 0; i < 1; ++i) {
|
||||||
|
auto root_offset1 = populate1(b1);
|
||||||
|
b1.Finish(root_offset1);
|
||||||
|
buffers.push_back(b1.Release());
|
||||||
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
||||||
|
|
||||||
|
// bring b1 back to life.
|
||||||
|
flatbuffers::grpc::MessageBuilder b2;
|
||||||
|
b1 = std::move(b2);
|
||||||
|
TEST_EQ_FUNC(b1.GetSize(), 0);
|
||||||
|
TEST_EQ_FUNC(b2.GetSize(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void builder_reusable_after_release_message_and_move_assign_test(TestSelector selector) {
|
||||||
|
if (!selector.count(REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b1;
|
||||||
|
std::vector<flatbuffers::grpc::Message<Monster>> buffers;
|
||||||
|
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
auto root_offset1 = populate1(b1);
|
||||||
|
b1.Finish(root_offset1);
|
||||||
|
buffers.push_back(b1.ReleaseMessage<Monster>());
|
||||||
|
TEST_ASSERT_FUNC(verify(buffers[i], m1_name, m1_color));
|
||||||
|
|
||||||
|
// bring b1 back to life.
|
||||||
|
flatbuffers::grpc::MessageBuilder b2;
|
||||||
|
b1 = std::move(b2);
|
||||||
|
TEST_EQ_FUNC(b1.GetSize(), 0);
|
||||||
|
TEST_EQ_FUNC(b2.GetSize(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void builder_reusable_after_releaseraw_and_move_assign_test(TestSelector selector) {
|
||||||
|
if (!selector.count(REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b1;
|
||||||
|
for (int i = 0; i < 5; ++i) {
|
||||||
|
auto root_offset1 = populate1(b1);
|
||||||
|
b1.Finish(root_offset1);
|
||||||
|
size_t size, offset;
|
||||||
|
grpc_slice slice = grpc_empty_slice();
|
||||||
|
const uint8_t *buf = b1.ReleaseRaw(size, offset, slice);
|
||||||
|
TEST_ASSERT_FUNC(verify(buf, offset, m1_name, m1_color));
|
||||||
|
grpc_slice_unref(slice);
|
||||||
|
|
||||||
|
flatbuffers::grpc::MessageBuilder b2;
|
||||||
|
b1 = std::move(b2);
|
||||||
|
TEST_EQ_FUNC(b1.GetSize(), 0);
|
||||||
|
TEST_EQ_FUNC(b2.GetSize(), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_tests(TestSelector selector) {
|
||||||
|
builder_reusable_after_release_test(selector);
|
||||||
|
builder_reusable_after_release_message_test(selector);
|
||||||
|
builder_reusable_after_releaseraw_test(selector);
|
||||||
|
builder_reusable_after_release_and_move_assign_test(selector);
|
||||||
|
builder_reusable_after_releaseraw_and_move_assign_test(selector);
|
||||||
|
builder_reusable_after_release_message_and_move_assign_test(selector);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void slice_allocator_tests() {
|
||||||
|
// move-construct no-delete test
|
||||||
|
{
|
||||||
|
size_t size = 2048;
|
||||||
|
flatbuffers::grpc::SliceAllocator sa1;
|
||||||
|
uint8_t *buf = sa1.allocate(size);
|
||||||
|
TEST_ASSERT_FUNC(buf != 0);
|
||||||
|
buf[0] = 100;
|
||||||
|
buf[size-1] = 200;
|
||||||
|
flatbuffers::grpc::SliceAllocator sa2(std::move(sa1));
|
||||||
|
// buf should be deleted after move-construct
|
||||||
|
TEST_EQ_FUNC(buf[0], 100);
|
||||||
|
TEST_EQ_FUNC(buf[size-1], 200);
|
||||||
|
// buf is freed here
|
||||||
|
}
|
||||||
|
|
||||||
|
// move-assign test
|
||||||
|
{
|
||||||
|
flatbuffers::grpc::SliceAllocator sa1, sa2;
|
||||||
|
uint8_t *buf = sa1.allocate(2048);
|
||||||
|
sa1 = std::move(sa2);
|
||||||
|
// sa1 deletes previously allocated memory in move-assign.
|
||||||
|
// So buf is no longer usable here.
|
||||||
|
TEST_ASSERT_FUNC(buf != 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void message_builder_tests() {
|
||||||
|
slice_allocator_tests();
|
||||||
|
BuilderTests<flatbuffers::grpc::MessageBuilder>::all_tests();
|
||||||
|
|
||||||
|
BuilderReuseTestSelector tests[6] = {
|
||||||
|
// REUSABLE_AFTER_RELEASE, // Assertion failed: (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_MESSAGE,
|
||||||
|
REUSABLE_AFTER_RELEASE_MESSAGE_AND_MOVE_ASSIGN,
|
||||||
|
REUSABLE_AFTER_RELEASE_RAW_AND_MOVE_ASSIGN
|
||||||
|
};
|
||||||
|
|
||||||
|
BuilderReuseTests<flatbuffers::grpc::MessageBuilder>::run_tests(TestSelector(tests, tests+6));
|
||||||
|
}
|
||||||
73
grpc/tests/pom.xml
Normal file
73
grpc/tests/pom.xml
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
|
<artifactId>flatbuffers-parent</artifactId>
|
||||||
|
<version>1.10.0</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>grpc-test</artifactId>
|
||||||
|
<description>Example/Test project demonstrating usage of flatbuffers with GRPC-Java instead of protobufs
|
||||||
|
</description>
|
||||||
|
<properties>
|
||||||
|
<gRPC.version>1.9.0</gRPC.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
|
<artifactId>flatbuffers-java</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
|
<artifactId>flatbuffers-java-grpc</artifactId>
|
||||||
|
<version>${project.parent.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.grpc</groupId>
|
||||||
|
<artifactId>grpc-stub</artifactId>
|
||||||
|
<version>${gRPC.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.grpc</groupId>
|
||||||
|
<artifactId>grpc-netty</artifactId>
|
||||||
|
<version>${gRPC.version}</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<version>4.12</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.codehaus.mojo</groupId>
|
||||||
|
<artifactId>build-helper-maven-plugin</artifactId>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>add-source</id>
|
||||||
|
<phase>generate-sources</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>add-test-source</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<sources>
|
||||||
|
<source>${project.basedir}</source>
|
||||||
|
<source>${project.basedir}/../../tests</source>
|
||||||
|
</sources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
<!--<testSourceDirectory>${project.basedir}</testSourceDirectory>-->
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
|
|
||||||
@@ -1,20 +1,40 @@
|
|||||||
#ifndef FLATBUFFERS_BASE_H_
|
#ifndef FLATBUFFERS_BASE_H_
|
||||||
#define FLATBUFFERS_BASE_H_
|
#define FLATBUFFERS_BASE_H_
|
||||||
|
|
||||||
|
// clang-format off
|
||||||
|
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||||
|
defined(_MSC_VER) && defined(_DEBUG)
|
||||||
|
#define _CRTDBG_MAP_ALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
|
#if !defined(FLATBUFFERS_ASSERT)
|
||||||
|
#define FLATBUFFERS_ASSERT assert
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef ARDUINO
|
#ifndef ARDUINO
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <string>
|
|
||||||
#ifndef ARDUINO
|
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||||
#include <utility>
|
defined(_MSC_VER) && defined(_DEBUG)
|
||||||
#else
|
#include <crtdbg.h>
|
||||||
#include <utility.h>
|
#define DEBUG_NEW new(_NORMAL_BLOCK, __FILE__, __LINE__)
|
||||||
|
#define new DEBUG_NEW
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(ARDUINO) && !defined(ARDUINOSTL_M_H)
|
||||||
|
#include <utility.h>
|
||||||
|
#else
|
||||||
|
#include <utility>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
@@ -29,6 +49,14 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "flatbuffers/stl_emulation.h"
|
||||||
|
|
||||||
|
// Note the __clang__ check is needed, because clang presents itself
|
||||||
|
// as an older GNUC compiler (4.2).
|
||||||
|
// Clang 3.3 and later implement all of the ISO C++ 2011 standard.
|
||||||
|
// Clang 3.4 and later implement all of the ISO C++ 2014 standard.
|
||||||
|
// http://clang.llvm.org/cxx_status.html
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
/// @cond FLATBUFFERS_INTERNAL
|
||||||
#if __cplusplus <= 199711L && \
|
#if __cplusplus <= 199711L && \
|
||||||
(!defined(_MSC_VER) || _MSC_VER < 1600) && \
|
(!defined(_MSC_VER) || _MSC_VER < 1600) && \
|
||||||
@@ -82,13 +110,14 @@
|
|||||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||||
|
|
||||||
#define FLATBUFFERS_VERSION_MAJOR 1
|
#define FLATBUFFERS_VERSION_MAJOR 1
|
||||||
#define FLATBUFFERS_VERSION_MINOR 7
|
#define FLATBUFFERS_VERSION_MINOR 10
|
||||||
#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)
|
||||||
|
|
||||||
#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)) || \
|
||||||
|
defined(__clang__)
|
||||||
#define FLATBUFFERS_FINAL_CLASS final
|
#define FLATBUFFERS_FINAL_CLASS final
|
||||||
#define FLATBUFFERS_OVERRIDE override
|
#define FLATBUFFERS_OVERRIDE override
|
||||||
#else
|
#else
|
||||||
@@ -97,14 +126,23 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
|
#if (!defined(_MSC_VER) || _MSC_VER >= 1900) && \
|
||||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406))
|
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
|
||||||
|
(defined(__cpp_constexpr) && __cpp_constexpr >= 200704)
|
||||||
#define FLATBUFFERS_CONSTEXPR constexpr
|
#define FLATBUFFERS_CONSTEXPR constexpr
|
||||||
#else
|
#else
|
||||||
#define FLATBUFFERS_CONSTEXPR
|
#define FLATBUFFERS_CONSTEXPR
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__GXX_EXPERIMENTAL_CXX0X__) && __GNUC__ * 10 + __GNUC_MINOR__ >= 46 || \
|
#if (defined(__cplusplus) && __cplusplus >= 201402L) || \
|
||||||
defined(_MSC_FULL_VER) && _MSC_FULL_VER >= 190023026
|
(defined(__cpp_constexpr) && __cpp_constexpr >= 201304)
|
||||||
|
#define FLATBUFFERS_CONSTEXPR_CPP14 FLATBUFFERS_CONSTEXPR
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_CONSTEXPR_CPP14
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 406)) || \
|
||||||
|
(defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 190023026)) || \
|
||||||
|
defined(__clang__)
|
||||||
#define FLATBUFFERS_NOEXCEPT noexcept
|
#define FLATBUFFERS_NOEXCEPT noexcept
|
||||||
#else
|
#else
|
||||||
#define FLATBUFFERS_NOEXCEPT
|
#define FLATBUFFERS_NOEXCEPT
|
||||||
@@ -113,16 +151,34 @@
|
|||||||
// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
|
// NOTE: the FLATBUFFERS_DELETE_FUNC macro may change the access mode to
|
||||||
// private, so be sure to put it at the end or reset access mode explicitly.
|
// private, so be sure to put it at the end or reset access mode explicitly.
|
||||||
#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
|
#if (!defined(_MSC_VER) || _MSC_FULL_VER >= 180020827) && \
|
||||||
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404))
|
(!defined(__GNUC__) || (__GNUC__ * 100 + __GNUC_MINOR__ >= 404)) || \
|
||||||
|
defined(__clang__)
|
||||||
#define FLATBUFFERS_DELETE_FUNC(func) func = delete;
|
#define FLATBUFFERS_DELETE_FUNC(func) func = delete;
|
||||||
#else
|
#else
|
||||||
#define FLATBUFFERS_DELETE_FUNC(func) private: func;
|
#define FLATBUFFERS_DELETE_FUNC(func) private: func;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#ifndef FLATBUFFERS_HAS_STRING_VIEW
|
||||||
#pragma warning(push)
|
// Only provide flatbuffers::string_view if __has_include can be used
|
||||||
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
// to detect a header that provides an implementation
|
||||||
|
#if defined(__has_include)
|
||||||
|
// Check for std::string_view (in c++17)
|
||||||
|
#if __has_include(<string_view>) && (__cplusplus >= 201606 || _HAS_CXX17)
|
||||||
|
#include <string_view>
|
||||||
|
namespace flatbuffers {
|
||||||
|
typedef std::string_view string_view;
|
||||||
|
}
|
||||||
|
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||||
|
// Check for std::experimental::string_view (in c++14, compiler-dependent)
|
||||||
|
#elif __has_include(<experimental/string_view>) && (__cplusplus >= 201411)
|
||||||
|
#include <experimental/string_view>
|
||||||
|
namespace flatbuffers {
|
||||||
|
typedef std::experimental::string_view string_view;
|
||||||
|
}
|
||||||
|
#define FLATBUFFERS_HAS_STRING_VIEW 1
|
||||||
#endif
|
#endif
|
||||||
|
#endif // __has_include
|
||||||
|
#endif // !FLATBUFFERS_HAS_STRING_VIEW
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
@@ -150,6 +206,54 @@ typedef uintmax_t largest_scalar_t;
|
|||||||
// 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
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template<typename T> T EndianSwap(T t) {
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define FLATBUFFERS_BYTESWAP16 _byteswap_ushort
|
||||||
|
#define FLATBUFFERS_BYTESWAP32 _byteswap_ulong
|
||||||
|
#define FLATBUFFERS_BYTESWAP64 _byteswap_uint64
|
||||||
|
#else
|
||||||
|
#if defined(__GNUC__) && __GNUC__ * 100 + __GNUC_MINOR__ < 408 && !defined(__clang__)
|
||||||
|
// __builtin_bswap16 was missing prior to GCC 4.8.
|
||||||
|
#define FLATBUFFERS_BYTESWAP16(x) \
|
||||||
|
static_cast<uint16_t>(__builtin_bswap32(static_cast<uint32_t>(x) << 16))
|
||||||
|
#else
|
||||||
|
#define FLATBUFFERS_BYTESWAP16 __builtin_bswap16
|
||||||
|
#endif
|
||||||
|
#define FLATBUFFERS_BYTESWAP32 __builtin_bswap32
|
||||||
|
#define FLATBUFFERS_BYTESWAP64 __builtin_bswap64
|
||||||
|
#endif
|
||||||
|
if (sizeof(T) == 1) { // Compile-time if-then's.
|
||||||
|
return t;
|
||||||
|
} else if (sizeof(T) == 2) {
|
||||||
|
union { T t; uint16_t i; } u;
|
||||||
|
u.t = t;
|
||||||
|
u.i = FLATBUFFERS_BYTESWAP16(u.i);
|
||||||
|
return u.t;
|
||||||
|
} else if (sizeof(T) == 4) {
|
||||||
|
union { T t; uint32_t i; } u;
|
||||||
|
u.t = t;
|
||||||
|
u.i = FLATBUFFERS_BYTESWAP32(u.i);
|
||||||
|
return u.t;
|
||||||
|
} else if (sizeof(T) == 8) {
|
||||||
|
union { T t; uint64_t i; } u;
|
||||||
|
u.t = t;
|
||||||
|
u.i = FLATBUFFERS_BYTESWAP64(u.i);
|
||||||
|
return u.t;
|
||||||
|
} else {
|
||||||
|
FLATBUFFERS_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
template<typename T> T EndianScalar(T t) {
|
template<typename T> T EndianScalar(T t) {
|
||||||
#if FLATBUFFERS_LITTLEENDIAN
|
#if FLATBUFFERS_LITTLEENDIAN
|
||||||
return t;
|
return t;
|
||||||
@@ -173,5 +277,5 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
} // namespace flatbuffers
|
||||||
#endif // FLATBUFFERS_BASE_H_
|
#endif // FLATBUFFERS_BASE_H_
|
||||||
|
|||||||
@@ -71,8 +71,7 @@ class BaseGenerator {
|
|||||||
public:
|
public:
|
||||||
virtual bool generate() = 0;
|
virtual bool generate() = 0;
|
||||||
|
|
||||||
static std::string NamespaceDir(const Parser &parser,
|
static std::string NamespaceDir(const Parser &parser, const std::string &path,
|
||||||
const std::string &path,
|
|
||||||
const Namespace &ns);
|
const Namespace &ns);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -128,8 +127,7 @@ struct CommentConfig {
|
|||||||
};
|
};
|
||||||
|
|
||||||
extern void GenComment(const std::vector<std::string> &dc,
|
extern void GenComment(const std::vector<std::string> &dc,
|
||||||
std::string *code_ptr,
|
std::string *code_ptr, const CommentConfig *config,
|
||||||
const CommentConfig *config,
|
|
||||||
const char *prefix = "");
|
const char *prefix = "");
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,12 +14,12 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "flatbuffers/flatbuffers.h"
|
|
||||||
#include "flatbuffers/idl.h"
|
|
||||||
#include "flatbuffers/util.h"
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "flatbuffers/idl.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
#ifndef FLATC_H_
|
#ifndef FLATC_H_
|
||||||
# define FLATC_H_
|
# define FLATC_H_
|
||||||
@@ -49,12 +49,10 @@ class FlatCompiler {
|
|||||||
MakeRuleFn make_rule;
|
MakeRuleFn make_rule;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef void (*WarnFn)(const FlatCompiler *flatc,
|
typedef void (*WarnFn)(const FlatCompiler *flatc, const std::string &warn,
|
||||||
const std::string &warn,
|
|
||||||
bool show_exe_name);
|
bool show_exe_name);
|
||||||
|
|
||||||
typedef void (*ErrorFn)(const FlatCompiler *flatc,
|
typedef void (*ErrorFn)(const FlatCompiler *flatc, const std::string &err,
|
||||||
const std::string &err,
|
|
||||||
bool usage, bool show_exe_name);
|
bool usage, bool show_exe_name);
|
||||||
|
|
||||||
// Parameters required to initialize the FlatCompiler.
|
// Parameters required to initialize the FlatCompiler.
|
||||||
@@ -78,8 +76,7 @@ class FlatCompiler {
|
|||||||
std::string GetUsageString(const char *program_name) const;
|
std::string GetUsageString(const char *program_name) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void ParseFile(flatbuffers::Parser &parser,
|
void ParseFile(flatbuffers::Parser &parser, const std::string &filename,
|
||||||
const std::string &filename,
|
|
||||||
const std::string &contents,
|
const std::string &contents,
|
||||||
std::vector<const char *> &include_directories) const;
|
std::vector<const char *> &include_directories) const;
|
||||||
|
|
||||||
@@ -91,7 +88,6 @@ class FlatCompiler {
|
|||||||
InitParams params_;
|
InitParams params_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
} // namespace flatbuffers
|
} // namespace flatbuffers
|
||||||
|
|
||||||
#endif // FLATC_H_
|
#endif // FLATC_H_
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user