summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-x.gitignore6
-rw-r--r--.travis.yml81
-rw-r--r--CMakeLists.txt2
-rwxr-xr-xandroid/AndroidManifest.xml11
-rw-r--r--android/build.gradle108
-rwxr-xr-xandroid/build_apk.sh511
-rw-r--r--android/gradle/wrapper/gradle-wrapper.jarbin0 -> 54706 bytes
-rw-r--r--android/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xandroid/gradlew172
-rw-r--r--android/gradlew.bat84
-rwxr-xr-xandroid/jni/Android.mk3
-rwxr-xr-xandroid/jni/Application.mk6
-rw-r--r--include/flatbuffers/base.h4
-rw-r--r--include/flatbuffers/flatbuffers.h60
-rw-r--r--include/flatbuffers/flexbuffers.h78
-rw-r--r--include/flatbuffers/idl.h31
-rw-r--r--include/flatbuffers/reflection.h9
-rw-r--r--include/flatbuffers/registry.h2
-rw-r--r--include/flatbuffers/stl_emulation.h215
-rw-r--r--include/flatbuffers/util.h21
-rwxr-xr-xsamples/android/AndroidManifest.xml11
-rw-r--r--samples/android/build.gradle108
-rwxr-xr-xsamples/android/build_apk.sh511
-rw-r--r--samples/android/gradle/wrapper/gradle-wrapper.jarbin0 -> 54706 bytes
-rw-r--r--samples/android/gradle/wrapper/gradle-wrapper.properties6
-rwxr-xr-xsamples/android/gradlew172
-rw-r--r--samples/android/gradlew.bat84
-rwxr-xr-xsamples/android/jni/Android.mk2
-rwxr-xr-xsamples/android/jni/Application.mk6
-rwxr-xr-xsamples/android_sample.sh7
-rw-r--r--samples/monster_generated.h18
-rw-r--r--src/code_generators.cpp8
-rw-r--r--src/idl_gen_cpp.cpp36
-rw-r--r--src/idl_gen_general.cpp6
-rw-r--r--src/idl_parser.cpp151
-rw-r--r--src/reflection.cpp29
-rw-r--r--tests/monster_test.bfbsbin3736 -> 4520 bytes
-rw-r--r--tests/monster_test.schema.json12
-rw-r--r--tests/monster_test_generated.h28
-rw-r--r--tests/test.cpp76
-rw-r--r--tests/union_vector/union_vector_generated.h10
41 files changed, 1445 insertions, 1246 deletions
diff --git a/.gitignore b/.gitignore
index aedeb3cb..bf6d665b 100755
--- a/.gitignore
+++ b/.gitignore
@@ -72,3 +72,9 @@ Testing/Temporary
.project
net/**/obj
node_modules/
+android/.externalNativeBuild/
+android/.gradle/
+android/build/
+samples/android/.externalNativeBuild/
+samples/android/.gradle/
+samples/android/build/
diff --git a/.travis.yml b/.travis.yml
index bee81694..297c406b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,31 +1,58 @@
-language: cpp
-
-os:
-- linux
-- osx
-
-compiler:
- - gcc
- #- clang
-
env:
- matrix:
- - BUILD_TYPE=Debug BIICODE=false
- - BUILD_TYPE=Release BIICODE=false
- # biicode .deb files no longer available.
- # - BUILD_TYPE=Release BIICODE=true
- # - BUILD_TYPE=Debug BIICODE=true
global:
+ # Set at the root level as this is ignored when set under matrix.env.
- GCC_VERSION="4.9"
+matrix:
+ include:
+ - language: cpp
+ os:
+ - linux
+ - osx
+
+ compiler:
+ - gcc
+ #- clang
+
+ env:
+ matrix:
+ - BUILD_TYPE=Debug BIICODE=false
+ - BUILD_TYPE=Release BIICODE=false
+ # biicode .deb files no longer available.
+ # - BUILD_TYPE=Release BIICODE=true
+ # - BUILD_TYPE=Debug BIICODE=true
+
+ before_install:
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test; fi
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get update -qq; fi
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq g++-$GCC_VERSION; fi
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo apt-get install -qq gcc-$GCC_VERSION; fi
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which g++-$GCC_VERSION) /usr/bin/g++; fi
+ - if [ "$TRAVIS_OS_NAME" == "linux" ]; then sudo ln -s -v -f $(which gcc-$GCC_VERSION) /usr/bin/gcc; fi
+
+ script:
+ - if [ "$BIICODE" == "false" ]; then cmake -DCMAKE_BUILD_TYPE=$BUILD_TYPE . && make && make test; fi
+ - if [ "$BIICODE" == "true" ] && [ "$TRAVIS_OS_NAME" == "linux" ]; then ./biicode/support/bii-travis.sh $BUILD_TYPE; fi
-before_install:
-- 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
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 53d453bb..e8353252 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -31,6 +31,7 @@ set(FlatBuffers_Library_SRCS
include/flatbuffers/util.h
include/flatbuffers/reflection.h
include/flatbuffers/reflection_generated.h
+ include/flatbuffers/stl_emulation.h
include/flatbuffers/flexbuffers.h
include/flatbuffers/registry.h
src/code_generators.cpp
@@ -198,6 +199,7 @@ function(compile_flatbuffers_schema_to_cpp SRC_FBS)
OUTPUT ${GEN_HEADER}
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}" -c --no-includes --gen-mutable
--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"
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
DEPENDS flatc)
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml
index a15f547b..846fd13c 100755
--- a/android/AndroidManifest.xml
+++ b/android/AndroidManifest.xml
@@ -17,17 +17,14 @@
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.FlatBufferTest"
- android:versionCode="1"
- android:versionName="1.0">
+ package="com.example.FlatBufferTest">
<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. -->
- <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.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
diff --git a/android/build.gradle b/android/build.gradle
new file mode 100644
index 00000000..73e4188c
--- /dev/null
+++ b/android/build.gradle
@@ -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"
+ }
+ }
+ }
+ }
+}
diff --git a/android/build_apk.sh b/android/build_apk.sh
deleted file mode 100755
index 1b9f4a45..00000000
--- a/android/build_apk.sh
+++ /dev/null
@@ -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 "$@"
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..b4163b81
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1e1168cf
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -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
diff --git a/android/gradlew b/android/gradlew
new file mode 100755
index 00000000..cccdd3d5
--- /dev/null
+++ b/android/gradlew
@@ -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" "$@"
diff --git a/android/gradlew.bat b/android/gradlew.bat
new file mode 100644
index 00000000..f9553162
--- /dev/null
+++ b/android/gradlew.bat
@@ -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
diff --git a/android/jni/Android.mk b/android/jni/Android.mk
index 0269dd3f..aec561a9 100755
--- a/android/jni/Android.mk
+++ b/android/jni/Android.mk
@@ -39,6 +39,7 @@ LOCAL_SRC_FILES := src/idl_parser.cpp \
src/util.cpp \
src/code_generators.cpp
LOCAL_STATIC_LIBRARIES := flatbuffers
+LOCAL_ARM_MODE := arm
include $(BUILD_STATIC_LIBRARY)
# FlatBuffers test
@@ -48,7 +49,7 @@ LOCAL_SRC_FILES := android/jni/main.cpp \
tests/test.cpp \
src/idl_gen_fbs.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_ARM_MODE := arm
include $(BUILD_SHARED_LIBRARY)
diff --git a/android/jni/Application.mk b/android/jni/Application.mk
index 2fc9c737..ca9e8004 100755
--- a/android/jni/Application.mk
+++ b/android/jni/Application.mk
@@ -13,10 +13,8 @@
# 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.
-APP_PLATFORM := android-10
+APP_PLATFORM := android-9
APP_PROJECT_PATH := $(call my-dir)/..
-APP_STL := gnustl_static
-
+APP_STL ?= stlport_static
APP_ABI := armeabi-v7a
-
APP_CPPFLAGS += -std=c++11
diff --git a/include/flatbuffers/base.h b/include/flatbuffers/base.h
index 38127f0f..497a2a96 100644
--- a/include/flatbuffers/base.h
+++ b/include/flatbuffers/base.h
@@ -29,6 +29,8 @@
#include <functional>
#endif
+#include "flatbuffers/stl_emulation.h"
+
/// @cond FLATBUFFERS_INTERNAL
#if __cplusplus <= 199711L && \
(!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);
}
-}
+} // namespace flatbuffers
#endif // FLATBUFFERS_BASE_H_
diff --git a/include/flatbuffers/flatbuffers.h b/include/flatbuffers/flatbuffers.h
index 9216cf4d..25a54798 100644
--- a/include/flatbuffers/flatbuffers.h
+++ b/include/flatbuffers/flatbuffers.h
@@ -816,10 +816,8 @@ class FlatBufferBuilder
void PopBytes(size_t amount) { buf_.pop(amount); }
template<typename T> void AssertScalarT() {
- #ifndef FLATBUFFERS_CPP98_STL
// The code assumes power of 2 sizes and endian-swap-ability.
- static_assert(std::is_scalar<T>::value, "T must be a scalar type");
- #endif
+ static_assert(flatbuffers::is_scalar<T>::value, "T must be a scalar type");
}
// Write a single aligned scalar to the buffer
@@ -1182,6 +1180,22 @@ class FlatBufferBuilder
}
#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`.
/// This is a convenience function for a common case.
/// @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());
}
-
#ifndef FLATBUFFERS_CPP98_STL
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
/// @tparam T The data type of the struct array elements.
@@ -1238,16 +1251,34 @@ class FlatBufferBuilder
/// accessors.
template<typename T> Offset<Vector<const T *>> CreateVectorOfStructs(
size_t vector_size, const std::function<void(size_t i, T *)> &filler) {
- StartVector(vector_size * sizeof(T) / AlignOf<T>(), AlignOf<T>());
- T *structs = reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
+ T* structs = StartVectorOfStructs<T>(vector_size);
for (size_t i = 0; i < vector_size; i++) {
filler(i, structs);
structs++;
}
- return Offset<Vector<const T *>>(EndVector(vector_size));
+ return EndVectorOfStructs<T>(vector_size);
}
#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`.
/// @tparam T The data type of the `std::vector` struct elements.
/// @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.
typedef std::set<Offset<String>, StringOffsetCompare> StringOffsetMap;
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));
+ }
};
/// @}
diff --git a/include/flatbuffers/flexbuffers.h b/include/flatbuffers/flexbuffers.h
index 67f82b94..15360375 100644
--- a/include/flatbuffers/flexbuffers.h
+++ b/include/flatbuffers/flexbuffers.h
@@ -18,6 +18,8 @@
#define FLATBUFFERS_FLEXBUFFERS_H_
#include <map>
+// Used to select STL variant.
+#include "flatbuffers/base.h"
// We use the basic binary writing functions from the regular FlatBuffers.
#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) {
- return GetRoot(buffer.data(), buffer.size());
+ return GetRoot(flatbuffers::vector_data(buffer), buffer.size());
}
// Flags that configure how the Builder behaves.
@@ -913,7 +915,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
return CreateBlob(data, len, 0, TYPE_BLOB);
}
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),
@@ -957,11 +959,15 @@ class Builder FLATBUFFERS_FINAL_CLASS {
// step automatically when appliccable, and encourage people to write in
// sorted fashion.
// 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,
[&](const TwoValue &a, const TwoValue &b) -> bool {
- auto as = reinterpret_cast<const char *>(buf_.data() + a.key.u_);
- auto bs = reinterpret_cast<const char *>(buf_.data() + b.key.u_);
+ auto as = reinterpret_cast<const char *>(
+ 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);
// If this assertion hits, you've added two keys with the same value to
// this map.
@@ -986,13 +992,25 @@ class Builder FLATBUFFERS_FINAL_CLASS {
f();
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) {
auto start = StartVector(key);
f();
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) {
- if (std::is_scalar<T>::value) {
+ if (flatbuffers::is_scalar<T>::value) {
// This path should be a lot quicker and use less space.
ScalarVector(elems, len, false);
} else {
@@ -1007,7 +1025,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
Vector(elems, len);
}
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) {
@@ -1015,18 +1033,29 @@ class Builder FLATBUFFERS_FINAL_CLASS {
f();
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) {
auto start = StartVector(key);
f();
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) {
// We only support a few fixed vector lengths. Anything bigger use a
// regular typed vector.
assert(len >= 2 && len <= 4);
// And only scalar values.
- assert(std::is_scalar<T>::value);
+ assert(flatbuffers::is_scalar<T>::value);
return ScalarVector(elems, len, true);
}
@@ -1041,11 +1070,22 @@ class Builder FLATBUFFERS_FINAL_CLASS {
f();
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) {
auto start = StartMap(key);
f();
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) {
auto start = StartMap();
for (auto it = map.begin(); it != map.end(); ++it)
@@ -1174,10 +1214,10 @@ class Builder FLATBUFFERS_FINAL_CLASS {
}
template<typename T> static Type GetScalarType() {
- assert(std::is_scalar<T>::value);
- return std::is_floating_point<T>::value
+ assert(flatbuffers::is_scalar<T>::value);
+ return flatbuffers::is_floating_point<T>::value
? TYPE_FLOAT
- : (std::is_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
+ : (flatbuffers::is_unsigned<T>::value ? TYPE_UINT : TYPE_INT);
}
struct Value {
@@ -1364,9 +1404,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
struct KeyOffsetCompare {
KeyOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
- bool operator() (size_t a, size_t b) const {
- auto stra = reinterpret_cast<const char *>(buf_->data() + a);
- auto strb = reinterpret_cast<const char *>(buf_->data() + b);
+ bool operator()(size_t a, size_t b) const {
+ auto stra =
+ 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;
}
const std::vector<uint8_t> *buf_;
@@ -1375,9 +1417,11 @@ class Builder FLATBUFFERS_FINAL_CLASS {
typedef std::pair<size_t, size_t> StringOffset;
struct StringOffsetCompare {
StringOffsetCompare(const std::vector<uint8_t> &buf) : buf_(&buf) {}
- bool operator() (const StringOffset &a, const StringOffset &b) const {
- auto stra = reinterpret_cast<const char *>(buf_->data() + a.first);
- auto strb = reinterpret_cast<const char *>(buf_->data() + b.first);
+ bool operator()(const StringOffset &a, const StringOffset &b) const {
+ auto stra = reinterpret_cast<const char *>(flatbuffers::vector_data(*buf_) +
+ 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;
}
const std::vector<uint8_t> *buf_;
diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h
index 4e27e30c..0f500243 100644
--- a/include/flatbuffers/idl.h
+++ b/include/flatbuffers/idl.h
@@ -20,13 +20,17 @@
#include <map>
#include <stack>
#include <memory>
-#include <functional>
+#include "flatbuffers/base.h"
#include "flatbuffers/flatbuffers.h"
#include "flatbuffers/hash.h"
#include "flatbuffers/reflection.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
// Definition Language) / schema file.
@@ -164,7 +168,7 @@ template<typename T> class SymbolTable {
}
bool Add(const std::string &name, T *e) {
- vec.emplace_back(e);
+ vector_emplace_back(&vec, e);
auto it = dict.find(name);
if (it != dict.end()) return true;
dict[name] = e;
@@ -571,15 +575,32 @@ private:
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
size_t parent_fieldn,
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,
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,
std::string *value, uoffset_t *ovalue);
void SerializeStruct(const StructDef &struct_def, const Value &val);
void AddVector(bool sortbysize, int count);
- FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t &count,
- const std::function<CheckedError()> &body);
+ #if defined(FLATBUFFERS_CPP98_STL)
+ 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 ParseMetaData(SymbolTable<Value> *attributes);
FLATBUFFERS_CHECKED_ERROR TryTypedValue(int dtoken, bool check, Value &e,
diff --git a/include/flatbuffers/reflection.h b/include/flatbuffers/reflection.h
index aab9f208..ad5c4562 100644
--- a/include/flatbuffers/reflection.h
+++ b/include/flatbuffers/reflection.h
@@ -361,12 +361,13 @@ template<typename T, typename U> class pointer_inside_vector {
public:
pointer_inside_vector(T *ptr, std::vector<U> &vec)
: offset_(reinterpret_cast<uint8_t *>(ptr) -
- reinterpret_cast<uint8_t *>(vec.data())),
+ reinterpret_cast<uint8_t *>(flatbuffers::vector_data(vec))),
vec_(vec) {}
T *operator*() const {
return reinterpret_cast<T *>(
- reinterpret_cast<uint8_t *>(vec_.data()) + offset_);
+ reinterpret_cast<uint8_t *>(
+ flatbuffers::vector_data(vec_)) + offset_);
}
T *operator->() const {
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,
const reflection::Object *root_table = nullptr);
-#ifndef FLATBUFFERS_CPP98_STL
template <typename T>
void ResizeVector(const reflection::Schema &schema, uoffset_t newsize, T val,
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".
for (int i = 0; i < delta_elem; i++) {
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) {
WriteScalar(loc, val);
} 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
// FlatBuffer. This can be used when any of the above methods are not
diff --git a/include/flatbuffers/registry.h b/include/flatbuffers/registry.h
index 9a227682..35771c18 100644
--- a/include/flatbuffers/registry.h
+++ b/include/flatbuffers/registry.h
@@ -107,7 +107,7 @@ class Registry {
}
// Parse schema.
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())) {
lasterror_ = parser->error_;
return false;
diff --git a/include/flatbuffers/stl_emulation.h b/include/flatbuffers/stl_emulation.h
new file mode 100644
index 00000000..7906648b
--- /dev/null
+++ b/include/flatbuffers/stl_emulation.h
@@ -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_
diff --git a/include/flatbuffers/util.h b/include/flatbuffers/util.h
index ee62b86d..6b7b7bc3 100644
--- a/include/flatbuffers/util.h
+++ b/include/flatbuffers/util.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) {
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.
template<> inline std::string NumToString<double>(double t) {
@@ -202,9 +216,10 @@ inline std::string ConCatPathFileName(const std::string &path,
const std::string &filename) {
std::string filepath = path;
if (filepath.length()) {
- if (filepath.back() == kPathSeparatorWindows) {
- filepath.back() = kPathSeparator;
- } else if (filepath.back() != kPathSeparator) {
+ char filepath_last_character = string_back(filepath);
+ if (filepath_last_character == kPathSeparatorWindows) {
+ filepath_last_character = kPathSeparator;
+ } else if (filepath_last_character != kPathSeparator) {
filepath += kPathSeparator;
}
}
diff --git a/samples/android/AndroidManifest.xml b/samples/android/AndroidManifest.xml
index 0fa3dcfc..352e0fad 100755
--- a/samples/android/AndroidManifest.xml
+++ b/samples/android/AndroidManifest.xml
@@ -17,17 +17,14 @@
-->
<!-- BEGIN_INCLUDE(manifest) -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.samples.FlatBufferSample"
- android:versionCode="1"
- android:versionName="1.0">
+ package="com.samples.FlatBufferSample">
<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. -->
- <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.
This will take care of integrating with our NDK code. -->
<activity android:name="android.app.NativeActivity"
diff --git a/samples/android/build.gradle b/samples/android/build.gradle
new file mode 100644
index 00000000..e6af6d6f
--- /dev/null
+++ b/samples/android/build.gradle
@@ -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"
+ }
+ }
+ }
+ }
+}
diff --git a/samples/android/build_apk.sh b/samples/android/build_apk.sh
deleted file mode 100755
index 1b9f4a45..00000000
--- a/samples/android/build_apk.sh
+++ /dev/null
@@ -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 "$@"
diff --git a/samples/android/gradle/wrapper/gradle-wrapper.jar b/samples/android/gradle/wrapper/gradle-wrapper.jar
new file mode 100644
index 00000000..b4163b81
--- /dev/null
+++ b/samples/android/gradle/wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/samples/android/gradle/wrapper/gradle-wrapper.properties b/samples/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 00000000..1e1168cf
--- /dev/null
+++ b/samples/android/gradle/wrapper/gradle-wrapper.properties
@@ -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
diff --git a/samples/android/gradlew b/samples/android/gradlew
new file mode 100755
index 00000000..cccdd3d5
--- /dev/null
+++ b/samples/android/gradlew
@@ -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" "$@"
diff --git a/samples/android/gradlew.bat b/samples/android/gradlew.bat
new file mode 100644
index 00000000..f9553162
--- /dev/null
+++ b/samples/android/gradlew.bat
@@ -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
diff --git a/samples/android/jni/Android.mk b/samples/android/jni/Android.mk
index 6f22d285..917c2f9e 100755
--- a/samples/android/jni/Android.mk
+++ b/samples/android/jni/Android.mk
@@ -38,7 +38,7 @@ $(info $(LOCAL_C_INCLUDES))
LOCAL_SRC_FILES := main.cpp
LOCAL_CPPFLAGS := -std=c++11 -fexceptions -Wall -Wno-literal-suffix
-LOCAL_LDLIBS := -llog -landroid
+LOCAL_LDLIBS := -llog -landroid -latomic
LOCAL_ARM_MODE := arm
LOCAL_STATIC_LIBRARIES := android_native_app_glue flatbuffers
diff --git a/samples/android/jni/Application.mk b/samples/android/jni/Application.mk
index 2fc9c737..ca9e8004 100755
--- a/samples/android/jni/Application.mk
+++ b/samples/android/jni/Application.mk
@@ -13,10 +13,8 @@
# 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.
-APP_PLATFORM := android-10
+APP_PLATFORM := android-9
APP_PROJECT_PATH := $(call my-dir)/..
-APP_STL := gnustl_static
-
+APP_STL ?= stlport_static
APP_ABI := armeabi-v7a
-
APP_CPPFLAGS += -std=c++11
diff --git a/samples/android_sample.sh b/samples/android_sample.sh
index ead8fd80..53633aca 100755
--- a/samples/android_sample.sh
+++ b/samples/android_sample.sh
@@ -29,8 +29,7 @@ fi
# Execute `build_apk.sh` to build and run the android app.
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
diff --git a/samples/monster_generated.h b/samples/monster_generated.h
index f4bdbb34..9fca774d 100644
--- a/samples/monster_generated.h
+++ b/samples/monster_generated.h
@@ -103,6 +103,7 @@ struct EquipmentUnion {
void Reset();
+#ifndef FLATBUFFERS_CPP98_STL
template <typename T>
void Set(T&& val) {
Reset();
@@ -111,6 +112,7 @@ struct EquipmentUnion {
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);
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 {
typedef Monster TableType;
- std::unique_ptr<Vec3> pos;
+ flatbuffers::unique_ptr<Vec3> pos;
int16_t mana;
int16_t hp;
std::string name;
std::vector<uint8_t> inventory;
Color color;
- std::vector<std::unique_ptr<WeaponT>> weapons;
+ std::vector<flatbuffers::unique_ptr<WeaponT>> weapons;
EquipmentUnion equipped;
MonsterT()
: 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 {
(void)_o;
(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 = hp(); _o->hp = _e; };
{ 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 = 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(); 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) {
(void)_rehasher;
(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 _mana = _o->mana;
auto _hp = _o->hp;
auto _name = _o->name.size() ? _fbb.CreateString(_o->name) : 0;
auto _inventory = _o->inventory.size() ? _fbb.CreateVector(_o->inventory) : 0;
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 = _o->equipped.Pack(_fbb);
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) {
(void)_rehasher;
(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 _damage = _o->damage;
return MyGame::Sample::CreateWeapon(
@@ -616,10 +620,10 @@ inline void FinishMonsterBuffer(
fbb.Finish(root);
}
-inline std::unique_ptr<MonsterT> UnPackMonster(
+inline flatbuffers::unique_ptr<MonsterT> UnPackMonster(
const void *buf,
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
diff --git a/src/code_generators.cpp b/src/code_generators.cpp
index 3126ce59..e0bee8ba 100644
--- a/src/code_generators.cpp
+++ b/src/code_generators.cpp
@@ -16,6 +16,7 @@
#include "flatbuffers/code_generators.h"
#include <assert.h>
+#include "flatbuffers/base.h"
#include "flatbuffers/util.h"
#if defined(_MSC_VER)
@@ -58,7 +59,7 @@ void CodeWriter::operator+=(std::string text) {
// Update the text to everything after the }}.
text = text.substr(end + 2);
}
- if (!text.empty() && text.back() == '\\') {
+ if (!text.empty() && string_back(text) == '\\') {
text.pop_back();
stream_ << text;
} else {
@@ -129,8 +130,8 @@ std::string BaseGenerator::GetNameSpace(const Definition &def) const {
std::string qualified_name = qualifying_start_;
for (auto it = ns->components.begin(); it != ns->components.end(); ++it) {
qualified_name += *it;
- if (std::next(it) != ns->components.end()) {
- qualified_name += qualifying_separator_;
+ if ((it + 1) != ns->components.end()) {
+ qualified_name += qualifying_separator_;
}
}
@@ -167,4 +168,3 @@ void GenComment(const std::vector<std::string> &dc, std::string *code_ptr,
#if defined(_MSC_VER)
#pragma warning(pop)
#endif
-
diff --git a/src/idl_gen_cpp.cpp b/src/idl_gen_cpp.cpp
index 242c8d9b..56d10e62 100644
--- a/src/idl_gen_cpp.cpp
+++ b/src/idl_gen_cpp.cpp
@@ -722,6 +722,7 @@ class CppGenerator : public BaseGenerator {
code_ += " void Reset();";
code_ += "";
if (!enum_def.uses_type_aliases) {
+ code_ += "#ifndef FLATBUFFERS_CPP98_STL";
code_ += " template <typename T>";
code_ += " void Set(T&& val) {";
code_ += " Reset();";
@@ -730,6 +731,7 @@ class CppGenerator : public BaseGenerator {
code_ += " value = new T(std::forward<T>(val));";
code_ += " }";
code_ += " }";
+ code_ += "#endif // FLATBUFFERS_CPP98_STL";
code_ += "";
}
code_ += " " + UnionUnPackSignature(enum_def, true) + ";";
@@ -1802,11 +1804,13 @@ class CppGenerator : public BaseGenerator {
code += "(" + value + ")";
} else {
code += "_fbb.CreateVector<flatbuffers::Offset<";
- code += WrapInNameSpace(*vector_type.struct_def) + ">>";
- code += "(" + value + ".size(), [&](size_t i) {";
- code += " return Create" + vector_type.struct_def->name;
- code += "(_fbb, " + value + "[i]" + GenPtrGet(field) + ", ";
- code += "_rehasher); })";
+ code += WrapInNameSpace(*vector_type.struct_def) + ">> ";
+ code += "(" + value + ".size(), ";
+ code += "[](size_t i, _VectorArgs *__va) { ";
+ code += "return Create" + vector_type.struct_def->name;
+ code += "(*__va->__fbb, __va->_" + value + "[i]" +
+ GenPtrGet(field) + ", ";
+ code += "__va->__rehasher); }, &_va )";
}
break;
}
@@ -1815,16 +1819,19 @@ class CppGenerator : public BaseGenerator {
break;
}
case BASE_TYPE_UNION: {
- code += "_fbb.CreateVector<flatbuffers::Offset<void>>(" + value +
- ".size(), [&](size_t i) { return " + value +
- "[i].Pack(_fbb, _rehasher); })";
+ code += "_fbb.CreateVector<flatbuffers::"
+ "Offset<void>>(" + value +
+ ".size(), [](size_t i, _VectorArgs *__va) { "
+ "return __va->_" + value +
+ "[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va)";
break;
}
case BASE_TYPE_UTYPE: {
value = StripUnionType(value);
code += "_fbb.CreateVector<uint8_t>(" + value +
- ".size(), [&](size_t i) { return static_cast<uint8_t>(" + value +
- "[i].type); })";
+ ".size(), [](size_t i, _VectorArgs *__va) { "
+ "return static_cast<uint8_t>(__va->_" + value +
+ "[i].type); }, &_va)";
break;
}
default: {
@@ -1935,6 +1942,15 @@ class CppGenerator : public BaseGenerator {
code_ += " (void)_rehasher;";
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();
it != struct_def.fields.vec.end(); ++it) {
auto &field = **it;
diff --git a/src/idl_gen_general.cpp b/src/idl_gen_general.cpp
index baeaddf6..fb5a822a 100644
--- a/src/idl_gen_general.cpp
+++ b/src/idl_gen_general.cpp
@@ -21,6 +21,10 @@
#include "flatbuffers/util.h"
#include "flatbuffers/code_generators.h"
+#if defined(FLATBUFFERS_CPP98_STL)
+ #include <cctype>
+#endif // defined(FLATBUFFERS_CPP98_STL)
+
namespace flatbuffers {
// Convert an underscore_based_indentifier in to camelCase.
@@ -204,7 +208,7 @@ class GeneralGenerator : public BaseGenerator {
std::string code;
if (lang_.language == IDLOptions::kCSharp) {
- code = "// <auto-generated>\n"
+ code = "// <auto-generated>\n"
"// " + std::string(FlatBuffersGeneratedWarning()) + "\n"
"// </auto-generated>\n\n";
} else {
diff --git a/src/idl_parser.cpp b/src/idl_parser.cpp
index a7468d55..af3f93e3 100644
--- a/src/idl_parser.cpp
+++ b/src/idl_parser.cpp
@@ -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,
T *val) {
int64_t i = StringToInt(s);
- const int64_t min = std::numeric_limits<T>::min();
- const int64_t max = std::numeric_limits<T>::max();
+ const int64_t min = flatbuffers::numeric_limits<T>::min();
+ const int64_t max = flatbuffers::numeric_limits<T>::max();
ECHECK(parser.CheckInRange(i, min, max));
*val = (T)i;
return NoError();
@@ -870,7 +870,8 @@ void Parser::SerializeStruct(const StructDef &struct_def, const Value &val) {
CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
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
// or vector[..] with all fields in order
char terminator = '}';
@@ -898,7 +899,7 @@ CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
}
if (!opts.protobuf_ascii_alike || !(Is('{') || Is('['))) EXPECT(':');
}
- ECHECK(body(name));
+ ECHECK(body(name, fieldn, struct_def, state));
if (Is(terminator)) break;
ECHECK(ParseComma());
}
@@ -911,52 +912,56 @@ CheckedError Parser::ParseTableDelimiters(size_t &fieldn,
CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
uoffset_t *ovalue) {
- size_t fieldn = 0;
- auto err = ParseTableDelimiters(fieldn, &struct_def,
- [&](const std::string &name) -> CheckedError {
+ size_t fieldn_outer = 0;
+ auto err = ParseTableDelimiters(fieldn_outer, &struct_def,
+ [](const std::string &name, size_t &fieldn,
+ const StructDef *struct_def_inner,
+ void *state) -> CheckedError {
+ Parser *parser = static_cast<Parser *>(state);
if (name == "$schema") {
- EXPECT(kTokenStringConstant);
+ ECHECK(parser->Expect(kTokenStringConstant));
return NoError();
}
- auto field = struct_def.fields.Lookup(name);
+ auto field = struct_def_inner->fields.Lookup(name);
if (!field) {
- if (!opts.skip_unexpected_fields_in_json) {
- return Error("unknown field: " + name);
+ if (!parser->opts.skip_unexpected_fields_in_json) {
+ return parser->Error("unknown field: " + name);
} else {
- ECHECK(SkipAnyJsonValue());
+ ECHECK(parser->SkipAnyJsonValue());
}
} else {
- if (Is(kTokenNull)) {
- NEXT(); // Ignore this field.
+ if (parser->Is(kTokenNull)) {
+ ECHECK(parser->Next()); // Ignore this field.
} else {
Value val = field->value;
if (field->flexbuffer) {
flexbuffers::Builder builder(1024,
flexbuffers::BUILDER_FLAG_SHARE_ALL);
- ECHECK(ParseFlexBufferValue(&builder));
+ ECHECK(parser->ParseFlexBufferValue(&builder));
builder.Finish();
- auto off = builder_.CreateVector(builder.GetBuffer());
+ auto off = parser->builder_.CreateVector(builder.GetBuffer());
val.constant = NumToString(off.o);
} else {
- ECHECK(ParseAnyValue(val, field, fieldn, &struct_def));
+ ECHECK(parser->ParseAnyValue(val, field, fieldn, struct_def_inner));
}
// Hardcoded insertion-sort with error-check.
// If fields are specified in order, then this loop exits immediately.
- auto elem = field_stack_.rbegin();
- for (; elem != field_stack_.rbegin() + fieldn; ++elem) {
+ auto elem = parser->field_stack_.rbegin();
+ for (; elem != parser->field_stack_.rbegin() + fieldn; ++elem) {
auto existing_field = elem->second;
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;
}
// Note: elem points to before the insertion point, thus .base() points
// 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++;
}
}
return NoError();
- });
+ }, this);
ECHECK(err);
// Check if all required fields are parsed.
@@ -968,7 +973,7 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
continue;
}
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) {
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);
auto start = struct_def.fixed
@@ -993,8 +998,9 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
size;
size /= 2) {
// Go through elements in reverse, since we're building the data backwards.
- for (auto it = field_stack_.rbegin();
- it != field_stack_.rbegin() + fieldn; ++it) {
+ for (auto it = field_stack_.rbegin(); it != field_stack_.rbegin() +
+ fieldn_outer;
+ ++it) {
auto &field_value = it->first;
auto field = it->second;
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) {
builder_.ClearOffsets();
@@ -1058,11 +1064,12 @@ CheckedError Parser::ParseTable(const StructDef &struct_def, std::string *value,
}
CheckedError Parser::ParseVectorDelimiters(size_t &count,
- const std::function<CheckedError()> &body) {
+ ParseVectorDelimitersBody body,
+ void *state) {
EXPECT('[');
for (;;) {
if ((!opts.strict_json || !count) && Is(']')) break;
- ECHECK(body());
+ ECHECK(body(count, state));
count++;
if (Is(']')) break;
ECHECK(ParseComma());
@@ -1073,13 +1080,18 @@ CheckedError Parser::ParseVectorDelimiters(size_t &count,
CheckedError Parser::ParseVector(const Type &type, uoffset_t *ovalue) {
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;
- val.type = type;
- ECHECK(ParseAnyValue(val, nullptr, 0, nullptr));
- field_stack_.push_back(std::make_pair(val, nullptr));
+ val.type = parser_and_type->second;
+ ECHECK(parser->ParseAnyValue(val, nullptr, 0, nullptr));
+ parser->field_stack_.push_back(std::make_pair(val, nullptr));
return NoError();
- });
+ }, &parser_and_type_state);
ECHECK(err);
builder_.StartVector(count * InlineSize(type) / InlineAlignment(type),
@@ -1927,17 +1939,25 @@ CheckedError Parser::ParseTypeFromProtoType(Type *type) {
CheckedError Parser::SkipAnyJsonValue() {
switch (token_) {
case '{': {
- size_t fieldn = 0;
- return ParseTableDelimiters(fieldn, nullptr,
- [&](const std::string &) -> CheckedError {
- ECHECK(SkipAnyJsonValue());
- fieldn++;
- return NoError();
- });
+ size_t fieldn_outer = 0;
+ return ParseTableDelimiters(fieldn_outer, nullptr,
+ [](const std::string &,
+ size_t &fieldn, const StructDef *,
+ void *state) -> CheckedError {
+ auto *parser = static_cast<Parser *>(state);
+ ECHECK(parser->SkipAnyJsonValue());
+ fieldn++;
+ return NoError();
+ },
+ this);
}
case '[': {
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:
EXPECT(kTokenStringConstant);
@@ -1957,15 +1977,25 @@ CheckedError Parser::SkipAnyJsonValue() {
CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
switch (token_) {
case '{': {
+ std::pair<Parser *, flexbuffers::Builder *> parser_and_builder_state(
+ this, builder);
auto start = builder->StartMap();
- size_t fieldn = 0;
- auto err = ParseTableDelimiters(fieldn, nullptr,
- [&](const std::string &name) -> CheckedError {
- builder->Key(name);
- ECHECK(ParseFlexBufferValue(builder));
- fieldn++;
- return NoError();
- });
+ size_t fieldn_outer = 0;
+ auto err = ParseTableDelimiters(fieldn_outer, nullptr,
+ [](const std::string &name,
+ size_t &fieldn, const StructDef *,
+ void *state) -> CheckedError {
+ auto *parser_and_builder =
+ 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);
builder->EndMap(start);
break;
@@ -1973,9 +2003,17 @@ CheckedError Parser::ParseFlexBufferValue(flexbuffers::Builder *builder) {
case '[':{
auto start = builder->StartVector();
size_t count = 0;
- ECHECK(ParseVectorDelimiters(count, [&]() {
- return ParseFlexBufferValue(builder);
- }));
+ std::pair<Parser *, flexbuffers::Builder *> parser_and_builder_state(
+ 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);
break;
}
@@ -2082,7 +2120,7 @@ CheckedError Parser::DoParse(const char *source,
ECHECK(ParseProtoDecl());
} else if (Is(kTokenNativeInclude)) {
NEXT();
- native_included_files_.emplace_back(attribute_);
+ vector_emplace_back(&native_included_files_, attribute_);
EXPECT(kTokenStringConstant);
} else if (Is(kTokenInclude) ||
(opts.proto_mode &&
@@ -2201,7 +2239,10 @@ std::set<std::string> Parser::GetIncludedFilesRecursive(
to_process.pop_front();
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) {
if (included_files.find(*it) == included_files.end())
to_process.push_back(*it);
diff --git a/src/reflection.cpp b/src/reflection.cpp
index 96b3e4aa..2eee4616 100644
--- a/src/reflection.cpp
+++ b/src/reflection.cpp
@@ -165,15 +165,15 @@ class ResizeContext {
ResizeContext(const reflection::Schema &schema, uoffset_t start, int delta,
std::vector<uint8_t> *flatbuf,
const reflection::Object *root_table = nullptr)
- : schema_(schema), startptr_(flatbuf->data() + start),
+ : schema_(schema), startptr_(vector_data(*flatbuf) + start),
delta_(delta), buf_(*flatbuf),
dag_check_(flatbuf->size() / sizeof(uoffset_t), false) {
auto mask = static_cast<int>(sizeof(largest_scalar_t) - 1);
delta_ = (delta_ + mask) & ~mask;
if (!delta_) return; // We can't shrink by less than largest_scalar_t.
// Now change all the offsets by delta_.
- auto root = GetAnyRoot(buf_.data());
- Straddle<uoffset_t, 1>(buf_.data(), root, buf_.data());
+ auto root = GetAnyRoot(vector_data(buf_));
+ Straddle<uoffset_t, 1>(vector_data(buf_), root, vector_data(buf_));
ResizeTable(root_table ? *root_table : *schema.root_table(), root);
// We can now add or remove bytes at start.
if (delta_ > 0) buf_.insert(buf_.begin() + start, delta_, 0);
@@ -200,7 +200,7 @@ class ResizeContext {
// will straddle and which won't.
uint8_t &DagCheck(const void *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];
}
@@ -296,19 +296,19 @@ void SetString(const reflection::Schema &schema, const std::string &val,
const reflection::Object *root_table) {
auto delta = static_cast<int>(val.size()) - static_cast<int>(str->Length());
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));
if (delta) {
// 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).
ResizeContext(schema, start, delta, flatbuf, root_table);
// Set the new length.
- WriteScalar(flatbuf->data() + str_start,
+ WriteScalar(vector_data(*flatbuf) + str_start,
static_cast<uoffset_t>(val.size()));
}
// 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,
@@ -317,7 +317,8 @@ uint8_t *ResizeAnyVector(const reflection::Schema &schema, uoffset_t newsize,
const reflection::Object *root_table) {
auto delta_elem = static_cast<int>(newsize) - static_cast<int>(num_elems);
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) +
elem_size * num_elems);
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
// buffer.
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);
- 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.
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,
@@ -349,7 +350,7 @@ const uint8_t *AddFlatBuffer(std::vector<uint8_t> &flatbuf,
// Insert the entire FlatBuffer minus the root pointer.
flatbuf.insert(flatbuf.end(), newbuf + sizeof(uoffset_t), newbuf + newlen);
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,
diff --git a/tests/monster_test.bfbs b/tests/monster_test.bfbs
index ea66514b..95f7c5e1 100644
--- a/tests/monster_test.bfbs
+++ b/tests/monster_test.bfbs
Binary files differ
diff --git a/tests/monster_test.schema.json b/tests/monster_test.schema.json
index 7c58f706..28bc11dd 100644
--- a/tests/monster_test.schema.json
+++ b/tests/monster_test.schema.json
@@ -18,6 +18,18 @@
"properties" : {
}
},
+ "MyGame_OtherNameSpace_TableB" : {
+ "type" : "object",
+ "properties" : {
+ "a" : { "$ref" : "#/definitions/TableA" }
+ }
+ },
+ "TableA" : {
+ "type" : "object",
+ "properties" : {
+ "b" : { "$ref" : "#/definitions/MyGame_OtherNameSpace_TableB" }
+ }
+ },
"MyGame_Example2_Monster" : {
"type" : "object",
"properties" : {
diff --git a/tests/monster_test_generated.h b/tests/monster_test_generated.h
index 580ed57b..d61db621 100644
--- a/tests/monster_test_generated.h
+++ b/tests/monster_test_generated.h
@@ -137,6 +137,7 @@ struct AnyUnion {
void Reset();
+#ifndef FLATBUFFERS_CPP98_STL
template <typename T>
void Set(T&& val) {
Reset();
@@ -145,6 +146,7 @@ struct AnyUnion {
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);
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 {
typedef Monster TableType;
- std::unique_ptr<Vec3> pos;
+ flatbuffers::unique_ptr<Vec3> pos;
int16_t mana;
int16_t hp;
std::string name;
@@ -525,10 +527,10 @@ struct MonsterT : public flatbuffers::NativeTable {
AnyUnion test;
std::vector<Test> test4;
std::vector<std::string> testarrayofstring;
- std::vector<std::unique_ptr<MonsterT>> testarrayoftables;
- std::unique_ptr<MonsterT> enemy;
+ std::vector<flatbuffers::unique_ptr<MonsterT>> testarrayoftables;
+ flatbuffers::unique_ptr<MonsterT> enemy;
std::vector<uint8_t> testnestedflatbuffer;
- std::unique_ptr<StatT> testempty;
+ flatbuffers::unique_ptr<StatT> testempty;
bool testbool;
int32_t testhashs32_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) {
(void)_rehasher;
(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(
_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) {
(void)_rehasher;
(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;
return MyGame::Example::CreateTestSimpleTableWithEnum(
_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) {
(void)_rehasher;
(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 _val = _o->val;
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 {
(void)_o;
(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 = hp(); _o->hp = _e; };
{ 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 = 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 = 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 = enemy(); if (_e) _o->enemy = std::unique_ptr<MonsterT>(_e->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 = 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 = 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 = testhashs32_fnv1(); _o->testhashs32_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) {
(void)_rehasher;
(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 _mana = _o->mana;
auto _hp = _o->hp;
@@ -1256,7 +1262,7 @@ inline flatbuffers::Offset<Monster> CreateMonster(flatbuffers::FlatBufferBuilder
auto _test = _o->test.Pack(_fbb);
auto _test4 = _o->test4.size() ? _fbb.CreateVectorOfStructs(_o->test4) : 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 _testnestedflatbuffer = _o->testnestedflatbuffer.size() ? _fbb.CreateVector(_o->testnestedflatbuffer) : 0;
auto _testempty = _o->testempty ? CreateStat(_fbb, _o->testempty.get(), _rehasher) : 0;
@@ -1452,10 +1458,10 @@ inline void FinishMonsterBuffer(
fbb.Finish(root, MonsterIdentifier());
}
-inline std::unique_ptr<MonsterT> UnPackMonster(
+inline flatbuffers::unique_ptr<MonsterT> UnPackMonster(
const void *buf,
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
diff --git a/tests/test.cpp b/tests/test.cpp
index fa7fa6e1..576fcf29 100644
--- a/tests/test.cpp
+++ b/tests/test.cpp
@@ -121,12 +121,13 @@ flatbuffers::DetachedBuffer CreateFlatBufferTest(std::string &buffer) {
mlocs[2] = mb3.Finish();
// Create an array of strings. Also test string pooling, and lambdas.
- const char *names[] = { "bob", "fred", "bob", "fred" };
auto vecofstrings =
builder.CreateVector<flatbuffers::Offset<flatbuffers::String>>(4,
- [&](size_t i) {
- return builder.CreateSharedString(names[i]);
- });
+ [](size_t i, flatbuffers::FlatBufferBuilder *b)
+ -> 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.
std::vector<std::string> names2;
@@ -541,7 +542,7 @@ void ParseAndGenerateTextTest() {
TEST_EQ(result, true);
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);
}
@@ -671,8 +672,8 @@ void ReflectionTest(uint8_t *flatbuf, size_t length) {
// Get the root.
// This time we wrap the result from GetAnyRoot in a smartpointer that
// will keep rroot valid as resizingbuf resizes.
- auto rroot = flatbuffers::piv(flatbuffers::GetAnyRoot(resizingbuf.data()),
- resizingbuf);
+ auto rroot = flatbuffers::piv(flatbuffers::GetAnyRoot(
+ flatbuffers::vector_data(resizingbuf)), resizingbuf);
SetString(schema, "totally new string", GetFieldS(**rroot, name_field),
&resizingbuf);
// 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 integrity of all resize operations above.
flatbuffers::Verifier resize_verifier(
- reinterpret_cast<const uint8_t *>(resizingbuf.data()),
+ reinterpret_cast<const uint8_t *>(
+ flatbuffers::vector_data(resizingbuf)),
resizingbuf.size());
TEST_EQ(VerifyMonsterBuffer(resize_verifier), true);
// 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);
// 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);
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);
}
}
@@ -1039,17 +1042,17 @@ void FuzzTest2() {
i -= std::min(static_cast<size_t>(10), i); // show some context;
size_t end = std::min(len, i + 20);
for (; i < end; i++)
- printf("at %d: found \"%c\", expected \"%c\"\n",
- static_cast<int>(i), jsongen[i], json[i]);
+ TEST_OUTPUT_LINE("at %d: found \"%c\", expected \"%c\"\n",
+ static_cast<int>(i), jsongen[i], json[i]);
break;
}
}
TEST_NOTNULL(NULL);
}
- printf("%dk schema tested with %dk of json\n",
- static_cast<int>(schema.length() / 1024),
- static_cast<int>(json.length() / 1024));
+ TEST_OUTPUT_LINE("%dk schema tested with %dk of json\n",
+ static_cast<int>(schema.length() / 1024),
+ static_cast<int>(json.length() / 1024));
}
// Test that parser errors are actually generated.
@@ -1526,18 +1529,20 @@ void ConformTest() {
flatbuffers::Parser parser;
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;
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_conform("table T { A:byte; }", "types differ for field");
- test_conform("table T { B:int; A:int; }", "offsets differ for field");
- test_conform("table T { A:int = 1; }", "defaults differ for field");
- test_conform("table T { B:float; }", "field renamed to different type");
- test_conform("enum E:byte { B, A }", "values differ for enum");
+ test_conform(parser, "table T { A:byte; }", "types differ for field");
+ test_conform(parser, "table T { B:int; A:int; }", "offsets differ for field");
+ test_conform(parser, "table T { A:int = 1; }", "defaults differ for field");
+ test_conform(parser, "table T { B:float; }",
+ "field renamed to different type");
+ test_conform(parser, "enum E:byte { B, A }", "values differ for enum");
}
void ParseProtoBufAsciiTest() {
@@ -1566,6 +1571,8 @@ void FlexBuffersTest() {
// Write the equivalent of:
// { 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.Vector("vec", [&]() {
slb += -100; // Equivalent to slb.Add(-100) or slb.Int(-100);
@@ -1581,9 +1588,27 @@ void FlexBuffersTest() {
});
});
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++)
- printf("%d ", slb.GetBuffer().data()[i]);
+ printf("%d ", flatbuffers::vector_data(slb.GetBuffer())[i]);
printf("\n");
auto map = flexbuffers::GetRoot(slb.GetBuffer()).AsMap();
@@ -1641,7 +1666,11 @@ int main(int /*argc*/, const char * /*argv*/[]) {
std::string rawbuf;
auto flatbuf1 = CreateFlatBufferTest(rawbuf);
+#if !defined(FLATBUFFERS_CPP98_STL)
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()),
rawbuf.length());
AccessFlatBufferTest(flatbuf.data(), flatbuf.size());
@@ -1692,4 +1721,3 @@ int main(int /*argc*/, const char * /*argv*/[]) {
return 1;
}
}
-
diff --git a/tests/union_vector/union_vector_generated.h b/tests/union_vector/union_vector_generated.h
index 98f96615..8758ad49 100644
--- a/tests/union_vector/union_vector_generated.h
+++ b/tests/union_vector/union_vector_generated.h
@@ -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) {
(void)_rehasher;
(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;
return CreateAttacker(
_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) {
(void)_rehasher;
(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 = _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 = _o->characters.size() ? _fbb.CreateVector<flatbuffers::Offset<void>>(_o->characters.size(), [&](size_t i) { return _o->characters[i].Pack(_fbb, _rehasher); }) : 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, _VectorArgs *__va) { return __va->__o->characters[i].Pack(*__va->__fbb, __va->__rehasher); }, &_va) : 0;
return CreateMovie(
_fbb,
_main_character_type,
@@ -602,10 +604,10 @@ inline void FinishMovieBuffer(
fbb.Finish(root, MovieIdentifier());
}
-inline std::unique_ptr<MovieT> UnPackMovie(
+inline flatbuffers::unique_ptr<MovieT> UnPackMovie(
const void *buf,
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_