mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-14 08:26:59 +00:00
Compare commits
90 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
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 |
0
.gitattributes
vendored
Executable file → Normal file
0
.gitattributes
vendored
Executable file → Normal file
9
.gitignore
vendored
Executable file → Normal file
9
.gitignore
vendored
Executable file → Normal file
@@ -5,6 +5,7 @@
|
|||||||
*.o.d
|
*.o.d
|
||||||
*.class
|
*.class
|
||||||
*.a
|
*.a
|
||||||
|
*.swp
|
||||||
*~
|
*~
|
||||||
*.vcxproj
|
*.vcxproj
|
||||||
*.vcxproj.filters
|
*.vcxproj.filters
|
||||||
@@ -43,12 +44,14 @@ flatsampletext.exe
|
|||||||
grpctest
|
grpctest
|
||||||
grpctest.exe
|
grpctest.exe
|
||||||
snapshot.sh
|
snapshot.sh
|
||||||
|
tags
|
||||||
tests/go_gen
|
tests/go_gen
|
||||||
tests/monsterdata_java_wire.mon
|
tests/monsterdata_java_wire.mon
|
||||||
tests/monsterdata_go_wire.mon
|
tests/monsterdata_go_wire.mon
|
||||||
tests/monsterdata_javascript_wire.mon
|
tests/monsterdata_javascript_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
|
||||||
@@ -72,3 +75,9 @@ 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/
|
||||||
|
|||||||
81
.travis.yml
81
.travis.yml
@@ -1,31 +1,58 @@
|
|||||||
language: cpp
|
|
||||||
|
|
||||||
os:
|
|
||||||
- linux
|
|
||||||
- osx
|
|
||||||
|
|
||||||
compiler:
|
|
||||||
- gcc
|
|
||||||
#- clang
|
|
||||||
|
|
||||||
env:
|
env:
|
||||||
matrix:
|
|
||||||
- BUILD_TYPE=Debug BIICODE=false
|
|
||||||
- BUILD_TYPE=Release BIICODE=false
|
|
||||||
# biicode .deb files no longer available.
|
|
||||||
# - BUILD_TYPE=Release BIICODE=true
|
|
||||||
# - BUILD_TYPE=Debug BIICODE=true
|
|
||||||
global:
|
global:
|
||||||
|
# Set at the root level as this is ignored when set under matrix.env.
|
||||||
- GCC_VERSION="4.9"
|
- GCC_VERSION="4.9"
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- language: cpp
|
||||||
|
os:
|
||||||
|
- linux
|
||||||
|
- osx
|
||||||
|
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
#- clang
|
||||||
|
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- BUILD_TYPE=Debug BIICODE=false
|
||||||
|
- BUILD_TYPE=Release BIICODE=false
|
||||||
|
# biicode .deb files no longer available.
|
||||||
|
# - BUILD_TYPE=Release BIICODE=true
|
||||||
|
# - BUILD_TYPE=Debug BIICODE=true
|
||||||
|
|
||||||
|
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 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:
|
||||||
|
- if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
|
||||||
|
- if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
|
||||||
|
|
||||||
before_install:
|
- language: android
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
sudo: true
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
android:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
components:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
- tools
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
- platform-tools
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
- build-tools-25.0.2
|
||||||
|
- android-25
|
||||||
script:
|
- extra-android-m2repository
|
||||||
- if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
|
compiler:
|
||||||
- if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
|
- 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))
|
||||||
|
|||||||
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)
|
||||||
|
|
||||||
@@ -31,8 +31,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
|
||||||
@@ -50,6 +52,7 @@ set(FlatBuffers_Compiler_SRCS
|
|||||||
src/idl_gen_python.cpp
|
src/idl_gen_python.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
|
||||||
@@ -128,8 +131,7 @@ 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(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++")
|
||||||
@@ -187,7 +189,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}.8.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)
|
||||||
@@ -197,6 +208,8 @@ function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
|||||||
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 -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)
|
||||||
@@ -231,19 +244,64 @@ if(FLATBUFFERS_BUILD_GRPCTEST)
|
|||||||
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()
|
||||||
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 pthread dl)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
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")
|
||||||
|
|
||||||
|
install(
|
||||||
|
FILES "CMake/FlatbuffersConfig.cmake"
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
|
|
||||||
if(FLATBUFFERS_BUILD_FLATLIB)
|
if(FLATBUFFERS_BUILD_FLATLIB)
|
||||||
install(TARGETS flatbuffers DESTINATION lib)
|
install(
|
||||||
|
TARGETS flatbuffers EXPORT FlatbuffersTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(EXPORT FlatbuffersTargets
|
||||||
|
FILE FlatbuffersTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
endif()
|
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)
|
install(
|
||||||
|
TARGETS flatbuffers_shared EXPORT FlatbuffersSharedTargets
|
||||||
|
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
RUNTIME DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||||
|
)
|
||||||
|
|
||||||
|
install(
|
||||||
|
EXPORT FlatbuffersSharedTargets
|
||||||
|
FILE FlatbuffersSharedTargets.cmake
|
||||||
|
NAMESPACE flatbuffers::
|
||||||
|
DESTINATION ${FB_CMAKE_DIR}
|
||||||
|
)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
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
|
||||||
3
android/jni/Android.mk
Executable file → Normal file
3
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
|
||||||
@@ -48,7 +49,7 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
|
|||||||
tests/test.cpp \
|
tests/test.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
40
appveyor.yml
40
appveyor.yml
@@ -5,6 +5,12 @@ 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: "14 2015"
|
- CMAKE_VS_VERSION: "14 2015"
|
||||||
@@ -26,17 +32,41 @@ build:
|
|||||||
project: ALL_BUILD.vcxproj
|
project: ALL_BUILD.vcxproj
|
||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
|
|
||||||
|
install:
|
||||||
|
- set PATH=%CONDA_INSTALL_LOCN%;%CONDA_INSTALL_LOCN%\scripts;%PATH%;
|
||||||
|
|
||||||
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 "---------------- 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 +77,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
|
||||||
|
|||||||
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
|
||||||
|
|||||||
0
docs/source/Building.md
Executable file → Normal file
0
docs/source/Building.md
Executable file → Normal file
3
docs/source/Compiler.md
Executable file → Normal file
3
docs/source/Compiler.md
Executable file → Normal file
@@ -125,5 +125,8 @@ 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.
|
||||||
|
|
||||||
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.
|
||||||
|
|||||||
24
docs/source/CppUsage.md
Executable file → Normal file
24
docs/source/CppUsage.md
Executable file → Normal file
@@ -231,6 +231,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
25
docs/source/Grammar.md
Executable file → Normal file
25
docs/source/Grammar.md
Executable file → Normal file
@@ -4,7 +4,7 @@ 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 `;`
|
||||||
|
|
||||||
@@ -14,16 +14,22 @@ attribute\_decl = `attribute` string\_constant `;`
|
|||||||
|
|
||||||
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]+)?
|
|
||||||
|
|||||||
22
docs/source/Internals.md
Executable file → Normal file
22
docs/source/Internals.md
Executable file → Normal file
@@ -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
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
|
||||||
|
|||||||
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
|
||||||
|
|||||||
0
docs/source/Support.md
Executable file → Normal file
0
docs/source/Support.md
Executable file → Normal file
@@ -210,12 +210,21 @@ The `Weapon` table is a sub-table used within our FlatBuffer. It is
|
|||||||
used twice: once within the `Monster` table and once within the `Equipment`
|
used twice: once within the `Monster` table and once within the `Equipment`
|
||||||
enum. For our `Monster`, it is used to populate a `vector of tables` via the
|
enum. For our `Monster`, it is used to populate a `vector of tables` via the
|
||||||
`weapons` field within our `Monster`. It is also the only table referenced by
|
`weapons` field within our `Monster`. It is also the only table referenced by
|
||||||
the `Equipment` enum.
|
the `Equipment` union.
|
||||||
|
|
||||||
The last part of the `schema` is the `root_type`. The root type declares what
|
The last part of the `schema` is the `root_type`. The root type declares what
|
||||||
will be the root table for the serialized data. In our case, the root type is
|
will be the root table for the serialized data. In our case, the root type is
|
||||||
our `Monster` table.
|
our `Monster` table.
|
||||||
|
|
||||||
|
The scalar types can also use alias type names such as `int16` instead
|
||||||
|
of `short` and `float32` instead of `float`. Thus we could also write
|
||||||
|
the `Weapon` table as:
|
||||||
|
|
||||||
|
table Weapon {
|
||||||
|
name:string;
|
||||||
|
damage:int16;
|
||||||
|
}
|
||||||
|
|
||||||
#### More Information About Schemas
|
#### More Information About Schemas
|
||||||
|
|
||||||
You can find a complete guide to writing `schema` files in the
|
You can find a complete guide to writing `schema` files in the
|
||||||
@@ -604,7 +613,7 @@ traversal. This is generally easy to do on any tree structures.
|
|||||||
|
|
||||||
// Create a `vector` representing the inventory of the Orc. Each number
|
// Create a `vector` representing the inventory of the Orc. Each number
|
||||||
// could correspond to an item that can be claimed after he is slain.
|
// could correspond to an item that can be claimed after he is slain.
|
||||||
unsigned char treasure = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
unsigned char treasure[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
|
||||||
auto inventory = builder.CreateVector(treasure, 10);
|
auto inventory = builder.CreateVector(treasure, 10);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -710,6 +719,10 @@ adding fields to our monster.
|
|||||||
other `vector`s), collect their offsets into a temporary data structure, and
|
other `vector`s), collect their offsets into a temporary data structure, and
|
||||||
then create an additional `vector` containing their offsets.*
|
then create an additional `vector` containing their offsets.*
|
||||||
|
|
||||||
|
If instead of creating a vector from an existing array you serialize elements
|
||||||
|
individually one by one, take care to note that this happens in reverse order,
|
||||||
|
as buffers are built back to front.
|
||||||
|
|
||||||
For example, take a look at the two `Weapon`s that we created earlier (`Sword`
|
For example, take a look at the two `Weapon`s that we created earlier (`Sword`
|
||||||
and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in
|
and `Axe`). These are both FlatBuffer `table`s, whose offsets we now store in
|
||||||
memory. Therefore we can create a FlatBuffer `vector` to contain these
|
memory. Therefore we can create a FlatBuffer `vector` to contain these
|
||||||
@@ -807,7 +820,7 @@ for the `path` field above:
|
|||||||
<div class="language-cpp">
|
<div class="language-cpp">
|
||||||
~~~{.cpp}
|
~~~{.cpp}
|
||||||
Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
|
Vec3 points[] = { Vec3(1.0f, 2.0f, 3.0f), Vec3(4.0f, 5.0f, 6.0f) };
|
||||||
auto path = fbb.CreateVectorOfStructs(points, 2);
|
auto path = builder.CreateVectorOfStructs(points, 2);
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
@@ -836,7 +849,7 @@ for the `path` field above:
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-python">
|
<div class="language-python">
|
||||||
~~~{.py}
|
~~~{.py}
|
||||||
MyGame.Example.Monster.MonsterStartPathVector(builder, 2)
|
MyGame.Sample.Monster.MonsterStartPathVector(builder, 2)
|
||||||
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
MyGame.Sample.Vec3.CreateVec3(builder, 1.0, 2.0, 3.0)
|
||||||
MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
|
MyGame.Sample.Vec3.CreateVec3(builder, 4.0, 5.0, 6.0)
|
||||||
path = builder.EndVector(2)
|
path = builder.EndVector(2)
|
||||||
@@ -844,7 +857,7 @@ for the `path` field above:
|
|||||||
</div>
|
</div>
|
||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
MyGame.Example.Monster.startPathVector(builder, 2);
|
MyGame.Sample.Monster.startPathVector(builder, 2);
|
||||||
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
|
MyGame.Sample.Vec3.createVec3(builder, 1.0, 2.0, 3.0);
|
||||||
MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
|
MyGame.Sample.Vec3.createVec3(builder, 4.0, 5.0, 6.0);
|
||||||
var path = builder.endVector();
|
var path = builder.endVector();
|
||||||
@@ -1024,13 +1037,14 @@ a bit more flexibility.
|
|||||||
// manually.
|
// manually.
|
||||||
MonsterBuilder monster_builder(builder);
|
MonsterBuilder monster_builder(builder);
|
||||||
monster_builder.add_pos(&pos);
|
monster_builder.add_pos(&pos);
|
||||||
|
auto pos = Vec3(1.0f, 2.0f, 3.0f);
|
||||||
monster_builder.add_hp(hp);
|
monster_builder.add_hp(hp);
|
||||||
monster_builder.add_name(name);
|
monster_builder.add_name(name);
|
||||||
monster_builder.add_inventory(inventory);
|
monster_builder.add_inventory(inventory);
|
||||||
monster_builder.add_color(Color_Red);
|
monster_builder.add_color(Color_Red);
|
||||||
monster_builder.add_weapons(weapons);
|
monster_builder.add_weapons(weapons);
|
||||||
monster_builder.add_equipped_type(Equipment_Weapon);
|
monster_builder.add_equipped_type(Equipment_Weapon);
|
||||||
monster_builder.add_equpped(axe);
|
monster_builder.add_equpped(axe.Union());
|
||||||
auto orc = monster_builder.Finish();
|
auto orc = monster_builder.Finish();
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -1162,7 +1176,7 @@ appropriate `finish` method.
|
|||||||
<div class="language-javascript">
|
<div class="language-javascript">
|
||||||
~~~{.js}
|
~~~{.js}
|
||||||
// Call `finish()` to instruct the builder that this monster is complete.
|
// Call `finish()` to instruct the builder that this monster is complete.
|
||||||
builder.finish(orc); // You could also call `MyGame.Example.Monster.finishMonsterBuffer(builder,
|
builder.finish(orc); // You could also call `MyGame.Sample.Monster.finishMonsterBuffer(builder,
|
||||||
// orc);`.
|
// orc);`.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
@@ -1380,6 +1394,8 @@ won't work**
|
|||||||
|
|
||||||
// `monster` is of type `Monster *`.
|
// `monster` is of type `Monster *`.
|
||||||
// Note: root object pointers are NOT the same as `buffer_pointer`.
|
// Note: root object pointers are NOT the same as `buffer_pointer`.
|
||||||
|
// `GetMonster` is a convenience function that calls `GetRoot<Monster>`,
|
||||||
|
// the latter is also available for non-root types.
|
||||||
~~~
|
~~~
|
||||||
</div>
|
</div>
|
||||||
<div class="language-java">
|
<div class="language-java">
|
||||||
|
|||||||
0
docs/source/WhitePaper.md
Executable file → Normal file
0
docs/source/WhitePaper.md
Executable file → Normal file
0
docs/source/doxyfile
Executable file → Normal file
0
docs/source/doxyfile
Executable file → Normal file
@@ -110,6 +110,11 @@ 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
|
||||||
|
|||||||
@@ -1,20 +1,35 @@
|
|||||||
#ifndef FLATBUFFERS_BASE_H_
|
#ifndef FLATBUFFERS_BASE_H_
|
||||||
#define FLATBUFFERS_BASE_H_
|
#define FLATBUFFERS_BASE_H_
|
||||||
|
|
||||||
|
#if defined(FLATBUFFERS_MEMORY_LEAK_TRACKING) && \
|
||||||
|
defined(_MSC_VER) && defined(_DEBUG)
|
||||||
|
#define _CRTDBG_MAP_ALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#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 +44,8 @@
|
|||||||
#include <functional>
|
#include <functional>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include "flatbuffers/stl_emulation.h"
|
||||||
|
|
||||||
/// @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,7 +99,7 @@
|
|||||||
#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 8
|
||||||
#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)
|
||||||
@@ -120,8 +137,8 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(push)
|
#pragma warning(push)
|
||||||
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
#pragma warning(disable: 4127) // C4127: conditional expression is constant
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// @endcond
|
/// @endcond
|
||||||
@@ -150,6 +167,45 @@ 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
|
||||||
|
|
||||||
|
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 {
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
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 +229,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_
|
||||||
|
|||||||
@@ -37,38 +37,6 @@ inline void EndianCheck() {
|
|||||||
(void)endiantest;
|
(void)endiantest;
|
||||||
}
|
}
|
||||||
|
|
||||||
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
|
|
||||||
// __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) {
|
|
||||||
auto r = FLATBUFFERS_BYTESWAP16(*reinterpret_cast<uint16_t *>(&t));
|
|
||||||
return *reinterpret_cast<T *>(&r);
|
|
||||||
} else if (sizeof(T) == 4) {
|
|
||||||
auto r = FLATBUFFERS_BYTESWAP32(*reinterpret_cast<uint32_t *>(&t));
|
|
||||||
return *reinterpret_cast<T *>(&r);
|
|
||||||
} else if (sizeof(T) == 8) {
|
|
||||||
auto r = FLATBUFFERS_BYTESWAP64(*reinterpret_cast<uint64_t *>(&t));
|
|
||||||
return *reinterpret_cast<T *>(&r);
|
|
||||||
} else {
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
|
template<typename T> FLATBUFFERS_CONSTEXPR size_t AlignOf() {
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
return __alignof(T);
|
return __alignof(T);
|
||||||
@@ -445,32 +413,26 @@ class DetachedBuffer {
|
|||||||
: allocator_(other.allocator_), own_allocator_(other.own_allocator_),
|
: allocator_(other.allocator_), own_allocator_(other.own_allocator_),
|
||||||
buf_(other.buf_), reserved_(other.reserved_), cur_(other.cur_),
|
buf_(other.buf_), reserved_(other.reserved_), cur_(other.cur_),
|
||||||
size_(other.size_) {
|
size_(other.size_) {
|
||||||
other.allocator_ = nullptr;
|
other.reset();
|
||||||
other.own_allocator_ = false;
|
|
||||||
other.buf_ = nullptr;
|
|
||||||
other.reserved_ = 0;
|
|
||||||
other.cur_ = nullptr;
|
|
||||||
other.size_ = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DetachedBuffer &operator=(DetachedBuffer &&other) {
|
DetachedBuffer &operator=(DetachedBuffer &&other) {
|
||||||
std::swap(allocator_, other.allocator_);
|
destroy();
|
||||||
std::swap(own_allocator_, other.own_allocator_);
|
|
||||||
std::swap(buf_, other.buf_);
|
allocator_ = other.allocator_;
|
||||||
std::swap(reserved_, other.reserved_);
|
own_allocator_ = other.own_allocator_;
|
||||||
std::swap(cur_, other.cur_);
|
buf_ = other.buf_;
|
||||||
std::swap(size_, other.size_);
|
reserved_ = other.reserved_;
|
||||||
|
cur_ = other.cur_;
|
||||||
|
size_ = other.size_;
|
||||||
|
|
||||||
|
other.reset();
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
~DetachedBuffer() {
|
~DetachedBuffer() {
|
||||||
if (buf_) {
|
destroy();
|
||||||
assert(allocator_);
|
|
||||||
allocator_->deallocate(buf_, reserved_);
|
|
||||||
}
|
|
||||||
if (own_allocator_ && allocator_) {
|
|
||||||
delete allocator_;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *data() const {
|
const uint8_t *data() const {
|
||||||
@@ -515,6 +477,27 @@ class DetachedBuffer {
|
|||||||
size_t reserved_;
|
size_t reserved_;
|
||||||
uint8_t *cur_;
|
uint8_t *cur_;
|
||||||
size_t size_;
|
size_t size_;
|
||||||
|
|
||||||
|
inline void destroy() {
|
||||||
|
if (buf_) {
|
||||||
|
assert(allocator_);
|
||||||
|
allocator_->deallocate(buf_, reserved_);
|
||||||
|
}
|
||||||
|
if (own_allocator_ && allocator_) {
|
||||||
|
delete allocator_;
|
||||||
|
}
|
||||||
|
|
||||||
|
reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void reset() {
|
||||||
|
allocator_ = nullptr;
|
||||||
|
own_allocator_ = false;
|
||||||
|
buf_ = nullptr;
|
||||||
|
reserved_ = 0;
|
||||||
|
cur_ = nullptr;
|
||||||
|
size_ = 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a minimal replication of std::vector<uint8_t> functionality,
|
// This is a minimal replication of std::vector<uint8_t> functionality,
|
||||||
@@ -704,8 +687,8 @@ class FlatBufferBuilder
|
|||||||
explicit FlatBufferBuilder(size_t initial_size = 1024,
|
explicit FlatBufferBuilder(size_t initial_size = 1024,
|
||||||
Allocator *allocator = nullptr,
|
Allocator *allocator = nullptr,
|
||||||
bool own_allocator = false)
|
bool own_allocator = false)
|
||||||
: buf_(initial_size, allocator, own_allocator), nested(false),
|
: buf_(initial_size, allocator, own_allocator), max_voffset_(0),
|
||||||
finished(false), minalign_(1), force_defaults_(false),
|
nested(false), finished(false), minalign_(1), force_defaults_(false),
|
||||||
dedup_vtables_(true), string_pool(nullptr) {
|
dedup_vtables_(true), string_pool(nullptr) {
|
||||||
offsetbuf_.reserve(16); // Avoid first few reallocs.
|
offsetbuf_.reserve(16); // Avoid first few reallocs.
|
||||||
vtables_.reserve(16);
|
vtables_.reserve(16);
|
||||||
@@ -725,7 +708,7 @@ class FlatBufferBuilder
|
|||||||
/// to construct another buffer.
|
/// to construct another buffer.
|
||||||
void Clear() {
|
void Clear() {
|
||||||
buf_.clear();
|
buf_.clear();
|
||||||
offsetbuf_.clear();
|
ClearOffsets();
|
||||||
nested = false;
|
nested = false;
|
||||||
finished = false;
|
finished = false;
|
||||||
vtables_.clear();
|
vtables_.clear();
|
||||||
@@ -816,10 +799,8 @@ class FlatBufferBuilder
|
|||||||
void PopBytes(size_t amount) { buf_.pop(amount); }
|
void PopBytes(size_t amount) { buf_.pop(amount); }
|
||||||
|
|
||||||
template<typename T> void AssertScalarT() {
|
template<typename T> void AssertScalarT() {
|
||||||
#ifndef FLATBUFFERS_CPP98_STL
|
|
||||||
// The code assumes power of 2 sizes and endian-swap-ability.
|
// The code assumes power of 2 sizes and endian-swap-ability.
|
||||||
static_assert(std::is_scalar<T>::value, "T must be a scalar type");
|
static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write a single aligned scalar to the buffer
|
// Write a single aligned scalar to the buffer
|
||||||
@@ -841,6 +822,7 @@ class FlatBufferBuilder
|
|||||||
void TrackField(voffset_t field, uoffset_t off) {
|
void TrackField(voffset_t field, uoffset_t off) {
|
||||||
FieldLoc fl = { off, field };
|
FieldLoc fl = { off, field };
|
||||||
offsetbuf_.push_back(fl);
|
offsetbuf_.push_back(fl);
|
||||||
|
max_voffset_ = (std::max)(max_voffset_, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Like PushElement, but additionally tracks the field this represents.
|
// Like PushElement, but additionally tracks the field this represents.
|
||||||
@@ -901,7 +883,7 @@ class FlatBufferBuilder
|
|||||||
// This finishes one serialized object by generating the vtable if it's a
|
// This finishes one serialized object by generating the vtable if it's a
|
||||||
// table, comparing it against existing vtables, and writing the
|
// table, comparing it against existing vtables, and writing the
|
||||||
// resulting vtable offset.
|
// resulting vtable offset.
|
||||||
uoffset_t EndTable(uoffset_t start, voffset_t numfields) {
|
uoffset_t EndTable(uoffset_t start) {
|
||||||
// If you get this assert, a corresponding StartTable wasn't called.
|
// If you get this assert, a corresponding StartTable wasn't called.
|
||||||
assert(nested);
|
assert(nested);
|
||||||
// Write the vtable offset, which is the start of any Table.
|
// Write the vtable offset, which is the start of any Table.
|
||||||
@@ -910,11 +892,17 @@ class FlatBufferBuilder
|
|||||||
// Write a vtable, which consists entirely of voffset_t elements.
|
// Write a vtable, which consists entirely of voffset_t elements.
|
||||||
// It starts with the number of offsets, followed by a type id, followed
|
// It starts with the number of offsets, followed by a type id, followed
|
||||||
// by the offsets themselves. In reverse:
|
// by the offsets themselves. In reverse:
|
||||||
buf_.fill_big(numfields * sizeof(voffset_t));
|
// Include space for the last offset and ensure empty tables have a
|
||||||
|
// minimum size.
|
||||||
|
max_voffset_ = (std::max)(static_cast<voffset_t>(max_voffset_ +
|
||||||
|
sizeof(voffset_t)),
|
||||||
|
FieldIndexToOffset(0));
|
||||||
|
buf_.fill_big(max_voffset_);
|
||||||
auto table_object_size = vtableoffsetloc - start;
|
auto table_object_size = vtableoffsetloc - start;
|
||||||
assert(table_object_size < 0x10000); // Vtable use 16bit offsets.
|
assert(table_object_size < 0x10000); // Vtable use 16bit offsets.
|
||||||
PushElement<voffset_t>(static_cast<voffset_t>(table_object_size));
|
WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
|
||||||
PushElement<voffset_t>(FieldIndexToOffset(numfields));
|
static_cast<voffset_t>(table_object_size));
|
||||||
|
WriteScalar<voffset_t>(buf_.data(), max_voffset_);
|
||||||
// Write the offsets into the table
|
// Write the offsets into the table
|
||||||
for (auto field_location = offsetbuf_.begin();
|
for (auto field_location = offsetbuf_.begin();
|
||||||
field_location != offsetbuf_.end();
|
field_location != offsetbuf_.end();
|
||||||
@@ -924,7 +912,7 @@ class FlatBufferBuilder
|
|||||||
assert(!ReadScalar<voffset_t>(buf_.data() + field_location->id));
|
assert(!ReadScalar<voffset_t>(buf_.data() + field_location->id));
|
||||||
WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
|
WriteScalar<voffset_t>(buf_.data() + field_location->id, pos);
|
||||||
}
|
}
|
||||||
offsetbuf_.clear();
|
ClearOffsets();
|
||||||
auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
|
auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
|
||||||
auto vt1_size = ReadScalar<voffset_t>(vt1);
|
auto vt1_size = ReadScalar<voffset_t>(vt1);
|
||||||
auto vt_use = GetSize();
|
auto vt_use = GetSize();
|
||||||
@@ -957,6 +945,11 @@ class FlatBufferBuilder
|
|||||||
return vtableoffsetloc;
|
return vtableoffsetloc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DEPRECATED: call the version above instead.
|
||||||
|
uoffset_t EndTable(uoffset_t start, voffset_t /*numfields*/) {
|
||||||
|
return EndTable(start);
|
||||||
|
}
|
||||||
|
|
||||||
// This checks a required field has been set in a given table that has
|
// This checks a required field has been set in a given table that has
|
||||||
// just been constructed.
|
// just been constructed.
|
||||||
template<typename T> void Required(Offset<T> table, voffset_t field) {
|
template<typename T> void Required(Offset<T> table, voffset_t field) {
|
||||||
@@ -975,7 +968,10 @@ class FlatBufferBuilder
|
|||||||
|
|
||||||
uoffset_t EndStruct() { return GetSize(); }
|
uoffset_t EndStruct() { return GetSize(); }
|
||||||
|
|
||||||
void ClearOffsets() { offsetbuf_.clear(); }
|
void ClearOffsets() {
|
||||||
|
offsetbuf_.clear();
|
||||||
|
max_voffset_ = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Aligns such that when "len" bytes are written, an object can be written
|
// Aligns such that when "len" bytes are written, an object can be written
|
||||||
// after it with "alignment" without padding.
|
// after it with "alignment" without padding.
|
||||||
@@ -1119,6 +1115,9 @@ class FlatBufferBuilder
|
|||||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
/// where the vector is stored.
|
/// where the vector is stored.
|
||||||
template<typename T> Offset<Vector<T>> CreateVector(const T *v, size_t len) {
|
template<typename T> Offset<Vector<T>> CreateVector(const T *v, size_t len) {
|
||||||
|
// If this assert hits, you're specifying a template argument that is
|
||||||
|
// causing the wrong overload to be selected, remove it.
|
||||||
|
AssertScalarT<T>();
|
||||||
StartVector(len, sizeof(T));
|
StartVector(len, sizeof(T));
|
||||||
#if FLATBUFFERS_LITTLEENDIAN
|
#if FLATBUFFERS_LITTLEENDIAN
|
||||||
PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
|
PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
|
||||||
@@ -1179,6 +1178,22 @@ class FlatBufferBuilder
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// @brief Serialize values returned by a function into a FlatBuffer `vector`.
|
||||||
|
/// This is a convenience function that takes care of iteration for you.
|
||||||
|
/// @tparam T The data type of the `std::vector` elements.
|
||||||
|
/// @param f A function that takes the current iteration 0..vector_size-1,
|
||||||
|
/// and the state parameter returning any type that you can construct a
|
||||||
|
/// FlatBuffers vector out of.
|
||||||
|
/// @param state State passed to f.
|
||||||
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
|
/// where the vector is stored.
|
||||||
|
template <typename T, typename F, typename S> Offset<Vector<T>> CreateVector(
|
||||||
|
size_t vector_size, F f, S *state) {
|
||||||
|
std::vector<T> elems(vector_size);
|
||||||
|
for (size_t i = 0; i < vector_size; i++) elems[i] = f(i, state);
|
||||||
|
return CreateVector(elems);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Serialize a `std::vector<std::string>` into a FlatBuffer `vector`.
|
/// @brief Serialize a `std::vector<std::string>` into a FlatBuffer `vector`.
|
||||||
/// This is a convenience function for a common case.
|
/// This is a convenience function for a common case.
|
||||||
/// @param v A const reference to the `std::vector` to serialize into the
|
/// @param v A const reference to the `std::vector` to serialize into the
|
||||||
@@ -1223,7 +1238,6 @@ class FlatBufferBuilder
|
|||||||
return CreateVectorOfStructs<T>(vv.data(), vv.size());
|
return CreateVectorOfStructs<T>(vv.data(), vv.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_CPP98_STL
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
||||||
/// @tparam T The data type of the struct array elements.
|
/// @tparam T The data type of the struct array elements.
|
||||||
@@ -1235,16 +1249,34 @@ class FlatBufferBuilder
|
|||||||
/// accessors.
|
/// accessors.
|
||||||
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
|
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
|
||||||
size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
|
size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
|
||||||
StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
|
T* structs = StartVectorOfStructs<T>(vector_size);
|
||||||
T *structs = reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
|
||||||
for (size_t i = 0; i < vector_size; i++) {
|
for (size_t i = 0; i < vector_size; i++) {
|
||||||
filler(i, structs);
|
filler(i, structs);
|
||||||
structs++;
|
structs++;
|
||||||
}
|
}
|
||||||
return Offset<Vector<const T *>>(EndVector(vector_size));
|
return EndVectorOfStructs<T>(vector_size);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
||||||
|
/// @tparam T The data type of the struct array elements.
|
||||||
|
/// @param[in] f A function that takes the current iteration 0..vector_size-1,
|
||||||
|
/// a pointer to the struct that must be filled and the state argument.
|
||||||
|
/// @param[in] state Arbitrary state to pass to f.
|
||||||
|
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||||
|
/// where the vector is stored.
|
||||||
|
/// This is mostly useful when flatbuffers are generated with mutation
|
||||||
|
/// accessors.
|
||||||
|
template <typename T, typename F, typename S> Offset<Vector<const T *>>
|
||||||
|
CreateVectorOfStructs(size_t vector_size, F f, S *state) {
|
||||||
|
T* structs = StartVectorOfStructs<T>(vector_size);
|
||||||
|
for (size_t i = 0; i < vector_size; i++) {
|
||||||
|
f(i, structs, state);
|
||||||
|
structs++;
|
||||||
|
}
|
||||||
|
return EndVectorOfStructs<T>(vector_size);
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
|
/// @brief Serialize a `std::vector` of structs into a FlatBuffer `vector`.
|
||||||
/// @tparam T The data type of the `std::vector` struct elements.
|
/// @tparam T The data type of the `std::vector` struct elements.
|
||||||
/// @param[in]] v A const reference to the `std::vector` of structs to
|
/// @param[in]] v A const reference to the `std::vector` of structs to
|
||||||
@@ -1476,6 +1508,9 @@ class FlatBufferBuilder
|
|||||||
|
|
||||||
// Accumulating offsets of table members while it is being built.
|
// Accumulating offsets of table members while it is being built.
|
||||||
std::vector<FieldLoc> offsetbuf_;
|
std::vector<FieldLoc> offsetbuf_;
|
||||||
|
// Track how much of the vtable is in use, so we can output the most compact
|
||||||
|
// possible vtable.
|
||||||
|
voffset_t max_voffset_;
|
||||||
|
|
||||||
// Ensure objects are not nested.
|
// Ensure objects are not nested.
|
||||||
bool nested;
|
bool nested;
|
||||||
@@ -1497,7 +1532,7 @@ class FlatBufferBuilder
|
|||||||
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
|
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
|
||||||
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
|
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
|
||||||
return strncmp(stra->c_str(), strb->c_str(),
|
return strncmp(stra->c_str(), strb->c_str(),
|
||||||
std::min(stra->size(), strb->size()) + 1) < 0;
|
(std::min)(stra->size(), strb->size()) + 1) < 0;
|
||||||
}
|
}
|
||||||
const vector_downward *buf_;
|
const vector_downward *buf_;
|
||||||
};
|
};
|
||||||
@@ -1505,6 +1540,21 @@ class FlatBufferBuilder
|
|||||||
// For use with CreateSharedString. Instantiated on first use only.
|
// For use with CreateSharedString. Instantiated on first use only.
|
||||||
typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
|
typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
|
||||||
StringOffsetMap *string_pool;
|
StringOffsetMap *string_pool;
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Allocates space for a vector of structures.
|
||||||
|
// Must be completed with EndVectorOfStructs().
|
||||||
|
template<typename T> T* StartVectorOfStructs(size_t vector_size) {
|
||||||
|
StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
|
||||||
|
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// End the vector of structues in the flatbuffers.
|
||||||
|
// Vector should have previously be started with StartVectorOfStructs().
|
||||||
|
template<typename T> Offset<Vector<const T *>> EndVectorOfStructs(
|
||||||
|
size_t vector_size) {
|
||||||
|
return Offset<Vector<const T *>>(EndVector(vector_size));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
@@ -1912,7 +1962,7 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
|||||||
auto table = reinterpret_cast<const Table *>(root);
|
auto table = reinterpret_cast<const Table *>(root);
|
||||||
auto vtable = table->GetVTable();
|
auto vtable = table->GetVTable();
|
||||||
// Either the vtable is before the root or after the root.
|
// Either the vtable is before the root or after the root.
|
||||||
auto start = std::min(vtable, reinterpret_cast<const uint8_t *>(root));
|
auto start = (std::min)(vtable, reinterpret_cast<const uint8_t *>(root));
|
||||||
// Align to at least sizeof(uoffset_t).
|
// Align to at least sizeof(uoffset_t).
|
||||||
start = reinterpret_cast<const uint8_t *>(
|
start = reinterpret_cast<const uint8_t *>(
|
||||||
reinterpret_cast<uintptr_t>(start) & ~(sizeof(uoffset_t) - 1));
|
reinterpret_cast<uintptr_t>(start) & ~(sizeof(uoffset_t) - 1));
|
||||||
@@ -2016,6 +2066,73 @@ inline int LookupEnum(const char **names, const char *name) {
|
|||||||
#error Unknown compiler, please define structure alignment macros
|
#error Unknown compiler, please define structure alignment macros
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Minimal reflection via code generation.
|
||||||
|
// Besides full-fat reflection (see reflection.h) and parsing/printing by
|
||||||
|
// loading schemas (see idl.h), we can also have code generation for mimimal
|
||||||
|
// reflection data which allows pretty-printing and other uses without needing
|
||||||
|
// a schema or a parser.
|
||||||
|
// Generate code with --reflect-types (types only) or --reflect-names (names
|
||||||
|
// also) to enable.
|
||||||
|
// See minireflect.h for utilities using this functionality.
|
||||||
|
|
||||||
|
// These types are organized slightly differently as the ones in idl.h.
|
||||||
|
enum SequenceType { ST_TABLE, ST_STRUCT, ST_UNION, ST_ENUM };
|
||||||
|
|
||||||
|
// Scalars have the same order as in idl.h
|
||||||
|
#define FLATBUFFERS_GEN_ELEMENTARY_TYPES(ET) \
|
||||||
|
ET(ET_UTYPE) \
|
||||||
|
ET(ET_BOOL) \
|
||||||
|
ET(ET_CHAR) \
|
||||||
|
ET(ET_UCHAR) \
|
||||||
|
ET(ET_SHORT) \
|
||||||
|
ET(ET_USHORT) \
|
||||||
|
ET(ET_INT) \
|
||||||
|
ET(ET_UINT) \
|
||||||
|
ET(ET_LONG) \
|
||||||
|
ET(ET_ULONG) \
|
||||||
|
ET(ET_FLOAT) \
|
||||||
|
ET(ET_DOUBLE) \
|
||||||
|
ET(ET_STRING) \
|
||||||
|
ET(ET_SEQUENCE) // See SequenceType.
|
||||||
|
|
||||||
|
enum ElementaryType {
|
||||||
|
#define FLATBUFFERS_ET(E) E,
|
||||||
|
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||||
|
#undef FLATBUFFERS_ET
|
||||||
|
};
|
||||||
|
|
||||||
|
inline const char **ElementaryTypeNames() {
|
||||||
|
static const char *names[] = {
|
||||||
|
#define FLATBUFFERS_ET(E) #E,
|
||||||
|
FLATBUFFERS_GEN_ELEMENTARY_TYPES(FLATBUFFERS_ET)
|
||||||
|
#undef FLATBUFFERS_ET
|
||||||
|
};
|
||||||
|
return names;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic type info cost just 16bits per field!
|
||||||
|
struct TypeCode {
|
||||||
|
uint16_t base_type : 4; // ElementaryType
|
||||||
|
uint16_t is_vector : 1;
|
||||||
|
int16_t sequence_ref : 11; // Index into type_refs below, or -1 for none.
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert(sizeof(TypeCode) == 2, "TypeCode");
|
||||||
|
|
||||||
|
struct TypeTable;
|
||||||
|
|
||||||
|
// Signature of the static method present in each type.
|
||||||
|
typedef TypeTable *(*TypeFunction)();
|
||||||
|
|
||||||
|
struct TypeTable {
|
||||||
|
SequenceType st;
|
||||||
|
size_t num_elems; // of each of the arrays below.
|
||||||
|
const TypeCode *type_codes;
|
||||||
|
const TypeFunction *type_refs;
|
||||||
|
const int32_t *values; // Only set for non-consecutive enum/union or structs.
|
||||||
|
const char **names; // Only set if compiled with --reflect-names.
|
||||||
|
};
|
||||||
|
|
||||||
// String which identifies the current version of FlatBuffers.
|
// String which identifies the current version of FlatBuffers.
|
||||||
// flatbuffer_version_string is used by Google developers to identify which
|
// flatbuffer_version_string is used by Google developers to identify which
|
||||||
// applications uploaded to Google Play are using this library. This allows
|
// applications uploaded to Google Play are using this library. This allows
|
||||||
|
|||||||
@@ -18,6 +18,8 @@
|
|||||||
#define FLATBUFFERS_FLEXBUFFERS_H_
|
#define FLATBUFFERS_FLEXBUFFERS_H_
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
// Used to select STL variant.
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
// We use the basic binary writing functions from the regular FlatBuffers.
|
// We use the basic binary writing functions from the regular FlatBuffers.
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
@@ -74,16 +76,18 @@ enum Type {
|
|||||||
TYPE_VECTOR_UINT4 = 23,
|
TYPE_VECTOR_UINT4 = 23,
|
||||||
TYPE_VECTOR_FLOAT4 = 24,
|
TYPE_VECTOR_FLOAT4 = 24,
|
||||||
TYPE_BLOB = 25,
|
TYPE_BLOB = 25,
|
||||||
|
TYPE_BOOL = 26,
|
||||||
|
TYPE_VECTOR_BOOL = 36, // To Allow the same type of conversion of type to vector type
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsInline(Type t) { return t <= TYPE_FLOAT; }
|
inline bool IsInline(Type t) { return t <= TYPE_FLOAT || t == TYPE_BOOL; }
|
||||||
|
|
||||||
inline bool IsTypedVectorElementType(Type t) {
|
inline bool IsTypedVectorElementType(Type t) {
|
||||||
return t >= TYPE_INT && t <= TYPE_STRING;
|
return (t >= TYPE_INT && t <= TYPE_STRING) || t == TYPE_BOOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsTypedVector(Type t) {
|
inline bool IsTypedVector(Type t) {
|
||||||
return t >= TYPE_VECTOR_INT && t <= TYPE_VECTOR_STRING;
|
return (t >= TYPE_VECTOR_INT && t <= TYPE_VECTOR_STRING) || t == TYPE_VECTOR_BOOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool IsFixedTypedVector(Type t) {
|
inline bool IsFixedTypedVector(Type t) {
|
||||||
@@ -228,14 +232,15 @@ class String : public Sized {
|
|||||||
|
|
||||||
class Blob : public Sized {
|
class Blob : public Sized {
|
||||||
public:
|
public:
|
||||||
Blob(const uint8_t *data, uint8_t byte_width)
|
Blob(const uint8_t *data_buf, uint8_t byte_width)
|
||||||
: Sized(data, byte_width) {}
|
: Sized(data_buf, byte_width) {}
|
||||||
|
|
||||||
static Blob EmptyBlob() {
|
static Blob EmptyBlob() {
|
||||||
static const uint8_t empty_blob[] = { 0/*len*/ };
|
static const uint8_t empty_blob[] = { 0/*len*/ };
|
||||||
return Blob(empty_blob + 1, 1);
|
return Blob(empty_blob + 1, 1);
|
||||||
}
|
}
|
||||||
bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; }
|
bool IsTheEmptyBlob() const { return data_ == EmptyBlob().data_; }
|
||||||
|
const uint8_t *data() const { return data_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class Vector : public Sized {
|
class Vector : public Sized {
|
||||||
@@ -346,6 +351,7 @@ class Reference {
|
|||||||
Type GetType() const { return type_; }
|
Type GetType() const { return type_; }
|
||||||
|
|
||||||
bool IsNull() const { return type_ == TYPE_NULL; }
|
bool IsNull() const { return type_ == TYPE_NULL; }
|
||||||
|
bool IsBool() const { return type_ == TYPE_BOOL; }
|
||||||
bool IsInt() const { return type_ == TYPE_INT ||
|
bool IsInt() const { return type_ == TYPE_INT ||
|
||||||
type_ == TYPE_INDIRECT_INT; }
|
type_ == TYPE_INDIRECT_INT; }
|
||||||
bool IsUInt() const { return type_ == TYPE_UINT||
|
bool IsUInt() const { return type_ == TYPE_UINT||
|
||||||
@@ -358,6 +364,11 @@ class Reference {
|
|||||||
bool IsKey() const { return type_ == TYPE_KEY; }
|
bool IsKey() const { return type_ == TYPE_KEY; }
|
||||||
bool IsVector() const { return type_ == TYPE_VECTOR || type_ == TYPE_MAP; }
|
bool IsVector() const { return type_ == TYPE_VECTOR || type_ == TYPE_MAP; }
|
||||||
bool IsMap() const { return type_ == TYPE_MAP; }
|
bool IsMap() const { return type_ == TYPE_MAP; }
|
||||||
|
bool IsBlob() const { return type_ == TYPE_BLOB; }
|
||||||
|
|
||||||
|
bool AsBool() const {
|
||||||
|
return (type_ == TYPE_BOOL ? ReadUInt64(data_, parent_width_) : AsUInt64()) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
// Reads any type as a int64_t. Never fails, does most sensible conversion.
|
// Reads any type as a int64_t. Never fails, does most sensible conversion.
|
||||||
// Truncates floats, strings are attempted to be parsed for a number,
|
// Truncates floats, strings are attempted to be parsed for a number,
|
||||||
@@ -377,6 +388,7 @@ class Reference {
|
|||||||
case TYPE_NULL: return 0;
|
case TYPE_NULL: return 0;
|
||||||
case TYPE_STRING: return flatbuffers::StringToInt(AsString().c_str());
|
case TYPE_STRING: return flatbuffers::StringToInt(AsString().c_str());
|
||||||
case TYPE_VECTOR: return static_cast<int64_t>(AsVector().size());
|
case TYPE_VECTOR: return static_cast<int64_t>(AsVector().size());
|
||||||
|
case TYPE_BOOL: return ReadInt64(data_, parent_width_);
|
||||||
default:
|
default:
|
||||||
// Convert other things to int.
|
// Convert other things to int.
|
||||||
return 0;
|
return 0;
|
||||||
@@ -404,6 +416,7 @@ class Reference {
|
|||||||
case TYPE_NULL: return 0;
|
case TYPE_NULL: return 0;
|
||||||
case TYPE_STRING: return flatbuffers::StringToUInt(AsString().c_str());
|
case TYPE_STRING: return flatbuffers::StringToUInt(AsString().c_str());
|
||||||
case TYPE_VECTOR: return static_cast<uint64_t>(AsVector().size());
|
case TYPE_VECTOR: return static_cast<uint64_t>(AsVector().size());
|
||||||
|
case TYPE_BOOL: return ReadUInt64(data_, parent_width_);
|
||||||
default:
|
default:
|
||||||
// Convert other things to uint.
|
// Convert other things to uint.
|
||||||
return 0;
|
return 0;
|
||||||
@@ -431,6 +444,8 @@ class Reference {
|
|||||||
case TYPE_NULL: return 0.0;
|
case TYPE_NULL: return 0.0;
|
||||||
case TYPE_STRING: return strtod(AsString().c_str(), nullptr);
|
case TYPE_STRING: return strtod(AsString().c_str(), nullptr);
|
||||||
case TYPE_VECTOR: return static_cast<double>(AsVector().size());
|
case TYPE_VECTOR: return static_cast<double>(AsVector().size());
|
||||||
|
case TYPE_BOOL: return static_cast<double>(
|
||||||
|
ReadUInt64(data_, parent_width_));
|
||||||
default:
|
default:
|
||||||
// Convert strings and other things to float.
|
// Convert strings and other things to float.
|
||||||
return 0;
|
return 0;
|
||||||
@@ -490,6 +505,8 @@ class Reference {
|
|||||||
s += flatbuffers::NumToString(AsDouble());
|
s += flatbuffers::NumToString(AsDouble());
|
||||||
} else if (IsNull()) {
|
} else if (IsNull()) {
|
||||||
s += "null";
|
s += "null";
|
||||||
|
} else if (IsBool()) {
|
||||||
|
s += AsBool() ? "true" : "false";
|
||||||
} else if (IsMap()) {
|
} else if (IsMap()) {
|
||||||
s += "{ ";
|
s += "{ ";
|
||||||
auto m = AsMap();
|
auto m = AsMap();
|
||||||
@@ -562,6 +579,8 @@ class Reference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T> T As();
|
||||||
|
|
||||||
// Experimental: Mutation functions.
|
// Experimental: Mutation functions.
|
||||||
// These allow scalars in an already created buffer to be updated in-place.
|
// These allow scalars in an already created buffer to be updated in-place.
|
||||||
// Since by default scalars are stored in the smallest possible space,
|
// Since by default scalars are stored in the smallest possible space,
|
||||||
@@ -584,6 +603,10 @@ class Reference {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool MutateBool(bool b) {
|
||||||
|
return type_ == TYPE_BOOL && Mutate(data_, b, parent_width_, BIT_WIDTH_8);
|
||||||
|
}
|
||||||
|
|
||||||
bool MutateUInt(uint64_t u) {
|
bool MutateUInt(uint64_t u) {
|
||||||
if (type_ == TYPE_UINT) {
|
if (type_ == TYPE_UINT) {
|
||||||
return Mutate(data_, u, parent_width_, WidthU(u));
|
return Mutate(data_, u, parent_width_, WidthU(u));
|
||||||
@@ -667,6 +690,31 @@ class Reference {
|
|||||||
Type type_;
|
Type type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Template specialization for As().
|
||||||
|
template<> inline bool Reference::As<bool>() { return AsBool(); }
|
||||||
|
|
||||||
|
template<> inline int8_t Reference::As<int8_t>() { return AsInt8(); }
|
||||||
|
template<> inline int16_t Reference::As<int16_t>() { return AsInt16(); }
|
||||||
|
template<> inline int32_t Reference::As<int32_t>() { return AsInt32(); }
|
||||||
|
template<> inline int64_t Reference::As<int64_t>() { return AsInt64(); }
|
||||||
|
|
||||||
|
template<> inline uint8_t Reference::As<uint8_t>() { return AsUInt8(); }
|
||||||
|
template<> inline uint16_t Reference::As<uint16_t>() { return AsUInt16(); }
|
||||||
|
template<> inline uint32_t Reference::As<uint32_t>() { return AsUInt32(); }
|
||||||
|
template<> inline uint64_t Reference::As<uint64_t>() { return AsUInt64(); }
|
||||||
|
|
||||||
|
template<> inline double Reference::As<double>() { return AsDouble(); }
|
||||||
|
template<> inline float Reference::As<float>() { return AsFloat(); }
|
||||||
|
|
||||||
|
template<> inline String Reference::As<String>() { return AsString(); }
|
||||||
|
template<> inline std::string Reference::As<std::string>() { return AsString().str(); }
|
||||||
|
|
||||||
|
template<> inline Blob Reference::As<Blob>() { return AsBlob(); }
|
||||||
|
template<> inline Vector Reference::As<Vector>() { return AsVector(); }
|
||||||
|
template<> inline TypedVector Reference::As<TypedVector>() { return AsTypedVector(); }
|
||||||
|
template<> inline FixedTypedVector Reference::As<FixedTypedVector>() { return AsFixedTypedVector(); }
|
||||||
|
template<> inline Map Reference::As<Map>() { return AsMap(); }
|
||||||
|
|
||||||
inline uint8_t PackedType(BitWidth bit_width, Type type) {
|
inline uint8_t PackedType(BitWidth bit_width, Type type) {
|
||||||
return static_cast<uint8_t>(bit_width | (type << 2));
|
return static_cast<uint8_t>(bit_width | (type << 2));
|
||||||
}
|
}
|
||||||
@@ -743,7 +791,7 @@ inline Reference GetRoot(const uint8_t *buffer, size_t size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline Reference GetRoot(const std::vector<uint8_t> &buffer) {
|
inline Reference GetRoot(const std::vector<uint8_t> &buffer) {
|
||||||
return GetRoot(buffer.data(), buffer.size());
|
return GetRoot(flatbuffers::vector_data(buffer), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flags that configure how the Builder behaves.
|
// Flags that configure how the Builder behaves.
|
||||||
@@ -782,6 +830,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
return buf_;
|
return buf_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Size of the buffer. Does not include unfinished values.
|
||||||
|
size_t GetSize() const {
|
||||||
|
return buf_.size();
|
||||||
|
}
|
||||||
|
|
||||||
// Reset all state so we can re-use the buffer.
|
// Reset all state so we can re-use the buffer.
|
||||||
void Clear() {
|
void Clear() {
|
||||||
buf_.clear();
|
buf_.clear();
|
||||||
@@ -812,7 +865,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
void Double(double f) { stack_.push_back(Value(f)); }
|
void Double(double f) { stack_.push_back(Value(f)); }
|
||||||
void Double(const char *key, double d) { Key(key); Double(d); }
|
void Double(const char *key, double d) { Key(key); Double(d); }
|
||||||
|
|
||||||
void Bool(bool b) { Int(static_cast<int64_t>(b)); }
|
void Bool(bool b) { stack_.push_back(Value(b)); }
|
||||||
void Bool(const char *key, bool b) { Key(key); Bool(b); }
|
void Bool(const char *key, bool b) { Key(key); Bool(b); }
|
||||||
|
|
||||||
void IndirectInt(int64_t i) {
|
void IndirectInt(int64_t i) {
|
||||||
@@ -913,7 +966,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
return CreateBlob(data, len, 0, TYPE_BLOB);
|
return CreateBlob(data, len, 0, TYPE_BLOB);
|
||||||
}
|
}
|
||||||
size_t Blob(const std::vector<uint8_t> &v) {
|
size_t Blob(const std::vector<uint8_t> &v) {
|
||||||
return CreateBlob(v.data(), v.size(), 0, TYPE_BLOB);
|
return CreateBlob(flatbuffers::vector_data(v), v.size(), 0, TYPE_BLOB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO(wvo): support all the FlexBuffer types (like flexbuffers::String),
|
// TODO(wvo): support all the FlexBuffer types (like flexbuffers::String),
|
||||||
@@ -957,11 +1010,15 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
// step automatically when appliccable, and encourage people to write in
|
// step automatically when appliccable, and encourage people to write in
|
||||||
// sorted fashion.
|
// sorted fashion.
|
||||||
// std::sort is typically already a lot faster on sorted data though.
|
// std::sort is typically already a lot faster on sorted data though.
|
||||||
auto dict = reinterpret_cast<TwoValue *>(stack_.data() + start);
|
auto dict =
|
||||||
|
reinterpret_cast<TwoValue *>(flatbuffers::vector_data(stack_) +
|
||||||
|
start);
|
||||||
std::sort(dict, dict + len,
|
std::sort(dict, dict + len,
|
||||||
[&](const TwoValue &a, const TwoValue &b) -> bool {
|
[&](const TwoValue &a, const TwoValue &b) -> bool {
|
||||||
auto as = reinterpret_cast<const char *>(buf_.data() + a.key.u_);
|
auto as = reinterpret_cast<const char *>(
|
||||||
auto bs = reinterpret_cast<const char *>(buf_.data() + b.key.u_);
|
flatbuffers::vector_data(buf_) + a.key.u_);
|
||||||
|
auto bs = reinterpret_cast<const char *>(
|
||||||
|
flatbuffers::vector_data(buf_) + b.key.u_);
|
||||||
auto comp = strcmp(as, bs);
|
auto comp = strcmp(as, bs);
|
||||||
// If this assertion hits, you've added two keys with the same value to
|
// If this assertion hits, you've added two keys with the same value to
|
||||||
// this map.
|
// this map.
|
||||||
@@ -986,13 +1043,25 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
f();
|
f();
|
||||||
return EndVector(start, false, false);
|
return EndVector(start, false, false);
|
||||||
}
|
}
|
||||||
|
template <typename F, typename T> size_t Vector(F f, T &state) {
|
||||||
|
auto start = StartVector();
|
||||||
|
f(state);
|
||||||
|
return EndVector(start, false, false);
|
||||||
|
}
|
||||||
template<typename F> size_t Vector(const char *key, F f) {
|
template<typename F> size_t Vector(const char *key, F f) {
|
||||||
auto start = StartVector(key);
|
auto start = StartVector(key);
|
||||||
f();
|
f();
|
||||||
return EndVector(start, false, false);
|
return EndVector(start, false, false);
|
||||||
}
|
}
|
||||||
|
template <typename F, typename T> size_t Vector(const char *key, F f,
|
||||||
|
T &state) {
|
||||||
|
auto start = StartVector(key);
|
||||||
|
f(state);
|
||||||
|
return EndVector(start, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> void Vector(const T *elems, size_t len) {
|
template<typename T> void Vector(const T *elems, size_t len) {
|
||||||
if (std::is_scalar<T>::value) {
|
if (flatbuffers::is_scalar<T>::value) {
|
||||||
// This path should be a lot quicker and use less space.
|
// This path should be a lot quicker and use less space.
|
||||||
ScalarVector(elems, len, false);
|
ScalarVector(elems, len, false);
|
||||||
} else {
|
} else {
|
||||||
@@ -1007,7 +1076,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
Vector(elems, len);
|
Vector(elems, len);
|
||||||
}
|
}
|
||||||
template<typename T> void Vector(const std::vector<T> &vec) {
|
template<typename T> void Vector(const std::vector<T> &vec) {
|
||||||
Vector(vec.data(), vec.size());
|
Vector(flatbuffers::vector_data(vec), vec.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename F> size_t TypedVector(F f) {
|
template<typename F> size_t TypedVector(F f) {
|
||||||
@@ -1015,18 +1084,29 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
f();
|
f();
|
||||||
return EndVector(start, true, false);
|
return EndVector(start, true, false);
|
||||||
}
|
}
|
||||||
|
template <typename F, typename T> size_t TypedVector(F f, T &state) {
|
||||||
|
auto start = StartVector();
|
||||||
|
f(state);
|
||||||
|
return EndVector(start, true, false);
|
||||||
|
}
|
||||||
template<typename F> size_t TypedVector(const char *key, F f) {
|
template<typename F> size_t TypedVector(const char *key, F f) {
|
||||||
auto start = StartVector(key);
|
auto start = StartVector(key);
|
||||||
f();
|
f();
|
||||||
return EndVector(start, true, false);
|
return EndVector(start, true, false);
|
||||||
}
|
}
|
||||||
|
template <typename F, typename T> size_t TypedVector(const char *key, F f,
|
||||||
|
T &state) {
|
||||||
|
auto start = StartVector(key);
|
||||||
|
f(state);
|
||||||
|
return EndVector(start, true, false);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T> size_t FixedTypedVector(const T *elems, size_t len) {
|
template<typename T> size_t FixedTypedVector(const T *elems, size_t len) {
|
||||||
// We only support a few fixed vector lengths. Anything bigger use a
|
// We only support a few fixed vector lengths. Anything bigger use a
|
||||||
// regular typed vector.
|
// regular typed vector.
|
||||||
assert(len >= 2 && len <= 4);
|
assert(len >= 2 && len <= 4);
|
||||||
// And only scalar values.
|
// And only scalar values.
|
||||||
assert(std::is_scalar<T>::value);
|
assert(flatbuffers::is_scalar<T>::value);
|
||||||
return ScalarVector(elems, len, true);
|
return ScalarVector(elems, len, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,11 +1121,22 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
f();
|
f();
|
||||||
return EndMap(start);
|
return EndMap(start);
|
||||||
}
|
}
|
||||||
|
template <typename F, typename T> size_t Map(F f, T &state) {
|
||||||
|
auto start = StartMap();
|
||||||
|
f(state);
|
||||||
|
return EndMap(start);
|
||||||
|
}
|
||||||
template<typename F> size_t Map(const char *key, F f) {
|
template<typename F> size_t Map(const char *key, F f) {
|
||||||
auto start = StartMap(key);
|
auto start = StartMap(key);
|
||||||
f();
|
f();
|
||||||
return EndMap(start);
|
return EndMap(start);
|
||||||
}
|
}
|
||||||
|
template <typename F, typename T> size_t Map(const char *key, F f,
|
||||||
|
T &state) {
|
||||||
|
auto start = StartMap(key);
|
||||||
|
f(state);
|
||||||
|
return EndMap(start);
|
||||||
|
}
|
||||||
template<typename T> void Map(const std::map<std::string, T> &map) {
|
template<typename T> void Map(const std::map<std::string, T> &map) {
|
||||||
auto start = StartMap();
|
auto start = StartMap();
|
||||||
for (auto it = map.begin(); it != map.end(); ++it)
|
for (auto it = map.begin(); it != map.end(); ++it)
|
||||||
@@ -1174,10 +1265,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> static Type GetScalarType() {
|
template<typename T> static Type GetScalarType() {
|
||||||
assert(std::is_scalar<T>::value);
|
assert(flatbuffers::is_scalar<T>::value);
|
||||||
return std::is_floating_point<T>::value
|
return flatbuffers::is_floating_point<T>::value
|
||||||
? TYPE_FLOAT
|
? TYPE_FLOAT
|
||||||
: (std::is_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
|
: flatbuffers::is_same<T, bool>::value ? TYPE_BOOL
|
||||||
|
: (flatbuffers::is_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Value {
|
struct Value {
|
||||||
@@ -1194,6 +1286,8 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
Value() : i_(0), type_(TYPE_NULL), min_bit_width_(BIT_WIDTH_8) {}
|
Value() : i_(0), type_(TYPE_NULL), min_bit_width_(BIT_WIDTH_8) {}
|
||||||
|
|
||||||
|
Value(bool b) : u_(static_cast<uint64_t>(b)), type_(TYPE_BOOL), min_bit_width_(BIT_WIDTH_8) {}
|
||||||
|
|
||||||
Value(int64_t i, Type t, BitWidth bw)
|
Value(int64_t i, Type t, BitWidth bw)
|
||||||
: i_(i), type_(t), min_bit_width_(bw) {}
|
: i_(i), type_(t), min_bit_width_(bw) {}
|
||||||
Value(uint64_t u, Type t, BitWidth bw)
|
Value(uint64_t u, Type t, BitWidth bw)
|
||||||
@@ -1239,7 +1333,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
|
BitWidth StoredWidth(BitWidth parent_bit_width_ = BIT_WIDTH_8) const {
|
||||||
if (IsInline(type_)) {
|
if (IsInline(type_)) {
|
||||||
return std::max(min_bit_width_, parent_bit_width_);
|
return (std::max)(min_bit_width_, parent_bit_width_);
|
||||||
} else {
|
} else {
|
||||||
return min_bit_width_;
|
return min_bit_width_;
|
||||||
}
|
}
|
||||||
@@ -1252,6 +1346,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
case TYPE_INT:
|
case TYPE_INT:
|
||||||
Write(val.i_, byte_width);
|
Write(val.i_, byte_width);
|
||||||
break;
|
break;
|
||||||
|
case TYPE_BOOL:
|
||||||
case TYPE_UINT:
|
case TYPE_UINT:
|
||||||
Write(val.u_, byte_width);
|
Write(val.u_, byte_width);
|
||||||
break;
|
break;
|
||||||
@@ -1297,19 +1392,19 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
|
Value CreateVector(size_t start, size_t vec_len, size_t step, bool typed,
|
||||||
bool fixed, const Value *keys = nullptr) {
|
bool fixed, const Value *keys = nullptr) {
|
||||||
// Figure out smallest bit width we can store this vector with.
|
// Figure out smallest bit width we can store this vector with.
|
||||||
auto bit_width = std::max(force_min_bit_width_, WidthU(vec_len));
|
auto bit_width = (std::max)(force_min_bit_width_, WidthU(vec_len));
|
||||||
auto prefix_elems = 1;
|
auto prefix_elems = 1;
|
||||||
if (keys) {
|
if (keys) {
|
||||||
// If this vector is part of a map, we will pre-fix an offset to the keys
|
// If this vector is part of a map, we will pre-fix an offset to the keys
|
||||||
// to this vector.
|
// to this vector.
|
||||||
bit_width = std::max(bit_width, keys->ElemWidth(buf_.size(), 0));
|
bit_width = (std::max)(bit_width, keys->ElemWidth(buf_.size(), 0));
|
||||||
prefix_elems += 2;
|
prefix_elems += 2;
|
||||||
}
|
}
|
||||||
Type vector_type = TYPE_KEY;
|
Type vector_type = TYPE_KEY;
|
||||||
// Check bit widths and types for all elements.
|
// Check bit widths and types for all elements.
|
||||||
for (size_t i = start; i < stack_.size(); i += step) {
|
for (size_t i = start; i < stack_.size(); i += step) {
|
||||||
auto elem_width = stack_[i].ElemWidth(buf_.size(), i + prefix_elems);
|
auto elem_width = stack_[i].ElemWidth(buf_.size(), i + prefix_elems);
|
||||||
bit_width = std::max(bit_width, elem_width);
|
bit_width = (std::max)(bit_width, elem_width);
|
||||||
if (typed) {
|
if (typed) {
|
||||||
if (i == start) {
|
if (i == start) {
|
||||||
vector_type = stack_[i].type_;
|
vector_type = stack_[i].type_;
|
||||||
@@ -1364,9 +1459,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
|
|
||||||
struct KeyOffsetCompare {
|
struct KeyOffsetCompare {
|
||||||
KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
|
KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
|
||||||
bool operator() (size_t a, size_t b) const {
|
bool operator()(size_t a, size_t b) const {
|
||||||
auto stra = reinterpret_cast<const char *>(buf_->data() + a);
|
auto stra =
|
||||||
auto strb = reinterpret_cast<const char *>(buf_->data() + b);
|
reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + a);
|
||||||
|
auto strb =
|
||||||
|
reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) + b);
|
||||||
return strcmp(stra, strb) < 0;
|
return strcmp(stra, strb) < 0;
|
||||||
}
|
}
|
||||||
const std::vector<uint8_t> *buf_;
|
const std::vector<uint8_t> *buf_;
|
||||||
@@ -1375,10 +1472,12 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
|||||||
typedef std::pair<size_t, size_t> StringOffset;
|
typedef std::pair<size_t, size_t> StringOffset;
|
||||||
struct StringOffsetCompare {
|
struct StringOffsetCompare {
|
||||||
StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
|
StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
|
||||||
bool operator() (const StringOffset &a, const StringOffset &b) const {
|
bool operator()(const StringOffset &a, const StringOffset &b) const {
|
||||||
auto stra = reinterpret_cast<const char *>(buf_->data() + a.first);
|
auto stra = reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) +
|
||||||
auto strb = reinterpret_cast<const char *>(buf_->data() + b.first);
|
a.first);
|
||||||
return strncmp(stra, strb, std::min(a.second, b.second) + 1) < 0;
|
auto strb = reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) +
|
||||||
|
b.first);
|
||||||
|
return strncmp(stra, strb, (std::min)(a.second, b.second) + 1) < 0;
|
||||||
}
|
}
|
||||||
const std::vector<uint8_t> *buf_;
|
const std::vector<uint8_t> *buf_;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,13 +20,17 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
|
||||||
|
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
#include "flatbuffers/flatbuffers.h"
|
#include "flatbuffers/flatbuffers.h"
|
||||||
#include "flatbuffers/hash.h"
|
#include "flatbuffers/hash.h"
|
||||||
#include "flatbuffers/reflection.h"
|
#include "flatbuffers/reflection.h"
|
||||||
#include "flatbuffers/flexbuffers.h"
|
#include "flatbuffers/flexbuffers.h"
|
||||||
|
|
||||||
|
#if !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#include <functional>
|
||||||
|
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
// This file defines the data types representing a parsed IDL (Interface
|
// This file defines the data types representing a parsed IDL (Interface
|
||||||
// Definition Language) / schema file.
|
// Definition Language) / schema file.
|
||||||
|
|
||||||
@@ -105,6 +109,7 @@ inline bool IsFloat (BaseType t) { return t == BASE_TYPE_FLOAT ||
|
|||||||
t == BASE_TYPE_DOUBLE; }
|
t == BASE_TYPE_DOUBLE; }
|
||||||
inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
||||||
t == BASE_TYPE_ULONG; }
|
t == BASE_TYPE_ULONG; }
|
||||||
|
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
|
||||||
|
|
||||||
extern const char *const kTypeNames[];
|
extern const char *const kTypeNames[];
|
||||||
extern const char kTypeSizes[];
|
extern const char kTypeSizes[];
|
||||||
@@ -164,7 +169,7 @@ template<typename T> class SymbolTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Add(const std::string &name, T *e) {
|
bool Add(const std::string &name, T *e) {
|
||||||
vec.emplace_back(e);
|
vector_emplace_back(&vec, e);
|
||||||
auto it = dict.find(name);
|
auto it = dict.find(name);
|
||||||
if (it != dict.end()) return true;
|
if (it != dict.end()) return true;
|
||||||
dict[name] = e;
|
dict[name] = e;
|
||||||
@@ -194,7 +199,8 @@ template<typename T> class SymbolTable {
|
|||||||
|
|
||||||
// A name space, as set in the schema.
|
// A name space, as set in the schema.
|
||||||
struct Namespace {
|
struct Namespace {
|
||||||
std::vector<std::string> components;
|
Namespace() : from_table(0) {}
|
||||||
|
|
||||||
|
|
||||||
// Given a (potentally unqualified) name, return the "fully qualified" name
|
// Given a (potentally unqualified) name, return the "fully qualified" name
|
||||||
// which has a full namespaced descriptor.
|
// which has a full namespaced descriptor.
|
||||||
@@ -202,12 +208,15 @@ struct Namespace {
|
|||||||
// the current namespace has.
|
// the current namespace has.
|
||||||
std::string GetFullyQualifiedName(const std::string &name,
|
std::string GetFullyQualifiedName(const std::string &name,
|
||||||
size_t max_components = 1000) const;
|
size_t max_components = 1000) const;
|
||||||
|
|
||||||
|
std::vector<std::string> components;
|
||||||
|
size_t from_table; // Part of the namespace corresponds to a message/table.
|
||||||
};
|
};
|
||||||
|
|
||||||
// Base class for all definition types (fields, structs_, enums_).
|
// Base class for all definition types (fields, structs_, enums_).
|
||||||
struct Definition {
|
struct Definition {
|
||||||
Definition() : generated(false), defined_namespace(nullptr),
|
Definition() : generated(false), defined_namespace(nullptr),
|
||||||
serialized_location(0), index(-1) {}
|
serialized_location(0), index(-1), refcount(1) {}
|
||||||
|
|
||||||
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<
|
flatbuffers::Offset<flatbuffers::Vector<flatbuffers::Offset<
|
||||||
reflection::KeyValue>>>
|
reflection::KeyValue>>>
|
||||||
@@ -224,11 +233,13 @@ struct Definition {
|
|||||||
// For use with Serialize()
|
// For use with Serialize()
|
||||||
uoffset_t serialized_location;
|
uoffset_t serialized_location;
|
||||||
int index; // Inside the vector it is stored.
|
int index; // Inside the vector it is stored.
|
||||||
|
int refcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FieldDef : public Definition {
|
struct FieldDef : public Definition {
|
||||||
FieldDef() : deprecated(false), required(false), key(false),
|
FieldDef() : deprecated(false), required(false), key(false),
|
||||||
flexbuffer(false), padding(0) {}
|
native_inline(false), flexbuffer(false), nested_flatbuffer(NULL),
|
||||||
|
padding(0) {}
|
||||||
|
|
||||||
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
|
Offset<reflection::Field> Serialize(FlatBufferBuilder *builder, uint16_t id,
|
||||||
const Parser &parser) const;
|
const Parser &parser) const;
|
||||||
@@ -241,6 +252,7 @@ struct FieldDef : public Definition {
|
|||||||
bool native_inline; // Field will be defined inline (instead of as a pointer)
|
bool native_inline; // Field will be defined inline (instead of as a pointer)
|
||||||
// for native tables if field is a struct.
|
// for native tables if field is a struct.
|
||||||
bool flexbuffer; // This field contains FlexBuffer data.
|
bool flexbuffer; // This field contains FlexBuffer data.
|
||||||
|
StructDef *nested_flatbuffer; // This field contains nested FlatBuffer data.
|
||||||
size_t padding; // Bytes to always pad after this field.
|
size_t padding; // Bytes to always pad after this field.
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -264,12 +276,15 @@ struct StructDef : public Definition {
|
|||||||
const Parser &parser) const;
|
const Parser &parser) const;
|
||||||
|
|
||||||
SymbolTable<FieldDef> fields;
|
SymbolTable<FieldDef> fields;
|
||||||
|
|
||||||
bool fixed; // If it's struct, not a table.
|
bool fixed; // If it's struct, not a table.
|
||||||
bool predecl; // If it's used before it was defined.
|
bool predecl; // If it's used before it was defined.
|
||||||
bool sortbysize; // Whether fields come in the declaration or size order.
|
bool sortbysize; // Whether fields come in the declaration or size order.
|
||||||
bool has_key; // It has a key field.
|
bool has_key; // It has a key field.
|
||||||
size_t minalign; // What the whole object needs to be aligned to.
|
size_t minalign; // What the whole object needs to be aligned to.
|
||||||
size_t bytesize; // Size if fixed.
|
size_t bytesize; // Size if fixed.
|
||||||
|
|
||||||
|
flatbuffers::unique_ptr<std::string> original_location;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool IsStruct(const Type &type) {
|
inline bool IsStruct(const Type &type) {
|
||||||
@@ -354,16 +369,19 @@ struct IDLOptions {
|
|||||||
bool generate_all;
|
bool generate_all;
|
||||||
bool skip_unexpected_fields_in_json;
|
bool skip_unexpected_fields_in_json;
|
||||||
bool generate_name_strings;
|
bool generate_name_strings;
|
||||||
bool escape_proto_identifiers;
|
|
||||||
bool generate_object_based_api;
|
bool generate_object_based_api;
|
||||||
std::string cpp_object_api_pointer_type;
|
std::string cpp_object_api_pointer_type;
|
||||||
std::string cpp_object_api_string_type;
|
std::string cpp_object_api_string_type;
|
||||||
|
bool gen_nullable;
|
||||||
|
std::string object_prefix;
|
||||||
|
std::string object_suffix;
|
||||||
bool union_value_namespacing;
|
bool union_value_namespacing;
|
||||||
bool allow_non_utf8;
|
bool allow_non_utf8;
|
||||||
std::string include_prefix;
|
std::string include_prefix;
|
||||||
bool keep_include_path;
|
bool keep_include_path;
|
||||||
bool binary_schema_comments;
|
bool binary_schema_comments;
|
||||||
bool skip_flatbuffers_import;
|
bool skip_flatbuffers_import;
|
||||||
|
std::string go_import;
|
||||||
std::string go_namespace;
|
std::string go_namespace;
|
||||||
bool reexport_ts_modules;
|
bool reexport_ts_modules;
|
||||||
bool protobuf_ascii_alike;
|
bool protobuf_ascii_alike;
|
||||||
@@ -380,11 +398,16 @@ struct IDLOptions {
|
|||||||
kJson = 1 << 7,
|
kJson = 1 << 7,
|
||||||
kBinary = 1 << 8,
|
kBinary = 1 << 8,
|
||||||
kTs = 1 << 9,
|
kTs = 1 << 9,
|
||||||
|
kJsonSchema = 1 << 10,
|
||||||
kMAX
|
kMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
Language lang;
|
Language lang;
|
||||||
|
|
||||||
|
enum MiniReflect { kNone, kTypes, kTypesAndNames };
|
||||||
|
|
||||||
|
MiniReflect mini_reflect;
|
||||||
|
|
||||||
// The corresponding language bit will be set if a language is included
|
// The corresponding language bit will be set if a language is included
|
||||||
// for code generation.
|
// for code generation.
|
||||||
unsigned long lang_to_generate;
|
unsigned long lang_to_generate;
|
||||||
@@ -403,9 +426,10 @@ struct IDLOptions {
|
|||||||
generate_all(false),
|
generate_all(false),
|
||||||
skip_unexpected_fields_in_json(false),
|
skip_unexpected_fields_in_json(false),
|
||||||
generate_name_strings(false),
|
generate_name_strings(false),
|
||||||
escape_proto_identifiers(false),
|
|
||||||
generate_object_based_api(false),
|
generate_object_based_api(false),
|
||||||
cpp_object_api_pointer_type("std::unique_ptr"),
|
cpp_object_api_pointer_type("std::unique_ptr"),
|
||||||
|
gen_nullable(false),
|
||||||
|
object_suffix("T"),
|
||||||
union_value_namespacing(true),
|
union_value_namespacing(true),
|
||||||
allow_non_utf8(false),
|
allow_non_utf8(false),
|
||||||
keep_include_path(false),
|
keep_include_path(false),
|
||||||
@@ -414,6 +438,7 @@ struct IDLOptions {
|
|||||||
reexport_ts_modules(true),
|
reexport_ts_modules(true),
|
||||||
protobuf_ascii_alike(false),
|
protobuf_ascii_alike(false),
|
||||||
lang(IDLOptions::kJava),
|
lang(IDLOptions::kJava),
|
||||||
|
mini_reflect(IDLOptions::kNone),
|
||||||
lang_to_generate(0) {}
|
lang_to_generate(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -474,13 +499,17 @@ class CheckedError {
|
|||||||
class Parser : public ParserState {
|
class Parser : public ParserState {
|
||||||
public:
|
public:
|
||||||
explicit Parser(const IDLOptions &options = IDLOptions())
|
explicit Parser(const IDLOptions &options = IDLOptions())
|
||||||
: root_struct_def_(nullptr),
|
: current_namespace_(nullptr),
|
||||||
|
empty_namespace_(nullptr),
|
||||||
|
root_struct_def_(nullptr),
|
||||||
opts(options),
|
opts(options),
|
||||||
uses_flexbuffers_(false),
|
uses_flexbuffers_(false),
|
||||||
source_(nullptr),
|
source_(nullptr),
|
||||||
anonymous_counter(0) {
|
anonymous_counter(0) {
|
||||||
// Just in case none are declared:
|
// Start out with the empty namespace being current.
|
||||||
namespaces_.push_back(new Namespace());
|
empty_namespace_ = new Namespace();
|
||||||
|
namespaces_.push_back(empty_namespace_);
|
||||||
|
current_namespace_ = empty_namespace_;
|
||||||
known_attributes_["deprecated"] = true;
|
known_attributes_["deprecated"] = true;
|
||||||
known_attributes_["required"] = true;
|
known_attributes_["required"] = true;
|
||||||
known_attributes_["key"] = true;
|
known_attributes_["key"] = true;
|
||||||
@@ -548,12 +577,17 @@ class Parser : public ParserState {
|
|||||||
|
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckInRange(int64_t val, int64_t min, int64_t max);
|
FLATBUFFERS_CHECKED_ERROR CheckInRange(int64_t val, int64_t min, int64_t max);
|
||||||
|
|
||||||
|
StructDef *LookupStruct(const std::string &id) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Message(const std::string &msg);
|
||||||
|
void Warning(const std::string &msg);
|
||||||
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
FLATBUFFERS_CHECKED_ERROR Error(const std::string &msg);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
|
FLATBUFFERS_CHECKED_ERROR ParseHexNum(int nibbles, uint64_t *val);
|
||||||
FLATBUFFERS_CHECKED_ERROR Next();
|
FLATBUFFERS_CHECKED_ERROR Next();
|
||||||
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
FLATBUFFERS_CHECKED_ERROR SkipByteOrderMark();
|
||||||
bool Is(int t);
|
bool Is(int t);
|
||||||
|
bool IsIdent(const char *id);
|
||||||
FLATBUFFERS_CHECKED_ERROR Expect(int t);
|
FLATBUFFERS_CHECKED_ERROR Expect(int t);
|
||||||
std::string TokenToStringId(int t);
|
std::string TokenToStringId(int t);
|
||||||
EnumDef *LookupEnum(const std::string &id);
|
EnumDef *LookupEnum(const std::string &id);
|
||||||
@@ -570,16 +604,36 @@ private:
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
||||||
size_t parent_fieldn,
|
size_t parent_fieldn,
|
||||||
const StructDef *parent_struct_def);
|
const StructDef *parent_struct_def);
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
typedef CheckedError (*ParseTableDelimitersBody)(
|
||||||
|
const std::string &name, size_t &fieldn, const StructDef *struct_def,
|
||||||
|
void *state);
|
||||||
|
#else
|
||||||
|
typedef std::function<CheckedError(const std::string&, size_t&,
|
||||||
|
const StructDef*, void*)>
|
||||||
|
ParseTableDelimitersBody;
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
|
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
|
||||||
const StructDef *struct_def,
|
const StructDef *struct_def,
|
||||||
const std::function<CheckedError(const std::string &name)> &body);
|
ParseTableDelimitersBody body,
|
||||||
|
void *state);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
FLATBUFFERS_CHECKED_ERROR ParseTable(const StructDef &struct_def,
|
||||||
std::string *value, uoffset_t *ovalue);
|
std::string *value, uoffset_t *ovalue);
|
||||||
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
void SerializeStruct(const StructDef &struct_def, const Value &val);
|
||||||
void AddVector(bool sortbysize, int count);
|
void AddVector(bool sortbysize, int count);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t &count,
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
const std::function<CheckedError()> &body);
|
typedef CheckedError (*ParseVectorDelimitersBody)(size_t &count,
|
||||||
|
void *state);
|
||||||
|
#else
|
||||||
|
typedef std::function<CheckedError(size_t&, void*)>
|
||||||
|
ParseVectorDelimitersBody;
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(
|
||||||
|
size_t &count, ParseVectorDelimitersBody body, void *state);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue);
|
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue);
|
||||||
|
FLATBUFFERS_CHECKED_ERROR ParseNestedFlatbuffer(Value &val, FieldDef *field,
|
||||||
|
size_t fieldn,
|
||||||
|
const StructDef *parent_struct_def);
|
||||||
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
|
FLATBUFFERS_CHECKED_ERROR ParseMetaData(SymbolTable<Value> *attributes);
|
||||||
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e,
|
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e,
|
||||||
BaseType req, bool *destmatch);
|
BaseType req, bool *destmatch);
|
||||||
@@ -607,21 +661,29 @@ private:
|
|||||||
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
|
FLATBUFFERS_CHECKED_ERROR ParseFlexBufferValue(flexbuffers::Builder *builder);
|
||||||
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
FLATBUFFERS_CHECKED_ERROR StartParseFile(const char *source,
|
||||||
const char *source_filename);
|
const char *source_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
FLATBUFFERS_CHECKED_ERROR ParseRoot(const char *_source,
|
||||||
const char **include_paths,
|
const char **include_paths,
|
||||||
const char *source_filename,
|
const char *source_filename);
|
||||||
const char *include_filename);
|
FLATBUFFERS_CHECKED_ERROR DoParse(const char *_source,
|
||||||
|
const char **include_paths,
|
||||||
|
const char *source_filename,
|
||||||
|
const char *include_filename);
|
||||||
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
|
FLATBUFFERS_CHECKED_ERROR CheckClash(std::vector<FieldDef*> &fields,
|
||||||
StructDef *struct_def,
|
StructDef *struct_def,
|
||||||
const char *suffix,
|
const char *suffix,
|
||||||
BaseType baseType);
|
BaseType baseType);
|
||||||
|
|
||||||
|
bool SupportsVectorOfUnions() const;
|
||||||
|
Namespace *UniqueNamespace(Namespace *ns);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SymbolTable<Type> types_;
|
SymbolTable<Type> types_;
|
||||||
SymbolTable<StructDef> structs_;
|
SymbolTable<StructDef> structs_;
|
||||||
SymbolTable<EnumDef> enums_;
|
SymbolTable<EnumDef> enums_;
|
||||||
SymbolTable<ServiceDef> services_;
|
SymbolTable<ServiceDef> services_;
|
||||||
std::vector<Namespace *> namespaces_;
|
std::vector<Namespace *> namespaces_;
|
||||||
|
Namespace *current_namespace_;
|
||||||
|
Namespace *empty_namespace_;
|
||||||
std::string error_; // User readable error_ if Parse() == false
|
std::string error_; // User readable error_ if Parse() == false
|
||||||
|
|
||||||
FlatBufferBuilder builder_; // any data contained in the file
|
FlatBufferBuilder builder_; // any data contained in the file
|
||||||
@@ -713,6 +775,12 @@ extern bool GeneratePython(const Parser &parser,
|
|||||||
const std::string &path,
|
const std::string &path,
|
||||||
const std::string &file_name);
|
const std::string &file_name);
|
||||||
|
|
||||||
|
// Generate Json schema file
|
||||||
|
// See idl_gen_json_schema.cpp.
|
||||||
|
extern bool GenerateJsonSchema(const Parser &parser,
|
||||||
|
const std::string &path,
|
||||||
|
const std::string &file_name);
|
||||||
|
|
||||||
// Generate C# files from the definitions in the Parser object.
|
// Generate C# files from the definitions in the Parser object.
|
||||||
// See idl_gen_csharp.cpp.
|
// See idl_gen_csharp.cpp.
|
||||||
extern bool GenerateCSharp(const Parser &parser,
|
extern bool GenerateCSharp(const Parser &parser,
|
||||||
|
|||||||
352
include/flatbuffers/minireflect.h
Normal file
352
include/flatbuffers/minireflect.h
Normal file
@@ -0,0 +1,352 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 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 FLATBUFFERS_MINIREFLECT_H_
|
||||||
|
#define FLATBUFFERS_MINIREFLECT_H_
|
||||||
|
|
||||||
|
#include "flatbuffers/flatbuffers.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Utilities that can be used with the "mini reflection" tables present
|
||||||
|
// in generated code with --reflect-types (only types) or --reflect-names
|
||||||
|
// (also names).
|
||||||
|
// This allows basic reflection functionality such as pretty-printing
|
||||||
|
// that does not require the use of the schema parser or loading of binary
|
||||||
|
// schema files at runtime (reflection.h).
|
||||||
|
|
||||||
|
// For any of the functions below that take `const TypeTable *`, you pass
|
||||||
|
// `FooTypeTable()` if the type of the root is `Foo`.
|
||||||
|
|
||||||
|
// First, a generic iterator that can be used by multiple algorithms.
|
||||||
|
|
||||||
|
struct IterationVisitor {
|
||||||
|
// These mark the scope of a table or struct.
|
||||||
|
virtual void StartSequence() {}
|
||||||
|
virtual void EndSequence() {}
|
||||||
|
// Called for each field regardless of wether it is present or not.
|
||||||
|
// If not present, val == nullptr. set_idx is the index of all set fields.
|
||||||
|
virtual void Field(size_t /*field_idx*/, size_t /*set_idx*/,
|
||||||
|
ElementaryType /*type*/, bool /*is_vector*/,
|
||||||
|
const TypeTable * /*type_table*/, const char * /*name*/,
|
||||||
|
const uint8_t * /*val*/) {}
|
||||||
|
// Called for a value that is actually present, after a field, or as part
|
||||||
|
// of a vector.
|
||||||
|
virtual void UType(uint8_t, const char *) {}
|
||||||
|
virtual void Bool(bool) {}
|
||||||
|
virtual void Char(int8_t, const char *) {}
|
||||||
|
virtual void UChar(uint8_t, const char *) {}
|
||||||
|
virtual void Short(int16_t, const char *) {}
|
||||||
|
virtual void UShort(uint16_t, const char *) {}
|
||||||
|
virtual void Int(int32_t, const char *) {}
|
||||||
|
virtual void UInt(uint32_t, const char *) {}
|
||||||
|
virtual void Long(int64_t) {}
|
||||||
|
virtual void ULong(uint64_t) {}
|
||||||
|
virtual void Float(float) {}
|
||||||
|
virtual void Double(double) {}
|
||||||
|
virtual void String(const String *) {}
|
||||||
|
virtual void Unknown(const uint8_t *) {} // From a future version.
|
||||||
|
// These mark the scope of a vector.
|
||||||
|
virtual void StartVector() {}
|
||||||
|
virtual void EndVector() {}
|
||||||
|
virtual void Element(size_t /*i*/, ElementaryType /*type*/,
|
||||||
|
const TypeTable * /*type_table*/,
|
||||||
|
const uint8_t * /*val*/)
|
||||||
|
{}
|
||||||
|
virtual ~IterationVisitor() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline size_t InlineSize(ElementaryType type, const TypeTable *type_table) {
|
||||||
|
switch (type) {
|
||||||
|
case ET_UTYPE:
|
||||||
|
case ET_BOOL:
|
||||||
|
case ET_CHAR:
|
||||||
|
case ET_UCHAR:
|
||||||
|
return 1;
|
||||||
|
case ET_SHORT:
|
||||||
|
case ET_USHORT:
|
||||||
|
return 2;
|
||||||
|
case ET_INT:
|
||||||
|
case ET_UINT:
|
||||||
|
case ET_FLOAT:
|
||||||
|
case ET_STRING:
|
||||||
|
return 4;
|
||||||
|
case ET_LONG:
|
||||||
|
case ET_ULONG:
|
||||||
|
case ET_DOUBLE:
|
||||||
|
return 8;
|
||||||
|
case ET_SEQUENCE:
|
||||||
|
switch (type_table->st) {
|
||||||
|
case ST_TABLE:
|
||||||
|
case ST_UNION:
|
||||||
|
return 4;
|
||||||
|
case ST_STRUCT:
|
||||||
|
return type_table->values[type_table->num_elems];
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(false);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t LookupEnum(int32_t enum_val, const int32_t *values,
|
||||||
|
size_t num_values) {
|
||||||
|
if (!values) return enum_val;
|
||||||
|
for (size_t i = 0; i < num_values; i++) {
|
||||||
|
if (enum_val == values[i]) return static_cast<int32_t>(i);
|
||||||
|
}
|
||||||
|
return -1; // Unknown enum value.
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> const char *EnumName(T tval, const TypeTable *type_table) {
|
||||||
|
if (!type_table || !type_table->names) return nullptr;
|
||||||
|
auto i = LookupEnum(static_cast<int32_t>(tval), type_table->values,
|
||||||
|
type_table->num_elems);
|
||||||
|
if (i >= 0 && i < static_cast<int32_t>(type_table->num_elems)) {
|
||||||
|
return type_table->names[i];
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||||
|
IterationVisitor *visitor);
|
||||||
|
|
||||||
|
inline void IterateValue(ElementaryType type, const uint8_t *val,
|
||||||
|
const TypeTable *type_table,
|
||||||
|
const uint8_t *prev_val,
|
||||||
|
soffset_t vector_index,
|
||||||
|
IterationVisitor *visitor) {
|
||||||
|
switch (type) {
|
||||||
|
case ET_UTYPE: {
|
||||||
|
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||||
|
visitor->UType(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_BOOL: {
|
||||||
|
visitor->Bool(*reinterpret_cast<const uint8_t *>(val) != 0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_CHAR: {
|
||||||
|
auto tval = *reinterpret_cast<const int8_t *>(val);
|
||||||
|
visitor->Char(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_UCHAR: {
|
||||||
|
auto tval = *reinterpret_cast<const uint8_t *>(val);
|
||||||
|
visitor->UChar(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_SHORT: {
|
||||||
|
auto tval = *reinterpret_cast<const int16_t *>(val);
|
||||||
|
visitor->Short(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_USHORT: {
|
||||||
|
auto tval = *reinterpret_cast<const uint16_t *>(val);
|
||||||
|
visitor->UShort(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_INT: {
|
||||||
|
auto tval = *reinterpret_cast<const int32_t *>(val);
|
||||||
|
visitor->Int(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_UINT: {
|
||||||
|
auto tval = *reinterpret_cast<const uint32_t *>(val);
|
||||||
|
visitor->UInt(tval, EnumName(tval, type_table));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_LONG: {
|
||||||
|
visitor->Long(*reinterpret_cast<const int64_t *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_ULONG: {
|
||||||
|
visitor->ULong(*reinterpret_cast<const uint64_t *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_FLOAT: {
|
||||||
|
visitor->Float(*reinterpret_cast<const float *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_DOUBLE: {
|
||||||
|
visitor->Double(*reinterpret_cast<const double *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_STRING: {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
visitor->String(reinterpret_cast<const String *>(val));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_SEQUENCE: {
|
||||||
|
switch (type_table->st) {
|
||||||
|
case ST_TABLE:
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
|
case ST_STRUCT:
|
||||||
|
IterateObject(val, type_table, visitor);
|
||||||
|
break;
|
||||||
|
case ST_UNION: {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
assert(prev_val);
|
||||||
|
auto union_type = *prev_val; // Always a uint8_t.
|
||||||
|
if (vector_index >= 0) {
|
||||||
|
auto type_vec = reinterpret_cast<const Vector<uint8_t> *>(prev_val);
|
||||||
|
union_type = type_vec->Get(static_cast<uoffset_t>(vector_index));
|
||||||
|
}
|
||||||
|
auto type_code_idx = LookupEnum(union_type, type_table->values,
|
||||||
|
type_table->num_elems);
|
||||||
|
if (type_code_idx >= 0 && type_code_idx <
|
||||||
|
static_cast<int32_t>(type_table->num_elems)) {
|
||||||
|
auto type_code = type_table->type_codes[type_code_idx];
|
||||||
|
switch (type_code.base_type) {
|
||||||
|
case ET_SEQUENCE: {
|
||||||
|
auto ref = type_table->type_refs[type_code.sequence_ref]();
|
||||||
|
IterateObject(val, ref, visitor);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ET_STRING:
|
||||||
|
visitor->String(reinterpret_cast<const String *>(val));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
visitor->Unknown(val);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
visitor->Unknown(val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ST_ENUM:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
visitor->Unknown(val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IterateObject(const uint8_t *obj, const TypeTable *type_table,
|
||||||
|
IterationVisitor *visitor) {
|
||||||
|
visitor->StartSequence();
|
||||||
|
const uint8_t *prev_val = nullptr;
|
||||||
|
size_t set_idx = 0;
|
||||||
|
for (size_t i = 0; i < type_table->num_elems; i++) {
|
||||||
|
auto type_code = type_table->type_codes[i];
|
||||||
|
auto type = static_cast<ElementaryType>(type_code.base_type);
|
||||||
|
auto is_vector = type_code.is_vector != 0;
|
||||||
|
auto ref_idx = type_code.sequence_ref;
|
||||||
|
const TypeTable *ref = nullptr;
|
||||||
|
if (ref_idx >= 0) {
|
||||||
|
ref = type_table->type_refs[ref_idx]();
|
||||||
|
}
|
||||||
|
auto name = type_table->names ? type_table->names[i] : nullptr;
|
||||||
|
const uint8_t *val = nullptr;
|
||||||
|
if (type_table->st == ST_TABLE) {
|
||||||
|
val = reinterpret_cast<const Table *>(obj)->GetAddressOf(
|
||||||
|
FieldIndexToOffset(static_cast<voffset_t>(i)));
|
||||||
|
} else {
|
||||||
|
val = obj + type_table->values[i];
|
||||||
|
}
|
||||||
|
visitor->Field(i, set_idx, type, is_vector, ref, name, val);
|
||||||
|
if (val) {
|
||||||
|
set_idx++;
|
||||||
|
if (is_vector) {
|
||||||
|
val += ReadScalar<uoffset_t>(val);
|
||||||
|
auto vec = reinterpret_cast<const Vector<uint8_t> *>(val);
|
||||||
|
visitor->StartVector();
|
||||||
|
auto elem_ptr = vec->Data();
|
||||||
|
for (size_t j = 0; j < vec->size(); j++) {
|
||||||
|
visitor->Element(j, type, ref, elem_ptr);
|
||||||
|
IterateValue(type, elem_ptr, ref, prev_val, static_cast<soffset_t>(j),
|
||||||
|
visitor);
|
||||||
|
elem_ptr += InlineSize(type, ref);
|
||||||
|
}
|
||||||
|
visitor->EndVector();
|
||||||
|
} else {
|
||||||
|
IterateValue(type, val, ref, prev_val, -1, visitor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
prev_val = val;
|
||||||
|
}
|
||||||
|
visitor->EndSequence();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void IterateFlatBuffer(const uint8_t *buffer,
|
||||||
|
const TypeTable *type_table,
|
||||||
|
IterationVisitor *callback) {
|
||||||
|
IterateObject(GetRoot<uint8_t>(buffer), type_table, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Outputting a Flatbuffer to a string. Tries to conform as close to JSON /
|
||||||
|
// the output generated by idl_gen_text.cpp.
|
||||||
|
|
||||||
|
struct ToStringVisitor : public IterationVisitor {
|
||||||
|
std::string s;
|
||||||
|
void StartSequence() { s += "{ "; }
|
||||||
|
void EndSequence() { s += " }"; }
|
||||||
|
void Field(size_t /*field_idx*/, size_t set_idx, ElementaryType /*type*/,
|
||||||
|
bool /*is_vector*/, const TypeTable * /*type_table*/,
|
||||||
|
const char *name, const uint8_t *val) {
|
||||||
|
if (!val) return;
|
||||||
|
if (set_idx) s += ", ";
|
||||||
|
if (name) { s += name; s += ": "; }
|
||||||
|
}
|
||||||
|
template<typename T> void Named(T x, const char *name) {
|
||||||
|
if (name) s+= name;
|
||||||
|
else s+= NumToString(x);
|
||||||
|
}
|
||||||
|
void UType(uint8_t x, const char *name) { Named(x, name); }
|
||||||
|
void Bool(bool x) { s+= x ? "true" : "false"; }
|
||||||
|
void Char(int8_t x, const char *name) { Named(x, name); }
|
||||||
|
void UChar(uint8_t x, const char *name) { Named(x, name); }
|
||||||
|
void Short(int16_t x, const char *name) { Named(x, name); }
|
||||||
|
void UShort(uint16_t x, const char *name) { Named(x, name); }
|
||||||
|
void Int(int32_t x, const char *name) { Named(x, name); }
|
||||||
|
void UInt(uint32_t x, const char *name) { Named(x, name); }
|
||||||
|
void Long(int64_t x) { s+= NumToString(x); }
|
||||||
|
void ULong(uint64_t x) { s+= NumToString(x); }
|
||||||
|
void Float(float x) { s+= NumToString(x); }
|
||||||
|
void Double(double x) { s+= NumToString(x); }
|
||||||
|
void String(const struct String *str) {
|
||||||
|
EscapeString(str->c_str(), str->size(), &s, true);
|
||||||
|
}
|
||||||
|
void Unknown(const uint8_t *) { s += "(?)"; }
|
||||||
|
void StartVector() { s += "[ "; }
|
||||||
|
void EndVector() { s += " ]"; }
|
||||||
|
void Element(size_t i, ElementaryType /*type*/,
|
||||||
|
const TypeTable * /*type_table*/, const uint8_t * /*val*/) {
|
||||||
|
if (i) s += ", ";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
inline std::string FlatBufferToString(const uint8_t *buffer,
|
||||||
|
const TypeTable *type_table) {
|
||||||
|
ToStringVisitor tostring_visitor;
|
||||||
|
IterateFlatBuffer(buffer, type_table, &tostring_visitor);
|
||||||
|
return tostring_visitor.s;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_MINIREFLECT_H_
|
||||||
@@ -361,12 +361,13 @@ template<typename T, typename U> class pointer_inside_vector {
|
|||||||
public:
|
public:
|
||||||
pointer_inside_vector(T *ptr, std::vector<U> &vec)
|
pointer_inside_vector(T *ptr, std::vector<U> &vec)
|
||||||
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
: offset_(reinterpret_cast<uint8_t *>(ptr) -
|
||||||
reinterpret_cast<uint8_t *>(vec.data())),
|
reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
|
||||||
vec_(vec) {}
|
vec_(vec) {}
|
||||||
|
|
||||||
T *operator*() const {
|
T *operator*() const {
|
||||||
return reinterpret_cast<T *>(
|
return reinterpret_cast<T *>(
|
||||||
reinterpret_cast<uint8_t *>(vec_.data()) + offset_);
|
reinterpret_cast<uint8_t *>(
|
||||||
|
flatbuffers::vector_data(vec_)) + offset_);
|
||||||
}
|
}
|
||||||
T *operator->() const {
|
T *operator->() const {
|
||||||
return operator*();
|
return operator*();
|
||||||
@@ -418,7 +419,6 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
|||||||
uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
|
uoffset_t elem_size, std::vector<uint8_t> *flatbuf,
|
||||||
const reflection::Object *root_table = nullptr);
|
const reflection::Object *root_table = nullptr);
|
||||||
|
|
||||||
#ifndef FLATBUFFERS_CPP98_STL
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
||||||
const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
|
const Vector<T> *vec, std::vector<uint8_t> *flatbuf,
|
||||||
@@ -432,7 +432,7 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
|||||||
// Set new elements to "val".
|
// Set new elements to "val".
|
||||||
for (int i = 0; i < delta_elem; i++) {
|
for (int i = 0; i < delta_elem; i++) {
|
||||||
auto loc = newelems + i * sizeof(T);
|
auto loc = newelems + i * sizeof(T);
|
||||||
auto is_scalar = std::is_scalar<T>::value;
|
auto is_scalar = flatbuffers::is_scalar<T>::value;
|
||||||
if (is_scalar) {
|
if (is_scalar) {
|
||||||
WriteScalar(loc, val);
|
WriteScalar(loc, val);
|
||||||
} else { // struct
|
} else { // struct
|
||||||
@@ -440,7 +440,6 @@ void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Adds any new data (in the form of a new FlatBuffer) to an existing
|
// Adds any new data (in the form of a new FlatBuffer) to an existing
|
||||||
// FlatBuffer. This can be used when any of the above methods are not
|
// FlatBuffer. This can be used when any of the above methods are not
|
||||||
|
|||||||
@@ -42,6 +42,29 @@ enum BaseType {
|
|||||||
Union = 16
|
Union = 16
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline BaseType (&EnumValuesBaseType())[17] {
|
||||||
|
static BaseType values[] = {
|
||||||
|
None,
|
||||||
|
UType,
|
||||||
|
Bool,
|
||||||
|
Byte,
|
||||||
|
UByte,
|
||||||
|
Short,
|
||||||
|
UShort,
|
||||||
|
Int,
|
||||||
|
UInt,
|
||||||
|
Long,
|
||||||
|
ULong,
|
||||||
|
Float,
|
||||||
|
Double,
|
||||||
|
String,
|
||||||
|
Vector,
|
||||||
|
Obj,
|
||||||
|
Union
|
||||||
|
};
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
inline const char **EnumNamesBaseType() {
|
inline const char **EnumNamesBaseType() {
|
||||||
static const char *names[] = {
|
static const char *names[] = {
|
||||||
"None",
|
"None",
|
||||||
@@ -113,7 +136,7 @@ struct TypeBuilder {
|
|||||||
}
|
}
|
||||||
TypeBuilder &operator=(const TypeBuilder &);
|
TypeBuilder &operator=(const TypeBuilder &);
|
||||||
flatbuffers::Offset<Type> Finish() {
|
flatbuffers::Offset<Type> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 3);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Type>(end);
|
auto o = flatbuffers::Offset<Type>(end);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@@ -173,7 +196,7 @@ struct KeyValueBuilder {
|
|||||||
}
|
}
|
||||||
KeyValueBuilder &operator=(const KeyValueBuilder &);
|
KeyValueBuilder &operator=(const KeyValueBuilder &);
|
||||||
flatbuffers::Offset<KeyValue> Finish() {
|
flatbuffers::Offset<KeyValue> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 2);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<KeyValue>(end);
|
auto o = flatbuffers::Offset<KeyValue>(end);
|
||||||
fbb_.Required(o, KeyValue::VT_KEY);
|
fbb_.Required(o, KeyValue::VT_KEY);
|
||||||
return o;
|
return o;
|
||||||
@@ -266,7 +289,7 @@ struct EnumValBuilder {
|
|||||||
}
|
}
|
||||||
EnumValBuilder &operator=(const EnumValBuilder &);
|
EnumValBuilder &operator=(const EnumValBuilder &);
|
||||||
flatbuffers::Offset<EnumVal> Finish() {
|
flatbuffers::Offset<EnumVal> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 4);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<EnumVal>(end);
|
auto o = flatbuffers::Offset<EnumVal>(end);
|
||||||
fbb_.Required(o, EnumVal::VT_NAME);
|
fbb_.Required(o, EnumVal::VT_NAME);
|
||||||
return o;
|
return o;
|
||||||
@@ -381,7 +404,7 @@ struct EnumBuilder {
|
|||||||
}
|
}
|
||||||
EnumBuilder &operator=(const EnumBuilder &);
|
EnumBuilder &operator=(const EnumBuilder &);
|
||||||
flatbuffers::Offset<Enum> Finish() {
|
flatbuffers::Offset<Enum> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 6);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Enum>(end);
|
auto o = flatbuffers::Offset<Enum>(end);
|
||||||
fbb_.Required(o, Enum::VT_NAME);
|
fbb_.Required(o, Enum::VT_NAME);
|
||||||
fbb_.Required(o, Enum::VT_VALUES);
|
fbb_.Required(o, Enum::VT_VALUES);
|
||||||
@@ -544,7 +567,7 @@ struct FieldBuilder {
|
|||||||
}
|
}
|
||||||
FieldBuilder &operator=(const FieldBuilder &);
|
FieldBuilder &operator=(const FieldBuilder &);
|
||||||
flatbuffers::Offset<Field> Finish() {
|
flatbuffers::Offset<Field> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 11);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Field>(end);
|
auto o = flatbuffers::Offset<Field>(end);
|
||||||
fbb_.Required(o, Field::VT_NAME);
|
fbb_.Required(o, Field::VT_NAME);
|
||||||
fbb_.Required(o, Field::VT_TYPE);
|
fbb_.Required(o, Field::VT_TYPE);
|
||||||
@@ -695,7 +718,7 @@ struct ObjectBuilder {
|
|||||||
}
|
}
|
||||||
ObjectBuilder &operator=(const ObjectBuilder &);
|
ObjectBuilder &operator=(const ObjectBuilder &);
|
||||||
flatbuffers::Offset<Object> Finish() {
|
flatbuffers::Offset<Object> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 7);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Object>(end);
|
auto o = flatbuffers::Offset<Object>(end);
|
||||||
fbb_.Required(o, Object::VT_NAME);
|
fbb_.Required(o, Object::VT_NAME);
|
||||||
fbb_.Required(o, Object::VT_FIELDS);
|
fbb_.Required(o, Object::VT_FIELDS);
|
||||||
@@ -808,7 +831,7 @@ struct SchemaBuilder {
|
|||||||
}
|
}
|
||||||
SchemaBuilder &operator=(const SchemaBuilder &);
|
SchemaBuilder &operator=(const SchemaBuilder &);
|
||||||
flatbuffers::Offset<Schema> Finish() {
|
flatbuffers::Offset<Schema> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 5);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Schema>(end);
|
auto o = flatbuffers::Offset<Schema>(end);
|
||||||
fbb_.Required(o, Schema::VT_OBJECTS);
|
fbb_.Required(o, Schema::VT_OBJECTS);
|
||||||
fbb_.Required(o, Schema::VT_ENUMS);
|
fbb_.Required(o, Schema::VT_ENUMS);
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ class Registry {
|
|||||||
}
|
}
|
||||||
// Parse schema.
|
// Parse schema.
|
||||||
parser->opts = opts_;
|
parser->opts = opts_;
|
||||||
if (!parser->Parse(schematext.c_str(), include_paths_.data(),
|
if (!parser->Parse(schematext.c_str(), vector_data(include_paths_),
|
||||||
schema.path_.c_str())) {
|
schema.path_.c_str())) {
|
||||||
lasterror_ = parser->error_;
|
lasterror_ = parser->error_;
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
222
include/flatbuffers/stl_emulation.h
Normal file
222
include/flatbuffers/stl_emulation.h
Normal file
@@ -0,0 +1,222 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2017 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 FLATBUFFERS_STL_EMULATION_H_
|
||||||
|
#define FLATBUFFERS_STL_EMULATION_H_
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
|
#if defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#define FLATBUFFERS_CPP98_STL
|
||||||
|
#endif // defined(_STLPORT_VERSION) && !defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#include <cctype>
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
|
// This header provides backwards compatibility for C++98 STLs like stlport.
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
// Retrieve ::back() from a string in a way that is compatible with pre C++11
|
||||||
|
// STLs (e.g stlport).
|
||||||
|
inline char string_back(const std::string &value) {
|
||||||
|
return value[value.length() - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper method that retrieves ::data() from a vector in a way that is
|
||||||
|
// compatible with pre C++11 STLs (e.g stlport).
|
||||||
|
template <typename T> inline T *vector_data(std::vector<T> &vector) {
|
||||||
|
// In some debug environments, operator[] does bounds checking, so &vector[0]
|
||||||
|
// can't be used.
|
||||||
|
return &(*vector.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline const T *vector_data(
|
||||||
|
const std::vector<T> &vector) {
|
||||||
|
return &(*vector.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename V>
|
||||||
|
inline void vector_emplace_back(std::vector<T> *vector, V &&data) {
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
vector->push_back(data);
|
||||||
|
#else
|
||||||
|
vector->emplace_back(std::forward<V>(data));
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
template <typename T>
|
||||||
|
using numeric_limits = std::numeric_limits<T>;
|
||||||
|
#else
|
||||||
|
template <typename T> class numeric_limits :
|
||||||
|
public std::numeric_limits<T> {};
|
||||||
|
#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
#else
|
||||||
|
template <typename T> class numeric_limits :
|
||||||
|
public std::numeric_limits<T> {};
|
||||||
|
|
||||||
|
template <> class numeric_limits<unsigned long long> {
|
||||||
|
public:
|
||||||
|
static unsigned long long min() { return 0ULL; }
|
||||||
|
static unsigned long long max() { return ~0ULL; }
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> class numeric_limits<long long> {
|
||||||
|
public:
|
||||||
|
static long long min() {
|
||||||
|
return static_cast<long long>(1ULL << ((sizeof(long long) << 3) - 1));
|
||||||
|
}
|
||||||
|
static long long max() {
|
||||||
|
return static_cast<long long>(
|
||||||
|
(1ULL << ((sizeof(long long) << 3) - 1)) - 1);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
template <typename T> using is_scalar = std::is_scalar<T>;
|
||||||
|
template <typename T, typename U> using is_same = std::is_same<T,U>;
|
||||||
|
template <typename T> using is_floating_point = std::is_floating_point<T>;
|
||||||
|
template <typename T> using is_unsigned = std::is_unsigned<T>;
|
||||||
|
#else
|
||||||
|
// Map C++ TR1 templates defined by stlport.
|
||||||
|
template <typename T> using is_scalar = std::tr1::is_scalar<T>;
|
||||||
|
template <typename T, typename U> using is_same = std::tr1::is_same<T,U>;
|
||||||
|
template <typename T> using is_floating_point =
|
||||||
|
std::tr1::is_floating_point<T>;
|
||||||
|
template <typename T> using is_unsigned = std::tr1::is_unsigned<T>;
|
||||||
|
#endif // !FLATBUFFERS_CPP98_STL
|
||||||
|
#else
|
||||||
|
// MSVC 2010 doesn't support C++11 aliases.
|
||||||
|
template <typename T> struct is_scalar : public std::is_scalar<T> {};
|
||||||
|
template <typename T, typename U> struct is_same : public std::is_same<T,U> {};
|
||||||
|
template <typename T> struct is_floating_point :
|
||||||
|
public std::is_floating_point<T> {};
|
||||||
|
template <typename T> struct is_unsigned : public std::is_unsigned<T> {};
|
||||||
|
#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
#if !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
template <class T> using unique_ptr = std::unique_ptr<T>;
|
||||||
|
#else
|
||||||
|
// MSVC 2010 doesn't support C++11 aliases.
|
||||||
|
// We're manually "aliasing" the class here as we want to bring unique_ptr
|
||||||
|
// into the flatbuffers namespace. We have unique_ptr in the flatbuffers
|
||||||
|
// namespace we have a completely independent implemenation (see below)
|
||||||
|
// for C++98 STL implementations.
|
||||||
|
template <class T> class unique_ptr : public std::unique_ptr<T> {
|
||||||
|
public:
|
||||||
|
unique_ptr() {}
|
||||||
|
explicit unique_ptr(T* p) : std::unique_ptr<T>(p) {}
|
||||||
|
unique_ptr(std::unique_ptr<T>&& u) { *this = std::move(u); }
|
||||||
|
unique_ptr(unique_ptr&& u) { *this = std::move(u); }
|
||||||
|
unique_ptr& operator=(std::unique_ptr<T>&& u) {
|
||||||
|
std::unique_ptr<T>::reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
unique_ptr& operator=(unique_ptr&& u) {
|
||||||
|
std::unique_ptr<T>::reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
unique_ptr& operator=(T* p) {
|
||||||
|
return std::unique_ptr<T>::operator=(p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif // !(defined(_MSC_VER) && _MSC_VER <= 1700 /* MSVC2012 */)
|
||||||
|
#else
|
||||||
|
// Very limited implementation of unique_ptr.
|
||||||
|
// This is provided simply to allow the C++ code generated from the default
|
||||||
|
// settings to function in C++98 environments with no modifications.
|
||||||
|
template <class T> class unique_ptr {
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
unique_ptr() : ptr_(nullptr) {}
|
||||||
|
explicit unique_ptr(T* p) : ptr_(p) {}
|
||||||
|
unique_ptr(unique_ptr&& u) : ptr_(nullptr) { reset(u.release()); }
|
||||||
|
unique_ptr(const unique_ptr& u) : ptr_(nullptr) {
|
||||||
|
reset(const_cast<unique_ptr*>(&u)->release());
|
||||||
|
}
|
||||||
|
~unique_ptr() { reset(); }
|
||||||
|
|
||||||
|
unique_ptr& operator=(const unique_ptr& u) {
|
||||||
|
reset(const_cast<unique_ptr*>(&u)->release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr& operator=(unique_ptr&& u) {
|
||||||
|
reset(u.release());
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unique_ptr& operator=(T* p) {
|
||||||
|
reset(p);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const T& operator*() const { return *ptr_; }
|
||||||
|
T* operator->() const { return ptr_; }
|
||||||
|
T* get() const noexcept { return ptr_; }
|
||||||
|
explicit operator bool() const { return ptr_ != nullptr; }
|
||||||
|
|
||||||
|
// modifiers
|
||||||
|
T* release() {
|
||||||
|
T* value = ptr_;
|
||||||
|
ptr_ = nullptr;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset(T* p = nullptr) {
|
||||||
|
T* value = ptr_;
|
||||||
|
ptr_ = p;
|
||||||
|
if (value) delete value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(unique_ptr& u) {
|
||||||
|
T* temp_ptr = ptr_;
|
||||||
|
ptr_ = u.ptr_;
|
||||||
|
u.ptr_ = temp_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
T* ptr_;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> bool operator==(const unique_ptr<T>& x,
|
||||||
|
const unique_ptr<T>& y) {
|
||||||
|
return x.get() == y.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T, class D> bool operator==(const unique_ptr<T>& x,
|
||||||
|
const D* y) {
|
||||||
|
return static_cast<D*>(x.get()) == y;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> bool operator==(const unique_ptr<T>& x, intptr_t y) {
|
||||||
|
return reinterpret_cast<intptr_t>(x.get()) == y;
|
||||||
|
}
|
||||||
|
#endif // !FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
|
} // namespace flatbuffers
|
||||||
|
|
||||||
|
#endif // FLATBUFFERS_STL_EMULATION_H_
|
||||||
@@ -60,6 +60,20 @@ template<> inline std::string NumToString<signed char>(signed char t) {
|
|||||||
template<> inline std::string NumToString<unsigned char>(unsigned char t) {
|
template<> inline std::string NumToString<unsigned char>(unsigned char t) {
|
||||||
return NumToString(static_cast<int>(t));
|
return NumToString(static_cast<int>(t));
|
||||||
}
|
}
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
template <> inline std::string NumToString<long long>(long long t) {
|
||||||
|
char buf[21]; // (log((1 << 63) - 1) / log(10)) + 2
|
||||||
|
snprintf(buf, sizeof(buf), "%lld", t);
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline std::string NumToString<unsigned long long>(
|
||||||
|
unsigned long long t) {
|
||||||
|
char buf[22]; // (log((1 << 63) - 1) / log(10)) + 1
|
||||||
|
snprintf(buf, sizeof(buf), "%llu", t);
|
||||||
|
return std::string(buf);
|
||||||
|
}
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
// Special versions for floats/doubles.
|
// Special versions for floats/doubles.
|
||||||
template<> inline std::string NumToString<double>(double t) {
|
template<> inline std::string NumToString<double>(double t) {
|
||||||
@@ -202,9 +216,10 @@ inline std::string ConCatPathFileName(const std::string &path,
|
|||||||
const std::string &filename) {
|
const std::string &filename) {
|
||||||
std::string filepath = path;
|
std::string filepath = path;
|
||||||
if (filepath.length()) {
|
if (filepath.length()) {
|
||||||
if (filepath.back() == kPathSeparatorWindows) {
|
char filepath_last_character = string_back(filepath);
|
||||||
filepath.back() = kPathSeparator;
|
if (filepath_last_character == kPathSeparatorWindows) {
|
||||||
} else if (filepath.back() != kPathSeparator) {
|
filepath_last_character = kPathSeparator;
|
||||||
|
} else if (filepath_last_character != kPathSeparator) {
|
||||||
filepath += kPathSeparator;
|
filepath += kPathSeparator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ package com.google.flatbuffers;
|
|||||||
|
|
||||||
import static com.google.flatbuffers.Constants.*;
|
import static com.google.flatbuffers.Constants.*;
|
||||||
|
|
||||||
import java.nio.CharBuffer;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.*;
|
||||||
import java.nio.charset.CharacterCodingException;
|
import java.nio.charset.CharacterCodingException;
|
||||||
import java.nio.charset.CharsetEncoder;
|
import java.nio.charset.CharsetEncoder;
|
||||||
import java.nio.charset.CoderResult;
|
import java.nio.charset.CoderResult;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.nio.ByteBuffer;
|
|
||||||
import java.nio.ByteOrder;
|
|
||||||
import java.nio.charset.Charset;
|
import java.nio.charset.Charset;
|
||||||
|
|
||||||
/// @file
|
/// @file
|
||||||
@@ -52,26 +52,51 @@ public class FlatBufferBuilder {
|
|||||||
boolean force_defaults = false; // False omits default values from the serialized data.
|
boolean force_defaults = false; // False omits default values from the serialized data.
|
||||||
CharsetEncoder encoder = utf8charset.newEncoder();
|
CharsetEncoder encoder = utf8charset.newEncoder();
|
||||||
ByteBuffer dst;
|
ByteBuffer dst;
|
||||||
|
ByteBufferFactory bb_factory; // Factory for allocating the internal buffer
|
||||||
/// @endcond
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start with a buffer of size `initial_size`, then grow as required.
|
||||||
|
*
|
||||||
|
* @param initial_size The initial size of the internal buffer to use.
|
||||||
|
* @param bb_factory The factory to be used for allocating the internal buffer
|
||||||
|
*/
|
||||||
|
public FlatBufferBuilder(int initial_size, ByteBufferFactory bb_factory) {
|
||||||
|
if (initial_size <= 0) initial_size = 1;
|
||||||
|
space = initial_size;
|
||||||
|
this.bb_factory = bb_factory;
|
||||||
|
bb = bb_factory.newByteBuffer(initial_size);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start with a buffer of size `initial_size`, then grow as required.
|
* Start with a buffer of size `initial_size`, then grow as required.
|
||||||
*
|
*
|
||||||
* @param initial_size The initial size of the internal buffer to use.
|
* @param initial_size The initial size of the internal buffer to use.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder(int initial_size) {
|
public FlatBufferBuilder(int initial_size) {
|
||||||
if (initial_size <= 0) initial_size = 1;
|
this(initial_size, new HeapByteBufferFactory());
|
||||||
space = initial_size;
|
|
||||||
bb = newByteBuffer(initial_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start with a buffer of 1KiB, then grow as required.
|
* Start with a buffer of 1KiB, then grow as required.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder() {
|
public FlatBufferBuilder() {
|
||||||
this(1024);
|
this(1024);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
|
||||||
|
* can still grow the buffer as necessary. User classes should make sure
|
||||||
|
* to call {@link #dataBuffer()} to obtain the resulting encoded message.
|
||||||
|
*
|
||||||
|
* @param existing_bb The byte buffer to reuse.
|
||||||
|
* @param bb_factory The factory to be used for allocating a new internal buffer if
|
||||||
|
* the existing buffer needs to grow
|
||||||
|
*/
|
||||||
|
public FlatBufferBuilder(ByteBuffer existing_bb, ByteBufferFactory bb_factory) {
|
||||||
|
init(existing_bb, bb_factory);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
|
* Alternative constructor allowing reuse of {@link ByteBuffer}s. The builder
|
||||||
* can still grow the buffer as necessary. User classes should make sure
|
* can still grow the buffer as necessary. User classes should make sure
|
||||||
@@ -80,7 +105,7 @@ public class FlatBufferBuilder {
|
|||||||
* @param existing_bb The byte buffer to reuse.
|
* @param existing_bb The byte buffer to reuse.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder(ByteBuffer existing_bb) {
|
public FlatBufferBuilder(ByteBuffer existing_bb) {
|
||||||
init(existing_bb);
|
init(existing_bb, new HeapByteBufferFactory());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -89,9 +114,12 @@ public class FlatBufferBuilder {
|
|||||||
* objects that have been allocated for temporary storage.
|
* objects that have been allocated for temporary storage.
|
||||||
*
|
*
|
||||||
* @param existing_bb The byte buffer to reuse.
|
* @param existing_bb The byte buffer to reuse.
|
||||||
|
* @param bb_factory The factory to be used for allocating a new internal buffer if
|
||||||
|
* the existing buffer needs to grow
|
||||||
* @return Returns `this`.
|
* @return Returns `this`.
|
||||||
*/
|
*/
|
||||||
public FlatBufferBuilder init(ByteBuffer existing_bb){
|
public FlatBufferBuilder init(ByteBuffer existing_bb, ByteBufferFactory bb_factory){
|
||||||
|
this.bb_factory = bb_factory;
|
||||||
bb = existing_bb;
|
bb = existing_bb;
|
||||||
bb.clear();
|
bb.clear();
|
||||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
@@ -106,6 +134,39 @@ public class FlatBufferBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An interface that provides a user of the FlatBufferBuilder class the ability to specify
|
||||||
|
* the method in which the internal buffer gets allocated. This allows for alternatives
|
||||||
|
* to the default behavior, which is to allocate memory for a new byte-array
|
||||||
|
* backed `ByteBuffer` array inside the JVM.
|
||||||
|
*
|
||||||
|
* The FlatBufferBuilder class contains the HeapByteBufferFactory class to
|
||||||
|
* preserve the default behavior in the event that the user does not provide
|
||||||
|
* their own implementation of this interface.
|
||||||
|
*/
|
||||||
|
public interface ByteBufferFactory {
|
||||||
|
/**
|
||||||
|
* Create a `ByteBuffer` with a given capacity.
|
||||||
|
*
|
||||||
|
* @param capacity The size of the `ByteBuffer` to allocate.
|
||||||
|
* @return Returns the new `ByteBuffer` that was allocated.
|
||||||
|
*/
|
||||||
|
ByteBuffer newByteBuffer(int capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of the ByteBufferFactory interface that is used when
|
||||||
|
* one is not provided by the user.
|
||||||
|
*
|
||||||
|
* Allocate memory for a new byte-array backed `ByteBuffer` array inside the JVM.
|
||||||
|
*/
|
||||||
|
public static final class HeapByteBufferFactory implements ByteBufferFactory {
|
||||||
|
@Override
|
||||||
|
public ByteBuffer newByteBuffer(int capacity) {
|
||||||
|
return ByteBuffer.allocate(capacity).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reset the FlatBufferBuilder by purging all data that it holds.
|
* Reset the FlatBufferBuilder by purging all data that it holds.
|
||||||
*/
|
*/
|
||||||
@@ -122,34 +183,22 @@ public class FlatBufferBuilder {
|
|||||||
vector_num_elems = 0;
|
vector_num_elems = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @cond FLATBUFFERS_INTERNAL
|
|
||||||
/**
|
|
||||||
* Create a `ByteBuffer` with a given capacity.
|
|
||||||
*
|
|
||||||
* @param capacity The size of the `ByteBuffer` to allocate.
|
|
||||||
* @return Returns the new `ByteBuffer` that was allocated.
|
|
||||||
*/
|
|
||||||
static ByteBuffer newByteBuffer(int capacity) {
|
|
||||||
ByteBuffer newbb = ByteBuffer.allocate(capacity);
|
|
||||||
newbb.order(ByteOrder.LITTLE_ENDIAN);
|
|
||||||
return newbb;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Doubles the size of the backing {@link ByteBuffer} and copies the old data towards the
|
* Doubles the size of the backing {@link ByteBuffer} and copies the old data towards the
|
||||||
* end of the new buffer (since we build the buffer backwards).
|
* end of the new buffer (since we build the buffer backwards).
|
||||||
*
|
*
|
||||||
* @param bb The current buffer with the existing data.
|
* @param bb The current buffer with the existing data.
|
||||||
|
* @param bb_factory The factory to be used for allocating the new internal buffer
|
||||||
* @return A new byte buffer with the old data copied copied to it. The data is
|
* @return A new byte buffer with the old data copied copied to it. The data is
|
||||||
* located at the end of the buffer.
|
* located at the end of the buffer.
|
||||||
*/
|
*/
|
||||||
static ByteBuffer growByteBuffer(ByteBuffer bb) {
|
static ByteBuffer growByteBuffer(ByteBuffer bb, ByteBufferFactory bb_factory) {
|
||||||
int old_buf_size = bb.capacity();
|
int old_buf_size = bb.capacity();
|
||||||
if ((old_buf_size & 0xC0000000) != 0) // Ensure we don't grow beyond what fits in an int.
|
if ((old_buf_size & 0xC0000000) != 0) // Ensure we don't grow beyond what fits in an int.
|
||||||
throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
|
throw new AssertionError("FlatBuffers: cannot grow buffer beyond 2 gigabytes.");
|
||||||
int new_buf_size = old_buf_size << 1;
|
int new_buf_size = old_buf_size << 1;
|
||||||
bb.position(0);
|
bb.position(0);
|
||||||
ByteBuffer nbb = newByteBuffer(new_buf_size);
|
ByteBuffer nbb = bb_factory.newByteBuffer(new_buf_size);
|
||||||
nbb.position(new_buf_size - old_buf_size);
|
nbb.position(new_buf_size - old_buf_size);
|
||||||
nbb.put(bb);
|
nbb.put(bb);
|
||||||
return nbb;
|
return nbb;
|
||||||
@@ -192,7 +241,7 @@ public class FlatBufferBuilder {
|
|||||||
// Reallocate the buffer if needed.
|
// Reallocate the buffer if needed.
|
||||||
while (space < align_size + size + additional_bytes) {
|
while (space < align_size + size + additional_bytes) {
|
||||||
int old_buf_size = bb.capacity();
|
int old_buf_size = bb.capacity();
|
||||||
bb = growByteBuffer(bb);
|
bb = growByteBuffer(bb, bb_factory);
|
||||||
space += bb.capacity() - old_buf_size;
|
space += bb.capacity() - old_buf_size;
|
||||||
}
|
}
|
||||||
pad(align_size);
|
pad(align_size);
|
||||||
@@ -429,7 +478,7 @@ public class FlatBufferBuilder {
|
|||||||
obj.sortTables(offsets, bb);
|
obj.sortTables(offsets, bb);
|
||||||
return createVectorOfTables(offsets);
|
return createVectorOfTables(offsets);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encode the string `s` in the buffer using UTF-8. If {@code s} is
|
* Encode the string `s` in the buffer using UTF-8. If {@code s} is
|
||||||
* already a {@link CharBuffer}, this method is allocation free.
|
* already a {@link CharBuffer}, this method is allocation free.
|
||||||
@@ -695,7 +744,11 @@ public class FlatBufferBuilder {
|
|||||||
addInt(0);
|
addInt(0);
|
||||||
int vtableloc = offset();
|
int vtableloc = offset();
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
for (int i = vtable_in_use - 1; i >= 0 ; i--) {
|
int i = vtable_in_use - 1;
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
for (; i >= 0 && vtable[i] == 0; i--) {}
|
||||||
|
int trimmed_size = i + 1;
|
||||||
|
for (; i >= 0 ; i--) {
|
||||||
// Offset relative to the start of the table.
|
// Offset relative to the start of the table.
|
||||||
short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0);
|
short off = (short)(vtable[i] != 0 ? vtableloc - vtable[i] : 0);
|
||||||
addShort(off);
|
addShort(off);
|
||||||
@@ -703,12 +756,12 @@ public class FlatBufferBuilder {
|
|||||||
|
|
||||||
final int standard_fields = 2; // The fields below:
|
final int standard_fields = 2; // The fields below:
|
||||||
addShort((short)(vtableloc - object_start));
|
addShort((short)(vtableloc - object_start));
|
||||||
addShort((short)((vtable_in_use + standard_fields) * SIZEOF_SHORT));
|
addShort((short)((trimmed_size + standard_fields) * SIZEOF_SHORT));
|
||||||
|
|
||||||
// Search for an existing vtable that matches the current one.
|
// Search for an existing vtable that matches the current one.
|
||||||
int existing_vtable = 0;
|
int existing_vtable = 0;
|
||||||
outer_loop:
|
outer_loop:
|
||||||
for (int i = 0; i < num_vtables; i++) {
|
for (i = 0; i < num_vtables; i++) {
|
||||||
int vt1 = bb.capacity() - vtables[i];
|
int vt1 = bb.capacity() - vtables[i];
|
||||||
int vt2 = space;
|
int vt2 = space;
|
||||||
short len = bb.getShort(vt1);
|
short len = bb.getShort(vt1);
|
||||||
@@ -853,6 +906,41 @@ public class FlatBufferBuilder {
|
|||||||
public byte[] sizedByteArray() {
|
public byte[] sizedByteArray() {
|
||||||
return sizedByteArray(space, bb.capacity() - space);
|
return sizedByteArray(space, bb.capacity() - space);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility function to return an InputStream to the ByteBuffer data
|
||||||
|
*
|
||||||
|
* @return An InputStream that starts at the beginning of the ByteBuffer data
|
||||||
|
* and can read to the end of it.
|
||||||
|
*/
|
||||||
|
public InputStream sizedInputStream() {
|
||||||
|
finished();
|
||||||
|
ByteBuffer duplicate = bb.duplicate();
|
||||||
|
duplicate.position(space);
|
||||||
|
duplicate.limit(bb.capacity());
|
||||||
|
return new ByteBufferBackedInputStream(duplicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that allows a user to create an InputStream from a ByteBuffer.
|
||||||
|
*/
|
||||||
|
static class ByteBufferBackedInputStream extends InputStream {
|
||||||
|
|
||||||
|
ByteBuffer buf;
|
||||||
|
|
||||||
|
public ByteBufferBackedInputStream(ByteBuffer buf) {
|
||||||
|
this.buf = buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int read() throws IOException {
|
||||||
|
try {
|
||||||
|
return buf.get() & 0xFF;
|
||||||
|
} catch(BufferUnderflowException e) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ public class Table {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) {
|
protected static int __offset(int vtable_offset, int offset, ByteBuffer bb) {
|
||||||
int vtable = bb.array().length - offset;
|
int vtable = bb.capacity() - offset;
|
||||||
return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable;
|
return bb.getShort(vtable + vtable_offset - bb.getInt(vtable)) + vtable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,10 +245,9 @@ public class Table {
|
|||||||
int startPos_1 = offset_1 + SIZEOF_INT;
|
int startPos_1 = offset_1 + SIZEOF_INT;
|
||||||
int startPos_2 = offset_2 + SIZEOF_INT;
|
int startPos_2 = offset_2 + SIZEOF_INT;
|
||||||
int len = Math.min(len_1, len_2);
|
int len = Math.min(len_1, len_2);
|
||||||
byte[] bbArray = bb.array();
|
|
||||||
for(int i = 0; i < len; i++) {
|
for(int i = 0; i < len; i++) {
|
||||||
if (bbArray[i + startPos_1] != bbArray[i + startPos_2])
|
if (bb.get(i + startPos_1) != bb.get(i + startPos_2))
|
||||||
return bbArray[i + startPos_1] - bbArray[i + startPos_2];
|
return bb.get(i + startPos_1) - bb.get(i + startPos_2);
|
||||||
}
|
}
|
||||||
return len_1 - len_2;
|
return len_1 - len_2;
|
||||||
}
|
}
|
||||||
@@ -266,10 +265,9 @@ public class Table {
|
|||||||
int len_2 = key.length;
|
int len_2 = key.length;
|
||||||
int startPos_1 = offset_1 + Constants.SIZEOF_INT;
|
int startPos_1 = offset_1 + Constants.SIZEOF_INT;
|
||||||
int len = Math.min(len_1, len_2);
|
int len = Math.min(len_1, len_2);
|
||||||
byte[] bbArray = bb.array();
|
|
||||||
for (int i = 0; i < len; i++) {
|
for (int i = 0; i < len; i++) {
|
||||||
if (bbArray[i + startPos_1] != key[i])
|
if (bb.get(i + startPos_1) != key[i])
|
||||||
return bbArray[i + startPos_1] - key[i];
|
return bb.get(i + startPos_1) - key[i];
|
||||||
}
|
}
|
||||||
return len_1 - len_2;
|
return len_1 - len_2;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -604,23 +604,28 @@ flatbuffers.Builder.prototype.endObject = function() {
|
|||||||
this.addInt32(0);
|
this.addInt32(0);
|
||||||
var vtableloc = this.offset();
|
var vtableloc = this.offset();
|
||||||
|
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
var i = this.vtable_in_use - 1;
|
||||||
|
for (; i >= 0 && this.vtable[i] == 0; i--) {}
|
||||||
|
var trimmed_size = i + 1;
|
||||||
|
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
for (var i = this.vtable_in_use - 1; i >= 0; i--) {
|
for (; i >= 0; i--) {
|
||||||
// Offset relative to the start of the table.
|
// Offset relative to the start of the table.
|
||||||
this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
|
this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
var standard_fields = 2; // The fields below:
|
var standard_fields = 2; // The fields below:
|
||||||
this.addInt16(vtableloc - this.object_start);
|
this.addInt16(vtableloc - this.object_start);
|
||||||
this.addInt16((this.vtable_in_use + standard_fields) * flatbuffers.SIZEOF_SHORT);
|
var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
|
||||||
|
this.addInt16(len);
|
||||||
|
|
||||||
// Search for an existing vtable that matches the current one.
|
// Search for an existing vtable that matches the current one.
|
||||||
var existing_vtable = 0;
|
var existing_vtable = 0;
|
||||||
|
var vt1 = this.space;
|
||||||
outer_loop:
|
outer_loop:
|
||||||
for (var i = 0; i < this.vtables.length; i++) {
|
for (i = 0; i < this.vtables.length; i++) {
|
||||||
var vt1 = this.bb.capacity() - this.vtables[i];
|
var vt2 = this.bb.capacity() - this.vtables[i];
|
||||||
var vt2 = this.space;
|
|
||||||
var len = this.bb.readInt16(vt1);
|
|
||||||
if (len == this.bb.readInt16(vt2)) {
|
if (len == this.bb.readInt16(vt2)) {
|
||||||
for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
|
for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
|
||||||
if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
|
if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
|
||||||
|
|||||||
0
net/FlatBuffers/ByteBuffer.cs
Executable file → Normal file
0
net/FlatBuffers/ByteBuffer.cs
Executable file → Normal file
@@ -500,7 +500,11 @@ namespace FlatBuffers
|
|||||||
AddInt((int)0);
|
AddInt((int)0);
|
||||||
var vtableloc = Offset;
|
var vtableloc = Offset;
|
||||||
// Write out the current vtable.
|
// Write out the current vtable.
|
||||||
for (int i = _vtableSize - 1; i >= 0 ; i--) {
|
int i = _vtableSize - 1;
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
for (; i >= 0 && _vtable[i] == 0; i--) {}
|
||||||
|
int trimmedSize = i + 1;
|
||||||
|
for (; i >= 0 ; i--) {
|
||||||
// Offset relative to the start of the table.
|
// Offset relative to the start of the table.
|
||||||
short off = (short)(_vtable[i] != 0
|
short off = (short)(_vtable[i] != 0
|
||||||
? vtableloc - _vtable[i]
|
? vtableloc - _vtable[i]
|
||||||
@@ -513,12 +517,12 @@ namespace FlatBuffers
|
|||||||
|
|
||||||
const int standardFields = 2; // The fields below:
|
const int standardFields = 2; // The fields below:
|
||||||
AddShort((short)(vtableloc - _objectStart));
|
AddShort((short)(vtableloc - _objectStart));
|
||||||
AddShort((short)((_vtableSize + standardFields) *
|
AddShort((short)((trimmedSize + standardFields) *
|
||||||
sizeof(short)));
|
sizeof(short)));
|
||||||
|
|
||||||
// Search for an existing vtable that matches the current one.
|
// Search for an existing vtable that matches the current one.
|
||||||
int existingVtable = 0;
|
int existingVtable = 0;
|
||||||
for (int i = 0; i < _numVtables; i++) {
|
for (i = 0; i < _numVtables; i++) {
|
||||||
int vt1 = _bb.Length - _vtables[i];
|
int vt1 = _bb.Length - _vtables[i];
|
||||||
int vt2 = _space;
|
int vt2 = _space;
|
||||||
short len = _bb.GetShort(vt1);
|
short len = _bb.GetShort(vt1);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "flatbuffers",
|
"name": "flatbuffers",
|
||||||
"version": "1.7.0",
|
"version": "1.8.0",
|
||||||
"description": "Memory Efficient Serialization Library",
|
"description": "Memory Efficient Serialization Library",
|
||||||
"files": ["js/flatbuffers.js"],
|
"files": ["js/flatbuffers.js"],
|
||||||
"main": "js/flatbuffers.js",
|
"main": "js/flatbuffers.js",
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ class FlatbufferBuilder
|
|||||||
if (function_exists('mb_detect_encoding')) {
|
if (function_exists('mb_detect_encoding')) {
|
||||||
return (bool) mb_detect_encoding($bytes, 'UTF-8', true);
|
return (bool) mb_detect_encoding($bytes, 'UTF-8', true);
|
||||||
}
|
}
|
||||||
|
|
||||||
$len = strlen($bytes);
|
$len = strlen($bytes);
|
||||||
if ($len < 1) {
|
if ($len < 1) {
|
||||||
/* NOTE: always return 1 when passed string is null */
|
/* NOTE: always return 1 when passed string is null */
|
||||||
@@ -812,14 +812,18 @@ class FlatbufferBuilder
|
|||||||
$this->addInt(0);
|
$this->addInt(0);
|
||||||
$vtableloc = $this->offset();
|
$vtableloc = $this->offset();
|
||||||
|
|
||||||
for ($i = $this->vtable_in_use -1; $i >= 0; $i--) {
|
$i = $this->vtable_in_use -1;
|
||||||
|
// Trim trailing zeroes.
|
||||||
|
for (; $i >= 0 && $this->vtable[$i] == 0; $i--) {}
|
||||||
|
$trimmed_size = $i + 1;
|
||||||
|
for (; $i >= 0; $i--) {
|
||||||
$off = ($this->vtable[$i] != 0) ? $vtableloc - $this->vtable[$i] : 0;
|
$off = ($this->vtable[$i] != 0) ? $vtableloc - $this->vtable[$i] : 0;
|
||||||
$this->addShort($off);
|
$this->addShort($off);
|
||||||
}
|
}
|
||||||
|
|
||||||
$standard_fields = 2; // the fields below
|
$standard_fields = 2; // the fields below
|
||||||
$this->addShort($vtableloc - $this->object_start);
|
$this->addShort($vtableloc - $this->object_start);
|
||||||
$this->addShort(($this->vtable_in_use + $standard_fields) * Constants::SIZEOF_SHORT);
|
$this->addShort(($trimmed_size + $standard_fields) * Constants::SIZEOF_SHORT);
|
||||||
|
|
||||||
// search for an existing vtable that matches the current one.
|
// search for an existing vtable that matches the current one.
|
||||||
$existing_vtable = 0;
|
$existing_vtable = 0;
|
||||||
|
|||||||
@@ -28,4 +28,14 @@ abstract class Struct
|
|||||||
* @var ByteBuffer $bb
|
* @var ByteBuffer $bb
|
||||||
*/
|
*/
|
||||||
protected $bb;
|
protected $bb;
|
||||||
|
|
||||||
|
public function setByteBufferPos($pos)
|
||||||
|
{
|
||||||
|
$this->bb_pos = $pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setByteBuffer($bb)
|
||||||
|
{
|
||||||
|
$this->bb = $bb;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,16 @@ abstract class Table
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setByteBufferPos($pos)
|
||||||
|
{
|
||||||
|
$this->bb_pos = $pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setByteBuffer($bb)
|
||||||
|
{
|
||||||
|
$this->bb = $bb;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* returns actual vtable offset
|
* returns actual vtable offset
|
||||||
*
|
*
|
||||||
@@ -107,8 +117,8 @@ abstract class Table
|
|||||||
protected function __union($table, $offset)
|
protected function __union($table, $offset)
|
||||||
{
|
{
|
||||||
$offset += $this->bb_pos;
|
$offset += $this->bb_pos;
|
||||||
$table->bb_pos = $offset + $this->bb->getInt($offset);
|
$table->setByteBufferPos($offset + $this->bb->getInt($offset));
|
||||||
$table->bb = $this->bb;
|
$table->setByteBuffer($this->bb);
|
||||||
return $table;
|
return $table;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
51
pom.xml
51
pom.xml
@@ -5,17 +5,20 @@
|
|||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>com.google.flatbuffers</groupId>
|
<groupId>com.google.flatbuffers</groupId>
|
||||||
<artifactId>flatbuffers-java</artifactId>
|
<artifactId>flatbuffers-java</artifactId>
|
||||||
<version>1.7.0-SNAPSHOT</version>
|
<version>1.8.0</version>
|
||||||
<packaging>bundle</packaging>
|
<packaging>bundle</packaging>
|
||||||
<name>FlatBuffers Java API</name>
|
<name>FlatBuffers Java API</name>
|
||||||
<description>
|
<description>
|
||||||
Memory Efficient Serialization Library
|
Memory Efficient Serialization Library
|
||||||
</description>
|
</description>
|
||||||
|
<developers>
|
||||||
|
<developer>
|
||||||
|
<name>Wouter van Oortmerssen</name>
|
||||||
|
</developer>
|
||||||
|
</developers>
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<url>https://github.com/google/flatbuffers</url>
|
<url>https://github.com/google/flatbuffers</url>
|
||||||
<licenses>
|
<licenses>
|
||||||
<license>
|
<license>
|
||||||
@@ -32,6 +35,12 @@
|
|||||||
</scm>
|
</scm>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
<distributionManagement>
|
||||||
|
<snapshotRepository>
|
||||||
|
<id>ossrh</id>
|
||||||
|
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
|
||||||
|
</snapshotRepository>
|
||||||
|
</distributionManagement>
|
||||||
<build>
|
<build>
|
||||||
<sourceDirectory>java</sourceDirectory>
|
<sourceDirectory>java</sourceDirectory>
|
||||||
<plugins>
|
<plugins>
|
||||||
@@ -84,6 +93,42 @@
|
|||||||
<version>3.0.1</version>
|
<version>3.0.1</version>
|
||||||
<extensions>true</extensions>
|
<extensions>true</extensions>
|
||||||
</plugin>
|
</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>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-gpg-plugin</artifactId>
|
||||||
|
<version>1.5</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>sign-artifacts</id>
|
||||||
|
<phase>verify</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>sign</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-release-plugin</artifactId>
|
||||||
|
<version>2.5.3</version>
|
||||||
|
<configuration>
|
||||||
|
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||||
|
<useReleaseProfile>false</useReleaseProfile>
|
||||||
|
<releaseProfiles>release</releaseProfiles>
|
||||||
|
<goals>deploy</goals>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -193,6 +193,10 @@ class Builder(object):
|
|||||||
objectOffset = self.Offset()
|
objectOffset = self.Offset()
|
||||||
existingVtable = None
|
existingVtable = None
|
||||||
|
|
||||||
|
# Trim trailing 0 offsets.
|
||||||
|
while self.current_vtable and self.current_vtable[-1] == 0:
|
||||||
|
self.current_vtable.pop()
|
||||||
|
|
||||||
# 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
|
||||||
@@ -417,6 +421,27 @@ class Builder(object):
|
|||||||
|
|
||||||
return self.EndVector(len(x))
|
return self.EndVector(len(x))
|
||||||
|
|
||||||
|
def CreateByteVector(self, x):
|
||||||
|
"""CreateString writes a byte vector."""
|
||||||
|
|
||||||
|
self.assertNotNested()
|
||||||
|
## @cond FLATBUFFERS_INTERNAL
|
||||||
|
self.nested = True
|
||||||
|
## @endcond
|
||||||
|
|
||||||
|
if not isinstance(x, compat.binary_types):
|
||||||
|
raise TypeError("non-byte vector passed to CreateByteVector")
|
||||||
|
|
||||||
|
self.Prep(N.UOffsetTFlags.bytewidth, len(x)*N.Uint8Flags.bytewidth)
|
||||||
|
|
||||||
|
l = UOffsetTFlags.py_type(len(x))
|
||||||
|
## @cond FLATBUFFERS_INTERNAL
|
||||||
|
self.head = UOffsetTFlags.py_type(self.Head() - l)
|
||||||
|
## @endcond
|
||||||
|
self.Bytes[self.Head():self.Head()+l] = x
|
||||||
|
|
||||||
|
return self.EndVector(len(x))
|
||||||
|
|
||||||
## @cond FLATBUFFERS_INTERNAL
|
## @cond FLATBUFFERS_INTERNAL
|
||||||
def assertNested(self):
|
def assertNested(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -12,9 +12,11 @@
|
|||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
""" A tiny version of `six` to help with backwards compability. """
|
""" A tiny version of `six` to help with backwards compability. Also includes
|
||||||
|
compatibility helpers for numpy. """
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
import imp
|
||||||
|
|
||||||
PY2 = sys.version_info[0] == 2
|
PY2 = sys.version_info[0] == 2
|
||||||
PY26 = sys.version_info[0:2] == (2, 6)
|
PY26 = sys.version_info[0:2] == (2, 6)
|
||||||
@@ -43,4 +45,37 @@ else:
|
|||||||
memoryview_type = memoryview
|
memoryview_type = memoryview
|
||||||
struct_bool_decl = "?"
|
struct_bool_decl = "?"
|
||||||
|
|
||||||
|
# Helper functions to facilitate making numpy optional instead of required
|
||||||
|
|
||||||
|
def import_numpy():
|
||||||
|
"""
|
||||||
|
Returns the numpy module if it exists on the system,
|
||||||
|
otherwise returns None.
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
imp.find_module('numpy')
|
||||||
|
numpy_exists = True
|
||||||
|
except ImportError:
|
||||||
|
numpy_exists = False
|
||||||
|
|
||||||
|
if numpy_exists:
|
||||||
|
# We do this outside of try/except block in case numpy exists
|
||||||
|
# but is not installed correctly. We do not want to catch an
|
||||||
|
# incorrect installation which would manifest as an
|
||||||
|
# ImportError.
|
||||||
|
import numpy as np
|
||||||
|
else:
|
||||||
|
np = None
|
||||||
|
|
||||||
|
return np
|
||||||
|
|
||||||
|
|
||||||
|
class NumpyRequiredForThisFeature(RuntimeError):
|
||||||
|
"""
|
||||||
|
Error raised when user tries to use a feature that
|
||||||
|
requires numpy without having numpy installed.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
# NOTE: Future Jython support may require code here (look at `six`).
|
# NOTE: Future Jython support may require code here (look at `six`).
|
||||||
|
|||||||
@@ -15,13 +15,26 @@
|
|||||||
from . import number_types as N
|
from . import number_types as N
|
||||||
from . import packer
|
from . import packer
|
||||||
from .compat import memoryview_type
|
from .compat import memoryview_type
|
||||||
|
from .compat import import_numpy, NumpyRequiredForThisFeature
|
||||||
|
|
||||||
|
np = import_numpy()
|
||||||
|
|
||||||
def Get(packer_type, buf, head):
|
def Get(packer_type, buf, head):
|
||||||
""" Get decodes a value at buf[head:] using `packer_type`. """
|
""" Get decodes a value at buf[head] using `packer_type`. """
|
||||||
return packer_type.unpack_from(memoryview_type(buf), head)[0]
|
return packer_type.unpack_from(memoryview_type(buf), head)[0]
|
||||||
|
|
||||||
|
|
||||||
|
def GetVectorAsNumpy(numpy_type, buf, count, offset):
|
||||||
|
""" GetVecAsNumpy decodes values starting at buf[head] as
|
||||||
|
`numpy_type`, where `numpy_type` is a numpy dtype. """
|
||||||
|
if np is not None:
|
||||||
|
# TODO: could set .flags.writeable = False to make users jump through
|
||||||
|
# hoops before modifying...
|
||||||
|
return np.frombuffer(buf, dtype=numpy_type, count=count, offset=offset)
|
||||||
|
else:
|
||||||
|
raise NumpyRequiredForThisFeature('Numpy was not found.')
|
||||||
|
|
||||||
|
|
||||||
def Write(packer_type, buf, head, n):
|
def Write(packer_type, buf, head, n):
|
||||||
""" Write encodes `n` at buf[head:] using `packer_type`. """
|
""" Write encodes `n` at buf[head] using `packer_type`. """
|
||||||
packer_type.pack_into(buf, head, n)
|
packer_type.pack_into(buf, head, n)
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import collections
|
|||||||
import struct
|
import struct
|
||||||
|
|
||||||
from . import packer
|
from . import packer
|
||||||
|
from .compat import import_numpy, NumpyRequiredForThisFeature
|
||||||
|
|
||||||
|
np = import_numpy()
|
||||||
|
|
||||||
# For reference, see:
|
# For reference, see:
|
||||||
# https://docs.python.org/2/library/ctypes.html#ctypes-fundamental-data-types-2
|
# https://docs.python.org/2/library/ctypes.html#ctypes-fundamental-data-types-2
|
||||||
@@ -170,3 +172,10 @@ def uint64_to_float64(n):
|
|||||||
packed = struct.pack("<1Q", n)
|
packed = struct.pack("<1Q", n)
|
||||||
(unpacked,) = struct.unpack("<1d", packed)
|
(unpacked,) = struct.unpack("<1d", packed)
|
||||||
return unpacked
|
return unpacked
|
||||||
|
|
||||||
|
|
||||||
|
def to_numpy_type(number_type):
|
||||||
|
if np is not None:
|
||||||
|
return np.dtype(number_type.name).newbyteorder('<')
|
||||||
|
else:
|
||||||
|
raise NumpyRequiredForThisFeature('Numpy was not found.')
|
||||||
|
|||||||
@@ -101,6 +101,18 @@ class Table(object):
|
|||||||
return d
|
return d
|
||||||
return self.Get(validator_flags, self.Pos + off)
|
return self.Get(validator_flags, self.Pos + off)
|
||||||
|
|
||||||
|
def GetVectorAsNumpy(self, flags, off):
|
||||||
|
"""
|
||||||
|
GetVectorAsNumpy returns the vector that starts at `Vector(off)`
|
||||||
|
as a numpy array with the type specified by `flags`. The array is
|
||||||
|
a `view` into Bytes, so modifying the returned array will
|
||||||
|
modify Bytes in place.
|
||||||
|
"""
|
||||||
|
offset = self.Vector(off)
|
||||||
|
length = self.VectorLen(off) # TODO: length accounts for bytewidth, right?
|
||||||
|
numpy_dtype = N.to_numpy_type(flags)
|
||||||
|
return encode.GetVectorAsNumpy(numpy_dtype, self.Bytes, length, offset)
|
||||||
|
|
||||||
def GetVOffsetTSlot(self, slot, d):
|
def GetVOffsetTSlot(self, slot, d):
|
||||||
"""
|
"""
|
||||||
GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
|
GetVOffsetTSlot retrieves the VOffsetT that the given vtable location
|
||||||
|
|||||||
11
samples/android/AndroidManifest.xml
Executable file → Normal file
11
samples/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.samples.FlatBufferSample"
|
package="com.samples.FlatBufferSample">
|
||||||
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
samples/android/build.gradle
Normal file
108
samples/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.samples.FlatBufferSample'
|
||||||
|
// 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 "FlatBufferSample"
|
||||||
|
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
samples/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
samples/android/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
samples/android/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
samples/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
samples/android/gradlew
vendored
Executable file
172
samples/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
samples/android/gradlew.bat
vendored
Normal file
84
samples/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
|
||||||
2
samples/android/jni/Android.mk
Executable file → Normal file
2
samples/android/jni/Android.mk
Executable file → Normal file
@@ -38,7 +38,7 @@ $(info $(LOCAL_C_INCLUDES))
|
|||||||
LOCAL_SRC_FILES := main.cpp
|
LOCAL_SRC_FILES := main.cpp
|
||||||
|
|
||||||
LOCAL_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix
|
LOCAL_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix
|
||||||
LOCAL_LDLIBS := -llog -landroid
|
LOCAL_LDLIBS := -llog -landroid -latomic
|
||||||
LOCAL_ARM_MODE := arm
|
LOCAL_ARM_MODE := arm
|
||||||
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers
|
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers
|
||||||
|
|
||||||
|
|||||||
6
samples/android/jni/Application.mk
Executable file → Normal file
6
samples/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
samples/android/res/values/strings.xml
Executable file → Normal file
0
samples/android/res/values/strings.xml
Executable file → Normal file
@@ -29,8 +29,7 @@ fi
|
|||||||
|
|
||||||
# Execute `build_apk.sh` to build and run the android app.
|
# Execute `build_apk.sh` to build and run the android app.
|
||||||
cd android
|
cd android
|
||||||
./build_apk.sh
|
./gradlew build
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Cleanup the temporary files.
|
|
||||||
rm build.xml local.properties proguard-project.txt project.properties
|
|
||||||
rm -rf bin libs obj
|
|
||||||
|
|||||||
0
samples/monster.fbs
Executable file → Normal file
0
samples/monster.fbs
Executable file → Normal file
@@ -103,6 +103,7 @@ struct EquipmentUnion {
|
|||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Set(T&& val) {
|
void Set(T&& val) {
|
||||||
Reset();
|
Reset();
|
||||||
@@ -111,6 +112,7 @@ struct EquipmentUnion {
|
|||||||
value = new T(std::forward<T>(val));
|
value = new T(std::forward<T>(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
static void *UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
|
static void *UnPack(const void *obj, Equipment type, const flatbuffers::resolver_function_t *resolver);
|
||||||
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
|
flatbuffers::Offset<void> Pack(flatbuffers::FlatBufferBuilder &_fbb, const flatbuffers::rehasher_function_t *_rehasher = nullptr) const;
|
||||||
@@ -119,6 +121,10 @@ struct EquipmentUnion {
|
|||||||
return type == Equipment_Weapon ?
|
return type == Equipment_Weapon ?
|
||||||
reinterpret_cast<WeaponT *>(value) : nullptr;
|
reinterpret_cast<WeaponT *>(value) : nullptr;
|
||||||
}
|
}
|
||||||
|
const WeaponT *AsWeapon() const {
|
||||||
|
return type == Equipment_Weapon ?
|
||||||
|
reinterpret_cast<const WeaponT *>(value) : nullptr;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type);
|
bool VerifyEquipment(flatbuffers::Verifier &verifier, const void *obj, Equipment type);
|
||||||
@@ -134,9 +140,6 @@ MANUALLY_ALIGNED_STRUCT(4) Vec3 FLATBUFFERS_FINAL_CLASS {
|
|||||||
Vec3() {
|
Vec3() {
|
||||||
memset(this, 0, sizeof(Vec3));
|
memset(this, 0, sizeof(Vec3));
|
||||||
}
|
}
|
||||||
Vec3(const Vec3 &_o) {
|
|
||||||
memcpy(this, &_o, sizeof(Vec3));
|
|
||||||
}
|
|
||||||
Vec3(float _x, float _y, float _z)
|
Vec3(float _x, float _y, float _z)
|
||||||
: x_(flatbuffers::EndianScalar(_x)),
|
: x_(flatbuffers::EndianScalar(_x)),
|
||||||
y_(flatbuffers::EndianScalar(_y)),
|
y_(flatbuffers::EndianScalar(_y)),
|
||||||
@@ -165,13 +168,13 @@ STRUCT_END(Vec3, 12);
|
|||||||
|
|
||||||
struct MonsterT : public flatbuffers::NativeTable {
|
struct MonsterT : public flatbuffers::NativeTable {
|
||||||
typedef Monster TableType;
|
typedef Monster TableType;
|
||||||
std::unique_ptr<Vec3> pos;
|
flatbuffers::unique_ptr<Vec3> pos;
|
||||||
int16_t mana;
|
int16_t mana;
|
||||||
int16_t hp;
|
int16_t hp;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<uint8_t> inventory;
|
std::vector<uint8_t> inventory;
|
||||||
Color color;
|
Color color;
|
||||||
std::vector<std::unique_ptr<WeaponT>> weapons;
|
std::vector<flatbuffers::unique_ptr<WeaponT>> weapons;
|
||||||
EquipmentUnion equipped;
|
EquipmentUnion equipped;
|
||||||
MonsterT()
|
MonsterT()
|
||||||
: mana(150),
|
: mana(150),
|
||||||
@@ -308,13 +311,13 @@ struct MonsterBuilder {
|
|||||||
void add_equipped(flatbuffers::Offset<void> equipped) {
|
void add_equipped(flatbuffers::Offset<void> equipped) {
|
||||||
fbb_.AddOffset(Monster::VT_EQUIPPED, equipped);
|
fbb_.AddOffset(Monster::VT_EQUIPPED, equipped);
|
||||||
}
|
}
|
||||||
MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
explicit MonsterBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
: fbb_(_fbb) {
|
: fbb_(_fbb) {
|
||||||
start_ = fbb_.StartTable();
|
start_ = fbb_.StartTable();
|
||||||
}
|
}
|
||||||
MonsterBuilder &operator=(const MonsterBuilder &);
|
MonsterBuilder &operator=(const MonsterBuilder &);
|
||||||
flatbuffers::Offset<Monster> Finish() {
|
flatbuffers::Offset<Monster> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 10);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Monster>(end);
|
auto o = flatbuffers::Offset<Monster>(end);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@@ -418,13 +421,13 @@ struct WeaponBuilder {
|
|||||||
void add_damage(int16_t damage) {
|
void add_damage(int16_t damage) {
|
||||||
fbb_.AddElement<int16_t>(Weapon::VT_DAMAGE, damage, 0);
|
fbb_.AddElement<int16_t>(Weapon::VT_DAMAGE, damage, 0);
|
||||||
}
|
}
|
||||||
WeaponBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
explicit WeaponBuilder(flatbuffers::FlatBufferBuilder &_fbb)
|
||||||
: fbb_(_fbb) {
|
: fbb_(_fbb) {
|
||||||
start_ = fbb_.StartTable();
|
start_ = fbb_.StartTable();
|
||||||
}
|
}
|
||||||
WeaponBuilder &operator=(const WeaponBuilder &);
|
WeaponBuilder &operator=(const WeaponBuilder &);
|
||||||
flatbuffers::Offset<Weapon> Finish() {
|
flatbuffers::Offset<Weapon> Finish() {
|
||||||
const auto end = fbb_.EndTable(start_, 2);
|
const auto end = fbb_.EndTable(start_);
|
||||||
auto o = flatbuffers::Offset<Weapon>(end);
|
auto o = flatbuffers::Offset<Weapon>(end);
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
@@ -461,13 +464,13 @@ inline MonsterT *Monster::UnPack(const flatbuffers::resolver_function_t *_resolv
|
|||||||
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
|
inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function_t *_resolver) const {
|
||||||
(void)_o;
|
(void)_o;
|
||||||
(void)_resolver;
|
(void)_resolver;
|
||||||
{ auto _e = pos(); if (_e) _o->pos = std::unique_ptr<Vec3>(new Vec3(*_e)); };
|
{ auto _e = pos(); if (_e) _o->pos = flatbuffers::unique_ptr<Vec3>(new Vec3(*_e)); };
|
||||||
{ auto _e = mana(); _o->mana = _e; };
|
{ auto _e = mana(); _o->mana = _e; };
|
||||||
{ auto _e = hp(); _o->hp = _e; };
|
{ auto _e = hp(); _o->hp = _e; };
|
||||||
{ auto _e = name(); if (_e) _o->name = _e->str(); };
|
{ auto _e = name(); if (_e) _o->name = _e->str(); };
|
||||||
{ auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
|
{ auto _e = inventory(); if (_e) { _o->inventory.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->inventory[_i] = _e->Get(_i); } } };
|
||||||
{ auto _e = color(); _o->color = _e; };
|
{ auto _e = color(); _o->color = _e; };
|
||||||
{ auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = std::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } };
|
{ auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = flatbuffers::unique_ptr<WeaponT>(_e->Get(_i)->UnPack(_resolver)); } } };
|
||||||
{ auto _e = equipped_type(); _o->equipped.type = _e; };
|
{ auto _e = equipped_type(); _o->equipped.type = _e; };
|
||||||
{ auto _e = equipped(); if (_e) _o->equipped.value = EquipmentUnion::UnPack(_e, equipped_type(), _resolver); };
|
{ auto _e = equipped(); if (_e) _o->equipped.value = EquipmentUnion::UnPack(_e, equipped_type(), _resolver); };
|
||||||
}
|
}
|
||||||
@@ -479,13 +482,14 @@ inline flatbuffers::Offset<Monster> Monster::Pack(flatbuffers::FlatBufferBuilder
|
|||||||
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder &_fbb, const MonsterT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
(void)_rehasher;
|
(void)_rehasher;
|
||||||
(void)_o;
|
(void)_o;
|
||||||
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MonsterT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
auto _pos = _o->pos ? _o->pos.get() : 0;
|
auto _pos = _o->pos ? _o->pos.get() : 0;
|
||||||
auto _mana = _o->mana;
|
auto _mana = _o->mana;
|
||||||
auto _hp = _o->hp;
|
auto _hp = _o->hp;
|
||||||
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
|
auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
|
||||||
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
|
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
|
||||||
auto _color = _o->color;
|
auto _color = _o->color;
|
||||||
auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>>(_o->weapons.size(), [&](size_t i) { return CreateWeapon(_fbb, _o->weapons[i].get(), _rehasher); }) : 0;
|
auto _weapons = _o->weapons.size() ? _fbb.CreateVector<flatbuffers::Offset<Weapon>> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateWeapon(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ) : 0;
|
||||||
auto _equipped_type = _o->equipped.type;
|
auto _equipped_type = _o->equipped.type;
|
||||||
auto _equipped = _o->equipped.Pack(_fbb);
|
auto _equipped = _o->equipped.Pack(_fbb);
|
||||||
return MyGame::Sample::CreateMonster(
|
return MyGame::Sample::CreateMonster(
|
||||||
@@ -521,7 +525,8 @@ inline flatbuffers::Offset<Weapon> Weapon::Pack(flatbuffers::FlatBufferBuilder &
|
|||||||
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<Weapon> CreateWeapon(flatbuffers::FlatBufferBuilder &_fbb, const WeaponT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
(void)_rehasher;
|
(void)_rehasher;
|
||||||
(void)_o;
|
(void)_o;
|
||||||
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const WeaponT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
|
auto _name = _o->name.empty() ? 0 : _fbb.CreateString(_o->name);
|
||||||
auto _damage = _o->damage;
|
auto _damage = _o->damage;
|
||||||
return MyGame::Sample::CreateWeapon(
|
return MyGame::Sample::CreateWeapon(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -597,6 +602,120 @@ inline void EquipmentUnion::Reset() {
|
|||||||
type = Equipment_NONE;
|
type = Equipment_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *Vec3TypeTable();
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *MonsterTypeTable();
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *WeaponTypeTable();
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *ColorTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
ColorTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"Red",
|
||||||
|
"Green",
|
||||||
|
"Blue"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_ENUM, 3, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *EquipmentTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
WeaponTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"NONE",
|
||||||
|
"Weapon"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_UNION, 2, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *Vec3TypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_FLOAT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const int32_t values[] = { 0, 4, 8, 12 };
|
||||||
|
static const char *names[] = {
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"z"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_STRUCT, 3, type_codes, nullptr, values, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *MonsterTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 0 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 },
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_BOOL, 0, -1 },
|
||||||
|
{ flatbuffers::ET_UCHAR, 1, -1 },
|
||||||
|
{ flatbuffers::ET_CHAR, 0, 1 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 1, 2 },
|
||||||
|
{ flatbuffers::ET_UTYPE, 0, 3 },
|
||||||
|
{ flatbuffers::ET_SEQUENCE, 0, 3 }
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeFunction type_refs[] = {
|
||||||
|
Vec3TypeTable,
|
||||||
|
ColorTypeTable,
|
||||||
|
WeaponTypeTable,
|
||||||
|
EquipmentTypeTable
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"pos",
|
||||||
|
"mana",
|
||||||
|
"hp",
|
||||||
|
"name",
|
||||||
|
"friendly",
|
||||||
|
"inventory",
|
||||||
|
"color",
|
||||||
|
"weapons",
|
||||||
|
"equipped_type",
|
||||||
|
"equipped"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 10, type_codes, type_refs, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline flatbuffers::TypeTable *WeaponTypeTable() {
|
||||||
|
static flatbuffers::TypeCode type_codes[] = {
|
||||||
|
{ flatbuffers::ET_STRING, 0, -1 },
|
||||||
|
{ flatbuffers::ET_SHORT, 0, -1 }
|
||||||
|
};
|
||||||
|
static const char *names[] = {
|
||||||
|
"name",
|
||||||
|
"damage"
|
||||||
|
};
|
||||||
|
static flatbuffers::TypeTable tt = {
|
||||||
|
flatbuffers::ST_TABLE, 2, type_codes, nullptr, nullptr, names
|
||||||
|
};
|
||||||
|
return &tt;
|
||||||
|
}
|
||||||
|
|
||||||
inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
|
inline const MyGame::Sample::Monster *GetMonster(const void *buf) {
|
||||||
return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
|
return flatbuffers::GetRoot<MyGame::Sample::Monster>(buf);
|
||||||
}
|
}
|
||||||
@@ -616,10 +735,10 @@ inline void FinishMonsterBuffer(
|
|||||||
fbb.Finish(root);
|
fbb.Finish(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unique_ptr<MonsterT> UnPackMonster(
|
inline flatbuffers::unique_ptr<MonsterT> UnPackMonster(
|
||||||
const void *buf,
|
const void *buf,
|
||||||
const flatbuffers::resolver_function_t *res = nullptr) {
|
const flatbuffers::resolver_function_t *res = nullptr) {
|
||||||
return std::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(res));
|
return flatbuffers::unique_ptr<MonsterT>(GetMonster(buf)->UnPack(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Sample
|
} // namespace Sample
|
||||||
|
|||||||
0
samples/monsterdata.json
Executable file → Normal file
0
samples/monsterdata.json
Executable file → Normal file
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "flatbuffers/code_generators.h"
|
#include "flatbuffers/code_generators.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include "flatbuffers/base.h"
|
||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@@ -58,7 +59,7 @@ void CodeWriter::operator+=(std::string text) {
|
|||||||
// Update the text to everything after the }}.
|
// Update the text to everything after the }}.
|
||||||
text = text.substr(end + 2);
|
text = text.substr(end + 2);
|
||||||
}
|
}
|
||||||
if (!text.empty() && text.back() == '\\') {
|
if (!text.empty() && string_back(text) == '\\') {
|
||||||
text.pop_back();
|
text.pop_back();
|
||||||
stream_ << text;
|
stream_ << text;
|
||||||
} else {
|
} else {
|
||||||
@@ -129,8 +130,8 @@ std::string BaseGenerator::GetNameSpace(const Definition &def) const {
|
|||||||
std::string qualified_name = qualifying_start_;
|
std::string qualified_name = qualifying_start_;
|
||||||
for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
|
for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
|
||||||
qualified_name += *it;
|
qualified_name += *it;
|
||||||
if (std::next(it) != ns->components.end()) {
|
if ((it + 1) != ns->components.end()) {
|
||||||
qualified_name += qualifying_separator_;
|
qualified_name += qualifying_separator_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -167,4 +168,3 @@ void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
|
|||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(pop)
|
#pragma warning(pop)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
#define FLATC_VERSION "1.7.0 (" __DATE__ ")"
|
#define FLATC_VERSION "1.8.0 (" __DATE__ ")"
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
@@ -83,16 +83,21 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
|
|||||||
" --no-includes Don\'t generate include statements for included\n"
|
" --no-includes Don\'t generate include statements for included\n"
|
||||||
" schemas the generated file depends on (C++).\n"
|
" schemas the generated file depends on (C++).\n"
|
||||||
" --gen-mutable Generate accessors that can mutate buffers in-place.\n"
|
" --gen-mutable Generate accessors that can mutate buffers in-place.\n"
|
||||||
" --gen-onefile Generate single output file for C#.\n"
|
" --gen-onefile Generate single output file for C# and Go.\n"
|
||||||
" --gen-name-strings Generate type name functions for C++.\n"
|
" --gen-name-strings Generate type name functions for C++.\n"
|
||||||
" --escape-proto-ids Disable appending '_' in namespaces names.\n"
|
|
||||||
" --gen-object-api Generate an additional object-based API.\n"
|
" --gen-object-api Generate an additional object-based API.\n"
|
||||||
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n"
|
" --cpp-ptr-type T Set object API pointer type (default std::unique_ptr)\n"
|
||||||
" --cpp-str-type T Set object API string type (default std::string)\n"
|
" --cpp-str-type T Set object API string type (default std::string)\n"
|
||||||
" T::c_str() and T::length() must be supported\n"
|
" T::c_str() and T::length() must be supported\n"
|
||||||
|
" --gen-nullable Add Clang _Nullable for C++ pointer. or @Nullable for Java\n"
|
||||||
|
" --object-prefix Customise class prefix for C++ object-based API.\n"
|
||||||
|
" --object-suffix Customise class suffix for C++ object-based API.\n"
|
||||||
|
" Default value is \"T\"\n"
|
||||||
" --no-js-exports Removes Node.js style export lines in JS.\n"
|
" --no-js-exports Removes Node.js style export lines in JS.\n"
|
||||||
" --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n"
|
" --goog-js-export Uses goog.exports* for closure compiler exporting in JS.\n"
|
||||||
" --go-namespace Generate the overrided namespace in Golang.\n"
|
" --go-namespace Generate the overrided namespace in Golang.\n"
|
||||||
|
" --go-import Generate the overrided import for flatbuffers in Golang.\n"
|
||||||
|
" (default is \"github.com/google/flatbuffers/go\")\n"
|
||||||
" --raw-binary Allow binaries without file_indentifier to be read.\n"
|
" --raw-binary Allow binaries without file_indentifier to be read.\n"
|
||||||
" This may crash flatc given a mismatched schema.\n"
|
" This may crash flatc given a mismatched schema.\n"
|
||||||
" --proto Input is a .proto, translate to .fbs.\n"
|
" --proto Input is a .proto, translate to .fbs.\n"
|
||||||
@@ -108,8 +113,10 @@ std::string FlatCompiler::GetUsageString(const char* program_name) const {
|
|||||||
" --keep-prefix Keep original prefix of schema include statement.\n"
|
" --keep-prefix Keep original prefix of schema include statement.\n"
|
||||||
" --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
|
" --no-fb-import Don't include flatbuffers import statement for TypeScript.\n"
|
||||||
" --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
|
" --no-ts-reexport Don't re-export imported dependencies for TypeScript.\n"
|
||||||
"FILEs may be schemas, or JSON files (conforming to preceding schema)\n"
|
" --reflect-types Add minimal type reflection to code generation.\n"
|
||||||
"FILEs after the -- must be binary flatbuffer format files.\n"
|
" --reflect-names Add minimal type/name reflection.\n"
|
||||||
|
"FILEs may be schemas (must end in .fbs), or JSON files (conforming to preceding\n"
|
||||||
|
"schema). FILEs after the -- must be binary flatbuffer format files.\n"
|
||||||
"Output files are named using the base file name of the input,\n"
|
"Output files are named using the base file name of the input,\n"
|
||||||
"and written to the current directory or the path given by -o.\n"
|
"and written to the current directory or the path given by -o.\n"
|
||||||
"example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
|
"example: " << program_name << " -c -b schema1.fbs schema2.fbs data.json\n";
|
||||||
@@ -178,6 +185,9 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
} else if(arg == "--go-namespace") {
|
} else if(arg == "--go-namespace") {
|
||||||
if (++argi >= argc) Error("missing golang namespace" + arg, true);
|
if (++argi >= argc) Error("missing golang namespace" + arg, true);
|
||||||
opts.go_namespace = argv[argi];
|
opts.go_namespace = argv[argi];
|
||||||
|
} else if(arg == "--go-import") {
|
||||||
|
if (++argi >= argc) Error("missing golang import" + arg, true);
|
||||||
|
opts.go_import = argv[argi];
|
||||||
} else if(arg == "--defaults-json") {
|
} else if(arg == "--defaults-json") {
|
||||||
opts.output_default_scalars_in_json = true;
|
opts.output_default_scalars_in_json = true;
|
||||||
} else if (arg == "--unknown-json") {
|
} else if (arg == "--unknown-json") {
|
||||||
@@ -201,6 +211,14 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
} else if (arg == "--cpp-str-type") {
|
} else if (arg == "--cpp-str-type") {
|
||||||
if (++argi >= argc) Error("missing type following" + arg, true);
|
if (++argi >= argc) Error("missing type following" + arg, true);
|
||||||
opts.cpp_object_api_string_type = argv[argi];
|
opts.cpp_object_api_string_type = argv[argi];
|
||||||
|
} else if (arg == "--gen-nullable") {
|
||||||
|
opts.gen_nullable = true;
|
||||||
|
} else if (arg == "--object-prefix") {
|
||||||
|
if (++argi >= argc) Error("missing prefix following" + arg, true);
|
||||||
|
opts.object_prefix = argv[argi];
|
||||||
|
} else if (arg == "--object-suffix") {
|
||||||
|
if (++argi >= argc) Error("missing suffix following" + arg, true);
|
||||||
|
opts.object_suffix = argv[argi];
|
||||||
} else if(arg == "--gen-all") {
|
} else if(arg == "--gen-all") {
|
||||||
opts.generate_all = true;
|
opts.generate_all = true;
|
||||||
opts.include_dependence_headers = false;
|
opts.include_dependence_headers = false;
|
||||||
@@ -217,8 +235,6 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
binary_files_from = filenames.size();
|
binary_files_from = filenames.size();
|
||||||
} else if(arg == "--proto") {
|
} else if(arg == "--proto") {
|
||||||
opts.proto_mode = true;
|
opts.proto_mode = true;
|
||||||
} else if(arg == "--escape-proto-ids") {
|
|
||||||
opts.escape_proto_identifiers = true;
|
|
||||||
} else if(arg == "--schema") {
|
} else if(arg == "--schema") {
|
||||||
schema_binary = true;
|
schema_binary = true;
|
||||||
} else if(arg == "-M") {
|
} else if(arg == "-M") {
|
||||||
@@ -234,6 +250,10 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
opts.skip_flatbuffers_import = true;
|
opts.skip_flatbuffers_import = true;
|
||||||
} else if(arg == "--no-ts-reexport") {
|
} else if(arg == "--no-ts-reexport") {
|
||||||
opts.reexport_ts_modules = false;
|
opts.reexport_ts_modules = false;
|
||||||
|
} else if(arg == "--reflect-types") {
|
||||||
|
opts.mini_reflect = IDLOptions::kTypes;
|
||||||
|
} else if(arg == "--reflect-names") {
|
||||||
|
opts.mini_reflect = IDLOptions::kTypesAndNames;
|
||||||
} else {
|
} else {
|
||||||
for (size_t i = 0; i < params_.num_generators; ++i) {
|
for (size_t i = 0; i < params_.num_generators; ++i) {
|
||||||
if (arg == params_.generators[i].generator_opt_long ||
|
if (arg == params_.generators[i].generator_opt_long ||
|
||||||
@@ -283,7 +303,8 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
|
|
||||||
bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
|
bool is_binary = static_cast<size_t>(file_it - filenames.begin()) >=
|
||||||
binary_files_from;
|
binary_files_from;
|
||||||
auto is_schema = flatbuffers::GetExtension(filename) == "fbs";
|
auto ext = flatbuffers::GetExtension(filename);
|
||||||
|
auto is_schema = ext == "fbs" || ext == "proto";
|
||||||
if (is_binary) {
|
if (is_binary) {
|
||||||
parser->builder_.Clear();
|
parser->builder_.Clear();
|
||||||
parser->builder_.PushFlatBuffer(
|
parser->builder_.PushFlatBuffer(
|
||||||
@@ -321,6 +342,12 @@ int FlatCompiler::Compile(int argc, const char** argv) {
|
|||||||
parser.reset(new flatbuffers::Parser(opts));
|
parser.reset(new flatbuffers::Parser(opts));
|
||||||
}
|
}
|
||||||
ParseFile(*parser.get(), filename, contents, include_directories);
|
ParseFile(*parser.get(), filename, contents, include_directories);
|
||||||
|
if (!is_schema && !parser->builder_.GetSize()) {
|
||||||
|
// If a file doesn't end in .fbs, it must be json/binary. Ensure we
|
||||||
|
// didn't just parse a schema with a different extension.
|
||||||
|
Error("input file is neither json nor a .fbs (schema) file: " +
|
||||||
|
filename, true);
|
||||||
|
}
|
||||||
if (is_schema && !conform_to_schema.empty()) {
|
if (is_schema && !conform_to_schema.empty()) {
|
||||||
auto err = parser->ConformTo(conform_parser);
|
auto err = parser->ConformTo(conform_parser);
|
||||||
if (!err.empty()) Error("schemas don\'t conform: " + err);
|
if (!err.empty()) Error("schemas don\'t conform: " + err);
|
||||||
|
|||||||
@@ -96,7 +96,12 @@ int main(int argc, const char *argv[]) {
|
|||||||
flatbuffers::IDLOptions::kPhp,
|
flatbuffers::IDLOptions::kPhp,
|
||||||
"Generate PHP files for tables/structs",
|
"Generate PHP files for tables/structs",
|
||||||
flatbuffers::GeneralMakeRule },
|
flatbuffers::GeneralMakeRule },
|
||||||
};
|
{ flatbuffers::GenerateJsonSchema, nullptr, "--jsonschema", "JsonSchema", true,
|
||||||
|
nullptr,
|
||||||
|
flatbuffers::IDLOptions::kJsonSchema,
|
||||||
|
"Generate Json schema",
|
||||||
|
flatbuffers::GeneralMakeRule },
|
||||||
|
};
|
||||||
|
|
||||||
flatbuffers::FlatCompiler::InitParams params;
|
flatbuffers::FlatCompiler::InitParams params;
|
||||||
params.generators = generators;
|
params.generators = generators;
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -23,18 +23,20 @@
|
|||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
static std::string GenType(const Type &type) {
|
static std::string GenType(const Type &type, bool underlying = false) {
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
case BASE_TYPE_STRUCT:
|
case BASE_TYPE_STRUCT:
|
||||||
return type.struct_def->defined_namespace->GetFullyQualifiedName(
|
return type.struct_def->defined_namespace->GetFullyQualifiedName(
|
||||||
type.struct_def->name);
|
type.struct_def->name);
|
||||||
case BASE_TYPE_UNION:
|
|
||||||
return type.enum_def->defined_namespace->GetFullyQualifiedName(
|
|
||||||
type.enum_def->name);
|
|
||||||
case BASE_TYPE_VECTOR:
|
case BASE_TYPE_VECTOR:
|
||||||
return "[" + GenType(type.VectorType()) + "]";
|
return "[" + GenType(type.VectorType()) + "]";
|
||||||
default:
|
default:
|
||||||
return kTypeNames[type.base_type];
|
if (type.enum_def && !underlying) {
|
||||||
|
return type.enum_def->defined_namespace->GetFullyQualifiedName(
|
||||||
|
type.enum_def->name);
|
||||||
|
} else {
|
||||||
|
return kTypeNames[type.base_type];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,14 +56,13 @@ static void GenNameSpace(const Namespace &name_space, std::string *_schema,
|
|||||||
|
|
||||||
// Generate a flatbuffer schema from the Parser's internal representation.
|
// Generate a flatbuffer schema from the Parser's internal representation.
|
||||||
std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
|
std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
|
||||||
// Proto namespaces may clash with table names, so we have to prefix all:
|
// Proto namespaces may clash with table names, escape the ones that were
|
||||||
if (!parser.opts.escape_proto_identifiers) {
|
// generated from a table:
|
||||||
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
|
for (auto it = parser.namespaces_.begin(); it != parser.namespaces_.end();
|
||||||
++it) {
|
++it) {
|
||||||
for (auto comp = (*it)->components.begin(); comp != (*it)->components.end();
|
auto &ns = **it;
|
||||||
++comp) {
|
for (size_t i = 0; i < ns.from_table; i++) {
|
||||||
(*comp) = "_" + (*comp);
|
ns.components[ns.components.size() - 1 - i] += "_";
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
|
|||||||
GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
|
GenNameSpace(*enum_def.defined_namespace, &schema, &last_namespace);
|
||||||
GenComment(enum_def.doc_comment, &schema, nullptr);
|
GenComment(enum_def.doc_comment, &schema, nullptr);
|
||||||
schema += "enum " + enum_def.name + " : ";
|
schema += "enum " + enum_def.name + " : ";
|
||||||
schema += GenType(enum_def.underlying_type) + " {\n";
|
schema += GenType(enum_def.underlying_type, true) + " {\n";
|
||||||
for (auto it = enum_def.vals.vec.begin();
|
for (auto it = enum_def.vals.vec.begin();
|
||||||
it != enum_def.vals.vec.end(); ++it) {
|
it != enum_def.vals.vec.end(); ++it) {
|
||||||
auto &ev = **it;
|
auto &ev = **it;
|
||||||
@@ -109,11 +110,13 @@ std::string GenerateFBS(const Parser &parser, const std::string &file_name) {
|
|||||||
for (auto field_it = struct_def.fields.vec.begin();
|
for (auto field_it = struct_def.fields.vec.begin();
|
||||||
field_it != struct_def.fields.vec.end(); ++field_it) {
|
field_it != struct_def.fields.vec.end(); ++field_it) {
|
||||||
auto &field = **field_it;
|
auto &field = **field_it;
|
||||||
GenComment(field.doc_comment, &schema, nullptr, " ");
|
if (field.value.type.base_type != BASE_TYPE_UTYPE) {
|
||||||
schema += " " + field.name + ":" + GenType(field.value.type);
|
GenComment(field.doc_comment, &schema, nullptr, " ");
|
||||||
if (field.value.constant != "0") schema += " = " + field.value.constant;
|
schema += " " + field.name + ":" + GenType(field.value.type);
|
||||||
if (field.required) schema += " (required)";
|
if (field.value.constant != "0") schema += " = " + field.value.constant;
|
||||||
schema += ";\n";
|
if (field.required) schema += " (required)";
|
||||||
|
schema += ";\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
schema += "}\n\n";
|
schema += "}\n\n";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@
|
|||||||
#include "flatbuffers/util.h"
|
#include "flatbuffers/util.h"
|
||||||
#include "flatbuffers/code_generators.h"
|
#include "flatbuffers/code_generators.h"
|
||||||
|
|
||||||
|
#if defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
#include <cctype>
|
||||||
|
#endif // defined(FLATBUFFERS_CPP98_STL)
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
// Convert an underscore_based_indentifier in to camelCase.
|
// Convert an underscore_based_indentifier in to camelCase.
|
||||||
@@ -66,6 +70,7 @@ struct LanguageParameters {
|
|||||||
std::string accessor_prefix_static;
|
std::string accessor_prefix_static;
|
||||||
std::string optional_suffix;
|
std::string optional_suffix;
|
||||||
std::string includes;
|
std::string includes;
|
||||||
|
std::string class_annotation;
|
||||||
CommentConfig comment_config;
|
CommentConfig comment_config;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -95,8 +100,8 @@ const LanguageParameters& GetLangParams(IDLOptions::Language lang) {
|
|||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\n"
|
"import java.nio.*;\nimport java.lang.*;\nimport java.util.*;\nimport com.google.flatbuffers.*;\n",
|
||||||
"import com.google.flatbuffers.*;\n\n@SuppressWarnings(\"unused\")\n",
|
"\n@SuppressWarnings(\"unused\")\n",
|
||||||
{
|
{
|
||||||
"/**",
|
"/**",
|
||||||
" *",
|
" *",
|
||||||
@@ -128,6 +133,7 @@ const LanguageParameters& GetLangParams(IDLOptions::Language lang) {
|
|||||||
"Table.",
|
"Table.",
|
||||||
"?",
|
"?",
|
||||||
"using global::System;\nusing global::FlatBuffers;\n\n",
|
"using global::System;\nusing global::FlatBuffers;\n\n",
|
||||||
|
"",
|
||||||
{
|
{
|
||||||
nullptr,
|
nullptr,
|
||||||
"///",
|
"///",
|
||||||
@@ -157,7 +163,7 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
GeneralGenerator &operator=(const GeneralGenerator &);
|
GeneralGenerator &operator=(const GeneralGenerator &);
|
||||||
bool generate() {
|
bool generate() {
|
||||||
std::string one_file_code;
|
std::string one_file_code;
|
||||||
cur_name_space_ = parser_.namespaces_.back();
|
cur_name_space_ = parser_.current_namespace_;
|
||||||
|
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
@@ -190,7 +196,7 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (parser_.opts.one_file) {
|
if (parser_.opts.one_file) {
|
||||||
return SaveType(file_name_, *parser_.namespaces_.back(),
|
return SaveType(file_name_, *parser_.current_namespace_,
|
||||||
one_file_code, true);
|
one_file_code, true);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -204,7 +210,7 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
if (lang_.language == IDLOptions::kCSharp) {
|
if (lang_.language == IDLOptions::kCSharp) {
|
||||||
code = "// <auto-generated>\n"
|
code = "// <auto-generated>\n"
|
||||||
"// " + std::string(FlatBuffersGeneratedWarning()) + "\n"
|
"// " + std::string(FlatBuffersGeneratedWarning()) + "\n"
|
||||||
"// </auto-generated>\n\n";
|
"// </auto-generated>\n\n";
|
||||||
} else {
|
} else {
|
||||||
@@ -216,7 +222,13 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
code += lang_.namespace_ident + namespace_name + lang_.namespace_begin;
|
code += lang_.namespace_ident + namespace_name + lang_.namespace_begin;
|
||||||
code += "\n\n";
|
code += "\n\n";
|
||||||
}
|
}
|
||||||
if (needs_includes) code += lang_.includes;
|
if (needs_includes) {
|
||||||
|
code += lang_.includes;
|
||||||
|
if (parser_.opts.gen_nullable) {
|
||||||
|
code += "\nimport javax.annotation.Nullable;\n";
|
||||||
|
}
|
||||||
|
code += lang_.class_annotation;
|
||||||
|
}
|
||||||
code += classcode;
|
code += classcode;
|
||||||
if (!namespace_name.empty()) code += lang_.namespace_end;
|
if (!namespace_name.empty()) code += lang_.namespace_end;
|
||||||
auto filename = NamespaceDir(ns) + defname + lang_.file_extension;
|
auto filename = NamespaceDir(ns) + defname + lang_.file_extension;
|
||||||
@@ -231,20 +243,28 @@ class GeneralGenerator : public BaseGenerator {
|
|||||||
: upper);
|
: upper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GenNullableAnnotation(const Type& t) {
|
||||||
|
return lang_.language == IDLOptions::kJava
|
||||||
|
&& parser_.opts.gen_nullable
|
||||||
|
&& !IsScalar(DestinationType(t, true).base_type) ? " @Nullable ": "";
|
||||||
|
}
|
||||||
|
|
||||||
static bool IsEnum(const Type& type) {
|
static bool IsEnum(const Type& type) {
|
||||||
return type.enum_def != nullptr && IsInteger(type.base_type);
|
return type.enum_def != nullptr && IsInteger(type.base_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
|
std::string GenTypeBasic(const Type &type, bool enableLangOverrides) {
|
||||||
static const char *java_typename[] = {
|
static const char *java_typename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
#JTYPE,
|
#JTYPE,
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *csharp_typename[] = {
|
static const char *csharp_typename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
#NTYPE,
|
#NTYPE,
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
@@ -690,7 +710,7 @@ void GenStructBody(const StructDef &struct_def, std::string *code_ptr,
|
|||||||
std::string GenByteBufferLength(const char *bb_name) {
|
std::string GenByteBufferLength(const char *bb_name) {
|
||||||
std::string bb_len = bb_name;
|
std::string bb_len = bb_name;
|
||||||
if (lang_.language == IDLOptions::kCSharp) bb_len += ".Length";
|
if (lang_.language == IDLOptions::kCSharp) bb_len += ".Length";
|
||||||
else bb_len += ".array().length";
|
else bb_len += ".capacity()";
|
||||||
return bb_len;
|
return bb_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -863,7 +883,8 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||||||
std::string dest_mask = DestinationMask(field.value.type, true);
|
std::string dest_mask = DestinationMask(field.value.type, true);
|
||||||
std::string dest_cast = DestinationCast(field.value.type);
|
std::string dest_cast = DestinationCast(field.value.type);
|
||||||
std::string src_cast = SourceCast(field.value.type);
|
std::string src_cast = SourceCast(field.value.type);
|
||||||
std::string method_start = " public " + type_name_dest + optional + " " +
|
std::string method_start = " public " + GenNullableAnnotation(field.value.type) +
|
||||||
|
type_name_dest + optional + " " +
|
||||||
MakeCamel(field.name, lang_.first_camel_upper);
|
MakeCamel(field.name, lang_.first_camel_upper);
|
||||||
std::string obj = lang_.language == IDLOptions::kCSharp
|
std::string obj = lang_.language == IDLOptions::kCSharp
|
||||||
? "(new " + type_name + "())"
|
? "(new " + type_name + "())"
|
||||||
@@ -1061,28 +1082,24 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// generate object accessors if is nested_flatbuffer
|
// generate object accessors if is nested_flatbuffer
|
||||||
auto nested = field.attributes.Lookup("nested_flatbuffer");
|
if (field.nested_flatbuffer) {
|
||||||
if (nested) {
|
auto nested_type_name = WrapInNameSpace(*field.nested_flatbuffer);
|
||||||
auto nested_qualified_name =
|
auto nested_method_name = MakeCamel(field.name, lang_.first_camel_upper)
|
||||||
parser_.namespaces_.back()->GetFullyQualifiedName(nested->constant);
|
|
||||||
auto nested_type = parser_.structs_.Lookup(nested_qualified_name);
|
|
||||||
auto nested_type_name = WrapInNameSpace(*nested_type);
|
|
||||||
auto nestedMethodName = MakeCamel(field.name, lang_.first_camel_upper)
|
|
||||||
+ "As" + nested_type_name;
|
+ "As" + nested_type_name;
|
||||||
auto getNestedMethodName = nestedMethodName;
|
auto get_nested_method_name = nested_method_name;
|
||||||
if (lang_.language == IDLOptions::kCSharp) {
|
if (lang_.language == IDLOptions::kCSharp) {
|
||||||
getNestedMethodName = "Get" + nestedMethodName;
|
get_nested_method_name = "Get" + nested_method_name;
|
||||||
conditional_cast = "(" + nested_type_name + lang_.optional_suffix + ")";
|
conditional_cast = "(" + nested_type_name + lang_.optional_suffix + ")";
|
||||||
}
|
}
|
||||||
if (lang_.language != IDLOptions::kCSharp) {
|
if (lang_.language != IDLOptions::kCSharp) {
|
||||||
code += " public " + nested_type_name + lang_.optional_suffix + " ";
|
code += " public " + nested_type_name + lang_.optional_suffix + " ";
|
||||||
code += nestedMethodName + "() { return ";
|
code += nested_method_name + "() { return ";
|
||||||
code += getNestedMethodName + "(new " + nested_type_name + "()); }\n";
|
code += get_nested_method_name + "(new " + nested_type_name + "()); }\n";
|
||||||
} else {
|
} else {
|
||||||
obj = "(new " + nested_type_name + "())";
|
obj = "(new " + nested_type_name + "())";
|
||||||
}
|
}
|
||||||
code += " public " + nested_type_name + lang_.optional_suffix + " ";
|
code += " public " + nested_type_name + lang_.optional_suffix + " ";
|
||||||
code += getNestedMethodName + "(";
|
code += get_nested_method_name + "(";
|
||||||
if (lang_.language != IDLOptions::kCSharp)
|
if (lang_.language != IDLOptions::kCSharp)
|
||||||
code += nested_type_name + " obj";
|
code += nested_type_name + " obj";
|
||||||
code += ") { int o = " + lang_.accessor_prefix + "__offset(";
|
code += ") { int o = " + lang_.accessor_prefix + "__offset(";
|
||||||
@@ -1165,7 +1182,9 @@ void GenStruct(StructDef &struct_def, std::string *code_ptr) {
|
|||||||
num_fields++;
|
num_fields++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_no_struct_fields && num_fields) {
|
// JVM specifications restrict default constructor params to be < 255.
|
||||||
|
// Longs and doubles take up 2 units, so we set the limit to be < 127.
|
||||||
|
if (has_no_struct_fields && num_fields && num_fields < 127) {
|
||||||
// Generate a table constructor of the form:
|
// Generate a table constructor of the form:
|
||||||
// public static int createName(FlatBufferBuilder builder, args...)
|
// public static int createName(FlatBufferBuilder builder, args...)
|
||||||
code += " public static " + GenOffsetType(struct_def) + " ";
|
code += " public static " + GenOffsetType(struct_def) + " ";
|
||||||
|
|||||||
@@ -34,6 +34,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace flatbuffers {
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
static std::string GeneratedFileName(const std::string &path,
|
||||||
|
const std::string &file_name) {
|
||||||
|
return path + file_name + "_generated.go";
|
||||||
|
}
|
||||||
|
|
||||||
namespace go {
|
namespace go {
|
||||||
|
|
||||||
// see https://golang.org/ref/spec#Keywords
|
// see https://golang.org/ref/spec#Keywords
|
||||||
@@ -694,7 +700,8 @@ static std::string GenMethod(const FieldDef &field) {
|
|||||||
|
|
||||||
static std::string GenTypeBasic(const Type &type) {
|
static std::string GenTypeBasic(const Type &type) {
|
||||||
static const char *ctypename[] = {
|
static const char *ctypename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
#GTYPE,
|
#GTYPE,
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
@@ -751,18 +758,35 @@ class GoGenerator : public BaseGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool generate() {
|
bool generate() {
|
||||||
|
std::string one_file_code;
|
||||||
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
for (auto it = parser_.enums_.vec.begin(); it != parser_.enums_.vec.end();
|
||||||
++it) {
|
++it) {
|
||||||
std::string enumcode;
|
std::string enumcode;
|
||||||
go::GenEnum(**it, &enumcode);
|
go::GenEnum(**it, &enumcode);
|
||||||
if (!SaveType(**it, enumcode, false)) return false;
|
if (parser_.opts.one_file) {
|
||||||
|
one_file_code += enumcode;
|
||||||
|
} else {
|
||||||
|
if (!SaveType(**it, enumcode, false)) return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto it = parser_.structs_.vec.begin();
|
for (auto it = parser_.structs_.vec.begin();
|
||||||
it != parser_.structs_.vec.end(); ++it) {
|
it != parser_.structs_.vec.end(); ++it) {
|
||||||
std::string declcode;
|
std::string declcode;
|
||||||
go::GenStruct(**it, &declcode);
|
go::GenStruct(**it, &declcode);
|
||||||
if (!SaveType(**it, declcode, true)) return false;
|
if (parser_.opts.one_file) {
|
||||||
|
one_file_code += declcode;
|
||||||
|
} else {
|
||||||
|
if (!SaveType(**it, declcode, true)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parser_.opts.one_file) {
|
||||||
|
std::string code = "";
|
||||||
|
BeginFile(LastNamespacePart(go_namespace_), true, &code);
|
||||||
|
code += one_file_code;
|
||||||
|
const std::string filename = GeneratedFileName(path_, file_name_);
|
||||||
|
return SaveFile(filename.c_str(), code, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -777,7 +801,11 @@ class GoGenerator : public BaseGenerator {
|
|||||||
code += "package " + name_space_name + "\n\n";
|
code += "package " + name_space_name + "\n\n";
|
||||||
if (needs_imports) {
|
if (needs_imports) {
|
||||||
code += "import (\n";
|
code += "import (\n";
|
||||||
code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n";
|
if (!parser_.opts.go_import.empty()) {
|
||||||
|
code += "\tflatbuffers \"" + parser_.opts.go_import +"\"\n";
|
||||||
|
} else{
|
||||||
|
code += "\tflatbuffers \"github.com/google/flatbuffers/go\"\n";
|
||||||
|
}
|
||||||
code += ")\n\n";
|
code += ")\n\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -214,11 +214,11 @@ class FlatBufFile : public grpc_generator::File {
|
|||||||
std::string service_header_ext() const { return ".grpc.fb.h"; }
|
std::string service_header_ext() const { return ".grpc.fb.h"; }
|
||||||
|
|
||||||
std::string package() const {
|
std::string package() const {
|
||||||
return parser_.namespaces_.back()->GetFullyQualifiedName("");
|
return parser_.current_namespace_->GetFullyQualifiedName("");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> package_parts() const {
|
std::vector<std::string> package_parts() const {
|
||||||
return parser_.namespaces_.back()->components;
|
return parser_.current_namespace_->components;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string additional_headers() const {
|
std::string additional_headers() const {
|
||||||
|
|||||||
@@ -289,9 +289,12 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr,
|
|||||||
std::string &code = *code_ptr;
|
std::string &code = *code_ptr;
|
||||||
std::string &exports = *exports_ptr;
|
std::string &exports = *exports_ptr;
|
||||||
GenDocComment(enum_def.doc_comment, code_ptr, "@enum");
|
GenDocComment(enum_def.doc_comment, code_ptr, "@enum");
|
||||||
|
std::string ns = GetNameSpace(enum_def);
|
||||||
if (lang_.language == IDLOptions::kTs) {
|
if (lang_.language == IDLOptions::kTs) {
|
||||||
code += "export namespace " + GetNameSpace(enum_def) + "{\n" +
|
if (!ns.empty()) {
|
||||||
"export enum " + enum_def.name + "{\n";
|
code += "export namespace " + ns + "{\n";
|
||||||
|
}
|
||||||
|
code += "export enum " + enum_def.name + "{\n";
|
||||||
} else {
|
} else {
|
||||||
if (enum_def.defined_namespace->components.empty()) {
|
if (enum_def.defined_namespace->components.empty()) {
|
||||||
code += "var ";
|
code += "var ";
|
||||||
@@ -329,11 +332,10 @@ void GenEnum(EnumDef &enum_def, std::string *code_ptr,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lang_.language == IDLOptions::kTs) {
|
if (lang_.language == IDLOptions::kTs && !ns.empty()) {
|
||||||
code += "}};\n\n";
|
code += "}";
|
||||||
} else {
|
|
||||||
code += "};\n\n";
|
|
||||||
}
|
}
|
||||||
|
code += "};\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GenType(const Type &type) {
|
static std::string GenType(const Type &type) {
|
||||||
@@ -554,13 +556,15 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
|
|||||||
std::string &exports = *exports_ptr;
|
std::string &exports = *exports_ptr;
|
||||||
|
|
||||||
std::string object_name;
|
std::string object_name;
|
||||||
|
std::string object_namespace = GetNameSpace(struct_def);
|
||||||
|
|
||||||
// Emit constructor
|
// Emit constructor
|
||||||
if (lang_.language == IDLOptions::kTs) {
|
if (lang_.language == IDLOptions::kTs) {
|
||||||
object_name = struct_def.name;
|
object_name = struct_def.name;
|
||||||
std::string object_namespace = GetNameSpace(struct_def);
|
|
||||||
GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
|
GenDocComment(struct_def.doc_comment, code_ptr, "@constructor");
|
||||||
code += "export namespace " + object_namespace + "{\n";
|
if (!object_namespace.empty()) {
|
||||||
|
code += "export namespace " + object_namespace + "{\n";
|
||||||
|
}
|
||||||
code += "export class " + struct_def.name;
|
code += "export class " + struct_def.name;
|
||||||
code += " {\n";
|
code += " {\n";
|
||||||
code += " /**\n";
|
code += " /**\n";
|
||||||
@@ -754,17 +758,37 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
|
|||||||
auto index = "this.bb.__vector(this.bb_pos + offset) + index" +
|
auto index = "this.bb.__vector(this.bb_pos + offset) + index" +
|
||||||
MaybeScale(inline_size);
|
MaybeScale(inline_size);
|
||||||
std::string args = "@param {number} index\n";
|
std::string args = "@param {number} index\n";
|
||||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
std::string ret_type;
|
||||||
args += "@param {" + vectortypename + "=} obj\n";
|
bool is_union = false;
|
||||||
} else if (vectortype.base_type == BASE_TYPE_STRING) {
|
switch (vectortype.base_type) {
|
||||||
args += "@param {flatbuffers.Encoding=} optionalEncoding\n";
|
case BASE_TYPE_STRUCT:
|
||||||
|
args += "@param {" + vectortypename + "=} obj\n";
|
||||||
|
ret_type = vectortypename;
|
||||||
|
break;
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
args += "@param {flatbuffers.Encoding=} optionalEncoding\n";
|
||||||
|
ret_type = vectortypename;
|
||||||
|
break;
|
||||||
|
case BASE_TYPE_UNION:
|
||||||
|
args += "@param {flatbuffers.Table=} obj\n";
|
||||||
|
ret_type = "?flatbuffers.Table";
|
||||||
|
is_union = true;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ret_type = vectortypename;
|
||||||
}
|
}
|
||||||
GenDocComment(field.doc_comment, code_ptr, args +
|
GenDocComment(field.doc_comment, code_ptr, args +
|
||||||
"@returns {" + vectortypename + "}");
|
"@returns {" + ret_type + "}");
|
||||||
if (lang_.language == IDLOptions::kTs) {
|
if (lang_.language == IDLOptions::kTs) {
|
||||||
std::string prefix = MakeCamel(field.name, false);
|
std::string prefix = MakeCamel(field.name, false);
|
||||||
|
if (is_union) {
|
||||||
|
prefix += "<T extends flatbuffers.Table>";
|
||||||
|
}
|
||||||
prefix += "(index: number";
|
prefix += "(index: number";
|
||||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
if (is_union) {
|
||||||
|
vectortypename = "T";
|
||||||
|
code += prefix + ", obj:T";
|
||||||
|
} else if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||||
vectortypename = GenPrefixedTypeName(vectortypename,
|
vectortypename = GenPrefixedTypeName(vectortypename,
|
||||||
vectortype.struct_def->file);
|
vectortype.struct_def->file);
|
||||||
code += prefix + ", obj?:" + vectortypename;
|
code += prefix + ", obj?:" + vectortypename;
|
||||||
@@ -781,7 +805,7 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
|
|||||||
} else {
|
} else {
|
||||||
code += object_name + ".prototype." + MakeCamel(field.name, false);
|
code += object_name + ".prototype." + MakeCamel(field.name, false);
|
||||||
code += " = function(index";
|
code += " = function(index";
|
||||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
if (vectortype.base_type == BASE_TYPE_STRUCT || is_union) {
|
||||||
code += ", obj";
|
code += ", obj";
|
||||||
} else if (vectortype.base_type == BASE_TYPE_STRING) {
|
} else if (vectortype.base_type == BASE_TYPE_STRING) {
|
||||||
code += ", optionalEncoding";
|
code += ", optionalEncoding";
|
||||||
@@ -797,7 +821,9 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
|
|||||||
: "this.bb.__indirect(" + index + ")";
|
: "this.bb.__indirect(" + index + ")";
|
||||||
code += ", this.bb)";
|
code += ", this.bb)";
|
||||||
} else {
|
} else {
|
||||||
if (vectortype.base_type == BASE_TYPE_STRING) {
|
if (is_union) {
|
||||||
|
index = "obj, " + index;
|
||||||
|
} else if (vectortype.base_type == BASE_TYPE_STRING) {
|
||||||
index += ", optionalEncoding";
|
index += ", optionalEncoding";
|
||||||
}
|
}
|
||||||
code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
|
code += offset_prefix + GenGetter(vectortype, "(" + index + ")");
|
||||||
@@ -1137,7 +1163,10 @@ void GenStruct(const Parser &parser, StructDef &struct_def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (lang_.language == IDLOptions::kTs) {
|
if (lang_.language == IDLOptions::kTs) {
|
||||||
code += "}\n}\n";
|
if (!object_namespace.empty()) {
|
||||||
|
code += "}\n";
|
||||||
|
}
|
||||||
|
code += "}\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
223
src/idl_gen_json_schema.cpp
Normal file
223
src/idl_gen_json_schema.cpp
Normal file
@@ -0,0 +1,223 @@
|
|||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "flatbuffers/code_generators.h"
|
||||||
|
#include "flatbuffers/idl.h"
|
||||||
|
#include "flatbuffers/util.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace flatbuffers {
|
||||||
|
|
||||||
|
static std::string GeneratedFileName(const std::string &path,
|
||||||
|
const std::string &file_name) {
|
||||||
|
return path + file_name + ".schema.json";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace jsons {
|
||||||
|
|
||||||
|
std::string GenNativeType(BaseType type) {
|
||||||
|
switch (type) {
|
||||||
|
case BASE_TYPE_BOOL:
|
||||||
|
return "boolean";
|
||||||
|
case BASE_TYPE_CHAR:
|
||||||
|
case BASE_TYPE_UCHAR:
|
||||||
|
case BASE_TYPE_SHORT:
|
||||||
|
case BASE_TYPE_USHORT:
|
||||||
|
case BASE_TYPE_INT:
|
||||||
|
case BASE_TYPE_UINT:
|
||||||
|
case BASE_TYPE_LONG:
|
||||||
|
case BASE_TYPE_ULONG:
|
||||||
|
case BASE_TYPE_FLOAT:
|
||||||
|
case BASE_TYPE_DOUBLE:
|
||||||
|
return "number";
|
||||||
|
case BASE_TYPE_STRING:
|
||||||
|
return "string";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> std::string GenFullName(const T *enum_def) {
|
||||||
|
std::string full_name;
|
||||||
|
const auto &name_spaces = enum_def->defined_namespace->components;
|
||||||
|
for (auto ns = name_spaces.cbegin(); ns != name_spaces.cend(); ++ns) {
|
||||||
|
full_name.append(*ns + "_");
|
||||||
|
}
|
||||||
|
full_name.append(enum_def->name);
|
||||||
|
return full_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T> std::string GenTypeRef(const T *enum_def) {
|
||||||
|
return "\"$ref\" : \"#/definitions/" + GenFullName(enum_def) + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GenType(const std::string &name) {
|
||||||
|
return "\"type\" : \"" + name + "\"";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GenType(const Type &type) {
|
||||||
|
if (type.enum_def != nullptr && !type.enum_def->is_union) {
|
||||||
|
// it is a reference to an enum type
|
||||||
|
return GenTypeRef(type.enum_def);
|
||||||
|
}
|
||||||
|
switch (type.base_type) {
|
||||||
|
case BASE_TYPE_VECTOR: {
|
||||||
|
std::string typeline;
|
||||||
|
typeline.append("\"type\" : \"array\", \"items\" : { ");
|
||||||
|
if (type.element == BASE_TYPE_STRUCT) {
|
||||||
|
typeline.append(GenTypeRef(type.struct_def));
|
||||||
|
} else {
|
||||||
|
typeline.append(GenType(GenNativeType(type.element)));
|
||||||
|
}
|
||||||
|
typeline.append(" }");
|
||||||
|
return typeline;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_STRUCT: {
|
||||||
|
return GenTypeRef(type.struct_def);
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UNION: {
|
||||||
|
std::string union_type_string("\"anyOf\": [");
|
||||||
|
const auto &union_types = type.enum_def->vals.vec;
|
||||||
|
for (auto ut = union_types.cbegin(); ut < union_types.cend(); ++ut) {
|
||||||
|
auto &union_type = *ut;
|
||||||
|
if (union_type->union_type.base_type == BASE_TYPE_NONE) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (union_type->union_type.base_type == BASE_TYPE_STRUCT) {
|
||||||
|
union_type_string.append("{ " + GenTypeRef(union_type->union_type.struct_def) + " }");
|
||||||
|
}
|
||||||
|
if (union_type != *type.enum_def->vals.vec.rbegin()) {
|
||||||
|
union_type_string.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
union_type_string.append("]");
|
||||||
|
return union_type_string;
|
||||||
|
}
|
||||||
|
case BASE_TYPE_UTYPE:
|
||||||
|
return GenTypeRef(type.enum_def);
|
||||||
|
default:
|
||||||
|
return GenType(GenNativeType(type.base_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JsonSchemaGenerator : public BaseGenerator {
|
||||||
|
private:
|
||||||
|
CodeWriter code_;
|
||||||
|
|
||||||
|
public:
|
||||||
|
JsonSchemaGenerator(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name)
|
||||||
|
: BaseGenerator(parser, path, file_name, "", "") {}
|
||||||
|
|
||||||
|
explicit JsonSchemaGenerator(const BaseGenerator &base_generator)
|
||||||
|
: BaseGenerator(base_generator) {}
|
||||||
|
|
||||||
|
bool generate() {
|
||||||
|
code_.Clear();
|
||||||
|
code_ += "{";
|
||||||
|
code_ += " \"$schema\": \"http://json-schema.org/draft-04/schema#\",";
|
||||||
|
code_ += " \"definitions\": {";
|
||||||
|
for (auto e = parser_.enums_.vec.cbegin();
|
||||||
|
e != parser_.enums_.vec.cend();
|
||||||
|
++e) {
|
||||||
|
code_ += " \"" + GenFullName(*e) + "\" : {";
|
||||||
|
code_ += " " + GenType("string") + ",";
|
||||||
|
std::string enumdef(" \"enum\": [");
|
||||||
|
for (auto enum_value = (*e)->vals.vec.begin();
|
||||||
|
enum_value != (*e)->vals.vec.end();
|
||||||
|
++enum_value) {
|
||||||
|
enumdef.append("\"" + (*enum_value)->name + "\"");
|
||||||
|
if (*enum_value != (*e)->vals.vec.back()) {
|
||||||
|
enumdef.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
enumdef.append("]");
|
||||||
|
code_ += enumdef;
|
||||||
|
code_ += " },"; // close type
|
||||||
|
}
|
||||||
|
for (auto s = parser_.structs_.vec.cbegin();
|
||||||
|
s != parser_.structs_.vec.cend();
|
||||||
|
++s) {
|
||||||
|
const auto &structure = *s;
|
||||||
|
code_ += " \"" + GenFullName(structure) + "\" : {";
|
||||||
|
code_ += " " + GenType("object") + ",";
|
||||||
|
std::string comment;
|
||||||
|
const auto &comment_lines = structure->doc_comment;
|
||||||
|
for (auto comment_line = comment_lines.cbegin();
|
||||||
|
comment_line != comment_lines.cend();
|
||||||
|
++comment_line) {
|
||||||
|
comment.append(*comment_line);
|
||||||
|
}
|
||||||
|
if (comment.size() > 0) {
|
||||||
|
code_ += " \"description\" : \"" + comment + "\",";
|
||||||
|
}
|
||||||
|
code_ += " \"properties\" : {";
|
||||||
|
|
||||||
|
const auto &properties = structure->fields.vec;
|
||||||
|
for (auto prop = properties.cbegin(); prop != properties.cend(); ++prop) {
|
||||||
|
const auto &property = *prop;
|
||||||
|
std::string typeLine(" \"" + property->name + "\" : { " + GenType(property->value.type) + " }");
|
||||||
|
if (property != properties.back()) {
|
||||||
|
typeLine.append(",");
|
||||||
|
}
|
||||||
|
code_ += typeLine;
|
||||||
|
}
|
||||||
|
code_ += " },"; // close properties
|
||||||
|
|
||||||
|
std::vector<FieldDef *> requiredProperties;
|
||||||
|
std::copy_if(properties.begin(), properties.end(),
|
||||||
|
back_inserter(requiredProperties),
|
||||||
|
[](FieldDef const *prop) { return prop->required; });
|
||||||
|
if (requiredProperties.size() > 0) {
|
||||||
|
std::string required_string(" \"required\" : [");
|
||||||
|
for (auto req_prop = requiredProperties.cbegin();
|
||||||
|
req_prop != requiredProperties.cend();
|
||||||
|
++req_prop) {
|
||||||
|
required_string.append("\"" + (*req_prop)->name + "\"");
|
||||||
|
if (*req_prop != requiredProperties.back()) {
|
||||||
|
required_string.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
required_string.append("],");
|
||||||
|
code_ += required_string;
|
||||||
|
}
|
||||||
|
code_ += " \"additionalProperties\" : false";
|
||||||
|
std::string closeType(" }");
|
||||||
|
if (*s != parser_.structs_.vec.back()) {
|
||||||
|
closeType.append(",");
|
||||||
|
}
|
||||||
|
code_ += closeType; // close type
|
||||||
|
}
|
||||||
|
code_ += " },"; // close definitions
|
||||||
|
|
||||||
|
// mark root type
|
||||||
|
code_ += " \"$ref\" : \"#/definitions/" +
|
||||||
|
GenFullName(parser_.root_struct_def_) + "\"";
|
||||||
|
|
||||||
|
code_ += "}"; // close schema root
|
||||||
|
const std::string file_path = GeneratedFileName(path_, file_name_);
|
||||||
|
const std::string final_code = code_.ToString();
|
||||||
|
return SaveFile(file_path.c_str(), final_code, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace jsons
|
||||||
|
|
||||||
|
bool GenerateJsonSchema(const Parser &parser, const std::string &path,
|
||||||
|
const std::string &file_name) {
|
||||||
|
jsons::JsonSchemaGenerator generator(parser, path, file_name);
|
||||||
|
return generator.generate();
|
||||||
|
}
|
||||||
|
} // namespace flatbuffers
|
||||||
@@ -67,7 +67,10 @@ namespace php {
|
|||||||
std::string &code = *code_ptr;
|
std::string &code = *code_ptr;
|
||||||
code += "<?php\n";
|
code += "<?php\n";
|
||||||
code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
|
code = code + "// " + FlatBuffersGeneratedWarning() + "\n\n";
|
||||||
code += "namespace " + name_space_name + ";\n\n";
|
|
||||||
|
if (!name_space_name.empty()) {
|
||||||
|
code += "namespace " + name_space_name + ";\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
if (needs_imports) {
|
if (needs_imports) {
|
||||||
code += "use \\Google\\FlatBuffers\\Struct;\n";
|
code += "use \\Google\\FlatBuffers\\Struct;\n";
|
||||||
@@ -428,6 +431,31 @@ namespace php {
|
|||||||
code += Indent + "}\n\n";
|
code += Indent + "}\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the value of a vector's union member. Uses a named return
|
||||||
|
// argument to conveniently set the zero value for the result.
|
||||||
|
void GetMemberOfVectorOfUnion(const FieldDef &field,
|
||||||
|
std::string *code_ptr) {
|
||||||
|
std::string &code = *code_ptr;
|
||||||
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
|
||||||
|
code += Indent + "/**\n";
|
||||||
|
code += Indent + " * @param int offset\n";
|
||||||
|
code += Indent + " * @return " + GenTypeGet(field.value.type) + "\n";
|
||||||
|
code += Indent + " */\n";
|
||||||
|
code += Indent + "public function get";
|
||||||
|
code += MakeCamel(field.name);
|
||||||
|
code += "($j, $obj)\n";
|
||||||
|
code += Indent + "{\n";
|
||||||
|
code += Indent + Indent +
|
||||||
|
"$o = $this->__offset(" +
|
||||||
|
NumToString(field.value.offset) +
|
||||||
|
");\n";
|
||||||
|
code += Indent + Indent + "return $o != 0 ? ";
|
||||||
|
code += "$this->__union($obj, $this->__vector($o) + $j * ";
|
||||||
|
code += NumToString(InlineSize(vectortype)) + " - $this->bb_pos) : null;\n";
|
||||||
|
code += Indent + "}\n\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Recursively generate arguments for a constructor, to deal with nested
|
// Recursively generate arguments for a constructor, to deal with nested
|
||||||
// structs.
|
// structs.
|
||||||
static void StructBuilderArgs(const StructDef &struct_def,
|
static void StructBuilderArgs(const StructDef &struct_def,
|
||||||
@@ -703,7 +731,9 @@ namespace php {
|
|||||||
break;
|
break;
|
||||||
case BASE_TYPE_VECTOR: {
|
case BASE_TYPE_VECTOR: {
|
||||||
auto vectortype = field.value.type.VectorType();
|
auto vectortype = field.value.type.VectorType();
|
||||||
if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
if (vectortype.base_type == BASE_TYPE_UNION) {
|
||||||
|
GetMemberOfVectorOfUnion(field, code_ptr);
|
||||||
|
} else if (vectortype.base_type == BASE_TYPE_STRUCT) {
|
||||||
GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
|
GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
|
||||||
} else {
|
} else {
|
||||||
GetMemberOfVectorOfNonStruct(field, code_ptr);
|
GetMemberOfVectorOfNonStruct(field, code_ptr);
|
||||||
@@ -879,7 +909,8 @@ namespace php {
|
|||||||
|
|
||||||
static std::string GenTypeBasic(const Type &type) {
|
static std::string GenTypeBasic(const Type &type) {
|
||||||
static const char *ctypename[] = {
|
static const char *ctypename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
#NTYPE,
|
#NTYPE,
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ static void GetStringField(const StructDef &struct_def,
|
|||||||
code += OffsetPrefix(field);
|
code += OffsetPrefix(field);
|
||||||
code += Indent + Indent + Indent + "return " + GenGetter(field.value.type);
|
code += Indent + Indent + Indent + "return " + GenGetter(field.value.type);
|
||||||
code += "o + self._tab.Pos)\n";
|
code += "o + self._tab.Pos)\n";
|
||||||
code += Indent + Indent + "return \"\"\n\n";
|
code += Indent + Indent + "return bytes()\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the value of a union from an object.
|
// Get the value of a union from an object.
|
||||||
@@ -274,6 +274,38 @@ static void GetMemberOfVectorOfNonStruct(const StructDef &struct_def,
|
|||||||
code += "\n";
|
code += "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns a non-struct vector as a numpy array. Much faster
|
||||||
|
// than iterating over the vector element by element.
|
||||||
|
static void GetVectorOfNonStructAsNumpy(const StructDef &struct_def,
|
||||||
|
const FieldDef &field,
|
||||||
|
std::string *code_ptr) {
|
||||||
|
std::string &code = *code_ptr;
|
||||||
|
auto vectortype = field.value.type.VectorType();
|
||||||
|
|
||||||
|
// Currently, we only support accessing as numpy array if
|
||||||
|
// the vector type is a scalar.
|
||||||
|
if (!(IsScalar(vectortype.base_type))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GenReceiver(struct_def, code_ptr);
|
||||||
|
code += MakeCamel(field.name) + "AsNumpy(self):";
|
||||||
|
code += OffsetPrefix(field);
|
||||||
|
|
||||||
|
code += Indent + Indent + Indent;
|
||||||
|
code += "return ";
|
||||||
|
code += "self._tab.GetVectorAsNumpy(flatbuffers.number_types.";
|
||||||
|
code += MakeCamel(GenTypeGet(field.value.type));
|
||||||
|
code += "Flags, o)\n";
|
||||||
|
|
||||||
|
if (vectortype.base_type == BASE_TYPE_STRING) {
|
||||||
|
code += Indent + Indent + "return \"\"\n";
|
||||||
|
} else {
|
||||||
|
code += Indent + Indent + "return 0\n";
|
||||||
|
}
|
||||||
|
code += "\n";
|
||||||
|
}
|
||||||
|
|
||||||
// Begin the creator function signature.
|
// Begin the creator function signature.
|
||||||
static void BeginBuilderArgs(const StructDef &struct_def,
|
static void BeginBuilderArgs(const StructDef &struct_def,
|
||||||
std::string *code_ptr) {
|
std::string *code_ptr) {
|
||||||
@@ -440,6 +472,7 @@ static void GenStructAccessor(const StructDef &struct_def,
|
|||||||
GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
|
GetMemberOfVectorOfStruct(struct_def, field, code_ptr);
|
||||||
} else {
|
} else {
|
||||||
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
|
GetMemberOfVectorOfNonStruct(struct_def, field, code_ptr);
|
||||||
|
GetVectorOfNonStructAsNumpy(struct_def, field, code_ptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -547,7 +580,8 @@ static std::string GenMethod(const FieldDef &field) {
|
|||||||
|
|
||||||
static std::string GenTypeBasic(const Type &type) {
|
static std::string GenTypeBasic(const Type &type) {
|
||||||
static const char *ctypename[] = {
|
static const char *ctypename[] = {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
#PTYPE,
|
#PTYPE,
|
||||||
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
@@ -643,7 +677,7 @@ class PythonGenerator : public BaseGenerator {
|
|||||||
if (!classcode.length()) return true;
|
if (!classcode.length()) return true;
|
||||||
|
|
||||||
std::string namespace_dir = path_;
|
std::string namespace_dir = path_;
|
||||||
auto &namespaces = parser_.namespaces_.back()->components;
|
auto &namespaces = def.defined_namespace->components;
|
||||||
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
for (auto it = namespaces.begin(); it != namespaces.end(); ++it) {
|
||||||
if (it != namespaces.begin()) namespace_dir += kPathSeparator;
|
if (it != namespaces.begin()) namespace_dir += kPathSeparator;
|
||||||
namespace_dir += *it;
|
namespace_dir += *it;
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ template<> bool Print<const void *>(const void *val,
|
|||||||
type = type.VectorType();
|
type = type.VectorType();
|
||||||
// Call PrintVector above specifically for each element type:
|
// Call PrintVector above specifically for each element type:
|
||||||
switch (type.base_type) {
|
switch (type.base_type) {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
PTYPE) \
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: \
|
||||||
if (!PrintVector<CTYPE>( \
|
if (!PrintVector<CTYPE>( \
|
||||||
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
*reinterpret_cast<const Vector<CTYPE> *>(val), \
|
||||||
@@ -165,6 +165,10 @@ template<typename T> static bool GenField(const FieldDef &fd,
|
|||||||
opts, _text);
|
opts, _text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool GenStruct(const StructDef &struct_def, const Table *table,
|
||||||
|
int indent, const IDLOptions &opts,
|
||||||
|
std::string *_text);
|
||||||
|
|
||||||
// Generate text for non-scalar field.
|
// Generate text for non-scalar field.
|
||||||
static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
||||||
int indent, Type *union_type,
|
int indent, Type *union_type,
|
||||||
@@ -178,8 +182,12 @@ static bool GenFieldOffset(const FieldDef &fd, const Table *table, bool fixed,
|
|||||||
} else if (fd.flexbuffer) {
|
} else if (fd.flexbuffer) {
|
||||||
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
||||||
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
|
auto root = flexbuffers::GetRoot(vec->data(), vec->size());
|
||||||
root.ToString(true, false, *_text);
|
root.ToString(true, opts.strict_json, *_text);
|
||||||
return true;
|
return true;
|
||||||
|
} else if (fd.nested_flatbuffer) {
|
||||||
|
auto vec = table->GetPointer<const Vector<uint8_t> *>(fd.value.offset);
|
||||||
|
auto root = GetRoot<Table>(vec->data());
|
||||||
|
return GenStruct(*fd.nested_flatbuffer, root, indent, opts, _text);
|
||||||
} else {
|
} else {
|
||||||
val = IsStruct(fd.value.type)
|
val = IsStruct(fd.value.type)
|
||||||
? table->GetStruct<const void *>(fd.value.offset)
|
? table->GetStruct<const void *>(fd.value.offset)
|
||||||
@@ -218,8 +226,8 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
text += " ";
|
text += " ";
|
||||||
if (is_present) {
|
if (is_present) {
|
||||||
switch (fd.value.type.base_type) {
|
switch (fd.value.type.base_type) {
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
PTYPE) \
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
case BASE_TYPE_ ## ENUM: \
|
case BASE_TYPE_ ## ENUM: \
|
||||||
if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
|
if (!GenField<CTYPE>(fd, table, struct_def.fixed, \
|
||||||
opts, indent + Indent(opts), _text)) { \
|
opts, indent + Indent(opts), _text)) { \
|
||||||
@@ -229,8 +237,8 @@ static bool GenStruct(const StructDef &struct_def, const Table *table,
|
|||||||
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
// Generate drop-thru case statements for all pointer types:
|
// Generate drop-thru case statements for all pointer types:
|
||||||
#define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, JTYPE, GTYPE, NTYPE, \
|
#define FLATBUFFERS_TD(ENUM, IDLTYPE, \
|
||||||
PTYPE) \
|
CTYPE, JTYPE, GTYPE, NTYPE, PTYPE) \
|
||||||
case BASE_TYPE_ ## ENUM:
|
case BASE_TYPE_ ## ENUM:
|
||||||
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
|
||||||
#undef FLATBUFFERS_TD
|
#undef FLATBUFFERS_TD
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -165,15 +165,15 @@ class ResizeContext {
|
|||||||
ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta,
|
ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta,
|
||||||
std::vector<uint8_t> *flatbuf,
|
std::vector<uint8_t> *flatbuf,
|
||||||
const reflection::Object *root_table = nullptr)
|
const reflection::Object *root_table = nullptr)
|
||||||
: schema_(schema), startptr_(flatbuf->data() + start),
|
: schema_(schema), startptr_(vector_data(*flatbuf) + start),
|
||||||
delta_(delta), buf_(*flatbuf),
|
delta_(delta), buf_(*flatbuf),
|
||||||
dag_check_(flatbuf->size() / sizeof(uoffset_t), false) {
|
dag_check_(flatbuf->size() / sizeof(uoffset_t), false) {
|
||||||
auto mask = static_cast<int>(sizeof(largest_scalar_t) - 1);
|
auto mask = static_cast<int>(sizeof(largest_scalar_t) - 1);
|
||||||
delta_ = (delta_ + mask) & ~mask;
|
delta_ = (delta_ + mask) & ~mask;
|
||||||
if (!delta_) return; // We can't shrink by less than largest_scalar_t.
|
if (!delta_) return; // We can't shrink by less than largest_scalar_t.
|
||||||
// Now change all the offsets by delta_.
|
// Now change all the offsets by delta_.
|
||||||
auto root = GetAnyRoot(buf_.data());
|
auto root = GetAnyRoot(vector_data(buf_));
|
||||||
Straddle<uoffset_t, 1>(buf_.data(), root, buf_.data());
|
Straddle<uoffset_t, 1>(vector_data(buf_), root, vector_data(buf_));
|
||||||
ResizeTable(root_table ? *root_table : *schema.root_table(), root);
|
ResizeTable(root_table ? *root_table : *schema.root_table(), root);
|
||||||
// We can now add or remove bytes at start.
|
// We can now add or remove bytes at start.
|
||||||
if (delta_ > 0) buf_.insert(buf_.begin() + start, delta_, 0);
|
if (delta_ > 0) buf_.insert(buf_.begin() + start, delta_, 0);
|
||||||
@@ -200,7 +200,7 @@ class ResizeContext {
|
|||||||
// will straddle and which won't.
|
// will straddle and which won't.
|
||||||
uint8_t &DagCheck(const void *offsetloc) {
|
uint8_t &DagCheck(const void *offsetloc) {
|
||||||
auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) -
|
auto dag_idx = reinterpret_cast<const uoffset_t *>(offsetloc) -
|
||||||
reinterpret_cast<const uoffset_t *>(buf_.data());
|
reinterpret_cast<const uoffset_t *>(vector_data(buf_));
|
||||||
return dag_check_[dag_idx];
|
return dag_check_[dag_idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -296,19 +296,19 @@ void SetString(const reflection::Schema &schema, const std::string &val,
|
|||||||
const reflection::Object *root_table) {
|
const reflection::Object *root_table) {
|
||||||
auto delta = static_cast<int>(val.size()) - static_cast<int>(str->Length());
|
auto delta = static_cast<int>(val.size()) - static_cast<int>(str->Length());
|
||||||
auto str_start = static_cast<uoffset_t>(
|
auto str_start = static_cast<uoffset_t>(
|
||||||
reinterpret_cast<const uint8_t *>(str) - flatbuf->data());
|
reinterpret_cast<const uint8_t *>(str) - vector_data(*flatbuf));
|
||||||
auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t));
|
auto start = str_start + static_cast<uoffset_t>(sizeof(uoffset_t));
|
||||||
if (delta) {
|
if (delta) {
|
||||||
// Clear the old string, since we don't want parts of it remaining.
|
// Clear the old string, since we don't want parts of it remaining.
|
||||||
memset(flatbuf->data() + start, 0, str->Length());
|
memset(vector_data(*flatbuf) + start, 0, str->Length());
|
||||||
// Different size, we must expand (or contract).
|
// Different size, we must expand (or contract).
|
||||||
ResizeContext(schema, start, delta, flatbuf, root_table);
|
ResizeContext(schema, start, delta, flatbuf, root_table);
|
||||||
// Set the new length.
|
// Set the new length.
|
||||||
WriteScalar(flatbuf->data() + str_start,
|
WriteScalar(vector_data(*flatbuf) + str_start,
|
||||||
static_cast<uoffset_t>(val.size()));
|
static_cast<uoffset_t>(val.size()));
|
||||||
}
|
}
|
||||||
// Copy new data. Safe because we created the right amount of space.
|
// Copy new data. Safe because we created the right amount of space.
|
||||||
memcpy(flatbuf->data() + start, val.c_str(), val.size() + 1);
|
memcpy(vector_data(*flatbuf) + start, val.c_str(), val.size() + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
||||||
@@ -317,7 +317,8 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
|||||||
const reflection::Object *root_table) {
|
const reflection::Object *root_table) {
|
||||||
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems);
|
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems);
|
||||||
auto delta_bytes = delta_elem * static_cast<int>(elem_size);
|
auto delta_bytes = delta_elem * static_cast<int>(elem_size);
|
||||||
auto vec_start = reinterpret_cast<const uint8_t *>(vec) - flatbuf->data();
|
auto vec_start = reinterpret_cast<const uint8_t *>(vec) -
|
||||||
|
vector_data(*flatbuf);
|
||||||
auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) +
|
auto start = static_cast<uoffset_t>(vec_start + sizeof(uoffset_t) +
|
||||||
elem_size * num_elems);
|
elem_size * num_elems);
|
||||||
if (delta_bytes) {
|
if (delta_bytes) {
|
||||||
@@ -325,16 +326,16 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
|
|||||||
// Clear elements we're throwing away, since some might remain in the
|
// Clear elements we're throwing away, since some might remain in the
|
||||||
// buffer.
|
// buffer.
|
||||||
auto size_clear = -delta_elem * elem_size;
|
auto size_clear = -delta_elem * elem_size;
|
||||||
memset(flatbuf->data() + start - size_clear, 0, size_clear);
|
memset(vector_data(*flatbuf) + start - size_clear, 0, size_clear);
|
||||||
}
|
}
|
||||||
ResizeContext(schema, start, delta_bytes, flatbuf, root_table);
|
ResizeContext(schema, start, delta_bytes, flatbuf, root_table);
|
||||||
WriteScalar(flatbuf->data() + vec_start, newsize); // Length field.
|
WriteScalar(vector_data(*flatbuf) + vec_start, newsize); // Length field.
|
||||||
// Set new elements to 0.. this can be overwritten by the caller.
|
// Set new elements to 0.. this can be overwritten by the caller.
|
||||||
if (delta_elem > 0) {
|
if (delta_elem > 0) {
|
||||||
memset(flatbuf->data() + start, 0, delta_elem * elem_size);
|
memset(vector_data(*flatbuf) + start, 0, delta_elem * elem_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return flatbuf->data() + start;
|
return vector_data(*flatbuf) + start;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
|
const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
|
||||||
@@ -349,7 +350,7 @@ const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
|
|||||||
// Insert the entire FlatBuffer minus the root pointer.
|
// Insert the entire FlatBuffer minus the root pointer.
|
||||||
flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen);
|
flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen);
|
||||||
auto root_offset = ReadScalar<uoffset_t>(newbuf) - sizeof(uoffset_t);
|
auto root_offset = ReadScalar<uoffset_t>(newbuf) - sizeof(uoffset_t);
|
||||||
return flatbuf.data() + insertion_point + root_offset;
|
return vector_data(flatbuf) + insertion_point + root_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef,
|
void CopyInline(FlatBufferBuilder &fbb, const reflection::Field &fielddef,
|
||||||
@@ -480,7 +481,7 @@ Offset<const Table *> CopyTable(FlatBufferBuilder &fbb,
|
|||||||
fbb.ClearOffsets();
|
fbb.ClearOffsets();
|
||||||
return fbb.EndStruct();
|
return fbb.EndStruct();
|
||||||
} else {
|
} else {
|
||||||
return fbb.EndTable(start, static_cast<voffset_t>(fielddefs->size()));
|
return fbb.EndTable(start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,6 +700,9 @@ bool VerifyObject(flatbuffers::Verifier &v,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!v.EndTable())
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -83,6 +83,9 @@
|
|||||||
<Compile Include="..\MyGame\Example\Ability.cs">
|
<Compile Include="..\MyGame\Example\Ability.cs">
|
||||||
<Link>MyGame\Example\Ability.cs</Link>
|
<Link>MyGame\Example\Ability.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="..\MyGame\InParentNamespace.cs">
|
||||||
|
<Link>MyGame\InParentNamespace.cs</Link>
|
||||||
|
</Compile>
|
||||||
<Compile Include="..\namespace_test\NamespaceA\NamespaceB\EnumInNestedNS.cs">
|
<Compile Include="..\namespace_test\NamespaceA\NamespaceB\EnumInNestedNS.cs">
|
||||||
<Link>NamespaceA\NamespaceB\EnumInNestedNS.cs</Link>
|
<Link>NamespaceA\NamespaceB\EnumInNestedNS.cs</Link>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -122,4 +125,4 @@
|
|||||||
<Target Name="AfterBuild">
|
<Target Name="AfterBuild">
|
||||||
</Target>
|
</Target>
|
||||||
-->
|
-->
|
||||||
</Project>
|
</Project>
|
||||||
@@ -205,11 +205,11 @@ namespace FlatBuffers.Test
|
|||||||
builder.EndObject();
|
builder.EndObject();
|
||||||
Assert.ArrayEqual(new byte[]
|
Assert.ArrayEqual(new byte[]
|
||||||
{
|
{
|
||||||
0, 0, 0, 0, 0, 0, // padding to 16 bytes
|
// No padding.
|
||||||
6, 0, // vtable bytes
|
4, 0, // vtable bytes
|
||||||
4, 0, // end of object from here
|
4, 0, // end of object from here
|
||||||
0, 0, // entry 0 is empty (default value)
|
// entry 0 is not stored (trimmed end of vtable)
|
||||||
6, 0, 0, 0, // int32 offset for start of vtable
|
4, 0, 0, 0, // int32 offset for start of vtable
|
||||||
},
|
},
|
||||||
builder.DataBuffer.Data);
|
builder.DataBuffer.Data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ mkdir -p ${go_src}/github.com/google/flatbuffers/go
|
|||||||
mkdir -p ${go_src}/flatbuffers_test
|
mkdir -p ${go_src}/flatbuffers_test
|
||||||
|
|
||||||
cp -a MyGame/Example/*.go ./go_gen/src/MyGame/Example/
|
cp -a MyGame/Example/*.go ./go_gen/src/MyGame/Example/
|
||||||
|
# do not compile the gRPC generated files, which are not tested by go_test.go
|
||||||
|
# below, but have their own test.
|
||||||
|
rm ./go_gen/src/MyGame/Example/*_grpc.go
|
||||||
cp -a ../go/* ./go_gen/src/github.com/google/flatbuffers/go
|
cp -a ../go/* ./go_gen/src/github.com/google/flatbuffers/go
|
||||||
cp -a ./go_test.go ./go_gen/src/flatbuffers_test/
|
cp -a ./go_test.go ./go_gen/src/flatbuffers_test/
|
||||||
|
|
||||||
|
|||||||
57
tests/JavaScriptUnionVectorTest.js
Normal file
57
tests/JavaScriptUnionVectorTest.js
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
var assert = require('assert');
|
||||||
|
|
||||||
|
var flatbuffers = require('../js/flatbuffers').flatbuffers;
|
||||||
|
var Test = require(process.argv[2]);
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
var fbb = new flatbuffers.Builder();
|
||||||
|
|
||||||
|
var charTypes = [
|
||||||
|
Test.Character.Belle,
|
||||||
|
Test.Character.MuLan,
|
||||||
|
Test.Character.BookFan,
|
||||||
|
];
|
||||||
|
|
||||||
|
Test.Attacker.startAttacker(fbb);
|
||||||
|
Test.Attacker.addSwordAttackDamage(fbb, 5);
|
||||||
|
var attackerOffset = Test.Attacker.endAttacker(fbb);
|
||||||
|
|
||||||
|
var charTypesOffset = Test.Movie.createCharactersTypeVector(fbb, charTypes);
|
||||||
|
var charsOffset = Test.Movie.createCharactersVector(
|
||||||
|
fbb,
|
||||||
|
[
|
||||||
|
Test.BookReader.createBookReader(fbb, 7),
|
||||||
|
attackerOffset,
|
||||||
|
Test.BookReader.createBookReader(fbb, 2),
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
|
Test.Movie.startMovie(fbb);
|
||||||
|
Test.Movie.addCharactersType(fbb, charTypesOffset);
|
||||||
|
Test.Movie.addCharacters(fbb, charsOffset);
|
||||||
|
Test.Movie.finishMovieBuffer(fbb, Test.Movie.endMovie(fbb));
|
||||||
|
|
||||||
|
var buf = new flatbuffers.ByteBuffer(fbb.asUint8Array());
|
||||||
|
|
||||||
|
var movie = Test.Movie.getRootAsMovie(buf);
|
||||||
|
|
||||||
|
assert.strictEqual(movie.charactersTypeLength(), charTypes.length);
|
||||||
|
assert.strictEqual(movie.charactersLength(), movie.charactersTypeLength());
|
||||||
|
|
||||||
|
for (var i = 0; i < charTypes.length; ++i) {
|
||||||
|
assert.strictEqual(movie.charactersType(i), charTypes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
var bookReader7 = movie.characters(0, new Test.BookReader());
|
||||||
|
assert.strictEqual(bookReader7.booksRead(), 7);
|
||||||
|
|
||||||
|
var attacker = movie.characters(1, new Test.Attacker());
|
||||||
|
assert.strictEqual(attacker.swordAttackDamage(), 5);
|
||||||
|
|
||||||
|
var bookReader2 = movie.characters(2, new Test.BookReader());
|
||||||
|
assert.strictEqual(bookReader2.booksRead(), 2);
|
||||||
|
|
||||||
|
console.log('FlatBuffers union vector test: completed successfully');
|
||||||
|
}
|
||||||
|
|
||||||
|
main();
|
||||||
0
tests/JavaTest.bat
Executable file → Normal file
0
tests/JavaTest.bat
Executable file → Normal file
307
tests/JavaTest.java
Executable file → Normal file
307
tests/JavaTest.java
Executable file → Normal file
@@ -16,6 +16,8 @@
|
|||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
import java.nio.channels.FileChannel;
|
||||||
import MyGame.Example.*;
|
import MyGame.Example.*;
|
||||||
import NamespaceA.*;
|
import NamespaceA.*;
|
||||||
import NamespaceA.NamespaceB.*;
|
import NamespaceA.NamespaceB.*;
|
||||||
@@ -51,133 +53,7 @@ class JavaTest {
|
|||||||
// better for performance.
|
// better for performance.
|
||||||
FlatBufferBuilder fbb = new FlatBufferBuilder(1);
|
FlatBufferBuilder fbb = new FlatBufferBuilder(1);
|
||||||
|
|
||||||
int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
|
TestBuilderBasics(fbb);
|
||||||
int[] off = new int[3];
|
|
||||||
Monster.startMonster(fbb);
|
|
||||||
Monster.addName(fbb, names[0]);
|
|
||||||
off[0] = Monster.endMonster(fbb);
|
|
||||||
Monster.startMonster(fbb);
|
|
||||||
Monster.addName(fbb, names[1]);
|
|
||||||
off[1] = Monster.endMonster(fbb);
|
|
||||||
Monster.startMonster(fbb);
|
|
||||||
Monster.addName(fbb, names[2]);
|
|
||||||
off[2] = Monster.endMonster(fbb);
|
|
||||||
int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);
|
|
||||||
|
|
||||||
// We set up the same values as monsterdata.json:
|
|
||||||
|
|
||||||
int str = fbb.createString("MyMonster");
|
|
||||||
|
|
||||||
int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
|
|
||||||
|
|
||||||
int fred = fbb.createString("Fred");
|
|
||||||
Monster.startMonster(fbb);
|
|
||||||
Monster.addName(fbb, fred);
|
|
||||||
int mon2 = Monster.endMonster(fbb);
|
|
||||||
|
|
||||||
Monster.startTest4Vector(fbb, 2);
|
|
||||||
Test.createTest(fbb, (short)10, (byte)20);
|
|
||||||
Test.createTest(fbb, (short)30, (byte)40);
|
|
||||||
int test4 = fbb.endVector();
|
|
||||||
|
|
||||||
int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
|
|
||||||
fbb.createString("test1"),
|
|
||||||
fbb.createString("test2")
|
|
||||||
});
|
|
||||||
|
|
||||||
Monster.startMonster(fbb);
|
|
||||||
Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
|
|
||||||
Color.Green, (short)5, (byte)6));
|
|
||||||
Monster.addHp(fbb, (short)80);
|
|
||||||
Monster.addName(fbb, str);
|
|
||||||
Monster.addInventory(fbb, inv);
|
|
||||||
Monster.addTestType(fbb, (byte)Any.Monster);
|
|
||||||
Monster.addTest(fbb, mon2);
|
|
||||||
Monster.addTest4(fbb, test4);
|
|
||||||
Monster.addTestarrayofstring(fbb, testArrayOfString);
|
|
||||||
Monster.addTestbool(fbb, false);
|
|
||||||
Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
|
|
||||||
Monster.addTestarrayoftables(fbb, sortMons);
|
|
||||||
int mon = Monster.endMonster(fbb);
|
|
||||||
|
|
||||||
Monster.finishMonsterBuffer(fbb, mon);
|
|
||||||
|
|
||||||
// Write the result to a file for debugging purposes:
|
|
||||||
// Note that the binaries are not necessarily identical, since the JSON
|
|
||||||
// parser may serialize in a slightly different order than the above
|
|
||||||
// Java code. They are functionally equivalent though.
|
|
||||||
|
|
||||||
try {
|
|
||||||
DataOutputStream os = new DataOutputStream(new FileOutputStream(
|
|
||||||
"monsterdata_java_wire.mon"));
|
|
||||||
os.write(fbb.dataBuffer().array(), fbb.dataBuffer().position(), fbb.offset());
|
|
||||||
os.close();
|
|
||||||
} catch(java.io.IOException e) {
|
|
||||||
System.out.println("FlatBuffers test: couldn't write file");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test it:
|
|
||||||
TestExtendedBuffer(fbb.dataBuffer());
|
|
||||||
|
|
||||||
// Make sure it also works with read only ByteBuffers. This is slower,
|
|
||||||
// since creating strings incurs an additional copy
|
|
||||||
// (see Table.__string).
|
|
||||||
TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
|
|
||||||
|
|
||||||
TestEnums();
|
|
||||||
|
|
||||||
//Attempt to mutate Monster fields and check whether the buffer has been mutated properly
|
|
||||||
// revert to original values after testing
|
|
||||||
Monster monster = Monster.getRootAsMonster(fbb.dataBuffer());
|
|
||||||
|
|
||||||
// mana is optional and does not exist in the buffer so the mutation should fail
|
|
||||||
// the mana field should retain its default value
|
|
||||||
TestEq(monster.mutateMana((short)10), false);
|
|
||||||
TestEq(monster.mana(), (short)150);
|
|
||||||
|
|
||||||
// Accessing a vector of sorted by the key tables
|
|
||||||
TestEq(monster.testarrayoftables(0).name(), "Barney");
|
|
||||||
TestEq(monster.testarrayoftables(1).name(), "Frodo");
|
|
||||||
TestEq(monster.testarrayoftables(2).name(), "Wilma");
|
|
||||||
|
|
||||||
// Example of searching for a table by the key
|
|
||||||
TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
|
|
||||||
TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
|
|
||||||
TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
|
|
||||||
|
|
||||||
// testType is an existing field and mutating it should succeed
|
|
||||||
TestEq(monster.testType(), (byte)Any.Monster);
|
|
||||||
TestEq(monster.mutateTestType(Any.NONE), true);
|
|
||||||
TestEq(monster.testType(), (byte)Any.NONE);
|
|
||||||
TestEq(monster.mutateTestType(Any.Monster), true);
|
|
||||||
TestEq(monster.testType(), (byte)Any.Monster);
|
|
||||||
|
|
||||||
//mutate the inventory vector
|
|
||||||
TestEq(monster.mutateInventory(0, 1), true);
|
|
||||||
TestEq(monster.mutateInventory(1, 2), true);
|
|
||||||
TestEq(monster.mutateInventory(2, 3), true);
|
|
||||||
TestEq(monster.mutateInventory(3, 4), true);
|
|
||||||
TestEq(monster.mutateInventory(4, 5), true);
|
|
||||||
|
|
||||||
for (int i = 0; i < monster.inventoryLength(); i++) {
|
|
||||||
TestEq(monster.inventory(i), i + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
//reverse mutation
|
|
||||||
TestEq(monster.mutateInventory(0, 0), true);
|
|
||||||
TestEq(monster.mutateInventory(1, 1), true);
|
|
||||||
TestEq(monster.mutateInventory(2, 2), true);
|
|
||||||
TestEq(monster.mutateInventory(3, 3), true);
|
|
||||||
TestEq(monster.mutateInventory(4, 4), true);
|
|
||||||
|
|
||||||
// get a struct field and edit one of its fields
|
|
||||||
Vec3 pos = monster.pos();
|
|
||||||
TestEq(pos.x(), 1.0f);
|
|
||||||
pos.mutateX(55.0f);
|
|
||||||
TestEq(pos.x(), 55.0f);
|
|
||||||
pos.mutateX(1.0f);
|
|
||||||
TestEq(pos.x(), 1.0f);
|
|
||||||
|
|
||||||
TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
|
TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
|
||||||
|
|
||||||
@@ -189,6 +65,10 @@ class JavaTest {
|
|||||||
|
|
||||||
TestCreateUninitializedVector();
|
TestCreateUninitializedVector();
|
||||||
|
|
||||||
|
TestByteBufferFactory();
|
||||||
|
|
||||||
|
TestSizedInputStream();
|
||||||
|
|
||||||
System.out.println("FlatBuffers test: completed successfully");
|
System.out.println("FlatBuffers test: completed successfully");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +227,179 @@ class JavaTest {
|
|||||||
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
|
TestEq(ByteBuffer.wrap(inventory), monsterObject.inventoryAsByteBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void TestByteBufferFactory() {
|
||||||
|
final class MappedByteBufferFactory implements FlatBufferBuilder.ByteBufferFactory {
|
||||||
|
@Override
|
||||||
|
public ByteBuffer newByteBuffer(int capacity) {
|
||||||
|
ByteBuffer bb;
|
||||||
|
try {
|
||||||
|
bb = new RandomAccessFile("javatest.bin", "rw").getChannel().map(FileChannel.MapMode.READ_WRITE, 0, capacity).order(ByteOrder.LITTLE_ENDIAN);
|
||||||
|
} catch(Throwable e) {
|
||||||
|
System.out.println("FlatBuffers test: couldn't map ByteBuffer to a file");
|
||||||
|
bb = null;
|
||||||
|
}
|
||||||
|
return bb;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatBufferBuilder fbb = new FlatBufferBuilder(1, new MappedByteBufferFactory());
|
||||||
|
|
||||||
|
TestBuilderBasics(fbb);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestSizedInputStream() {
|
||||||
|
// Test on default FlatBufferBuilder that uses HeapByteBuffer
|
||||||
|
FlatBufferBuilder fbb = new FlatBufferBuilder(1);
|
||||||
|
|
||||||
|
TestBuilderBasics(fbb);
|
||||||
|
|
||||||
|
InputStream in = fbb.sizedInputStream();
|
||||||
|
byte[] array = fbb.sizedByteArray();
|
||||||
|
int count = 0;
|
||||||
|
int currentVal = 0;
|
||||||
|
|
||||||
|
while (currentVal != -1 && count < array.length) {
|
||||||
|
try {
|
||||||
|
currentVal = in.read();
|
||||||
|
} catch(java.io.IOException e) {
|
||||||
|
System.out.println("FlatBuffers test: couldn't read from InputStream");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TestEq((byte)currentVal, array[count]);
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
TestEq(count, array.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void TestBuilderBasics(FlatBufferBuilder fbb) {
|
||||||
|
int[] names = {fbb.createString("Frodo"), fbb.createString("Barney"), fbb.createString("Wilma")};
|
||||||
|
int[] off = new int[3];
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addName(fbb, names[0]);
|
||||||
|
off[0] = Monster.endMonster(fbb);
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addName(fbb, names[1]);
|
||||||
|
off[1] = Monster.endMonster(fbb);
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addName(fbb, names[2]);
|
||||||
|
off[2] = Monster.endMonster(fbb);
|
||||||
|
int sortMons = fbb.createSortedVectorOfTables(new Monster(), off);
|
||||||
|
|
||||||
|
// We set up the same values as monsterdata.json:
|
||||||
|
|
||||||
|
int str = fbb.createString("MyMonster");
|
||||||
|
|
||||||
|
int inv = Monster.createInventoryVector(fbb, new byte[] { 0, 1, 2, 3, 4 });
|
||||||
|
|
||||||
|
int fred = fbb.createString("Fred");
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addName(fbb, fred);
|
||||||
|
int mon2 = Monster.endMonster(fbb);
|
||||||
|
|
||||||
|
Monster.startTest4Vector(fbb, 2);
|
||||||
|
Test.createTest(fbb, (short)10, (byte)20);
|
||||||
|
Test.createTest(fbb, (short)30, (byte)40);
|
||||||
|
int test4 = fbb.endVector();
|
||||||
|
|
||||||
|
int testArrayOfString = Monster.createTestarrayofstringVector(fbb, new int[] {
|
||||||
|
fbb.createString("test1"),
|
||||||
|
fbb.createString("test2")
|
||||||
|
});
|
||||||
|
|
||||||
|
Monster.startMonster(fbb);
|
||||||
|
Monster.addPos(fbb, Vec3.createVec3(fbb, 1.0f, 2.0f, 3.0f, 3.0,
|
||||||
|
Color.Green, (short)5, (byte)6));
|
||||||
|
Monster.addHp(fbb, (short)80);
|
||||||
|
Monster.addName(fbb, str);
|
||||||
|
Monster.addInventory(fbb, inv);
|
||||||
|
Monster.addTestType(fbb, (byte)Any.Monster);
|
||||||
|
Monster.addTest(fbb, mon2);
|
||||||
|
Monster.addTest4(fbb, test4);
|
||||||
|
Monster.addTestarrayofstring(fbb, testArrayOfString);
|
||||||
|
Monster.addTestbool(fbb, false);
|
||||||
|
Monster.addTesthashu32Fnv1(fbb, Integer.MAX_VALUE + 1L);
|
||||||
|
Monster.addTestarrayoftables(fbb, sortMons);
|
||||||
|
int mon = Monster.endMonster(fbb);
|
||||||
|
|
||||||
|
Monster.finishMonsterBuffer(fbb, mon);
|
||||||
|
|
||||||
|
// Write the result to a file for debugging purposes:
|
||||||
|
// Note that the binaries are not necessarily identical, since the JSON
|
||||||
|
// parser may serialize in a slightly different order than the above
|
||||||
|
// Java code. They are functionally equivalent though.
|
||||||
|
|
||||||
|
try {
|
||||||
|
FileChannel fc = new FileOutputStream("monsterdata_java_wire.mon").getChannel();
|
||||||
|
fc.write(fbb.dataBuffer().duplicate());
|
||||||
|
fc.close();
|
||||||
|
} catch(java.io.IOException e) {
|
||||||
|
System.out.println("FlatBuffers test: couldn't write file");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test it:
|
||||||
|
TestExtendedBuffer(fbb.dataBuffer());
|
||||||
|
|
||||||
|
// Make sure it also works with read only ByteBuffers. This is slower,
|
||||||
|
// since creating strings incurs an additional copy
|
||||||
|
// (see Table.__string).
|
||||||
|
TestExtendedBuffer(fbb.dataBuffer().asReadOnlyBuffer());
|
||||||
|
|
||||||
|
TestEnums();
|
||||||
|
|
||||||
|
//Attempt to mutate Monster fields and check whether the buffer has been mutated properly
|
||||||
|
// revert to original values after testing
|
||||||
|
Monster monster = Monster.getRootAsMonster(fbb.dataBuffer());
|
||||||
|
|
||||||
|
// mana is optional and does not exist in the buffer so the mutation should fail
|
||||||
|
// the mana field should retain its default value
|
||||||
|
TestEq(monster.mutateMana((short)10), false);
|
||||||
|
TestEq(monster.mana(), (short)150);
|
||||||
|
|
||||||
|
// Accessing a vector of sorted by the key tables
|
||||||
|
TestEq(monster.testarrayoftables(0).name(), "Barney");
|
||||||
|
TestEq(monster.testarrayoftables(1).name(), "Frodo");
|
||||||
|
TestEq(monster.testarrayoftables(2).name(), "Wilma");
|
||||||
|
|
||||||
|
// Example of searching for a table by the key
|
||||||
|
TestEq(monster.testarrayoftablesByKey("Frodo").name(), "Frodo");
|
||||||
|
TestEq(monster.testarrayoftablesByKey("Barney").name(), "Barney");
|
||||||
|
TestEq(monster.testarrayoftablesByKey("Wilma").name(), "Wilma");
|
||||||
|
|
||||||
|
// testType is an existing field and mutating it should succeed
|
||||||
|
TestEq(monster.testType(), (byte)Any.Monster);
|
||||||
|
TestEq(monster.mutateTestType(Any.NONE), true);
|
||||||
|
TestEq(monster.testType(), (byte)Any.NONE);
|
||||||
|
TestEq(monster.mutateTestType(Any.Monster), true);
|
||||||
|
TestEq(monster.testType(), (byte)Any.Monster);
|
||||||
|
|
||||||
|
//mutate the inventory vector
|
||||||
|
TestEq(monster.mutateInventory(0, 1), true);
|
||||||
|
TestEq(monster.mutateInventory(1, 2), true);
|
||||||
|
TestEq(monster.mutateInventory(2, 3), true);
|
||||||
|
TestEq(monster.mutateInventory(3, 4), true);
|
||||||
|
TestEq(monster.mutateInventory(4, 5), true);
|
||||||
|
|
||||||
|
for (int i = 0; i < monster.inventoryLength(); i++) {
|
||||||
|
TestEq(monster.inventory(i), i + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
//reverse mutation
|
||||||
|
TestEq(monster.mutateInventory(0, 0), true);
|
||||||
|
TestEq(monster.mutateInventory(1, 1), true);
|
||||||
|
TestEq(monster.mutateInventory(2, 2), true);
|
||||||
|
TestEq(monster.mutateInventory(3, 3), true);
|
||||||
|
TestEq(monster.mutateInventory(4, 4), true);
|
||||||
|
|
||||||
|
// get a struct field and edit one of its fields
|
||||||
|
Vec3 pos = monster.pos();
|
||||||
|
TestEq(pos.x(), 1.0f);
|
||||||
|
pos.mutateX(55.0f);
|
||||||
|
TestEq(pos.x(), 55.0f);
|
||||||
|
pos.mutateX(1.0f);
|
||||||
|
TestEq(pos.x(), 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
static <T> void TestEq(T a, T b) {
|
static <T> void TestEq(T a, T b) {
|
||||||
if (!a.equals(b)) {
|
if (!a.equals(b)) {
|
||||||
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
System.out.println("" + a.getClass().getName() + " " + b.getClass().getName());
|
||||||
|
|||||||
@@ -87,8 +87,19 @@ public struct Monster : IFlatbufferObject
|
|||||||
public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
|
public int FlexLength { get { int o = __p.__offset(64); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||||
public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
|
public ArraySegment<byte>? GetFlexBytes() { return __p.__vector_as_arraysegment(64); }
|
||||||
public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
|
public bool MutateFlex(int j, byte flex) { int o = __p.__offset(64); if (o != 0) { __p.bb.Put(__p.__vector(o) + j * 1, flex); return true; } else { return false; } }
|
||||||
|
public Test? Test5(int j) { int o = __p.__offset(66); return o != 0 ? (Test?)(new Test()).__assign(__p.__vector(o) + j * 4, __p.bb) : null; }
|
||||||
|
public int Test5Length { get { int o = __p.__offset(66); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||||
|
public long VectorOfLongs(int j) { int o = __p.__offset(68); return o != 0 ? __p.bb.GetLong(__p.__vector(o) + j * 8) : (long)0; }
|
||||||
|
public int VectorOfLongsLength { get { int o = __p.__offset(68); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||||
|
public ArraySegment<byte>? GetVectorOfLongsBytes() { return __p.__vector_as_arraysegment(68); }
|
||||||
|
public bool MutateVectorOfLongs(int j, long vector_of_longs) { int o = __p.__offset(68); if (o != 0) { __p.bb.PutLong(__p.__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
|
||||||
|
public double VectorOfDoubles(int j) { int o = __p.__offset(70); return o != 0 ? __p.bb.GetDouble(__p.__vector(o) + j * 8) : (double)0; }
|
||||||
|
public int VectorOfDoublesLength { get { int o = __p.__offset(70); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||||
|
public ArraySegment<byte>? GetVectorOfDoublesBytes() { return __p.__vector_as_arraysegment(70); }
|
||||||
|
public bool MutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __p.__offset(70); if (o != 0) { __p.bb.PutDouble(__p.__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
|
||||||
|
public MyGame.InParentNamespace? ParentNamespaceTest { get { int o = __p.__offset(72); return o != 0 ? (MyGame.InParentNamespace?)(new MyGame.InParentNamespace()).__assign(__p.__indirect(o + __p.bb_pos), __p.bb) : null; } }
|
||||||
|
|
||||||
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(31); }
|
public static void StartMonster(FlatBufferBuilder builder) { builder.StartObject(35); }
|
||||||
public static void AddPos(FlatBufferBuilder builder, Offset<Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
|
public static void AddPos(FlatBufferBuilder builder, Offset<Vec3> posOffset) { builder.AddStruct(0, posOffset.Value, 0); }
|
||||||
public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }
|
public static void AddMana(FlatBufferBuilder builder, short mana) { builder.AddShort(1, mana, 150); }
|
||||||
public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }
|
public static void AddHp(FlatBufferBuilder builder, short hp) { builder.AddShort(2, hp, 100); }
|
||||||
@@ -135,6 +146,15 @@ public struct Monster : IFlatbufferObject
|
|||||||
public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
|
public static void AddFlex(FlatBufferBuilder builder, VectorOffset flexOffset) { builder.AddOffset(30, flexOffset.Value, 0); }
|
||||||
public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
|
public static VectorOffset CreateFlexVector(FlatBufferBuilder builder, byte[] data) { builder.StartVector(1, data.Length, 1); for (int i = data.Length - 1; i >= 0; i--) builder.AddByte(data[i]); return builder.EndVector(); }
|
||||||
public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
|
public static void StartFlexVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(1, numElems, 1); }
|
||||||
|
public static void AddTest5(FlatBufferBuilder builder, VectorOffset test5Offset) { builder.AddOffset(31, test5Offset.Value, 0); }
|
||||||
|
public static void StartTest5Vector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 2); }
|
||||||
|
public static void AddVectorOfLongs(FlatBufferBuilder builder, VectorOffset vectorOfLongsOffset) { builder.AddOffset(32, vectorOfLongsOffset.Value, 0); }
|
||||||
|
public static VectorOffset CreateVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddLong(data[i]); return builder.EndVector(); }
|
||||||
|
public static void StartVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
|
||||||
|
public static void AddVectorOfDoubles(FlatBufferBuilder builder, VectorOffset vectorOfDoublesOffset) { builder.AddOffset(33, vectorOfDoublesOffset.Value, 0); }
|
||||||
|
public static VectorOffset CreateVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.StartVector(8, data.Length, 8); for (int i = data.Length - 1; i >= 0; i--) builder.AddDouble(data[i]); return builder.EndVector(); }
|
||||||
|
public static void StartVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(8, numElems, 8); }
|
||||||
|
public static void AddParentNamespaceTest(FlatBufferBuilder builder, Offset<MyGame.InParentNamespace> parentNamespaceTestOffset) { builder.AddOffset(34, parentNamespaceTestOffset.Value, 0); }
|
||||||
public static Offset<Monster> EndMonster(FlatBufferBuilder builder) {
|
public static Offset<Monster> EndMonster(FlatBufferBuilder builder) {
|
||||||
int o = builder.EndObject();
|
int o = builder.EndObject();
|
||||||
builder.Required(o, 10); // name
|
builder.Required(o, 10); // name
|
||||||
|
|||||||
@@ -463,8 +463,74 @@ func (rcv *Monster) FlexBytes() []byte {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) Test5(obj *Test, j int) bool {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(66))
|
||||||
|
if o != 0 {
|
||||||
|
x := rcv._tab.Vector(o)
|
||||||
|
x += flatbuffers.UOffsetT(j) * 4
|
||||||
|
obj.Init(rcv._tab.Bytes, x)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) Test5Length() int {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(66))
|
||||||
|
if o != 0 {
|
||||||
|
return rcv._tab.VectorLen(o)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) VectorOfLongs(j int) int64 {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
|
||||||
|
if o != 0 {
|
||||||
|
a := rcv._tab.Vector(o)
|
||||||
|
return rcv._tab.GetInt64(a + flatbuffers.UOffsetT(j*8))
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) VectorOfLongsLength() int {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(68))
|
||||||
|
if o != 0 {
|
||||||
|
return rcv._tab.VectorLen(o)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) VectorOfDoubles(j int) float64 {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
|
||||||
|
if o != 0 {
|
||||||
|
a := rcv._tab.Vector(o)
|
||||||
|
return rcv._tab.GetFloat64(a + flatbuffers.UOffsetT(j*8))
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) VectorOfDoublesLength() int {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(70))
|
||||||
|
if o != 0 {
|
||||||
|
return rcv._tab.VectorLen(o)
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rcv *Monster) ParentNamespaceTest(obj *InParentNamespace) *InParentNamespace {
|
||||||
|
o := flatbuffers.UOffsetT(rcv._tab.Offset(72))
|
||||||
|
if o != 0 {
|
||||||
|
x := rcv._tab.Indirect(o + rcv._tab.Pos)
|
||||||
|
if obj == nil {
|
||||||
|
obj = new(InParentNamespace)
|
||||||
|
}
|
||||||
|
obj.Init(rcv._tab.Bytes, x)
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func MonsterStart(builder *flatbuffers.Builder) {
|
func MonsterStart(builder *flatbuffers.Builder) {
|
||||||
builder.StartObject(31)
|
builder.StartObject(35)
|
||||||
}
|
}
|
||||||
func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) {
|
func MonsterAddPos(builder *flatbuffers.Builder, pos flatbuffers.UOffsetT) {
|
||||||
builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0)
|
builder.PrependStructSlot(0, flatbuffers.UOffsetT(pos), 0)
|
||||||
@@ -583,6 +649,27 @@ func MonsterAddFlex(builder *flatbuffers.Builder, flex flatbuffers.UOffsetT) {
|
|||||||
func MonsterStartFlexVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
func MonsterStartFlexVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||||
return builder.StartVector(1, numElems, 1)
|
return builder.StartVector(1, numElems, 1)
|
||||||
}
|
}
|
||||||
|
func MonsterAddTest5(builder *flatbuffers.Builder, test5 flatbuffers.UOffsetT) {
|
||||||
|
builder.PrependUOffsetTSlot(31, flatbuffers.UOffsetT(test5), 0)
|
||||||
|
}
|
||||||
|
func MonsterStartTest5Vector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||||
|
return builder.StartVector(4, numElems, 2)
|
||||||
|
}
|
||||||
|
func MonsterAddVectorOfLongs(builder *flatbuffers.Builder, vectorOfLongs flatbuffers.UOffsetT) {
|
||||||
|
builder.PrependUOffsetTSlot(32, flatbuffers.UOffsetT(vectorOfLongs), 0)
|
||||||
|
}
|
||||||
|
func MonsterStartVectorOfLongsVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||||
|
return builder.StartVector(8, numElems, 8)
|
||||||
|
}
|
||||||
|
func MonsterAddVectorOfDoubles(builder *flatbuffers.Builder, vectorOfDoubles flatbuffers.UOffsetT) {
|
||||||
|
builder.PrependUOffsetTSlot(33, flatbuffers.UOffsetT(vectorOfDoubles), 0)
|
||||||
|
}
|
||||||
|
func MonsterStartVectorOfDoublesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||||
|
return builder.StartVector(8, numElems, 8)
|
||||||
|
}
|
||||||
|
func MonsterAddParentNamespaceTest(builder *flatbuffers.Builder, parentNamespaceTest flatbuffers.UOffsetT) {
|
||||||
|
builder.PrependUOffsetTSlot(34, flatbuffers.UOffsetT(parentNamespaceTest), 0)
|
||||||
|
}
|
||||||
func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
func MonsterEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||||
return builder.EndObject()
|
return builder.EndObject()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,8 +95,21 @@ public final class Monster extends Table {
|
|||||||
public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
|
public int flexLength() { int o = __offset(64); return o != 0 ? __vector_len(o) : 0; }
|
||||||
public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
|
public ByteBuffer flexAsByteBuffer() { return __vector_as_bytebuffer(64, 1); }
|
||||||
public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)flex); return true; } else { return false; } }
|
public boolean mutateFlex(int j, int flex) { int o = __offset(64); if (o != 0) { bb.put(__vector(o) + j * 1, (byte)flex); return true; } else { return false; } }
|
||||||
|
public Test test5(int j) { return test5(new Test(), j); }
|
||||||
|
public Test test5(Test obj, int j) { int o = __offset(66); return o != 0 ? obj.__assign(__vector(o) + j * 4, bb) : null; }
|
||||||
|
public int test5Length() { int o = __offset(66); return o != 0 ? __vector_len(o) : 0; }
|
||||||
|
public long vectorOfLongs(int j) { int o = __offset(68); return o != 0 ? bb.getLong(__vector(o) + j * 8) : 0; }
|
||||||
|
public int vectorOfLongsLength() { int o = __offset(68); return o != 0 ? __vector_len(o) : 0; }
|
||||||
|
public ByteBuffer vectorOfLongsAsByteBuffer() { return __vector_as_bytebuffer(68, 8); }
|
||||||
|
public boolean mutateVectorOfLongs(int j, long vector_of_longs) { int o = __offset(68); if (o != 0) { bb.putLong(__vector(o) + j * 8, vector_of_longs); return true; } else { return false; } }
|
||||||
|
public double vectorOfDoubles(int j) { int o = __offset(70); return o != 0 ? bb.getDouble(__vector(o) + j * 8) : 0; }
|
||||||
|
public int vectorOfDoublesLength() { int o = __offset(70); return o != 0 ? __vector_len(o) : 0; }
|
||||||
|
public ByteBuffer vectorOfDoublesAsByteBuffer() { return __vector_as_bytebuffer(70, 8); }
|
||||||
|
public boolean mutateVectorOfDoubles(int j, double vector_of_doubles) { int o = __offset(70); if (o != 0) { bb.putDouble(__vector(o) + j * 8, vector_of_doubles); return true; } else { return false; } }
|
||||||
|
public MyGame.InParentNamespace parentNamespaceTest() { return parentNamespaceTest(new MyGame.InParentNamespace()); }
|
||||||
|
public MyGame.InParentNamespace parentNamespaceTest(MyGame.InParentNamespace obj) { int o = __offset(72); return o != 0 ? obj.__assign(__indirect(o + bb_pos), bb) : null; }
|
||||||
|
|
||||||
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(31); }
|
public static void startMonster(FlatBufferBuilder builder) { builder.startObject(35); }
|
||||||
public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
|
public static void addPos(FlatBufferBuilder builder, int posOffset) { builder.addStruct(0, posOffset, 0); }
|
||||||
public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
|
public static void addMana(FlatBufferBuilder builder, short mana) { builder.addShort(1, mana, 150); }
|
||||||
public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
|
public static void addHp(FlatBufferBuilder builder, short hp) { builder.addShort(2, hp, 100); }
|
||||||
@@ -143,6 +156,15 @@ public final class Monster extends Table {
|
|||||||
public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
|
public static void addFlex(FlatBufferBuilder builder, int flexOffset) { builder.addOffset(30, flexOffset, 0); }
|
||||||
public static int createFlexVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
|
public static int createFlexVector(FlatBufferBuilder builder, byte[] data) { builder.startVector(1, data.length, 1); for (int i = data.length - 1; i >= 0; i--) builder.addByte(data[i]); return builder.endVector(); }
|
||||||
public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
|
public static void startFlexVector(FlatBufferBuilder builder, int numElems) { builder.startVector(1, numElems, 1); }
|
||||||
|
public static void addTest5(FlatBufferBuilder builder, int test5Offset) { builder.addOffset(31, test5Offset, 0); }
|
||||||
|
public static void startTest5Vector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 2); }
|
||||||
|
public static void addVectorOfLongs(FlatBufferBuilder builder, int vectorOfLongsOffset) { builder.addOffset(32, vectorOfLongsOffset, 0); }
|
||||||
|
public static int createVectorOfLongsVector(FlatBufferBuilder builder, long[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addLong(data[i]); return builder.endVector(); }
|
||||||
|
public static void startVectorOfLongsVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
|
||||||
|
public static void addVectorOfDoubles(FlatBufferBuilder builder, int vectorOfDoublesOffset) { builder.addOffset(33, vectorOfDoublesOffset, 0); }
|
||||||
|
public static int createVectorOfDoublesVector(FlatBufferBuilder builder, double[] data) { builder.startVector(8, data.length, 8); for (int i = data.length - 1; i >= 0; i--) builder.addDouble(data[i]); return builder.endVector(); }
|
||||||
|
public static void startVectorOfDoublesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(8, numElems, 8); }
|
||||||
|
public static void addParentNamespaceTest(FlatBufferBuilder builder, int parentNamespaceTestOffset) { builder.addOffset(34, parentNamespaceTestOffset, 0); }
|
||||||
public static int endMonster(FlatBufferBuilder builder) {
|
public static int endMonster(FlatBufferBuilder builder) {
|
||||||
int o = builder.endObject();
|
int o = builder.endObject();
|
||||||
builder.required(o, 10); // name
|
builder.required(o, 10); // name
|
||||||
@@ -160,7 +182,7 @@ public final class Monster extends Table {
|
|||||||
while (span != 0) {
|
while (span != 0) {
|
||||||
int middle = span / 2;
|
int middle = span / 2;
|
||||||
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
int tableOffset = __indirect(vectorLocation + 4 * (start + middle), bb);
|
||||||
int comp = compareStrings(__offset(10, bb.array().length - tableOffset, bb), byteKey, bb);
|
int comp = compareStrings(__offset(10, bb.capacity() - tableOffset, bb), byteKey, bb);
|
||||||
if (comp > 0) {
|
if (comp > 0) {
|
||||||
span = middle;
|
span = middle;
|
||||||
} else if (comp < 0) {
|
} else if (comp < 0) {
|
||||||
|
|||||||
@@ -425,22 +425,86 @@ class Monster extends Table
|
|||||||
return $this->__vector_as_bytes(64);
|
return $this->__vector_as_bytes(64);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returnVectorOffset
|
||||||
|
*/
|
||||||
|
public function getTest5($j)
|
||||||
|
{
|
||||||
|
$o = $this->__offset(66);
|
||||||
|
$obj = new Test();
|
||||||
|
return $o != 0 ? $obj->init($this->__vector($o) + $j *4, $this->bb) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getTest5Length()
|
||||||
|
{
|
||||||
|
$o = $this->__offset(66);
|
||||||
|
return $o != 0 ? $this->__vector_len($o) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int offset
|
||||||
|
* @return long
|
||||||
|
*/
|
||||||
|
public function getVectorOfLongs($j)
|
||||||
|
{
|
||||||
|
$o = $this->__offset(68);
|
||||||
|
return $o != 0 ? $this->bb->getLong($this->__vector($o) + $j * 8) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getVectorOfLongsLength()
|
||||||
|
{
|
||||||
|
$o = $this->__offset(68);
|
||||||
|
return $o != 0 ? $this->__vector_len($o) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int offset
|
||||||
|
* @return double
|
||||||
|
*/
|
||||||
|
public function getVectorOfDoubles($j)
|
||||||
|
{
|
||||||
|
$o = $this->__offset(70);
|
||||||
|
return $o != 0 ? $this->bb->getDouble($this->__vector($o) + $j * 8) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getVectorOfDoublesLength()
|
||||||
|
{
|
||||||
|
$o = $this->__offset(70);
|
||||||
|
return $o != 0 ? $this->__vector_len($o) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParentNamespaceTest()
|
||||||
|
{
|
||||||
|
$obj = new InParentNamespace();
|
||||||
|
$o = $this->__offset(72);
|
||||||
|
return $o != 0 ? $obj->init($this->__indirect($o + $this->bb_pos), $this->bb) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FlatBufferBuilder $builder
|
* @param FlatBufferBuilder $builder
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public static function startMonster(FlatBufferBuilder $builder)
|
public static function startMonster(FlatBufferBuilder $builder)
|
||||||
{
|
{
|
||||||
$builder->StartObject(31);
|
$builder->StartObject(35);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FlatBufferBuilder $builder
|
* @param FlatBufferBuilder $builder
|
||||||
* @return Monster
|
* @return Monster
|
||||||
*/
|
*/
|
||||||
public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex)
|
public static function createMonster(FlatBufferBuilder $builder, $pos, $mana, $hp, $name, $inventory, $color, $test_type, $test, $test4, $testarrayofstring, $testarrayoftables, $enemy, $testnestedflatbuffer, $testempty, $testbool, $testhashs32_fnv1, $testhashu32_fnv1, $testhashs64_fnv1, $testhashu64_fnv1, $testhashs32_fnv1a, $testhashu32_fnv1a, $testhashs64_fnv1a, $testhashu64_fnv1a, $testarrayofbools, $testf, $testf2, $testf3, $testarrayofstring2, $testarrayofsortedstruct, $flex, $test5, $vector_of_longs, $vector_of_doubles, $parent_namespace_test)
|
||||||
{
|
{
|
||||||
$builder->startObject(31);
|
$builder->startObject(35);
|
||||||
self::addPos($builder, $pos);
|
self::addPos($builder, $pos);
|
||||||
self::addMana($builder, $mana);
|
self::addMana($builder, $mana);
|
||||||
self::addHp($builder, $hp);
|
self::addHp($builder, $hp);
|
||||||
@@ -471,6 +535,10 @@ class Monster extends Table
|
|||||||
self::addTestarrayofstring2($builder, $testarrayofstring2);
|
self::addTestarrayofstring2($builder, $testarrayofstring2);
|
||||||
self::addTestarrayofsortedstruct($builder, $testarrayofsortedstruct);
|
self::addTestarrayofsortedstruct($builder, $testarrayofsortedstruct);
|
||||||
self::addFlex($builder, $flex);
|
self::addFlex($builder, $flex);
|
||||||
|
self::addTest5($builder, $test5);
|
||||||
|
self::addVectorOfLongs($builder, $vector_of_longs);
|
||||||
|
self::addVectorOfDoubles($builder, $vector_of_doubles);
|
||||||
|
self::addParentNamespaceTest($builder, $parent_namespace_test);
|
||||||
$o = $builder->endObject();
|
$o = $builder->endObject();
|
||||||
$builder->required($o, 10); // name
|
$builder->required($o, 10); // name
|
||||||
return $o;
|
return $o;
|
||||||
@@ -987,6 +1055,118 @@ class Monster extends Table
|
|||||||
$builder->startVector(1, $numElems, 1);
|
$builder->startVector(1, $numElems, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param VectorOffset
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function addTest5(FlatBufferBuilder $builder, $test5)
|
||||||
|
{
|
||||||
|
$builder->addOffsetX(31, $test5, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param array offset array
|
||||||
|
* @return int vector offset
|
||||||
|
*/
|
||||||
|
public static function createTest5Vector(FlatBufferBuilder $builder, array $data)
|
||||||
|
{
|
||||||
|
$builder->startVector(4, count($data), 2);
|
||||||
|
for ($i = count($data) - 1; $i >= 0; $i--) {
|
||||||
|
$builder->addOffset($data[$i]);
|
||||||
|
}
|
||||||
|
return $builder->endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param int $numElems
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function startTest5Vector(FlatBufferBuilder $builder, $numElems)
|
||||||
|
{
|
||||||
|
$builder->startVector(4, $numElems, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param VectorOffset
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function addVectorOfLongs(FlatBufferBuilder $builder, $vectorOfLongs)
|
||||||
|
{
|
||||||
|
$builder->addOffsetX(32, $vectorOfLongs, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param array offset array
|
||||||
|
* @return int vector offset
|
||||||
|
*/
|
||||||
|
public static function createVectorOfLongsVector(FlatBufferBuilder $builder, array $data)
|
||||||
|
{
|
||||||
|
$builder->startVector(8, count($data), 8);
|
||||||
|
for ($i = count($data) - 1; $i >= 0; $i--) {
|
||||||
|
$builder->addLong($data[$i]);
|
||||||
|
}
|
||||||
|
return $builder->endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param int $numElems
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function startVectorOfLongsVector(FlatBufferBuilder $builder, $numElems)
|
||||||
|
{
|
||||||
|
$builder->startVector(8, $numElems, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param VectorOffset
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function addVectorOfDoubles(FlatBufferBuilder $builder, $vectorOfDoubles)
|
||||||
|
{
|
||||||
|
$builder->addOffsetX(33, $vectorOfDoubles, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param array offset array
|
||||||
|
* @return int vector offset
|
||||||
|
*/
|
||||||
|
public static function createVectorOfDoublesVector(FlatBufferBuilder $builder, array $data)
|
||||||
|
{
|
||||||
|
$builder->startVector(8, count($data), 8);
|
||||||
|
for ($i = count($data) - 1; $i >= 0; $i--) {
|
||||||
|
$builder->addDouble($data[$i]);
|
||||||
|
}
|
||||||
|
return $builder->endVector();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param int $numElems
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function startVectorOfDoublesVector(FlatBufferBuilder $builder, $numElems)
|
||||||
|
{
|
||||||
|
$builder->startVector(8, $numElems, 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param FlatBufferBuilder $builder
|
||||||
|
* @param int
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public static function addParentNamespaceTest(FlatBufferBuilder $builder, $parentNamespaceTest)
|
||||||
|
{
|
||||||
|
$builder->addOffsetX(34, $parentNamespaceTest, 0);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FlatBufferBuilder $builder
|
* @param FlatBufferBuilder $builder
|
||||||
* @return int table offset
|
* @return int table offset
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user