mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-30 23:01:37 +00:00
C++98 (stlport) support for core FlatBuffers and FlexBuffers.
* Added internal - limited - implementation of flatbuffers::unique_ptr for STLs that don't ship with std::unique_ptr. In C++11 and beyond this is just an alias for std::unique_ptr. * Aliased used type traits structs is_scalar is_floating_point is_unsigned into flatbuffers namespace so they can be replaced in C++98 implementations. Right now these point at stlport's TR1 implementations. * Wrapped vector::data() in vector_data(). * Wrapped vector::emplace_back() in vector_emplace_back(). * Wrapper string::back() in string_back(). * Added variants of FlatBufferBuilder::CreateVector() and FlatBufferBuilder::CreateVectorOfStructs() that allow the use of plain function pointers. Generated code has also been modified to use plain functions to build objects rather than std::function() so all generated code will work in C++98 applications. * Added flexbuffers::Builder::Vector(), flexbuffers::Builder::TypedVector() and flexbuffers::Builder::Map() methods that allow the use of plain function pointers. * Changed Parser to internally use plain function pointers when parsing table and vector delimiters. * Added specializations of NumToString() for 64-bit types that aren't supported by stringstream in stlport. * Overloaded numeric_limits for 64-bit types not supported by stlport. * Replaced build_apk.sh (which was broken by deprecation of the "android" tool in the Android SDK) with build.gradle and the appropriate gradle wrapper to build an APK. * Switched Android build to build against all STL variants. * Updated travis configuration to build Android test and sample. Tested: * Verified all tests continue to work on Linux, OSX and Android. * Verified Travis build is green. Change-Id: I9e634363793f85b9f141d21454b10686020a2065
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -72,3 +72,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/
|
||||||
|
|||||||
79
.travis.yml
79
.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
|
||||||
|
|
||||||
before_install:
|
compiler:
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
- gcc
|
||||||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
#- clang
|
||||||
- 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:
|
env:
|
||||||
- if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
|
matrix:
|
||||||
- if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
|
- 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
|
||||||
|
|
||||||
|
- language: android
|
||||||
|
sudo: true
|
||||||
|
android:
|
||||||
|
components:
|
||||||
|
- tools
|
||||||
|
- platform-tools
|
||||||
|
- build-tools-25.0.2
|
||||||
|
- android-25
|
||||||
|
- extra-android-m2repository
|
||||||
|
compiler:
|
||||||
|
- gcc
|
||||||
|
before_install:
|
||||||
|
- git clone https://github.com/urho3d/android-ndk.git $HOME/android-ndk-root
|
||||||
|
- export ANDROID_NDK_HOME=$HOME/android-ndk-root
|
||||||
|
# Setup environment for Linux build which is required to build the sample.
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
|
||||||
|
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
|
||||||
|
script:
|
||||||
|
- for build_gradle in $(git ls-files | grep build.gradle); do ( cd "$(dirname "${build_gradle}")" && ./gradlew build ); done
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ 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
|
||||||
src/code_generators.cpp
|
src/code_generators.cpp
|
||||||
@@ -198,6 +199,7 @@ 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
|
||||||
-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)
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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)
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -29,6 +29,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) && \
|
||||||
@@ -173,5 +175,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_
|
||||||
|
|||||||
@@ -816,10 +816,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
|
||||||
@@ -1182,6 +1180,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
|
||||||
@@ -1226,7 +1240,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.
|
||||||
@@ -1238,16 +1251,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
|
||||||
@@ -1508,6 +1539,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> const 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));
|
||||||
|
}
|
||||||
};
|
};
|
||||||
/// @}
|
/// @}
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
@@ -743,7 +745,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.
|
||||||
@@ -913,7 +915,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 +959,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 +992,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 +1025,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 +1033,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 +1070,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 +1214,10 @@ 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_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Value {
|
struct Value {
|
||||||
@@ -1364,9 +1404,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,9 +1417,11 @@ 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);
|
||||||
|
auto strb = reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) +
|
||||||
|
b.first);
|
||||||
return strncmp(stra, strb, std::min(a.second, b.second) + 1) < 0;
|
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.
|
||||||
|
|
||||||
@@ -164,7 +168,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;
|
||||||
@@ -571,15 +575,32 @@ 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 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,
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
215
include/flatbuffers/stl_emulation.h
Normal file
215
include/flatbuffers/stl_emulation.h
Normal file
@@ -0,0 +1,215 @@
|
|||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#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) {
|
||||||
|
return &(vector[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> inline const T *vector_data(
|
||||||
|
const std::vector<T> &vector) {
|
||||||
|
return &(vector[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
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> 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> 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> 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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -165,13 +167,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),
|
||||||
@@ -461,13 +463,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 +481,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.size() ? _fbb.CreateString(_o->name) : 0;
|
||||||
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,6 +524,7 @@ 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;
|
||||||
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const WeaponT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
|
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
|
||||||
auto _damage = _o->damage;
|
auto _damage = _o->damage;
|
||||||
return MyGame::Sample::CreateWeapon(
|
return MyGame::Sample::CreateWeapon(
|
||||||
@@ -616,10 +620,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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -722,6 +722,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " void Reset();";
|
code_ += " void Reset();";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
if (!enum_def.uses_type_aliases) {
|
if (!enum_def.uses_type_aliases) {
|
||||||
|
code_ += "#ifndef FLATBUFFERS_CPP98_STL";
|
||||||
code_ += " template <typename T>";
|
code_ += " template <typename T>";
|
||||||
code_ += " void Set(T&& val) {";
|
code_ += " void Set(T&& val) {";
|
||||||
code_ += " Reset();";
|
code_ += " Reset();";
|
||||||
@@ -730,6 +731,7 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " value = new T(std::forward<T>(val));";
|
code_ += " value = new T(std::forward<T>(val));";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
code_ += " }";
|
code_ += " }";
|
||||||
|
code_ += "#endif // FLATBUFFERS_CPP98_STL";
|
||||||
code_ += "";
|
code_ += "";
|
||||||
}
|
}
|
||||||
code_ += " " + UnionUnPackSignature(enum_def, true) + ";";
|
code_ += " " + UnionUnPackSignature(enum_def, true) + ";";
|
||||||
@@ -1802,11 +1804,13 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code += "(" + value + ")";
|
code += "(" + value + ")";
|
||||||
} else {
|
} else {
|
||||||
code += "_fbb.CreateVector<flatbuffers::Offset<";
|
code += "_fbb.CreateVector<flatbuffers::Offset<";
|
||||||
code += WrapInNameSpace(*vector_type.struct_def) + ">>";
|
code += WrapInNameSpace(*vector_type.struct_def) + ">> ";
|
||||||
code += "(" + value + ".size(), [&](size_t i) {";
|
code += "(" + value + ".size(), ";
|
||||||
code += " return Create" + vector_type.struct_def->name;
|
code += "[](size_t i, _VectorArgs *__va) { ";
|
||||||
code += "(_fbb, " + value + "[i]" + GenPtrGet(field) + ", ";
|
code += "return Create" + vector_type.struct_def->name;
|
||||||
code += "_rehasher); })";
|
code += "(*__va->__fbb, __va->_" + value + "[i]" +
|
||||||
|
GenPtrGet(field) + ", ";
|
||||||
|
code += "__va->__rehasher); }, &_va )";
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1815,16 +1819,19 @@ class CppGenerator : public BaseGenerator {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UNION: {
|
case BASE_TYPE_UNION: {
|
||||||
code += "_fbb.CreateVector<flatbuffers::Offset<void>>(" + value +
|
code += "_fbb.CreateVector<flatbuffers::"
|
||||||
".size(), [&](size_t i) { return " + value +
|
"Offset<void>>(" + value +
|
||||||
"[i].Pack(_fbb, _rehasher); })";
|
".size(), [](size_t i, _VectorArgs *__va) { "
|
||||||
|
"return __va->_" + value +
|
||||||
|
"[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va)";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case BASE_TYPE_UTYPE: {
|
case BASE_TYPE_UTYPE: {
|
||||||
value = StripUnionType(value);
|
value = StripUnionType(value);
|
||||||
code += "_fbb.CreateVector<uint8_t>(" + value +
|
code += "_fbb.CreateVector<uint8_t>(" + value +
|
||||||
".size(), [&](size_t i) { return static_cast<uint8_t>(" + value +
|
".size(), [](size_t i, _VectorArgs *__va) { "
|
||||||
"[i].type); })";
|
"return static_cast<uint8_t>(__va->_" + value +
|
||||||
|
"[i].type); }, &_va)";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
@@ -1935,6 +1942,15 @@ class CppGenerator : public BaseGenerator {
|
|||||||
code_ += " (void)_rehasher;";
|
code_ += " (void)_rehasher;";
|
||||||
code_ += " (void)_o;";
|
code_ += " (void)_o;";
|
||||||
|
|
||||||
|
code_ +=
|
||||||
|
" struct _VectorArgs "
|
||||||
|
"{ flatbuffers::FlatBufferBuilder *__fbb; "
|
||||||
|
"const " +
|
||||||
|
NativeName(struct_def.name, &struct_def) +
|
||||||
|
"* __o; "
|
||||||
|
"const flatbuffers::rehasher_function_t *__rehasher; } _va = { "
|
||||||
|
"&_fbb, _o, _rehasher}; (void)_va;";
|
||||||
|
|
||||||
for (auto it = struct_def.fields.vec.begin();
|
for (auto it = struct_def.fields.vec.begin();
|
||||||
it != struct_def.fields.vec.end(); ++it) {
|
it != struct_def.fields.vec.end(); ++it) {
|
||||||
auto &field = **it;
|
auto &field = **it;
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -106,8 +106,8 @@ CheckedError Parser::CheckInRange(int64_t val, int64_t min, int64_t max) {
|
|||||||
template<typename T> inline CheckedError atot(const char *s, Parser &parser,
|
template<typename T> inline CheckedError atot(const char *s, Parser &parser,
|
||||||
T *val) {
|
T *val) {
|
||||||
int64_t i = StringToInt(s);
|
int64_t i = StringToInt(s);
|
||||||
const int64_t min = std::numeric_limits<T>::min();
|
const int64_t min = flatbuffers::numeric_limits<T>::min();
|
||||||
const int64_t max = std::numeric_limits<T>::max();
|
const int64_t max = flatbuffers::numeric_limits<T>::max();
|
||||||
ECHECK(parser.CheckInRange(i, min, max));
|
ECHECK(parser.CheckInRange(i, min, max));
|
||||||
*val = (T)i;
|
*val = (T)i;
|
||||||
return NoError();
|
return NoError();
|
||||||
@@ -870,7 +870,8 @@ void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) {
|
|||||||
|
|
||||||
CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
|
CheckedError Parser::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) {
|
||||||
// We allow tables both as JSON object{ .. } with field names
|
// We allow tables both as JSON object{ .. } with field names
|
||||||
// or vector[..] with all fields in order
|
// or vector[..] with all fields in order
|
||||||
char terminator = '}';
|
char terminator = '}';
|
||||||
@@ -898,7 +899,7 @@ CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
|
|||||||
}
|
}
|
||||||
if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':');
|
if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':');
|
||||||
}
|
}
|
||||||
ECHECK(body(name));
|
ECHECK(body(name, fieldn, struct_def, state));
|
||||||
if (Is(terminator)) break;
|
if (Is(terminator)) break;
|
||||||
ECHECK(ParseComma());
|
ECHECK(ParseComma());
|
||||||
}
|
}
|
||||||
@@ -911,52 +912,56 @@ CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
|
|||||||
|
|
||||||
CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
||||||
uoffset_t *ovalue) {
|
uoffset_t *ovalue) {
|
||||||
size_t fieldn = 0;
|
size_t fieldn_outer = 0;
|
||||||
auto err = ParseTableDelimiters(fieldn, &struct_def,
|
auto err = ParseTableDelimiters(fieldn_outer, &struct_def,
|
||||||
[&](const std::string &name) -> CheckedError {
|
[](const std::string &name, size_t &fieldn,
|
||||||
|
const StructDef *struct_def_inner,
|
||||||
|
void *state) -> CheckedError {
|
||||||
|
Parser *parser = static_cast<Parser *>(state);
|
||||||
if (name == "$schema") {
|
if (name == "$schema") {
|
||||||
EXPECT(kTokenStringConstant);
|
ECHECK(parser->Expect(kTokenStringConstant));
|
||||||
return NoError();
|
return NoError();
|
||||||
}
|
}
|
||||||
auto field = struct_def.fields.Lookup(name);
|
auto field = struct_def_inner->fields.Lookup(name);
|
||||||
if (!field) {
|
if (!field) {
|
||||||
if (!opts.skip_unexpected_fields_in_json) {
|
if (!parser->opts.skip_unexpected_fields_in_json) {
|
||||||
return Error("unknown field: " + name);
|
return parser->Error("unknown field: " + name);
|
||||||
} else {
|
} else {
|
||||||
ECHECK(SkipAnyJsonValue());
|
ECHECK(parser->SkipAnyJsonValue());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (Is(kTokenNull)) {
|
if (parser->Is(kTokenNull)) {
|
||||||
NEXT(); // Ignore this field.
|
ECHECK(parser->Next()); // Ignore this field.
|
||||||
} else {
|
} else {
|
||||||
Value val = field->value;
|
Value val = field->value;
|
||||||
if (field->flexbuffer) {
|
if (field->flexbuffer) {
|
||||||
flexbuffers::Builder builder(1024,
|
flexbuffers::Builder builder(1024,
|
||||||
flexbuffers::BUILDER_FLAG_SHARE_ALL);
|
flexbuffers::BUILDER_FLAG_SHARE_ALL);
|
||||||
ECHECK(ParseFlexBufferValue(&builder));
|
ECHECK(parser->ParseFlexBufferValue(&builder));
|
||||||
builder.Finish();
|
builder.Finish();
|
||||||
auto off = builder_.CreateVector(builder.GetBuffer());
|
auto off = parser->builder_.CreateVector(builder.GetBuffer());
|
||||||
val.constant = NumToString(off.o);
|
val.constant = NumToString(off.o);
|
||||||
} else {
|
} else {
|
||||||
ECHECK(ParseAnyValue(val, field, fieldn, &struct_def));
|
ECHECK(parser->ParseAnyValue(val, field, fieldn, struct_def_inner));
|
||||||
}
|
}
|
||||||
// Hardcoded insertion-sort with error-check.
|
// Hardcoded insertion-sort with error-check.
|
||||||
// If fields are specified in order, then this loop exits immediately.
|
// If fields are specified in order, then this loop exits immediately.
|
||||||
auto elem = field_stack_.rbegin();
|
auto elem = parser->field_stack_.rbegin();
|
||||||
for (; elem != field_stack_.rbegin() + fieldn; ++elem) {
|
for (; elem != parser->field_stack_.rbegin() + fieldn; ++elem) {
|
||||||
auto existing_field = elem->second;
|
auto existing_field = elem->second;
|
||||||
if (existing_field == field)
|
if (existing_field == field)
|
||||||
return Error("field set more than once: " + field->name);
|
return parser->Error("field set more than once: " + field->name);
|
||||||
if (existing_field->value.offset < field->value.offset) break;
|
if (existing_field->value.offset < field->value.offset) break;
|
||||||
}
|
}
|
||||||
// Note: elem points to before the insertion point, thus .base() points
|
// Note: elem points to before the insertion point, thus .base() points
|
||||||
// to the correct spot.
|
// to the correct spot.
|
||||||
field_stack_.insert(elem.base(), std::make_pair(val, field));
|
parser->field_stack_.insert(elem.base(),
|
||||||
|
std::make_pair(val, field));
|
||||||
fieldn++;
|
fieldn++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NoError();
|
return NoError();
|
||||||
});
|
}, this);
|
||||||
ECHECK(err);
|
ECHECK(err);
|
||||||
|
|
||||||
// Check if all required fields are parsed.
|
// Check if all required fields are parsed.
|
||||||
@@ -968,7 +973,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (auto pf_it = field_stack_.end() - fieldn;
|
for (auto pf_it = field_stack_.end() - fieldn_outer;
|
||||||
pf_it != field_stack_.end();
|
pf_it != field_stack_.end();
|
||||||
++pf_it) {
|
++pf_it) {
|
||||||
auto parsed_field = pf_it->second;
|
auto parsed_field = pf_it->second;
|
||||||
@@ -982,7 +987,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (struct_def.fixed && fieldn != struct_def.fields.vec.size())
|
if (struct_def.fixed && fieldn_outer != struct_def.fields.vec.size())
|
||||||
return Error("struct: wrong number of initializers: " + struct_def.name);
|
return Error("struct: wrong number of initializers: " + struct_def.name);
|
||||||
|
|
||||||
auto start = struct_def.fixed
|
auto start = struct_def.fixed
|
||||||
@@ -993,8 +998,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
size;
|
size;
|
||||||
size /= 2) {
|
size /= 2) {
|
||||||
// Go through elements in reverse, since we're building the data backwards.
|
// Go through elements in reverse, since we're building the data backwards.
|
||||||
for (auto it = field_stack_.rbegin();
|
for (auto it = field_stack_.rbegin(); it != field_stack_.rbegin() +
|
||||||
it != field_stack_.rbegin() + fieldn; ++it) {
|
fieldn_outer;
|
||||||
|
++it) {
|
||||||
auto &field_value = it->first;
|
auto &field_value = it->first;
|
||||||
auto field = it->second;
|
auto field = it->second;
|
||||||
if (!struct_def.sortbysize ||
|
if (!struct_def.sortbysize ||
|
||||||
@@ -1035,7 +1041,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < fieldn; i++) field_stack_.pop_back();
|
for (size_t i = 0; i < fieldn_outer; i++) field_stack_.pop_back();
|
||||||
|
|
||||||
if (struct_def.fixed) {
|
if (struct_def.fixed) {
|
||||||
builder_.ClearOffsets();
|
builder_.ClearOffsets();
|
||||||
@@ -1058,11 +1064,12 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CheckedError Parser::ParseVectorDelimiters(size_t &count,
|
CheckedError Parser::ParseVectorDelimiters(size_t &count,
|
||||||
const std::function<CheckedError()> &body) {
|
ParseVectorDelimitersBody body,
|
||||||
|
void *state) {
|
||||||
EXPECT('[');
|
EXPECT('[');
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if ((!opts.strict_json || !count) && Is(']')) break;
|
if ((!opts.strict_json || !count) && Is(']')) break;
|
||||||
ECHECK(body());
|
ECHECK(body(count, state));
|
||||||
count++;
|
count++;
|
||||||
if (Is(']')) break;
|
if (Is(']')) break;
|
||||||
ECHECK(ParseComma());
|
ECHECK(ParseComma());
|
||||||
@@ -1073,13 +1080,18 @@ CheckedError Parser::ParseVectorDelimiters(size_t &count,
|
|||||||
|
|
||||||
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue) {
|
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue) {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
auto err = ParseVectorDelimiters(count, [&]() -> CheckedError {
|
std::pair<Parser *, const Type &> parser_and_type_state(this, type);
|
||||||
|
auto err = ParseVectorDelimiters(count,
|
||||||
|
[](size_t &, void *state) -> CheckedError {
|
||||||
|
auto *parser_and_type =
|
||||||
|
static_cast<std::pair<Parser *, const Type &> *>(state);
|
||||||
|
auto *parser = parser_and_type->first;
|
||||||
Value val;
|
Value val;
|
||||||
val.type = type;
|
val.type = parser_and_type->second;
|
||||||
ECHECK(ParseAnyValue(val, nullptr, 0, nullptr));
|
ECHECK(parser->ParseAnyValue(val, nullptr, 0, nullptr));
|
||||||
field_stack_.push_back(std::make_pair(val, nullptr));
|
parser->field_stack_.push_back(std::make_pair(val, nullptr));
|
||||||
return NoError();
|
return NoError();
|
||||||
});
|
}, &parser_and_type_state);
|
||||||
ECHECK(err);
|
ECHECK(err);
|
||||||
|
|
||||||
builder_.StartVector(count * InlineSize(type) / InlineAlignment(type),
|
builder_.StartVector(count * InlineSize(type) / InlineAlignment(type),
|
||||||
@@ -1927,17 +1939,25 @@ CheckedError Parser::ParseTypeFromProtoType(Type *type) {
|
|||||||
CheckedError Parser::SkipAnyJsonValue() {
|
CheckedError Parser::SkipAnyJsonValue() {
|
||||||
switch (token_) {
|
switch (token_) {
|
||||||
case '{': {
|
case '{': {
|
||||||
size_t fieldn = 0;
|
size_t fieldn_outer = 0;
|
||||||
return ParseTableDelimiters(fieldn, nullptr,
|
return ParseTableDelimiters(fieldn_outer, nullptr,
|
||||||
[&](const std::string &) -> CheckedError {
|
[](const std::string &,
|
||||||
ECHECK(SkipAnyJsonValue());
|
size_t &fieldn, const StructDef *,
|
||||||
fieldn++;
|
void *state) -> CheckedError {
|
||||||
return NoError();
|
auto *parser = static_cast<Parser *>(state);
|
||||||
});
|
ECHECK(parser->SkipAnyJsonValue());
|
||||||
|
fieldn++;
|
||||||
|
return NoError();
|
||||||
|
},
|
||||||
|
this);
|
||||||
}
|
}
|
||||||
case '[': {
|
case '[': {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
return ParseVectorDelimiters(count, [&]() { return SkipAnyJsonValue(); });
|
return ParseVectorDelimiters(count, [](size_t &,
|
||||||
|
void *state) -> CheckedError {
|
||||||
|
return static_cast<Parser *>(state)->SkipAnyJsonValue();
|
||||||
|
},
|
||||||
|
this);
|
||||||
}
|
}
|
||||||
case kTokenStringConstant:
|
case kTokenStringConstant:
|
||||||
EXPECT(kTokenStringConstant);
|
EXPECT(kTokenStringConstant);
|
||||||
@@ -1957,15 +1977,25 @@ CheckedError Parser::SkipAnyJsonValue() {
|
|||||||
CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
||||||
switch (token_) {
|
switch (token_) {
|
||||||
case '{': {
|
case '{': {
|
||||||
|
std::pair<Parser *, flexbuffers::Builder *> parser_and_builder_state(
|
||||||
|
this, builder);
|
||||||
auto start = builder->StartMap();
|
auto start = builder->StartMap();
|
||||||
size_t fieldn = 0;
|
size_t fieldn_outer = 0;
|
||||||
auto err = ParseTableDelimiters(fieldn, nullptr,
|
auto err = ParseTableDelimiters(fieldn_outer, nullptr,
|
||||||
[&](const std::string &name) -> CheckedError {
|
[](const std::string &name,
|
||||||
builder->Key(name);
|
size_t &fieldn, const StructDef *,
|
||||||
ECHECK(ParseFlexBufferValue(builder));
|
void *state) -> CheckedError {
|
||||||
fieldn++;
|
auto *parser_and_builder =
|
||||||
return NoError();
|
static_cast<std::pair<Parser *, flexbuffers::Builder *> *>(
|
||||||
});
|
state);
|
||||||
|
auto *parser = parser_and_builder->first;
|
||||||
|
auto *current_builder = parser_and_builder->second;
|
||||||
|
current_builder->Key(name);
|
||||||
|
ECHECK(parser->ParseFlexBufferValue(current_builder));
|
||||||
|
fieldn++;
|
||||||
|
return NoError();
|
||||||
|
},
|
||||||
|
&parser_and_builder_state);
|
||||||
ECHECK(err);
|
ECHECK(err);
|
||||||
builder->EndMap(start);
|
builder->EndMap(start);
|
||||||
break;
|
break;
|
||||||
@@ -1973,9 +2003,17 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
|
|||||||
case '[':{
|
case '[':{
|
||||||
auto start = builder->StartVector();
|
auto start = builder->StartVector();
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
ECHECK(ParseVectorDelimiters(count, [&]() {
|
std::pair<Parser *, flexbuffers::Builder *> parser_and_builder_state(
|
||||||
return ParseFlexBufferValue(builder);
|
this, builder);
|
||||||
}));
|
ECHECK(ParseVectorDelimiters(count, [](size_t &,
|
||||||
|
void *state) -> CheckedError {
|
||||||
|
auto *parser_and_builder =
|
||||||
|
static_cast<std::pair<Parser *, flexbuffers::Builder *> *>(
|
||||||
|
state);
|
||||||
|
return parser_and_builder->first->ParseFlexBufferValue(
|
||||||
|
parser_and_builder->second);
|
||||||
|
},
|
||||||
|
&parser_and_builder_state));
|
||||||
builder->EndVector(start, false, false);
|
builder->EndVector(start, false, false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -2082,7 +2120,7 @@ CheckedError Parser::DoParse(const char *source,
|
|||||||
ECHECK(ParseProtoDecl());
|
ECHECK(ParseProtoDecl());
|
||||||
} else if (Is(kTokenNativeInclude)) {
|
} else if (Is(kTokenNativeInclude)) {
|
||||||
NEXT();
|
NEXT();
|
||||||
native_included_files_.emplace_back(attribute_);
|
vector_emplace_back(&native_included_files_, attribute_);
|
||||||
EXPECT(kTokenStringConstant);
|
EXPECT(kTokenStringConstant);
|
||||||
} else if (Is(kTokenInclude) ||
|
} else if (Is(kTokenInclude) ||
|
||||||
(opts.proto_mode &&
|
(opts.proto_mode &&
|
||||||
@@ -2201,7 +2239,10 @@ std::set<std::string> Parser::GetIncludedFilesRecursive(
|
|||||||
to_process.pop_front();
|
to_process.pop_front();
|
||||||
included_files.insert(current);
|
included_files.insert(current);
|
||||||
|
|
||||||
auto new_files = files_included_per_file_.at(current);
|
// Workaround the lack of const accessor in C++98 maps.
|
||||||
|
auto &new_files =
|
||||||
|
(*const_cast<std::map<std::string, std::set<std::string>> *>(
|
||||||
|
&files_included_per_file_))[current];
|
||||||
for (auto it = new_files.begin(); it != new_files.end(); ++it) {
|
for (auto it = new_files.begin(); it != new_files.end(); ++it) {
|
||||||
if (included_files.find(*it) == included_files.end())
|
if (included_files.find(*it) == included_files.end())
|
||||||
to_process.push_back(*it);
|
to_process.push_back(*it);
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
Binary file not shown.
@@ -18,6 +18,18 @@
|
|||||||
"properties" : {
|
"properties" : {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MyGame_OtherNameSpace_TableB" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"a" : { "$ref" : "#/definitions/TableA" }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"TableA" : {
|
||||||
|
"type" : "object",
|
||||||
|
"properties" : {
|
||||||
|
"b" : { "$ref" : "#/definitions/MyGame_OtherNameSpace_TableB" }
|
||||||
|
}
|
||||||
|
},
|
||||||
"MyGame_Example2_Monster" : {
|
"MyGame_Example2_Monster" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"properties" : {
|
"properties" : {
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ struct AnyUnion {
|
|||||||
|
|
||||||
void Reset();
|
void Reset();
|
||||||
|
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void Set(T&& val) {
|
void Set(T&& val) {
|
||||||
Reset();
|
Reset();
|
||||||
@@ -145,6 +146,7 @@ struct AnyUnion {
|
|||||||
value = new T(std::forward<T>(val));
|
value = new T(std::forward<T>(val));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif // FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
static void *UnPack(const void *obj, Any type, const flatbuffers::resolver_function_t *resolver);
|
static void *UnPack(const void *obj, Any 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;
|
||||||
@@ -516,7 +518,7 @@ flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const
|
|||||||
|
|
||||||
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;
|
||||||
@@ -525,10 +527,10 @@ struct MonsterT : public flatbuffers::NativeTable {
|
|||||||
AnyUnion test;
|
AnyUnion test;
|
||||||
std::vector<Test> test4;
|
std::vector<Test> test4;
|
||||||
std::vector<std::string> testarrayofstring;
|
std::vector<std::string> testarrayofstring;
|
||||||
std::vector<std::unique_ptr<MonsterT>> testarrayoftables;
|
std::vector<flatbuffers::unique_ptr<MonsterT>> testarrayoftables;
|
||||||
std::unique_ptr<MonsterT> enemy;
|
flatbuffers::unique_ptr<MonsterT> enemy;
|
||||||
std::vector<uint8_t> testnestedflatbuffer;
|
std::vector<uint8_t> testnestedflatbuffer;
|
||||||
std::unique_ptr<StatT> testempty;
|
flatbuffers::unique_ptr<StatT> testempty;
|
||||||
bool testbool;
|
bool testbool;
|
||||||
int32_t testhashs32_fnv1;
|
int32_t testhashs32_fnv1;
|
||||||
uint32_t testhashu32_fnv1;
|
uint32_t testhashu32_fnv1;
|
||||||
@@ -1134,6 +1136,7 @@ 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;
|
||||||
return MyGame::Example2::CreateMonster(
|
return MyGame::Example2::CreateMonster(
|
||||||
_fbb);
|
_fbb);
|
||||||
}
|
}
|
||||||
@@ -1161,6 +1164,7 @@ inline flatbuffers::Offset<TestSimpleTableWithEnum> TestSimpleTableWithEnum::Pac
|
|||||||
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<TestSimpleTableWithEnum> CreateTestSimpleTableWithEnum(flatbuffers::FlatBufferBuilder &_fbb, const TestSimpleTableWithEnumT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
(void)_rehasher;
|
(void)_rehasher;
|
||||||
(void)_o;
|
(void)_o;
|
||||||
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const TestSimpleTableWithEnumT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
auto _color = _o->color;
|
auto _color = _o->color;
|
||||||
return MyGame::Example::CreateTestSimpleTableWithEnum(
|
return MyGame::Example::CreateTestSimpleTableWithEnum(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -1188,6 +1192,7 @@ inline flatbuffers::Offset<Stat> Stat::Pack(flatbuffers::FlatBufferBuilder &_fbb
|
|||||||
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<Stat> CreateStat(flatbuffers::FlatBufferBuilder &_fbb, const StatT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
(void)_rehasher;
|
(void)_rehasher;
|
||||||
(void)_o;
|
(void)_o;
|
||||||
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const StatT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
auto _id = _o->id.size() ? _fbb.CreateString(_o->id) : 0;
|
auto _id = _o->id.size() ? _fbb.CreateString(_o->id) : 0;
|
||||||
auto _val = _o->val;
|
auto _val = _o->val;
|
||||||
auto _count = _o->count;
|
auto _count = _o->count;
|
||||||
@@ -1207,7 +1212,7 @@ 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(); };
|
||||||
@@ -1217,10 +1222,10 @@ inline void Monster::UnPackTo(MonsterT *_o, const flatbuffers::resolver_function
|
|||||||
{ auto _e = test(); if (_e) _o->test.value = AnyUnion::UnPack(_e, test_type(), _resolver); };
|
{ auto _e = test(); if (_e) _o->test.value = AnyUnion::UnPack(_e, test_type(), _resolver); };
|
||||||
{ auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } };
|
{ auto _e = test4(); if (_e) { _o->test4.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->test4[_i] = *_e->Get(_i); } } };
|
||||||
{ auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } };
|
{ auto _e = testarrayofstring(); if (_e) { _o->testarrayofstring.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayofstring[_i] = _e->Get(_i)->str(); } } };
|
||||||
{ auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = std::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } };
|
{ auto _e = testarrayoftables(); if (_e) { _o->testarrayoftables.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testarrayoftables[_i] = flatbuffers::unique_ptr<MonsterT>(_e->Get(_i)->UnPack(_resolver)); } } };
|
||||||
{ auto _e = enemy(); if (_e) _o->enemy = std::unique_ptr<MonsterT>(_e->UnPack(_resolver)); };
|
{ auto _e = enemy(); if (_e) _o->enemy = flatbuffers::unique_ptr<MonsterT>(_e->UnPack(_resolver)); };
|
||||||
{ auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } };
|
{ auto _e = testnestedflatbuffer(); if (_e) { _o->testnestedflatbuffer.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->testnestedflatbuffer[_i] = _e->Get(_i); } } };
|
||||||
{ auto _e = testempty(); if (_e) _o->testempty = std::unique_ptr<StatT>(_e->UnPack(_resolver)); };
|
{ auto _e = testempty(); if (_e) _o->testempty = flatbuffers::unique_ptr<StatT>(_e->UnPack(_resolver)); };
|
||||||
{ auto _e = testbool(); _o->testbool = _e; };
|
{ auto _e = testbool(); _o->testbool = _e; };
|
||||||
{ auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
|
{ auto _e = testhashs32_fnv1(); _o->testhashs32_fnv1 = _e; };
|
||||||
{ auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
|
{ auto _e = testhashu32_fnv1(); _o->testhashu32_fnv1 = _e; };
|
||||||
@@ -1246,6 +1251,7 @@ 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;
|
||||||
@@ -1256,7 +1262,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
|
|||||||
auto _test = _o->test.Pack(_fbb);
|
auto _test = _o->test.Pack(_fbb);
|
||||||
auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
|
auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 0;
|
||||||
auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
|
auto _testarrayofstring = _o->testarrayofstring.size() ? _fbb.CreateVectorOfStrings(_o->testarrayofstring) : 0;
|
||||||
auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>>(_o->testarrayoftables.size(), [&](size_t i) { return CreateMonster(_fbb, _o->testarrayoftables[i].get(), _rehasher); }) : 0;
|
auto _testarrayoftables = _o->testarrayoftables.size() ? _fbb.CreateVector<flatbuffers::Offset<Monster>> (_o->testarrayoftables.size(), [](size_t i, _VectorArgs *__va) { return CreateMonster(*__va->__fbb, __va->__o->testarrayoftables[i].get(), __va->__rehasher); }, &_va ) : 0;
|
||||||
auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
|
auto _enemy = _o->enemy ? CreateMonster(_fbb, _o->enemy.get(), _rehasher) : 0;
|
||||||
auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
|
auto _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
|
||||||
auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
|
auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
|
||||||
@@ -1452,10 +1458,10 @@ inline void FinishMonsterBuffer(
|
|||||||
fbb.Finish(root, MonsterIdentifier());
|
fbb.Finish(root, MonsterIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
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 Example
|
} // namespace Example
|
||||||
|
|||||||
@@ -121,12 +121,13 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
|
|||||||
mlocs[2] = mb3.Finish();
|
mlocs[2] = mb3.Finish();
|
||||||
|
|
||||||
// Create an array of strings. Also test string pooling, and lambdas.
|
// Create an array of strings. Also test string pooling, and lambdas.
|
||||||
const char *names[] = { "bob", "fred", "bob", "fred" };
|
|
||||||
auto vecofstrings =
|
auto vecofstrings =
|
||||||
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(4,
|
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(4,
|
||||||
[&](size_t i) {
|
[](size_t i, flatbuffers::FlatBufferBuilder *b)
|
||||||
return builder.CreateSharedString(names[i]);
|
-> flatbuffers::Offset<flatbuffers::String> {
|
||||||
});
|
static const char *names[] = { "bob", "fred", "bob", "fred" };
|
||||||
|
return b->CreateSharedString(names[i]);
|
||||||
|
}, &builder);
|
||||||
|
|
||||||
// Creating vectors of strings in one convenient call.
|
// Creating vectors of strings in one convenient call.
|
||||||
std::vector<std::string> names2;
|
std::vector<std::string> names2;
|
||||||
@@ -541,7 +542,7 @@ void ParseAndGenerateTextTest() {
|
|||||||
TEST_EQ(result, true);
|
TEST_EQ(result, true);
|
||||||
|
|
||||||
if (jsongen != jsonfile) {
|
if (jsongen != jsonfile) {
|
||||||
printf("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
TEST_OUTPUT_LINE("%s----------------\n%s", jsongen.c_str(), jsonfile.c_str());
|
||||||
TEST_NOTNULL(NULL);
|
TEST_NOTNULL(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -671,8 +672,8 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
|
|||||||
// Get the root.
|
// Get the root.
|
||||||
// This time we wrap the result from GetAnyRoot in a smartpointer that
|
// This time we wrap the result from GetAnyRoot in a smartpointer that
|
||||||
// will keep rroot valid as resizingbuf resizes.
|
// will keep rroot valid as resizingbuf resizes.
|
||||||
auto rroot = flatbuffers::piv(flatbuffers::GetAnyRoot(resizingbuf.data()),
|
auto rroot = flatbuffers::piv(flatbuffers::GetAnyRoot(
|
||||||
resizingbuf);
|
flatbuffers::vector_data(resizingbuf)), resizingbuf);
|
||||||
SetString(schema, "totally new string", GetFieldS(**rroot, name_field),
|
SetString(schema, "totally new string", GetFieldS(**rroot, name_field),
|
||||||
&resizingbuf);
|
&resizingbuf);
|
||||||
// Here resizingbuf has changed, but rroot is still valid.
|
// Here resizingbuf has changed, but rroot is still valid.
|
||||||
@@ -718,12 +719,14 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
|
|||||||
TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
|
TEST_EQ_STR(rtestarrayofstring->Get(2)->c_str(), "hank");
|
||||||
// Test integrity of all resize operations above.
|
// Test integrity of all resize operations above.
|
||||||
flatbuffers::Verifier resize_verifier(
|
flatbuffers::Verifier resize_verifier(
|
||||||
reinterpret_cast<const uint8_t *>(resizingbuf.data()),
|
reinterpret_cast<const uint8_t *>(
|
||||||
|
flatbuffers::vector_data(resizingbuf)),
|
||||||
resizingbuf.size());
|
resizingbuf.size());
|
||||||
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
|
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
|
||||||
|
|
||||||
// Test buffer is valid using reflection as well
|
// Test buffer is valid using reflection as well
|
||||||
TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(), resizingbuf.data(),
|
TEST_EQ(flatbuffers::Verify(schema, *schema.root_table(),
|
||||||
|
flatbuffers::vector_data(resizingbuf),
|
||||||
resizingbuf.size()), true);
|
resizingbuf.size()), true);
|
||||||
|
|
||||||
// As an additional test, also set it on the name field.
|
// As an additional test, also set it on the name field.
|
||||||
@@ -778,7 +781,7 @@ void ParseProtoTest() {
|
|||||||
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
|
TEST_EQ(parser2.Parse(fbs.c_str(), nullptr), true);
|
||||||
|
|
||||||
if (fbs != goldenfile) {
|
if (fbs != goldenfile) {
|
||||||
printf("%s----------------\n%s", fbs.c_str(), goldenfile.c_str());
|
TEST_OUTPUT_LINE("%s----------------\n%s", fbs.c_str(), goldenfile.c_str());
|
||||||
TEST_NOTNULL(NULL);
|
TEST_NOTNULL(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1039,17 +1042,17 @@ void FuzzTest2() {
|
|||||||
i -= std::min(static_cast<size_t>(10), i); // show some context;
|
i -= std::min(static_cast<size_t>(10), i); // show some context;
|
||||||
size_t end = std::min(len, i + 20);
|
size_t end = std::min(len, i + 20);
|
||||||
for (; i < end; i++)
|
for (; i < end; i++)
|
||||||
printf("at %d: found \"%c\", expected \"%c\"\n",
|
TEST_OUTPUT_LINE("at %d: found \"%c\", expected \"%c\"\n",
|
||||||
static_cast<int>(i), jsongen[i], json[i]);
|
static_cast<int>(i), jsongen[i], json[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TEST_NOTNULL(NULL);
|
TEST_NOTNULL(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%dk schema tested with %dk of json\n",
|
TEST_OUTPUT_LINE("%dk schema tested with %dk of json\n",
|
||||||
static_cast<int>(schema.length() / 1024),
|
static_cast<int>(schema.length() / 1024),
|
||||||
static_cast<int>(json.length() / 1024));
|
static_cast<int>(json.length() / 1024));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that parser errors are actually generated.
|
// Test that parser errors are actually generated.
|
||||||
@@ -1526,18 +1529,20 @@ void ConformTest() {
|
|||||||
flatbuffers::Parser parser;
|
flatbuffers::Parser parser;
|
||||||
TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
|
TEST_EQ(parser.Parse("table T { A:int; } enum E:byte { A }"), true);
|
||||||
|
|
||||||
auto test_conform = [&](const char *test, const char *expected_err) {
|
auto test_conform = [](flatbuffers::Parser &parser1,
|
||||||
|
const char *test, const char *expected_err) {
|
||||||
flatbuffers::Parser parser2;
|
flatbuffers::Parser parser2;
|
||||||
TEST_EQ(parser2.Parse(test), true);
|
TEST_EQ(parser2.Parse(test), true);
|
||||||
auto err = parser2.ConformTo(parser);
|
auto err = parser2.ConformTo(parser1);
|
||||||
TEST_NOTNULL(strstr(err.c_str(), expected_err));
|
TEST_NOTNULL(strstr(err.c_str(), expected_err));
|
||||||
};
|
};
|
||||||
|
|
||||||
test_conform("table T { A:byte; }", "types differ for field");
|
test_conform(parser, "table T { A:byte; }", "types differ for field");
|
||||||
test_conform("table T { B:int; A:int; }", "offsets differ for field");
|
test_conform(parser, "table T { B:int; A:int; }", "offsets differ for field");
|
||||||
test_conform("table T { A:int = 1; }", "defaults differ for field");
|
test_conform(parser, "table T { A:int = 1; }", "defaults differ for field");
|
||||||
test_conform("table T { B:float; }", "field renamed to different type");
|
test_conform(parser, "table T { B:float; }",
|
||||||
test_conform("enum E:byte { B, A }", "values differ for enum");
|
"field renamed to different type");
|
||||||
|
test_conform(parser, "enum E:byte { B, A }", "values differ for enum");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseProtoBufAsciiTest() {
|
void ParseProtoBufAsciiTest() {
|
||||||
@@ -1566,6 +1571,8 @@ void FlexBuffersTest() {
|
|||||||
|
|
||||||
// Write the equivalent of:
|
// Write the equivalent of:
|
||||||
// { vec: [ -100, "Fred", 4.0 ], bar: [ 1, 2, 3 ], foo: 100 }
|
// { vec: [ -100, "Fred", 4.0 ], bar: [ 1, 2, 3 ], foo: 100 }
|
||||||
|
#ifndef FLATBUFFERS_CPP98_STL
|
||||||
|
// It's possible to do this without std::function support as well.
|
||||||
slb.Map([&]() {
|
slb.Map([&]() {
|
||||||
slb.Vector("vec", [&]() {
|
slb.Vector("vec", [&]() {
|
||||||
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
||||||
@@ -1581,9 +1588,27 @@ void FlexBuffersTest() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
slb.Finish();
|
slb.Finish();
|
||||||
|
#else
|
||||||
|
// It's possible to do this without std::function support as well.
|
||||||
|
slb.Map([](flexbuffers::Builder& slb2) {
|
||||||
|
slb2.Vector("vec", [](flexbuffers::Builder& slb3) {
|
||||||
|
slb3 += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
|
||||||
|
slb3 += "Fred";
|
||||||
|
slb3.IndirectFloat(4.0f);
|
||||||
|
}, slb2);
|
||||||
|
int ints[] = { 1, 2, 3 };
|
||||||
|
slb2.Vector("bar", ints, 3);
|
||||||
|
slb2.FixedTypedVector("bar3", ints, 3);
|
||||||
|
slb2.Double("foo", 100);
|
||||||
|
slb2.Map("mymap", [](flexbuffers::Builder& slb3) {
|
||||||
|
slb3.String("foo", "Fred"); // Testing key and string reuse.
|
||||||
|
}, slb2);
|
||||||
|
}, slb);
|
||||||
|
slb.Finish();
|
||||||
|
#endif // FLATBUFFERS_CPP98_STL
|
||||||
|
|
||||||
for (size_t i = 0; i < slb.GetBuffer().size(); i++)
|
for (size_t i = 0; i < slb.GetBuffer().size(); i++)
|
||||||
printf("%d ", slb.GetBuffer().data()[i]);
|
printf("%d ", flatbuffers::vector_data(slb.GetBuffer())[i]);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
|
||||||
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
|
||||||
@@ -1641,7 +1666,11 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
|
|
||||||
std::string rawbuf;
|
std::string rawbuf;
|
||||||
auto flatbuf1 = CreateFlatBufferTest(rawbuf);
|
auto flatbuf1 = CreateFlatBufferTest(rawbuf);
|
||||||
|
#if !defined(FLATBUFFERS_CPP98_STL)
|
||||||
auto flatbuf = std::move(flatbuf1); // Test move assignment.
|
auto flatbuf = std::move(flatbuf1); // Test move assignment.
|
||||||
|
#else
|
||||||
|
auto &flatbuf = flatbuf1;
|
||||||
|
#endif // !defined(FLATBUFFERS_CPP98_STL)
|
||||||
AccessFlatBufferTest(reinterpret_cast<const uint8_t *>(rawbuf.c_str()),
|
AccessFlatBufferTest(reinterpret_cast<const uint8_t *>(rawbuf.c_str()),
|
||||||
rawbuf.length());
|
rawbuf.length());
|
||||||
AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
|
AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
|
||||||
@@ -1692,4 +1721,3 @@ int main(int /*argc*/, const char * /*argv*/[]) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -364,6 +364,7 @@ inline flatbuffers::Offset<Attacker> Attacker::Pack(flatbuffers::FlatBufferBuild
|
|||||||
inline flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<Attacker> CreateAttacker(flatbuffers::FlatBufferBuilder &_fbb, const AttackerT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
(void)_rehasher;
|
(void)_rehasher;
|
||||||
(void)_o;
|
(void)_o;
|
||||||
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const AttackerT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
auto _sword_attack_damage = _o->sword_attack_damage;
|
auto _sword_attack_damage = _o->sword_attack_damage;
|
||||||
return CreateAttacker(
|
return CreateAttacker(
|
||||||
_fbb,
|
_fbb,
|
||||||
@@ -392,10 +393,11 @@ inline flatbuffers::Offset<Movie> Movie::Pack(flatbuffers::FlatBufferBuilder &_f
|
|||||||
inline flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
inline flatbuffers::Offset<Movie> CreateMovie(flatbuffers::FlatBufferBuilder &_fbb, const MovieT *_o, const flatbuffers::rehasher_function_t *_rehasher) {
|
||||||
(void)_rehasher;
|
(void)_rehasher;
|
||||||
(void)_o;
|
(void)_o;
|
||||||
|
struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const MovieT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va;
|
||||||
auto _main_character_type = _o->main_character.type;
|
auto _main_character_type = _o->main_character.type;
|
||||||
auto _main_character = _o->main_character.Pack(_fbb);
|
auto _main_character = _o->main_character.Pack(_fbb);
|
||||||
auto _characters_type = _o->characters.size() ? _fbb.CreateVector<uint8_t>(_o->characters.size(), [&](size_t i) { return static_cast<uint8_t>(_o->characters[i].type); }) : 0;
|
auto _characters_type = _o->characters.size() ? _fbb.CreateVector<uint8_t>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return static_cast<uint8_t>(__va->__o->characters[i].type); }, &_va) : 0;
|
||||||
auto _characters = _o->characters.size() ? _fbb.CreateVector<flatbuffers::Offset<void>>(_o->characters.size(), [&](size_t i) { return _o->characters[i].Pack(_fbb, _rehasher); }) : 0;
|
auto _characters = _o->characters.size() ? _fbb.CreateVector<flatbuffers::Offset<void>>(_o->characters.size(), [](size_t i, _VectorArgs *__va) { return __va->__o->characters[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va) : 0;
|
||||||
return CreateMovie(
|
return CreateMovie(
|
||||||
_fbb,
|
_fbb,
|
||||||
_main_character_type,
|
_main_character_type,
|
||||||
@@ -602,10 +604,10 @@ inline void FinishMovieBuffer(
|
|||||||
fbb.Finish(root, MovieIdentifier());
|
fbb.Finish(root, MovieIdentifier());
|
||||||
}
|
}
|
||||||
|
|
||||||
inline std::unique_ptr<MovieT> UnPackMovie(
|
inline flatbuffers::unique_ptr<MovieT> UnPackMovie(
|
||||||
const void *buf,
|
const void *buf,
|
||||||
const flatbuffers::resolver_function_t *res = nullptr) {
|
const flatbuffers::resolver_function_t *res = nullptr) {
|
||||||
return std::unique_ptr<MovieT>(GetMovie(buf)->UnPack(res));
|
return flatbuffers::unique_ptr<MovieT>(GetMovie(buf)->UnPack(res));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
|
#endif // FLATBUFFERS_GENERATED_UNIONVECTOR_H_
|
||||||
|
|||||||
Reference in New Issue
Block a user