mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-06 21:37:36 +00:00
Merge branch 'master' into master
This commit is contained in:
3
.bazelrc
3
.bazelrc
@@ -1 +1,4 @@
|
||||
# We cannot use "common" here because the "version" command doesn't support
|
||||
# --deleted_packages. We need to specify it for both build and query instead.
|
||||
build --deleted_packages=tests/ts/bazel_repository_test_dir
|
||||
query --deleted_packages=tests/ts/bazel_repository_test_dir
|
||||
|
||||
2
.github/labeler.yml
vendored
2
.github/labeler.yml
vendored
@@ -48,11 +48,11 @@ java:
|
||||
kotlin:
|
||||
- '**/*.kt'
|
||||
- src/idl_gen_kotlin.cpp
|
||||
- src/idl_gen_kotlin_kmp.cpp
|
||||
|
||||
lua:
|
||||
- '**/*.lua'
|
||||
- lua/**/*
|
||||
- src/idl_gen_lua.cpp
|
||||
- src/bfbs_gen_lua.cpp
|
||||
|
||||
lobster:
|
||||
|
||||
50
.github/workflows/build.yml
vendored
50
.github/workflows/build.yml
vendored
@@ -76,6 +76,28 @@ jobs:
|
||||
- name: build
|
||||
run: make -j
|
||||
|
||||
build-linux-out-of-source:
|
||||
name: Build Linux with out-of-source build location
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: make build directory
|
||||
run: mkdir build
|
||||
- name: cmake
|
||||
working-directory: build
|
||||
run: >
|
||||
CXX=clang++-12 cmake .. -G "Unix Makefiles" -DFLATBUFFERS_STRICT_MODE=ON
|
||||
-DFLATBUFFERS_BUILD_CPP17=ON -DFLATBUFFERS_CPP_STD=17
|
||||
- name: build
|
||||
working-directory: build
|
||||
run: make -j
|
||||
- name: test
|
||||
working-directory: build
|
||||
run: pwd && ./flattests
|
||||
- name: test C++17
|
||||
working-directory: build
|
||||
run: ./flattests_cpp17
|
||||
|
||||
build-linux-cpp-std:
|
||||
name: Build Linux C++
|
||||
runs-on: ubuntu-latest
|
||||
@@ -400,9 +422,14 @@ jobs:
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- name: Build flatc
|
||||
run: |
|
||||
cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF .
|
||||
make -j
|
||||
echo "${PWD}" >> $GITHUB_PATH
|
||||
- name: Build
|
||||
working-directory: kotlin
|
||||
run: ./gradlew clean iosX64Test macosX64Test
|
||||
run: ./gradlew clean iosSimulatorArm64Test macosX64Test macosArm64Test
|
||||
|
||||
build-kotlin-linux:
|
||||
name: Build Kotlin Linux
|
||||
@@ -415,6 +442,11 @@ jobs:
|
||||
distribution: 'temurin'
|
||||
java-version: '11'
|
||||
- uses: gradle/wrapper-validation-action@v1.0.5
|
||||
- name: Build flatc
|
||||
run: |
|
||||
cmake -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF .
|
||||
make -j
|
||||
echo "${PWD}" >> $GITHUB_PATH
|
||||
- name: Build
|
||||
working-directory: kotlin
|
||||
# we are using docker's version of gradle
|
||||
@@ -422,20 +454,32 @@ jobs:
|
||||
# gradlew
|
||||
run: gradle jvmMainClasses jvmTest jsTest jsBrowserTest
|
||||
|
||||
build-rust:
|
||||
name: Build Rust
|
||||
build-rust-linux:
|
||||
name: Build Rust Linux
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: test
|
||||
working-directory: tests
|
||||
run: bash RustTest.sh
|
||||
|
||||
build-rust-windows:
|
||||
name: Build Rust Windows
|
||||
runs-on: windows-2019
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: test
|
||||
working-directory: tests
|
||||
run: ./RustTest.bat
|
||||
|
||||
build-python:
|
||||
name: Build Python
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: flatc
|
||||
# FIXME: make test script not rely on flatc
|
||||
run: cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DFLATBUFFERS_BUILD_TESTS=OFF -DFLATBUFFERS_INSTALL=OFF -DFLATBUFFERS_BUILD_FLATLIB=OFF -DFLATBUFFERS_BUILD_FLATHASH=OFF -DFLATBUFFERS_STRICT_MODE=ON . && make -j
|
||||
- name: test
|
||||
working-directory: tests
|
||||
run: bash PythonTest.sh
|
||||
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -151,3 +151,5 @@ flatbuffers.pc
|
||||
# https://cmake.org/cmake/help/latest/module/FetchContent.html#variable:FETCHCONTENT_BASE_DIR
|
||||
cmake-build-debug/
|
||||
_deps/
|
||||
**/.gradle/**
|
||||
kotlin/**/generated
|
||||
|
||||
52
CHANGELOG.md
52
CHANGELOG.md
@@ -4,6 +4,58 @@ All major or breaking changes will be documented in this file, as well as any
|
||||
new features that should be highlighted. Minor fixes or improvements are not
|
||||
necessarily listed.
|
||||
|
||||
## [23.5.26 (May 26 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.26)
|
||||
|
||||
* Mostly bug fixing for 64-bit support
|
||||
* Adds support for specifying underling type of unions in C++ and TS/JS (#7954)
|
||||
|
||||
## [23.5.9 (May 9 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.9)
|
||||
|
||||
* 64-bit support for C++ (#7935)
|
||||
|
||||
## [23.5.8 (May 8 2023)](https://github.com/google/flatbuffers/releases/tag/v23.5.8)
|
||||
|
||||
* add key_field to compiled tests
|
||||
* Add golden language directory
|
||||
* Rework cmake flatc codegeneration (#7938)
|
||||
* remove defining generated files in test srcs
|
||||
* Add binary schema reflection (#7932)
|
||||
* Migrate from rules_nodejs to rules_js/rules_ts (take 2) (#7928)
|
||||
* `flat_buffers.dart`: mark const variable finals for internal Dart linters
|
||||
* fixed some windows warnings (#7929)
|
||||
* inject no long for FBS generation to remove logs in flattests (#7926)
|
||||
* Revert "Migrate from rules_nodejs to rules_js/rules_ts (#7923)" (#7927)
|
||||
* Migrate from rules_nodejs to rules_js/rules_ts (#7923)
|
||||
* Only generate @kotlin.ExperimentalUnsigned annotation on create*Vector methods having an unsigned array type parameter. (#7881)
|
||||
* additional check for absl::string_view availability (#7897)
|
||||
* Optionally generate Python type annotations (#7858)
|
||||
* Replace deprecated command with environment file (#7921)
|
||||
* drop glibc from runtime dependencies (#7906)
|
||||
* Make JSON supporting advanced union features (#7869)
|
||||
* Allow to use functions from `BuildFlatBuffers.cmake` from a flatbuffers installation installed with CMake. (#7912)
|
||||
* TS/JS: Use TypeError instead of Error when appropriate (#7910)
|
||||
* Go: make generated code more compliant to "go fmt" (#7907)
|
||||
* Support file_identifier in Go (#7904)
|
||||
* Optionally generate type prefixes and suffixes for python code (#7857)
|
||||
* Go: add test for FinishWithFileIdentifier (#7905)
|
||||
* Fix go_sample.sh (#7903)
|
||||
* [TS/JS] Upgrade dependencies (#7889)
|
||||
* Add a FileWriter interface (#7821)
|
||||
* TS/JS: Use minvalue from enum if not found (#7888)
|
||||
* [CS] Verifier (#7850)
|
||||
* README.md: PyPI case typo (#7880)
|
||||
* Update go documentation link to point to root module (#7879)
|
||||
* use Bool for flatbuffers bool instead of Byte (#7876)
|
||||
* fix using null string in vector (#7872)
|
||||
* Add `flatbuffers-64` branch to CI for pushes
|
||||
* made changes to the rust docs so they would compile. new_with_capacity is deprecated should use with_capacity, get_root_as_monster should be root_as_monster (#7871)
|
||||
* Adding comment for code clarification (#7856)
|
||||
* ToCamelCase() when kLowerCamel now converts first char to lower. (#7838)
|
||||
* Fix help output for --java-checkerframework (#7854)
|
||||
* Update filename to README.md and improve formatting (#7855)
|
||||
* Update stale.yml
|
||||
* Updated remaining usages of LICENSE.txt
|
||||
|
||||
## [23.3.3 (Mar 3 2023)](https://github.com/google/flatbuffers/releases/tag/v23.3.3)
|
||||
|
||||
* Refactoring of `flatc` generators to use an interface (#7797).
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
set(VERSION_MAJOR 23)
|
||||
set(VERSION_MINOR 3)
|
||||
set(VERSION_PATCH 3)
|
||||
set(VERSION_MINOR 5)
|
||||
set(VERSION_PATCH 26)
|
||||
set(VERSION_COMMIT 0)
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
|
||||
|
||||
220
CMakeLists.txt
220
CMakeLists.txt
@@ -21,7 +21,7 @@ option(FLATBUFFERS_BUILD_FLATC "Enable the build of the flatbuffers compiler"
|
||||
ON)
|
||||
option(FLATBUFFERS_STATIC_FLATC "Build flatbuffers compiler with -static flag"
|
||||
OFF)
|
||||
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" ON)
|
||||
option(FLATBUFFERS_BUILD_FLATHASH "Enable the build of flathash" OFF)
|
||||
option(FLATBUFFERS_BUILD_BENCHMARKS "Enable the build of flatbenchmark."
|
||||
OFF)
|
||||
option(FLATBUFFERS_BUILD_GRPCTEST "Enable the build of grpctest" OFF)
|
||||
@@ -160,13 +160,13 @@ set(FlatBuffers_Compiler_SRCS
|
||||
src/idl_gen_csharp.cpp
|
||||
src/idl_gen_dart.cpp
|
||||
src/idl_gen_kotlin.cpp
|
||||
src/idl_gen_kotlin_kmp.cpp
|
||||
src/idl_gen_go.cpp
|
||||
src/idl_gen_java.cpp
|
||||
src/idl_gen_ts.cpp
|
||||
src/idl_gen_php.cpp
|
||||
src/idl_gen_python.cpp
|
||||
src/idl_gen_lobster.cpp
|
||||
src/idl_gen_lua.cpp
|
||||
src/idl_gen_rust.cpp
|
||||
src/idl_gen_fbs.cpp
|
||||
src/idl_gen_grpc.cpp
|
||||
@@ -234,31 +234,10 @@ set(FlatBuffers_Tests_SRCS
|
||||
tests/native_type_test_impl.cpp
|
||||
tests/alignment_test.h
|
||||
tests/alignment_test.cpp
|
||||
tests/64bit/offset64_test.h
|
||||
tests/64bit/offset64_test.cpp
|
||||
include/flatbuffers/code_generators.h
|
||||
src/code_generators.cpp
|
||||
# file generate by running compiler on tests/monster_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||
# file generate by running compiler on namespace_test/namespace_test1.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test1_generated.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/namespace_test/namespace_test2_generated.h
|
||||
# file generate by running compiler on union_vector/union_vector.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/union_vector/union_vector_generated.h
|
||||
# file generate by running compiler on tests/arrays_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/arrays_test_generated.h
|
||||
# file generate by running compiler on tests/native_type_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/native_type_test_generated.h
|
||||
# file generate by running compiler on tests/monster_extra.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_extra_generated.h
|
||||
# file generate by running compiler on tests/monster_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_bfbs_generated.h
|
||||
# file generate by running compiler on tests/optional_scalars.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/optional_scalars_generated.h
|
||||
# file generate by running compiler on tests/native_inline_table_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/native_inline_table_test_generated.h
|
||||
# file generate by running compiler on tests/alignment_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/alignment_test_generated.h
|
||||
# file generate by running compiler on tests/key_field/key_field_sample.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/key_field/key_field_sample_generated.h
|
||||
)
|
||||
|
||||
set(FlatBuffers_Tests_CPP17_SRCS
|
||||
@@ -266,32 +245,20 @@ set(FlatBuffers_Tests_CPP17_SRCS
|
||||
tests/test_assert.h
|
||||
tests/test_assert.cpp
|
||||
tests/cpp17/test_cpp17.cpp
|
||||
# file generate by running compiler on tests/monster_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/monster_test_generated.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/cpp17/generated_cpp17/optional_scalars_generated.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/optional_scalars_generated.h
|
||||
)
|
||||
|
||||
set(FlatBuffers_Sample_Binary_SRCS
|
||||
include/flatbuffers/flatbuffers.h
|
||||
samples/sample_binary.cpp
|
||||
# file generated by running compiler on samples/monster.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||
)
|
||||
|
||||
set(FlatBuffers_Sample_Text_SRCS
|
||||
${FlatBuffers_Library_SRCS}
|
||||
samples/sample_text.cpp
|
||||
# file generated by running compiler on samples/monster.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||
)
|
||||
|
||||
set(FlatBuffers_Sample_BFBS_SRCS
|
||||
${FlatBuffers_Library_SRCS}
|
||||
samples/sample_bfbs.cpp
|
||||
# file generated by running compiler on samples/monster.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/samples/monster_generated.h
|
||||
)
|
||||
|
||||
set(FlatBuffers_GRPCTest_SRCS
|
||||
@@ -307,8 +274,6 @@ set(FlatBuffers_GRPCTest_SRCS
|
||||
tests/test_builder.cpp
|
||||
grpc/tests/grpctest.cpp
|
||||
grpc/tests/message_builder_test.cpp
|
||||
# file generate by running compiler on tests/monster_test.fbs
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests/monster_test_generated.h
|
||||
)
|
||||
|
||||
# TODO(dbaileychess): Figure out how this would now work. I posted a question on
|
||||
@@ -523,145 +488,89 @@ if(FLATBUFFERS_BUILD_SHAREDLIB)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Global list of generated files.
|
||||
# Use the global property to be independent of PARENT_SCOPE.
|
||||
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
|
||||
|
||||
function(get_generated_output generated_files)
|
||||
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
|
||||
set(${generated_files} ${tmp} PARENT_SCOPE)
|
||||
endfunction(get_generated_output)
|
||||
|
||||
function(register_generated_output file_name)
|
||||
get_property(tmp GLOBAL PROPERTY FBS_GENERATED_OUTPUTS)
|
||||
list(APPEND tmp ${file_name})
|
||||
set_property(GLOBAL PROPERTY FBS_GENERATED_OUTPUTS ${tmp})
|
||||
endfunction(register_generated_output)
|
||||
|
||||
function(compile_flatbuffers_schema_to_cpp_opt SRC_FBS OPT)
|
||||
if(FLATBUFFERS_BUILD_LEGACY)
|
||||
set(OPT ${OPT};--cpp-std c++0x)
|
||||
else()
|
||||
# --cpp-std is defined by flatc default settings.
|
||||
endif()
|
||||
message(STATUS "`${SRC_FBS}`: add generation of C++ code with '${OPT}'")
|
||||
function(compile_schema SRC_FBS OPT OUT_GEN_FILE)
|
||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||
string(REGEX REPLACE "\\.fbs$" "_generated.h" GEN_HEADER ${SRC_FBS})
|
||||
add_custom_command(
|
||||
OUTPUT ${GEN_HEADER}
|
||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
|
||||
--cpp --gen-mutable --gen-object-api --reflect-names
|
||||
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||
${OPT}
|
||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||
-o "${SRC_FBS_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||
DEPENDS flatc
|
||||
COMMENT "Run generation: '${GEN_HEADER}'")
|
||||
register_generated_output(${GEN_HEADER})
|
||||
${OPT}
|
||||
-o "${SRC_FBS_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||
DEPENDS flatc ${SRC_FBS}
|
||||
COMMENT "flatc generation: `${SRC_FBS}` -> `${GEN_HEADER}`"
|
||||
)
|
||||
set(${OUT_GEN_FILE} ${GEN_HEADER} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
function(compile_flatbuffers_schema_to_cpp SRC_FBS)
|
||||
compile_flatbuffers_schema_to_cpp_opt(${SRC_FBS} "--no-includes;--gen-compare")
|
||||
function(compile_schema_for_test SRC_FBS OPT)
|
||||
compile_schema("${SRC_FBS}" "${OPT}" GEN_FILE)
|
||||
target_sources(flattests PRIVATE ${GEN_FILE})
|
||||
endfunction()
|
||||
|
||||
function(compile_flatbuffers_schema_to_binary SRC_FBS)
|
||||
message(STATUS "`${SRC_FBS}`: add generation of binary (.bfbs) schema")
|
||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||
string(REGEX REPLACE "\\.fbs$" ".bfbs" GEN_BINARY_SCHEMA ${SRC_FBS})
|
||||
# For details about flags see generate_code.py
|
||||
add_custom_command(
|
||||
OUTPUT ${GEN_BINARY_SCHEMA}
|
||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
|
||||
-b --schema --bfbs-comments --bfbs-builtins
|
||||
--bfbs-filenames "${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS_DIR}"
|
||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||
-o "${SRC_FBS_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||
DEPENDS flatc
|
||||
COMMENT "Run generation: '${GEN_BINARY_SCHEMA}'")
|
||||
register_generated_output(${GEN_BINARY_SCHEMA})
|
||||
endfunction()
|
||||
|
||||
function(compile_flatbuffers_schema_to_embedded_binary SRC_FBS OPT)
|
||||
if(FLATBUFFERS_BUILD_LEGACY)
|
||||
set(OPT ${OPT};--cpp-std c++0x)
|
||||
else()
|
||||
# --cpp-std is defined by flatc default settings.
|
||||
endif()
|
||||
message(STATUS "`${SRC_FBS}`: add generation of C++ embedded binary schema code with '${OPT}'")
|
||||
get_filename_component(SRC_FBS_DIR ${SRC_FBS} PATH)
|
||||
string(REGEX REPLACE "\\.fbs$" "_bfbs_generated.h" GEN_BFBS_HEADER ${SRC_FBS})
|
||||
# For details about flags see generate_code.py
|
||||
add_custom_command(
|
||||
OUTPUT ${GEN_BFBS_HEADER}
|
||||
COMMAND "${FLATBUFFERS_FLATC_EXECUTABLE}"
|
||||
--cpp --gen-mutable --gen-object-api --reflect-names
|
||||
--cpp-ptr-type flatbuffers::unique_ptr # Used to test with C++98 STLs
|
||||
${OPT}
|
||||
--bfbs-comments --bfbs-builtins --bfbs-gen-embed
|
||||
--bfbs-filenames ${SRC_FBS_DIR}
|
||||
-I "${CMAKE_CURRENT_SOURCE_DIR}/tests/include_test"
|
||||
-o "${SRC_FBS_DIR}"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/${SRC_FBS}"
|
||||
DEPENDS flatc
|
||||
COMMENT "Run generation: '${GEN_BFBS_HEADER}'")
|
||||
register_generated_output(${GEN_BFBS_HEADER})
|
||||
function(compile_schema_for_samples SRC_FBS OPT)
|
||||
compile_schema("${SRC_FBS}" "${OPT}" GEN_FILE)
|
||||
target_sources(flatsample PRIVATE ${GEN_FILE})
|
||||
endfunction()
|
||||
|
||||
if(FLATBUFFERS_BUILD_TESTS)
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/tests" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/samples" DESTINATION "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
# TODO Add (monster_test.fbs monsterdata_test.json)->monsterdata_test.mon
|
||||
compile_flatbuffers_schema_to_cpp(tests/monster_test.fbs)
|
||||
compile_flatbuffers_schema_to_binary(tests/monster_test.fbs)
|
||||
compile_flatbuffers_schema_to_cpp_opt(tests/namespace_test/namespace_test1.fbs "--no-includes;--gen-compare;--gen-name-strings")
|
||||
compile_flatbuffers_schema_to_cpp_opt(tests/namespace_test/namespace_test2.fbs "--no-includes;--gen-compare;--gen-name-strings")
|
||||
compile_flatbuffers_schema_to_cpp_opt(tests/union_vector/union_vector.fbs "--no-includes;--gen-compare;")
|
||||
compile_flatbuffers_schema_to_cpp(tests/optional_scalars.fbs)
|
||||
compile_flatbuffers_schema_to_cpp_opt(tests/native_type_test.fbs "")
|
||||
compile_flatbuffers_schema_to_cpp_opt(tests/arrays_test.fbs "--scoped-enums;--gen-compare")
|
||||
compile_flatbuffers_schema_to_binary(tests/arrays_test.fbs)
|
||||
compile_flatbuffers_schema_to_embedded_binary(tests/monster_test.fbs "--no-includes;--gen-compare")
|
||||
compile_flatbuffers_schema_to_cpp(tests/native_inline_table_test.fbs "--gen-compare")
|
||||
compile_flatbuffers_schema_to_cpp(tests/alignment_test.fbs "--gen-compare")
|
||||
compile_flatbuffers_schema_to_cpp(tests/key_field/key_field_sample.fbs)
|
||||
if(NOT (MSVC AND (MSVC_VERSION LESS 1900)))
|
||||
compile_flatbuffers_schema_to_cpp(tests/monster_extra.fbs) # Test floating-point NAN/INF.
|
||||
endif()
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/tests)
|
||||
add_executable(flattests ${FlatBuffers_Tests_SRCS})
|
||||
target_link_libraries(flattests PRIVATE $<BUILD_INTERFACE:ProjectConfig>)
|
||||
target_include_directories(flattests PUBLIC
|
||||
# Ideally everything is fully qualified from the root directories
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
# TODO(derekbailey): update includes to fully qualify src/ and tests/
|
||||
src
|
||||
tests
|
||||
${CMAKE_CURRENT_BINARY_DIR}/tests
|
||||
)
|
||||
|
||||
add_dependencies(flattests generated_code)
|
||||
# Have tests load data from the source directory, not the build directory.
|
||||
add_definitions(-DFLATBUFFERS_TEST_PATH_PREFIX=${CMAKE_CURRENT_SOURCE_DIR}/)
|
||||
|
||||
# The flattest target needs some generated files
|
||||
SET(FLATC_OPT --cpp --gen-mutable --gen-object-api --reflect-names)
|
||||
SET(FLATC_OPT_COMP ${FLATC_OPT};--gen-compare)
|
||||
SET(FLATC_OPT_SCOPED_ENUMS ${FLATC_OPT_COMP};--scoped-enums)
|
||||
|
||||
compile_schema_for_test(tests/alignment_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/arrays_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
|
||||
compile_schema_for_test(tests/native_inline_table_test.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/native_type_test.fbs "${FLATC_OPT}")
|
||||
compile_schema_for_test(tests/key_field/key_field_sample.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/64bit/test_64bit.fbs "${FLATC_OPT_COMP};--bfbs-gen-embed")
|
||||
compile_schema_for_test(tests/64bit/evolution/v1.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/64bit/evolution/v2.fbs "${FLATC_OPT_COMP}")
|
||||
compile_schema_for_test(tests/union_underlying_type_test.fbs "${FLATC_OPT_SCOPED_ENUMS}")
|
||||
|
||||
if(FLATBUFFERS_CODE_SANITIZE)
|
||||
add_fsanitize_to_target(flattests ${FLATBUFFERS_CODE_SANITIZE})
|
||||
endif()
|
||||
|
||||
compile_flatbuffers_schema_to_cpp(samples/monster.fbs)
|
||||
compile_flatbuffers_schema_to_binary(samples/monster.fbs)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_BINARY_DIR}/samples)
|
||||
|
||||
add_executable(flatsamplebinary ${FlatBuffers_Sample_Binary_SRCS})
|
||||
target_link_libraries(flatsamplebinary PRIVATE $<BUILD_INTERFACE:ProjectConfig>)
|
||||
add_dependencies(flatsamplebinary generated_code)
|
||||
|
||||
add_executable(flatsampletext ${FlatBuffers_Sample_Text_SRCS})
|
||||
target_link_libraries(flatsampletext PRIVATE $<BUILD_INTERFACE:ProjectConfig>)
|
||||
add_dependencies(flatsampletext generated_code)
|
||||
|
||||
add_executable(flatsamplebfbs ${FlatBuffers_Sample_BFBS_SRCS})
|
||||
target_link_libraries(flatsamplebfbs PRIVATE $<BUILD_INTERFACE:ProjectConfig>)
|
||||
add_dependencies(flatsamplebfbs generated_code)
|
||||
|
||||
# Add a library so there is a single target that the generated samples can
|
||||
# link too.
|
||||
add_library(flatsample INTERFACE)
|
||||
|
||||
# Since flatsample has no sources, we have to explicitly set the linker lang.
|
||||
set_target_properties(flatsample PROPERTIES LINKER_LANGUAGE CXX)
|
||||
|
||||
compile_schema_for_samples(samples/monster.fbs "${FLATC_OPT_COMP}")
|
||||
|
||||
target_link_libraries(flatsamplebinary PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample)
|
||||
target_link_libraries(flatsampletext PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample)
|
||||
target_link_libraries(flatsamplebfbs PRIVATE $<BUILD_INTERFACE:ProjectConfig> flatsample)
|
||||
|
||||
if(FLATBUFFERS_BUILD_CPP17)
|
||||
# Don't generate header for flattests_cpp17 target.
|
||||
# This target uses "generated_cpp17/monster_test_generated.h"
|
||||
add_executable(flattests_cpp17 ${FlatBuffers_Tests_CPP17_SRCS})
|
||||
add_dependencies(flattests_cpp17 generated_code)
|
||||
target_link_libraries(flattests_cpp17 PRIVATE $<BUILD_INTERFACE:ProjectConfig>)
|
||||
target_include_directories(flattests_cpp17 PUBLIC src tests)
|
||||
target_compile_features(flattests_cpp17 PRIVATE cxx_std_17) # requires cmake 3.8
|
||||
|
||||
if(FLATBUFFERS_CODE_SANITIZE)
|
||||
@@ -685,7 +594,6 @@ if(FLATBUFFERS_BUILD_GRPCTEST)
|
||||
find_package(protobuf CONFIG REQUIRED)
|
||||
find_package(gRPC CONFIG REQUIRED)
|
||||
add_executable(grpctest ${FlatBuffers_GRPCTest_SRCS})
|
||||
add_dependencies(grpctest generated_code)
|
||||
target_link_libraries(grpctext
|
||||
PRIVATE
|
||||
$<BUILD_INTERFACE:ProjectConfig>
|
||||
@@ -778,16 +686,6 @@ if(FLATBUFFERS_BUILD_TESTS)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# This target is sync-barrier.
|
||||
# Other generate-dependent targets can depend on 'generated_code' only.
|
||||
get_generated_output(fbs_generated)
|
||||
if(fbs_generated)
|
||||
# message(STATUS "Add generated_code target with files:${fbs_generated}")
|
||||
add_custom_target(generated_code
|
||||
DEPENDS ${fbs_generated}
|
||||
COMMENT "All generated files were updated.")
|
||||
endif()
|
||||
|
||||
include(CMake/BuildFlatBuffers.cmake)
|
||||
|
||||
if(UNIX)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'FlatBuffers'
|
||||
s.version = '23.3.3'
|
||||
s.version = '23.5.26'
|
||||
s.summary = 'FlatBuffers: Memory Efficient Serialization Library'
|
||||
|
||||
s.description = "FlatBuffers is a cross platform serialization library architected for
|
||||
|
||||
43
README.md
43
README.md
@@ -14,6 +14,47 @@
|
||||
**FlatBuffers** is a cross platform serialization library architected for
|
||||
maximum memory efficiency. It allows you to directly access serialized data without parsing/unpacking it first, while still having great forwards/backwards compatibility.
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Build the compiler for flatbuffers (`flatc`)
|
||||
|
||||
Use `cmake` to create the build files for your platform and then perform the compliation (Linux example).
|
||||
|
||||
```
|
||||
cmake -G "Unix Makefiles"
|
||||
make -j
|
||||
```
|
||||
|
||||
2. Define your flatbuffer schema (`.fbs`)
|
||||
|
||||
Write the [schema](https://flatbuffers.dev/flatbuffers_guide_writing_schema.html) to define the data you want to serialize. See [monster.fbs](https://github.com/google/flatbuffers/blob/master/samples/monster.fbs) for an example.
|
||||
|
||||
3. Generate code for your language(s)
|
||||
|
||||
Use the `flatc` compiler to take your schema and generate language-specific code:
|
||||
|
||||
```
|
||||
./flatc --cpp --rust monster.fbs
|
||||
```
|
||||
|
||||
Which generates `monster_generated.h` and `monster_generated.rs` files.
|
||||
|
||||
4. Serialize data
|
||||
|
||||
Use the generated code, as well as the `FlatBufferBuilder` to construct your serialized buffer. ([`C++` example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.cpp#L24-L56))
|
||||
|
||||
5. Transmit/store/save Buffer
|
||||
|
||||
Use your serialized buffer however you want. Send it to someone, save it for later, etc...
|
||||
|
||||
6. Read the data
|
||||
|
||||
Use the generated accessors to read the data from the serialized buffer.
|
||||
|
||||
It doesn't need to be the same language/schema version, FlatBuffers ensures the data is readable across languages and schema versions. See the [`Rust` example](https://github.com/google/flatbuffers/blob/master/samples/sample_binary.rs#L92-L106) reading the data written by `C++`.
|
||||
|
||||
## Documentation
|
||||
|
||||
**Go to our [landing page][] to browse our documentation.**
|
||||
|
||||
## Supported operating systems
|
||||
@@ -46,7 +87,7 @@ Code generation and runtime libraries for many popular languages.
|
||||
|
||||
## Versioning
|
||||
|
||||
FlatBuffers does not follow traditional Semver versioning (see [rationale](https://github.com/google/flatbuffers/wiki/Versioning)) but rather uses a format of the date of the release.
|
||||
FlatBuffers does not follow traditional SemVer versioning (see [rationale](https://github.com/google/flatbuffers/wiki/Versioning)) but rather uses a format of the date of the release.
|
||||
|
||||
## Contribution
|
||||
|
||||
|
||||
@@ -148,6 +148,7 @@ esbuild_register_toolchains(
|
||||
http_file(
|
||||
name = "bazel_linux_x86_64",
|
||||
downloaded_file_path = "bazel",
|
||||
executable = True,
|
||||
sha256 = "e89747d63443e225b140d7d37ded952dacea73aaed896bca01ccd745827c6289",
|
||||
urls = [
|
||||
"https://github.com/bazelbuild/bazel/releases/download/6.1.2/bazel-6.1.2-linux-x86_64",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
</natures>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1677235311958</id>
|
||||
<id>1672434305228</id>
|
||||
<name></name>
|
||||
<type>30</type>
|
||||
<matcher>
|
||||
|
||||
@@ -48,7 +48,6 @@ find_library( # Sets the name of the path variable.
|
||||
target_link_libraries( # Specifies the target library.
|
||||
native-lib
|
||||
flatbuffers
|
||||
flatbuffers_tests
|
||||
# Links the target library to the log library
|
||||
# included in the NDK.
|
||||
${log-lib} )
|
||||
|
||||
@@ -48,26 +48,9 @@ set(FlatBuffers_Library_SRCS
|
||||
${FLATBUFFERS_SRC}/src/code_generators.cpp
|
||||
)
|
||||
|
||||
set(FlatBuffers_Test_SRCS
|
||||
${FLATBUFFERS_SRC}/tests/test.cpp
|
||||
${FLATBUFFERS_SRC}/tests/test_assert.h
|
||||
${FLATBUFFERS_SRC}/tests/test_builder.h
|
||||
${FLATBUFFERS_SRC}/tests/test_assert.cpp
|
||||
${FLATBUFFERS_SRC}/tests/test_builder.cpp
|
||||
${FLATBUFFERS_SRC}/tests/native_type_test_impl.h
|
||||
${FLATBUFFERS_SRC}/tests/native_type_test_impl.cpp
|
||||
)
|
||||
|
||||
add_library( # Sets the name of the library.
|
||||
flatbuffers
|
||||
|
||||
${FlatBuffers_Library_SRCS}
|
||||
${FlatBuffers_Test_SRCS}
|
||||
${Generated_SRCS}
|
||||
)
|
||||
|
||||
add_library( # Sets the name of the library.
|
||||
flatbuffers_tests
|
||||
|
||||
${FlatBuffers_Test_SRCS}
|
||||
)
|
||||
|
||||
@@ -57,7 +57,7 @@ class Animal : Table() {
|
||||
return if(o != 0) bb.getShort(o + bb_pos).toUShort() else 0u
|
||||
}
|
||||
companion object {
|
||||
fun validateVersion() = Constants.FLATBUFFERS_23_3_3()
|
||||
fun validateVersion() = Constants.FLATBUFFERS_23_5_26()
|
||||
fun getRootAsAnimal(_bb: ByteBuffer): Animal = getRootAsAnimal(_bb, Animal())
|
||||
fun getRootAsAnimal(_bb: ByteBuffer, obj: Animal): Animal {
|
||||
_bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
|
||||
@@ -87,6 +87,7 @@ def flatbuffer_library_public(
|
||||
optionally a Fileset([reflection_name]) with all generated reflection
|
||||
binaries.
|
||||
"""
|
||||
reflection_include_paths = include_paths
|
||||
if include_paths == None:
|
||||
include_paths = default_include_paths(flatc_path)
|
||||
include_paths_cmd = ["-I %s" % (s) for s in include_paths]
|
||||
@@ -124,13 +125,16 @@ def flatbuffer_library_public(
|
||||
**kwargs
|
||||
)
|
||||
if reflection_name:
|
||||
if reflection_include_paths == None:
|
||||
reflection_include_paths = default_include_paths(TRUE_FLATC_PATH)
|
||||
reflection_include_paths_cmd = ["-I %s" % (s) for s in reflection_include_paths]
|
||||
reflection_genrule_cmd = " ".join([
|
||||
"SRCS=($(SRCS));",
|
||||
"for f in $${SRCS[@]:0:%s}; do" % len(srcs),
|
||||
"$(location %s)" % (TRUE_FLATC_PATH),
|
||||
"-b --schema",
|
||||
" ".join(flatc_args),
|
||||
" ".join(include_paths_cmd),
|
||||
" ".join(reflection_include_paths_cmd),
|
||||
language_flag,
|
||||
output_directory,
|
||||
"$$f;",
|
||||
@@ -165,6 +169,7 @@ def flatbuffer_cc_library(
|
||||
name,
|
||||
srcs,
|
||||
srcs_filegroup_name = "",
|
||||
outs = [],
|
||||
out_prefix = "",
|
||||
deps = [],
|
||||
includes = [],
|
||||
@@ -185,6 +190,7 @@ def flatbuffer_cc_library(
|
||||
srcs_filegroup_name: Name of the output filegroup that holds srcs. Pass this
|
||||
filegroup into the `includes` parameter of any other
|
||||
flatbuffer_cc_library that depends on this one's schemas.
|
||||
outs: Additional outputs expected to be generated by flatc.
|
||||
out_prefix: Prepend this path to the front of all generated files. Usually
|
||||
is a directory name.
|
||||
deps: Optional, list of other flatbuffer_cc_library's to depend on. Cannot be specified
|
||||
@@ -232,7 +238,7 @@ def flatbuffer_cc_library(
|
||||
flatbuffer_library_public(
|
||||
name = srcs_lib,
|
||||
srcs = srcs,
|
||||
outs = output_headers,
|
||||
outs = outs + output_headers,
|
||||
language_flag = "-c",
|
||||
out_prefix = out_prefix,
|
||||
includes = includes,
|
||||
|
||||
@@ -304,7 +304,7 @@ class Builder {
|
||||
assert(_inVTable);
|
||||
// Prepare for writing the VTable.
|
||||
_prepare(_sizeofInt32, 1);
|
||||
var tableTail = _tail;
|
||||
final tableTail = _tail;
|
||||
// Prepare the size of the current table.
|
||||
final currentVTable = _currentVTable!;
|
||||
currentVTable.tableSize = tableTail - _currentTableEndTail;
|
||||
@@ -514,7 +514,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setUint32AtTail(tail, tail - value);
|
||||
tail -= _sizeofUint32;
|
||||
}
|
||||
@@ -529,7 +529,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setFloat64AtTail(tail, value);
|
||||
tail -= _sizeofFloat64;
|
||||
}
|
||||
@@ -544,7 +544,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setFloat32AtTail(tail, value);
|
||||
tail -= _sizeofFloat32;
|
||||
}
|
||||
@@ -559,7 +559,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setInt64AtTail(tail, value);
|
||||
tail -= _sizeofInt64;
|
||||
}
|
||||
@@ -574,7 +574,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setUint64AtTail(tail, value);
|
||||
tail -= _sizeofUint64;
|
||||
}
|
||||
@@ -589,7 +589,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setInt32AtTail(tail, value);
|
||||
tail -= _sizeofInt32;
|
||||
}
|
||||
@@ -604,7 +604,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setUint32AtTail(tail, value);
|
||||
tail -= _sizeofUint32;
|
||||
}
|
||||
@@ -619,7 +619,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setInt16AtTail(tail, value);
|
||||
tail -= _sizeofInt16;
|
||||
}
|
||||
@@ -634,7 +634,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setUint16AtTail(tail, value);
|
||||
tail -= _sizeofUint16;
|
||||
}
|
||||
@@ -654,7 +654,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setInt8AtTail(tail, value);
|
||||
tail -= _sizeofUint8;
|
||||
}
|
||||
@@ -669,7 +669,7 @@ class Builder {
|
||||
var tail = _tail;
|
||||
_setUint32AtTail(tail, values.length);
|
||||
tail -= _sizeofUint32;
|
||||
for (var value in values) {
|
||||
for (final value in values) {
|
||||
_setUint8AtTail(tail, value);
|
||||
tail -= _sizeofUint8;
|
||||
}
|
||||
@@ -777,17 +777,17 @@ class Builder {
|
||||
_maxAlign = size;
|
||||
}
|
||||
// Prepare amount of required space.
|
||||
var dataSize = size * count + additionalBytes;
|
||||
var alignDelta = (-(_tail + dataSize)) & (size - 1);
|
||||
var bufSize = alignDelta + dataSize;
|
||||
final dataSize = size * count + additionalBytes;
|
||||
final alignDelta = (-(_tail + dataSize)) & (size - 1);
|
||||
final bufSize = alignDelta + dataSize;
|
||||
// Ensure that we have the required amount of space.
|
||||
{
|
||||
var oldCapacity = _buf.lengthInBytes;
|
||||
final oldCapacity = _buf.lengthInBytes;
|
||||
if (_tail + bufSize > oldCapacity) {
|
||||
var desiredNewCapacity = (oldCapacity + bufSize) * 2;
|
||||
final desiredNewCapacity = (oldCapacity + bufSize) * 2;
|
||||
var deltaCapacity = desiredNewCapacity - oldCapacity;
|
||||
deltaCapacity += (-deltaCapacity) & (_maxAlign - 1);
|
||||
var newCapacity = oldCapacity + deltaCapacity;
|
||||
final newCapacity = oldCapacity + deltaCapacity;
|
||||
_buf = _allocator.resize(_buf, newCapacity, _tail, 0);
|
||||
}
|
||||
}
|
||||
@@ -1023,22 +1023,22 @@ abstract class Reader<T> {
|
||||
/// Read the value of the given [field] in the given [object].
|
||||
@pragma('vm:prefer-inline')
|
||||
T vTableGet(BufferContext object, int offset, int field, T defaultValue) {
|
||||
var fieldOffset = _vTableFieldOffset(object, offset, field);
|
||||
final fieldOffset = _vTableFieldOffset(object, offset, field);
|
||||
return fieldOffset == 0 ? defaultValue : read(object, offset + fieldOffset);
|
||||
}
|
||||
|
||||
/// Read the value of the given [field] in the given [object].
|
||||
@pragma('vm:prefer-inline')
|
||||
T? vTableGetNullable(BufferContext object, int offset, int field) {
|
||||
var fieldOffset = _vTableFieldOffset(object, offset, field);
|
||||
final fieldOffset = _vTableFieldOffset(object, offset, field);
|
||||
return fieldOffset == 0 ? null : read(object, offset + fieldOffset);
|
||||
}
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
int _vTableFieldOffset(BufferContext object, int offset, int field) {
|
||||
var vTableSOffset = object._getInt32(offset);
|
||||
var vTableOffset = offset - vTableSOffset;
|
||||
var vTableSize = object._getUint16(vTableOffset);
|
||||
final vTableSOffset = object._getInt32(offset);
|
||||
final vTableOffset = offset - vTableSOffset;
|
||||
final vTableSize = object._getUint16(vTableOffset);
|
||||
if (field >= vTableSize) return 0;
|
||||
return object._getUint16(vTableOffset + field);
|
||||
}
|
||||
@@ -1057,9 +1057,9 @@ class StringReader extends Reader<String> {
|
||||
@override
|
||||
@pragma('vm:prefer-inline')
|
||||
String read(BufferContext bc, int offset) {
|
||||
var strOffset = bc.derefObject(offset);
|
||||
var length = bc._getUint32(strOffset);
|
||||
var bytes = bc._asUint8List(strOffset + _sizeofUint32, length);
|
||||
final strOffset = bc.derefObject(offset);
|
||||
final length = bc._getUint32(strOffset);
|
||||
final bytes = bc._asUint8List(strOffset + _sizeofUint32, length);
|
||||
if (asciiOptimization && _isLatin(bytes)) {
|
||||
return String.fromCharCodes(bytes);
|
||||
}
|
||||
@@ -1068,7 +1068,7 @@ class StringReader extends Reader<String> {
|
||||
|
||||
@pragma('vm:prefer-inline')
|
||||
static bool _isLatin(Uint8List bytes) {
|
||||
var length = bytes.length;
|
||||
final length = bytes.length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
if (bytes[i] > 127) {
|
||||
return false;
|
||||
@@ -1104,7 +1104,7 @@ abstract class TableReader<T> extends Reader<T> {
|
||||
|
||||
@override
|
||||
T read(BufferContext bc, int offset) {
|
||||
var objectOffset = bc.derefObject(offset);
|
||||
final objectOffset = bc.derefObject(offset);
|
||||
return createObject(bc, objectOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: flat_buffers
|
||||
version: 23.3.3
|
||||
version: 23.5.26
|
||||
description: FlatBuffers reading and writing library for Dart. Based on original work by Konstantin Scheglov and Paul Berry of the Dart SDK team.
|
||||
homepage: https://github.com/google/flatbuffers
|
||||
documentation: https://google.github.io/flatbuffers/index.html
|
||||
|
||||
26
goldens/README.md
Normal file
26
goldens/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Golden Generated Files
|
||||
|
||||
This directory is a repository for the generated files of `flatc`.
|
||||
|
||||
We check in the generated code so we can see, during a PR review, how the
|
||||
changes affect the generated output. Its also useful as a reference to point too
|
||||
as how things work across various languages.
|
||||
|
||||
These files are **NOT** intended to be depended on by any code, such as tests or
|
||||
or compiled examples.
|
||||
|
||||
## Languages Specifics
|
||||
|
||||
Each language should keep their generated code in their respective directories.
|
||||
However, the parent schemas can, and should, be shared so we have a consistent
|
||||
view of things across languages. These are kept in the `schema/` directory.
|
||||
|
||||
Some languages may not support every generation feature, so each language is
|
||||
required to specify the `flatc` arguments individually.
|
||||
|
||||
* Try to avoid includes and nested directories, preferring it as flat as
|
||||
possible.
|
||||
|
||||
## Updating
|
||||
|
||||
Just run the `generate_goldens.py` script and it should generate them all.
|
||||
157
goldens/cpp/basic_generated.h
Normal file
157
goldens/cpp/basic_generated.h
Normal file
@@ -0,0 +1,157 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
#ifndef FLATBUFFERS_GENERATED_BASIC_H_
|
||||
#define FLATBUFFERS_GENERATED_BASIC_H_
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
|
||||
// Ensure the included flatbuffers.h is the same version as when this file was
|
||||
// generated, otherwise it may not be compatible.
|
||||
static_assert(FLATBUFFERS_VERSION_MAJOR == 23 &&
|
||||
FLATBUFFERS_VERSION_MINOR == 5 &&
|
||||
FLATBUFFERS_VERSION_REVISION == 9,
|
||||
"Non-compatible flatbuffers version included");
|
||||
|
||||
struct Galaxy;
|
||||
struct GalaxyBuilder;
|
||||
|
||||
struct Universe;
|
||||
struct UniverseBuilder;
|
||||
|
||||
struct Galaxy FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
typedef GalaxyBuilder Builder;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_NUM_STARS = 4
|
||||
};
|
||||
int64_t num_stars() const {
|
||||
return GetField<int64_t>(VT_NUM_STARS, 0);
|
||||
}
|
||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<int64_t>(verifier, VT_NUM_STARS, 8) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct GalaxyBuilder {
|
||||
typedef Galaxy Table;
|
||||
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||
::flatbuffers::uoffset_t start_;
|
||||
void add_num_stars(int64_t num_stars) {
|
||||
fbb_.AddElement<int64_t>(Galaxy::VT_NUM_STARS, num_stars, 0);
|
||||
}
|
||||
explicit GalaxyBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
::flatbuffers::Offset<Galaxy> Finish() {
|
||||
const auto end = fbb_.EndTable(start_);
|
||||
auto o = ::flatbuffers::Offset<Galaxy>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline ::flatbuffers::Offset<Galaxy> CreateGalaxy(
|
||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||
int64_t num_stars = 0) {
|
||||
GalaxyBuilder builder_(_fbb);
|
||||
builder_.add_num_stars(num_stars);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
struct Universe FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
typedef UniverseBuilder Builder;
|
||||
enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE {
|
||||
VT_AGE = 4,
|
||||
VT_GALAXIES = 6
|
||||
};
|
||||
double age() const {
|
||||
return GetField<double>(VT_AGE, 0.0);
|
||||
}
|
||||
const ::flatbuffers::Vector<::flatbuffers::Offset<Galaxy>> *galaxies() const {
|
||||
return GetPointer<const ::flatbuffers::Vector<::flatbuffers::Offset<Galaxy>> *>(VT_GALAXIES);
|
||||
}
|
||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyField<double>(verifier, VT_AGE, 8) &&
|
||||
VerifyOffset(verifier, VT_GALAXIES) &&
|
||||
verifier.VerifyVector(galaxies()) &&
|
||||
verifier.VerifyVectorOfTables(galaxies()) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
|
||||
struct UniverseBuilder {
|
||||
typedef Universe Table;
|
||||
::flatbuffers::FlatBufferBuilder &fbb_;
|
||||
::flatbuffers::uoffset_t start_;
|
||||
void add_age(double age) {
|
||||
fbb_.AddElement<double>(Universe::VT_AGE, age, 0.0);
|
||||
}
|
||||
void add_galaxies(::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<Galaxy>>> galaxies) {
|
||||
fbb_.AddOffset(Universe::VT_GALAXIES, galaxies);
|
||||
}
|
||||
explicit UniverseBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
}
|
||||
::flatbuffers::Offset<Universe> Finish() {
|
||||
const auto end = fbb_.EndTable(start_);
|
||||
auto o = ::flatbuffers::Offset<Universe>(end);
|
||||
return o;
|
||||
}
|
||||
};
|
||||
|
||||
inline ::flatbuffers::Offset<Universe> CreateUniverse(
|
||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||
double age = 0.0,
|
||||
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<Galaxy>>> galaxies = 0) {
|
||||
UniverseBuilder builder_(_fbb);
|
||||
builder_.add_age(age);
|
||||
builder_.add_galaxies(galaxies);
|
||||
return builder_.Finish();
|
||||
}
|
||||
|
||||
inline ::flatbuffers::Offset<Universe> CreateUniverseDirect(
|
||||
::flatbuffers::FlatBufferBuilder &_fbb,
|
||||
double age = 0.0,
|
||||
const std::vector<::flatbuffers::Offset<Galaxy>> *galaxies = nullptr) {
|
||||
auto galaxies__ = galaxies ? _fbb.CreateVector<::flatbuffers::Offset<Galaxy>>(*galaxies) : 0;
|
||||
return CreateUniverse(
|
||||
_fbb,
|
||||
age,
|
||||
galaxies__);
|
||||
}
|
||||
|
||||
inline const Universe *GetUniverse(const void *buf) {
|
||||
return ::flatbuffers::GetRoot<Universe>(buf);
|
||||
}
|
||||
|
||||
inline const Universe *GetSizePrefixedUniverse(const void *buf) {
|
||||
return ::flatbuffers::GetSizePrefixedRoot<Universe>(buf);
|
||||
}
|
||||
|
||||
inline bool VerifyUniverseBuffer(
|
||||
::flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifyBuffer<Universe>(nullptr);
|
||||
}
|
||||
|
||||
inline bool VerifySizePrefixedUniverseBuffer(
|
||||
::flatbuffers::Verifier &verifier) {
|
||||
return verifier.VerifySizePrefixedBuffer<Universe>(nullptr);
|
||||
}
|
||||
|
||||
inline void FinishUniverseBuffer(
|
||||
::flatbuffers::FlatBufferBuilder &fbb,
|
||||
::flatbuffers::Offset<Universe> root) {
|
||||
fbb.Finish(root);
|
||||
}
|
||||
|
||||
inline void FinishSizePrefixedUniverseBuffer(
|
||||
::flatbuffers::FlatBufferBuilder &fbb,
|
||||
::flatbuffers::Offset<Universe> root) {
|
||||
fbb.FinishSizePrefixed(root);
|
||||
}
|
||||
|
||||
#endif // FLATBUFFERS_GENERATED_BASIC_H_
|
||||
10
goldens/cpp/generate.py
Normal file
10
goldens/cpp/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with C++ specifics
|
||||
flatc_golden(options=["--cpp"] + options, schema=schema, prefix="cpp")
|
||||
|
||||
|
||||
def GenerateCpp():
|
||||
flatc([], "basic.fbs")
|
||||
45
goldens/csharp/Galaxy.cs
Normal file
45
goldens/csharp/Galaxy.cs
Normal file
@@ -0,0 +1,45 @@
|
||||
// <auto-generated>
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// </auto-generated>
|
||||
|
||||
using global::System;
|
||||
using global::System.Collections.Generic;
|
||||
using global::Google.FlatBuffers;
|
||||
|
||||
public struct Galaxy : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_26(); }
|
||||
public static Galaxy GetRootAsGalaxy(ByteBuffer _bb) { return GetRootAsGalaxy(_bb, new Galaxy()); }
|
||||
public static Galaxy GetRootAsGalaxy(ByteBuffer _bb, Galaxy obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
|
||||
public Galaxy __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public long NumStars { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetLong(o + __p.bb_pos) : (long)0; } }
|
||||
|
||||
public static Offset<Galaxy> CreateGalaxy(FlatBufferBuilder builder,
|
||||
long num_stars = 0) {
|
||||
builder.StartTable(1);
|
||||
Galaxy.AddNumStars(builder, num_stars);
|
||||
return Galaxy.EndGalaxy(builder);
|
||||
}
|
||||
|
||||
public static void StartGalaxy(FlatBufferBuilder builder) { builder.StartTable(1); }
|
||||
public static void AddNumStars(FlatBufferBuilder builder, long numStars) { builder.AddLong(0, numStars, 0); }
|
||||
public static Offset<Galaxy> EndGalaxy(FlatBufferBuilder builder) {
|
||||
int o = builder.EndTable();
|
||||
return new Offset<Galaxy>(o);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public class GalaxyVerify
|
||||
{
|
||||
static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
|
||||
{
|
||||
return verifier.VerifyTableStart(tablePos)
|
||||
&& verifier.VerifyField(tablePos, 4 /*NumStars*/, 8 /*long*/, 8, false)
|
||||
&& verifier.VerifyTableEnd(tablePos);
|
||||
}
|
||||
}
|
||||
59
goldens/csharp/Universe.cs
Normal file
59
goldens/csharp/Universe.cs
Normal file
@@ -0,0 +1,59 @@
|
||||
// <auto-generated>
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// </auto-generated>
|
||||
|
||||
using global::System;
|
||||
using global::System.Collections.Generic;
|
||||
using global::Google.FlatBuffers;
|
||||
|
||||
public struct Universe : IFlatbufferObject
|
||||
{
|
||||
private Table __p;
|
||||
public ByteBuffer ByteBuffer { get { return __p.bb; } }
|
||||
public static void ValidateVersion() { FlatBufferConstants.FLATBUFFERS_23_5_26(); }
|
||||
public static Universe GetRootAsUniverse(ByteBuffer _bb) { return GetRootAsUniverse(_bb, new Universe()); }
|
||||
public static Universe GetRootAsUniverse(ByteBuffer _bb, Universe obj) { return (obj.__assign(_bb.GetInt(_bb.Position) + _bb.Position, _bb)); }
|
||||
public static bool VerifyUniverse(ByteBuffer _bb) {Google.FlatBuffers.Verifier verifier = new Google.FlatBuffers.Verifier(_bb); return verifier.VerifyBuffer("", false, UniverseVerify.Verify); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __p = new Table(_i, _bb); }
|
||||
public Universe __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public double Age { get { int o = __p.__offset(4); return o != 0 ? __p.bb.GetDouble(o + __p.bb_pos) : (double)0.0; } }
|
||||
public Galaxy? Galaxies(int j) { int o = __p.__offset(6); return o != 0 ? (Galaxy?)(new Galaxy()).__assign(__p.__indirect(__p.__vector(o) + j * 4), __p.bb) : null; }
|
||||
public int GalaxiesLength { get { int o = __p.__offset(6); return o != 0 ? __p.__vector_len(o) : 0; } }
|
||||
|
||||
public static Offset<Universe> CreateUniverse(FlatBufferBuilder builder,
|
||||
double age = 0.0,
|
||||
VectorOffset galaxiesOffset = default(VectorOffset)) {
|
||||
builder.StartTable(2);
|
||||
Universe.AddAge(builder, age);
|
||||
Universe.AddGalaxies(builder, galaxiesOffset);
|
||||
return Universe.EndUniverse(builder);
|
||||
}
|
||||
|
||||
public static void StartUniverse(FlatBufferBuilder builder) { builder.StartTable(2); }
|
||||
public static void AddAge(FlatBufferBuilder builder, double age) { builder.AddDouble(0, age, 0.0); }
|
||||
public static void AddGalaxies(FlatBufferBuilder builder, VectorOffset galaxiesOffset) { builder.AddOffset(1, galaxiesOffset.Value, 0); }
|
||||
public static VectorOffset CreateGalaxiesVector(FlatBufferBuilder builder, Offset<Galaxy>[] data) { builder.StartVector(4, data.Length, 4); for (int i = data.Length - 1; i >= 0; i--) builder.AddOffset(data[i].Value); return builder.EndVector(); }
|
||||
public static VectorOffset CreateGalaxiesVectorBlock(FlatBufferBuilder builder, Offset<Galaxy>[] data) { builder.StartVector(4, data.Length, 4); builder.Add(data); return builder.EndVector(); }
|
||||
public static VectorOffset CreateGalaxiesVectorBlock(FlatBufferBuilder builder, ArraySegment<Offset<Galaxy>> data) { builder.StartVector(4, data.Count, 4); builder.Add(data); return builder.EndVector(); }
|
||||
public static VectorOffset CreateGalaxiesVectorBlock(FlatBufferBuilder builder, IntPtr dataPtr, int sizeInBytes) { builder.StartVector(1, sizeInBytes, 1); builder.Add<Offset<Galaxy>>(dataPtr, sizeInBytes); return builder.EndVector(); }
|
||||
public static void StartGalaxiesVector(FlatBufferBuilder builder, int numElems) { builder.StartVector(4, numElems, 4); }
|
||||
public static Offset<Universe> EndUniverse(FlatBufferBuilder builder) {
|
||||
int o = builder.EndTable();
|
||||
return new Offset<Universe>(o);
|
||||
}
|
||||
public static void FinishUniverseBuffer(FlatBufferBuilder builder, Offset<Universe> offset) { builder.Finish(offset.Value); }
|
||||
public static void FinishSizePrefixedUniverseBuffer(FlatBufferBuilder builder, Offset<Universe> offset) { builder.FinishSizePrefixed(offset.Value); }
|
||||
}
|
||||
|
||||
|
||||
static public class UniverseVerify
|
||||
{
|
||||
static public bool Verify(Google.FlatBuffers.Verifier verifier, uint tablePos)
|
||||
{
|
||||
return verifier.VerifyTableStart(tablePos)
|
||||
&& verifier.VerifyField(tablePos, 4 /*Age*/, 8 /*double*/, 8, false)
|
||||
&& verifier.VerifyVectorOfTables(tablePos, 6 /*Galaxies*/, GalaxyVerify.Verify, false)
|
||||
&& verifier.VerifyTableEnd(tablePos);
|
||||
}
|
||||
}
|
||||
10
goldens/csharp/generate.py
Normal file
10
goldens/csharp/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with C# specifics
|
||||
flatc_golden(options=["--csharp"] + options, schema=schema, prefix="csharp")
|
||||
|
||||
|
||||
def GenerateCSharp():
|
||||
flatc([], "basic.fbs")
|
||||
160
goldens/dart/basic_generated.dart
Normal file
160
goldens/dart/basic_generated.dart
Normal file
@@ -0,0 +1,160 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// ignore_for_file: unused_import, unused_field, unused_element, unused_local_variable
|
||||
|
||||
import 'dart:typed_data' show Uint8List;
|
||||
import 'package:flat_buffers/flat_buffers.dart' as fb;
|
||||
|
||||
|
||||
class Galaxy {
|
||||
Galaxy._(this._bc, this._bcOffset);
|
||||
factory Galaxy(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<Galaxy> reader = _GalaxyReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
int get numStars => const fb.Int64Reader().vTableGet(_bc, _bcOffset, 4, 0);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Galaxy{numStars: ${numStars}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _GalaxyReader extends fb.TableReader<Galaxy> {
|
||||
const _GalaxyReader();
|
||||
|
||||
@override
|
||||
Galaxy createObject(fb.BufferContext bc, int offset) =>
|
||||
Galaxy._(bc, offset);
|
||||
}
|
||||
|
||||
class GalaxyBuilder {
|
||||
GalaxyBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(1);
|
||||
}
|
||||
|
||||
int addNumStars(int? numStars) {
|
||||
fbBuilder.addInt64(0, numStars);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class GalaxyObjectBuilder extends fb.ObjectBuilder {
|
||||
final int? _numStars;
|
||||
|
||||
GalaxyObjectBuilder({
|
||||
int? numStars,
|
||||
})
|
||||
: _numStars = numStars;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
fbBuilder.startTable(1);
|
||||
fbBuilder.addInt64(0, _numStars);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
class Universe {
|
||||
Universe._(this._bc, this._bcOffset);
|
||||
factory Universe(List<int> bytes) {
|
||||
final rootRef = fb.BufferContext.fromBytes(bytes);
|
||||
return reader.read(rootRef, 0);
|
||||
}
|
||||
|
||||
static const fb.Reader<Universe> reader = _UniverseReader();
|
||||
|
||||
final fb.BufferContext _bc;
|
||||
final int _bcOffset;
|
||||
|
||||
double get age => const fb.Float64Reader().vTableGet(_bc, _bcOffset, 4, 0.0);
|
||||
List<Galaxy>? get galaxies => const fb.ListReader<Galaxy>(Galaxy.reader).vTableGetNullable(_bc, _bcOffset, 6);
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Universe{age: ${age}, galaxies: ${galaxies}}';
|
||||
}
|
||||
}
|
||||
|
||||
class _UniverseReader extends fb.TableReader<Universe> {
|
||||
const _UniverseReader();
|
||||
|
||||
@override
|
||||
Universe createObject(fb.BufferContext bc, int offset) =>
|
||||
Universe._(bc, offset);
|
||||
}
|
||||
|
||||
class UniverseBuilder {
|
||||
UniverseBuilder(this.fbBuilder);
|
||||
|
||||
final fb.Builder fbBuilder;
|
||||
|
||||
void begin() {
|
||||
fbBuilder.startTable(2);
|
||||
}
|
||||
|
||||
int addAge(double? age) {
|
||||
fbBuilder.addFloat64(0, age);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
int addGalaxiesOffset(int? offset) {
|
||||
fbBuilder.addOffset(1, offset);
|
||||
return fbBuilder.offset;
|
||||
}
|
||||
|
||||
int finish() {
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
}
|
||||
|
||||
class UniverseObjectBuilder extends fb.ObjectBuilder {
|
||||
final double? _age;
|
||||
final List<GalaxyObjectBuilder>? _galaxies;
|
||||
|
||||
UniverseObjectBuilder({
|
||||
double? age,
|
||||
List<GalaxyObjectBuilder>? galaxies,
|
||||
})
|
||||
: _age = age,
|
||||
_galaxies = galaxies;
|
||||
|
||||
/// Finish building, and store into the [fbBuilder].
|
||||
@override
|
||||
int finish(fb.Builder fbBuilder) {
|
||||
final int? galaxiesOffset = _galaxies == null ? null
|
||||
: fbBuilder.writeList(_galaxies!.map((b) => b.getOrCreateOffset(fbBuilder)).toList());
|
||||
fbBuilder.startTable(2);
|
||||
fbBuilder.addFloat64(0, _age);
|
||||
fbBuilder.addOffset(1, galaxiesOffset);
|
||||
return fbBuilder.endTable();
|
||||
}
|
||||
|
||||
/// Convenience method to serialize to byte list.
|
||||
@override
|
||||
Uint8List toBytes([String? fileIdentifier]) {
|
||||
final fbBuilder = fb.Builder(deduplicateTables: false);
|
||||
fbBuilder.finish(finish(fbBuilder), fileIdentifier);
|
||||
return fbBuilder.buffer;
|
||||
}
|
||||
}
|
||||
10
goldens/dart/generate.py
Normal file
10
goldens/dart/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Dart specifics
|
||||
flatc_golden(options=["--dart"] + options, schema=schema, prefix="dart")
|
||||
|
||||
|
||||
def GenerateDart():
|
||||
flatc([], "basic.fbs")
|
||||
32
goldens/generate_goldens.py
Executable file
32
goldens/generate_goldens.py
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from cpp.generate import GenerateCpp
|
||||
from csharp.generate import GenerateCSharp
|
||||
from dart.generate import GenerateDart
|
||||
from go.generate import GenerateGo
|
||||
from java.generate import GenerateJava
|
||||
from kotlin.generate import GenerateKotlin
|
||||
from lobster.generate import GenerateLobster
|
||||
from lua.generate import GenerateLua
|
||||
from nim.generate import GenerateNim
|
||||
from php.generate import GeneratePhp
|
||||
from py.generate import GeneratePython
|
||||
from rust.generate import GenerateRust
|
||||
from swift.generate import GenerateSwift
|
||||
from ts.generate import GenerateTs
|
||||
|
||||
# Run each language generation logic
|
||||
GenerateCpp()
|
||||
GenerateCSharp()
|
||||
GenerateDart()
|
||||
GenerateGo()
|
||||
GenerateJava()
|
||||
GenerateKotlin()
|
||||
GenerateLobster()
|
||||
GenerateLua()
|
||||
GenerateNim()
|
||||
GeneratePhp()
|
||||
GeneratePython()
|
||||
GenerateRust()
|
||||
GenerateSwift()
|
||||
GenerateTs()
|
||||
64
goldens/go/Galaxy.go
Normal file
64
goldens/go/Galaxy.go
Normal file
@@ -0,0 +1,64 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package Galaxy
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type Galaxy struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsGalaxy(buf []byte, offset flatbuffers.UOffsetT) *Galaxy {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &Galaxy{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishGalaxyBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.Finish(offset)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsGalaxy(buf []byte, offset flatbuffers.UOffsetT) *Galaxy {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &Galaxy{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedGalaxyBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.FinishSizePrefixed(offset)
|
||||
}
|
||||
|
||||
func (rcv *Galaxy) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Galaxy) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *Galaxy) NumStars() int64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetInt64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func (rcv *Galaxy) MutateNumStars(n int64) bool {
|
||||
return rcv._tab.MutateInt64Slot(4, n)
|
||||
}
|
||||
|
||||
func GalaxyStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(1)
|
||||
}
|
||||
func GalaxyAddNumStars(builder *flatbuffers.Builder, numStars int64) {
|
||||
builder.PrependInt64Slot(0, numStars, 0)
|
||||
}
|
||||
func GalaxyEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
90
goldens/go/Universe.go
Normal file
90
goldens/go/Universe.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Code generated by the FlatBuffers compiler. DO NOT EDIT.
|
||||
|
||||
package Universe
|
||||
|
||||
import (
|
||||
flatbuffers "github.com/google/flatbuffers/go"
|
||||
)
|
||||
|
||||
type Universe struct {
|
||||
_tab flatbuffers.Table
|
||||
}
|
||||
|
||||
func GetRootAsUniverse(buf []byte, offset flatbuffers.UOffsetT) *Universe {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset:])
|
||||
x := &Universe{}
|
||||
x.Init(buf, n+offset)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishUniverseBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.Finish(offset)
|
||||
}
|
||||
|
||||
func GetSizePrefixedRootAsUniverse(buf []byte, offset flatbuffers.UOffsetT) *Universe {
|
||||
n := flatbuffers.GetUOffsetT(buf[offset+flatbuffers.SizeUint32:])
|
||||
x := &Universe{}
|
||||
x.Init(buf, n+offset+flatbuffers.SizeUint32)
|
||||
return x
|
||||
}
|
||||
|
||||
func FinishSizePrefixedUniverseBuffer(builder *flatbuffers.Builder, offset flatbuffers.UOffsetT) {
|
||||
builder.FinishSizePrefixed(offset)
|
||||
}
|
||||
|
||||
func (rcv *Universe) Init(buf []byte, i flatbuffers.UOffsetT) {
|
||||
rcv._tab.Bytes = buf
|
||||
rcv._tab.Pos = i
|
||||
}
|
||||
|
||||
func (rcv *Universe) Table() flatbuffers.Table {
|
||||
return rcv._tab
|
||||
}
|
||||
|
||||
func (rcv *Universe) Age() float64 {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(4))
|
||||
if o != 0 {
|
||||
return rcv._tab.GetFloat64(o + rcv._tab.Pos)
|
||||
}
|
||||
return 0.0
|
||||
}
|
||||
|
||||
func (rcv *Universe) MutateAge(n float64) bool {
|
||||
return rcv._tab.MutateFloat64Slot(4, n)
|
||||
}
|
||||
|
||||
func (rcv *Universe) Galaxies(obj *Galaxy, j int) bool {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
x := rcv._tab.Vector(o)
|
||||
x += flatbuffers.UOffsetT(j) * 4
|
||||
x = rcv._tab.Indirect(x)
|
||||
obj.Init(rcv._tab.Bytes, x)
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (rcv *Universe) GalaxiesLength() int {
|
||||
o := flatbuffers.UOffsetT(rcv._tab.Offset(6))
|
||||
if o != 0 {
|
||||
return rcv._tab.VectorLen(o)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func UniverseStart(builder *flatbuffers.Builder) {
|
||||
builder.StartObject(2)
|
||||
}
|
||||
func UniverseAddAge(builder *flatbuffers.Builder, age float64) {
|
||||
builder.PrependFloat64Slot(0, age, 0.0)
|
||||
}
|
||||
func UniverseAddGalaxies(builder *flatbuffers.Builder, galaxies flatbuffers.UOffsetT) {
|
||||
builder.PrependUOffsetTSlot(1, flatbuffers.UOffsetT(galaxies), 0)
|
||||
}
|
||||
func UniverseStartGalaxiesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
}
|
||||
func UniverseEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
|
||||
return builder.EndObject()
|
||||
}
|
||||
10
goldens/go/generate.py
Normal file
10
goldens/go/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Go specifics
|
||||
flatc_golden(options=["--go"] + options, schema=schema, prefix="go")
|
||||
|
||||
|
||||
def GenerateGo():
|
||||
flatc([], "basic.fbs")
|
||||
30
goldens/golden_utils.py
Normal file
30
goldens/golden_utils.py
Normal file
@@ -0,0 +1,30 @@
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
# Get the path where this script is located so we can invoke the script from
|
||||
# any directory and have the paths work correctly.
|
||||
script_path = Path(__file__).parent.resolve()
|
||||
|
||||
# Get the root path as an absolute path, so all derived paths are absolute.
|
||||
root_path = script_path.parent.absolute()
|
||||
|
||||
# Get the location of the schema
|
||||
schema_path = Path(script_path, "schema")
|
||||
|
||||
# Too add the util package in /scripts/util.py
|
||||
sys.path.append(str(root_path.absolute()))
|
||||
|
||||
from scripts.util import flatc
|
||||
|
||||
|
||||
def flatc_golden(options, schema, prefix):
|
||||
# wrap the generic flatc call with specifis for these goldens.
|
||||
flatc(
|
||||
options=options,
|
||||
# where the files are generated, typically the language (e.g. "cpp").
|
||||
prefix=prefix,
|
||||
# The schema are relative to the schema directory.
|
||||
schema=str(Path(schema_path, schema)),
|
||||
# Run flatc from this location.
|
||||
cwd=script_path,
|
||||
)
|
||||
51
goldens/java/Galaxy.java
Normal file
51
goldens/java/Galaxy.java
Normal file
@@ -0,0 +1,51 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
import com.google.flatbuffers.BaseVector;
|
||||
import com.google.flatbuffers.BooleanVector;
|
||||
import com.google.flatbuffers.ByteVector;
|
||||
import com.google.flatbuffers.Constants;
|
||||
import com.google.flatbuffers.DoubleVector;
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
import com.google.flatbuffers.FloatVector;
|
||||
import com.google.flatbuffers.IntVector;
|
||||
import com.google.flatbuffers.LongVector;
|
||||
import com.google.flatbuffers.ShortVector;
|
||||
import com.google.flatbuffers.StringVector;
|
||||
import com.google.flatbuffers.Struct;
|
||||
import com.google.flatbuffers.Table;
|
||||
import com.google.flatbuffers.UnionVector;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Galaxy extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Galaxy getRootAsGalaxy(ByteBuffer _bb) { return getRootAsGalaxy(_bb, new Galaxy()); }
|
||||
public static Galaxy getRootAsGalaxy(ByteBuffer _bb, Galaxy obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
public Galaxy __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public long numStars() { int o = __offset(4); return o != 0 ? bb.getLong(o + bb_pos) : 0L; }
|
||||
|
||||
public static int createGalaxy(FlatBufferBuilder builder,
|
||||
long numStars) {
|
||||
builder.startTable(1);
|
||||
Galaxy.addNumStars(builder, numStars);
|
||||
return Galaxy.endGalaxy(builder);
|
||||
}
|
||||
|
||||
public static void startGalaxy(FlatBufferBuilder builder) { builder.startTable(1); }
|
||||
public static void addNumStars(FlatBufferBuilder builder, long numStars) { builder.addLong(0, numStars, 0L); }
|
||||
public static int endGalaxy(FlatBufferBuilder builder) {
|
||||
int o = builder.endTable();
|
||||
return o;
|
||||
}
|
||||
|
||||
public static final class Vector extends BaseVector {
|
||||
public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
|
||||
|
||||
public Galaxy get(int j) { return get(new Galaxy(), j); }
|
||||
public Galaxy get(Galaxy obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
|
||||
}
|
||||
}
|
||||
|
||||
63
goldens/java/Universe.java
Normal file
63
goldens/java/Universe.java
Normal file
@@ -0,0 +1,63 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
import com.google.flatbuffers.BaseVector;
|
||||
import com.google.flatbuffers.BooleanVector;
|
||||
import com.google.flatbuffers.ByteVector;
|
||||
import com.google.flatbuffers.Constants;
|
||||
import com.google.flatbuffers.DoubleVector;
|
||||
import com.google.flatbuffers.FlatBufferBuilder;
|
||||
import com.google.flatbuffers.FloatVector;
|
||||
import com.google.flatbuffers.IntVector;
|
||||
import com.google.flatbuffers.LongVector;
|
||||
import com.google.flatbuffers.ShortVector;
|
||||
import com.google.flatbuffers.StringVector;
|
||||
import com.google.flatbuffers.Struct;
|
||||
import com.google.flatbuffers.Table;
|
||||
import com.google.flatbuffers.UnionVector;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Universe extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Universe getRootAsUniverse(ByteBuffer _bb) { return getRootAsUniverse(_bb, new Universe()); }
|
||||
public static Universe getRootAsUniverse(ByteBuffer _bb, Universe obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
public Universe __assign(int _i, ByteBuffer _bb) { __init(_i, _bb); return this; }
|
||||
|
||||
public double age() { int o = __offset(4); return o != 0 ? bb.getDouble(o + bb_pos) : 0.0; }
|
||||
public Galaxy galaxies(int j) { return galaxies(new Galaxy(), j); }
|
||||
public Galaxy galaxies(Galaxy obj, int j) { int o = __offset(6); return o != 0 ? obj.__assign(__indirect(__vector(o) + j * 4), bb) : null; }
|
||||
public int galaxiesLength() { int o = __offset(6); return o != 0 ? __vector_len(o) : 0; }
|
||||
public Galaxy.Vector galaxiesVector() { return galaxiesVector(new Galaxy.Vector()); }
|
||||
public Galaxy.Vector galaxiesVector(Galaxy.Vector obj) { int o = __offset(6); return o != 0 ? obj.__assign(__vector(o), 4, bb) : null; }
|
||||
|
||||
public static int createUniverse(FlatBufferBuilder builder,
|
||||
double age,
|
||||
int galaxiesOffset) {
|
||||
builder.startTable(2);
|
||||
Universe.addAge(builder, age);
|
||||
Universe.addGalaxies(builder, galaxiesOffset);
|
||||
return Universe.endUniverse(builder);
|
||||
}
|
||||
|
||||
public static void startUniverse(FlatBufferBuilder builder) { builder.startTable(2); }
|
||||
public static void addAge(FlatBufferBuilder builder, double age) { builder.addDouble(0, age, 0.0); }
|
||||
public static void addGalaxies(FlatBufferBuilder builder, int galaxiesOffset) { builder.addOffset(1, galaxiesOffset, 0); }
|
||||
public static int createGalaxiesVector(FlatBufferBuilder builder, int[] data) { builder.startVector(4, data.length, 4); for (int i = data.length - 1; i >= 0; i--) builder.addOffset(data[i]); return builder.endVector(); }
|
||||
public static void startGalaxiesVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
|
||||
public static int endUniverse(FlatBufferBuilder builder) {
|
||||
int o = builder.endTable();
|
||||
return o;
|
||||
}
|
||||
public static void finishUniverseBuffer(FlatBufferBuilder builder, int offset) { builder.finish(offset); }
|
||||
public static void finishSizePrefixedUniverseBuffer(FlatBufferBuilder builder, int offset) { builder.finishSizePrefixed(offset); }
|
||||
|
||||
public static final class Vector extends BaseVector {
|
||||
public Vector __assign(int _vector, int _element_size, ByteBuffer _bb) { __reset(_vector, _element_size, _bb); return this; }
|
||||
|
||||
public Universe get(int j) { return get(new Universe(), j); }
|
||||
public Universe get(Universe obj, int j) { return obj.__assign(__indirect(__element(j), bb), bb); }
|
||||
}
|
||||
}
|
||||
|
||||
10
goldens/java/generate.py
Normal file
10
goldens/java/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Java specifics
|
||||
flatc_golden(options=["--java"] + options, schema=schema, prefix="java")
|
||||
|
||||
|
||||
def GenerateJava():
|
||||
flatc([], "basic.fbs")
|
||||
53
goldens/kotlin/Galaxy.kt
Normal file
53
goldens/kotlin/Galaxy.kt
Normal file
@@ -0,0 +1,53 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
import com.google.flatbuffers.BaseVector
|
||||
import com.google.flatbuffers.BooleanVector
|
||||
import com.google.flatbuffers.ByteVector
|
||||
import com.google.flatbuffers.Constants
|
||||
import com.google.flatbuffers.DoubleVector
|
||||
import com.google.flatbuffers.FlatBufferBuilder
|
||||
import com.google.flatbuffers.FloatVector
|
||||
import com.google.flatbuffers.LongVector
|
||||
import com.google.flatbuffers.StringVector
|
||||
import com.google.flatbuffers.Struct
|
||||
import com.google.flatbuffers.Table
|
||||
import com.google.flatbuffers.UnionVector
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import kotlin.math.sign
|
||||
|
||||
@Suppress("unused")
|
||||
class Galaxy : Table() {
|
||||
|
||||
fun __init(_i: Int, _bb: ByteBuffer) {
|
||||
__reset(_i, _bb)
|
||||
}
|
||||
fun __assign(_i: Int, _bb: ByteBuffer) : Galaxy {
|
||||
__init(_i, _bb)
|
||||
return this
|
||||
}
|
||||
val numStars : Long
|
||||
get() {
|
||||
val o = __offset(4)
|
||||
return if(o != 0) bb.getLong(o + bb_pos) else 0L
|
||||
}
|
||||
companion object {
|
||||
fun validateVersion() = Constants.FLATBUFFERS_23_5_26()
|
||||
fun getRootAsGalaxy(_bb: ByteBuffer): Galaxy = getRootAsGalaxy(_bb, Galaxy())
|
||||
fun getRootAsGalaxy(_bb: ByteBuffer, obj: Galaxy): Galaxy {
|
||||
_bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
|
||||
}
|
||||
fun createGalaxy(builder: FlatBufferBuilder, numStars: Long) : Int {
|
||||
builder.startTable(1)
|
||||
addNumStars(builder, numStars)
|
||||
return endGalaxy(builder)
|
||||
}
|
||||
fun startGalaxy(builder: FlatBufferBuilder) = builder.startTable(1)
|
||||
fun addNumStars(builder: FlatBufferBuilder, numStars: Long) = builder.addLong(0, numStars, 0L)
|
||||
fun endGalaxy(builder: FlatBufferBuilder) : Int {
|
||||
val o = builder.endTable()
|
||||
return o
|
||||
}
|
||||
}
|
||||
}
|
||||
78
goldens/kotlin/Universe.kt
Normal file
78
goldens/kotlin/Universe.kt
Normal file
@@ -0,0 +1,78 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
import com.google.flatbuffers.BaseVector
|
||||
import com.google.flatbuffers.BooleanVector
|
||||
import com.google.flatbuffers.ByteVector
|
||||
import com.google.flatbuffers.Constants
|
||||
import com.google.flatbuffers.DoubleVector
|
||||
import com.google.flatbuffers.FlatBufferBuilder
|
||||
import com.google.flatbuffers.FloatVector
|
||||
import com.google.flatbuffers.LongVector
|
||||
import com.google.flatbuffers.StringVector
|
||||
import com.google.flatbuffers.Struct
|
||||
import com.google.flatbuffers.Table
|
||||
import com.google.flatbuffers.UnionVector
|
||||
import java.nio.ByteBuffer
|
||||
import java.nio.ByteOrder
|
||||
import kotlin.math.sign
|
||||
|
||||
@Suppress("unused")
|
||||
class Universe : Table() {
|
||||
|
||||
fun __init(_i: Int, _bb: ByteBuffer) {
|
||||
__reset(_i, _bb)
|
||||
}
|
||||
fun __assign(_i: Int, _bb: ByteBuffer) : Universe {
|
||||
__init(_i, _bb)
|
||||
return this
|
||||
}
|
||||
val age : Double
|
||||
get() {
|
||||
val o = __offset(4)
|
||||
return if(o != 0) bb.getDouble(o + bb_pos) else 0.0
|
||||
}
|
||||
fun galaxies(j: Int) : Galaxy? = galaxies(Galaxy(), j)
|
||||
fun galaxies(obj: Galaxy, j: Int) : Galaxy? {
|
||||
val o = __offset(6)
|
||||
return if (o != 0) {
|
||||
obj.__assign(__indirect(__vector(o) + j * 4), bb)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
val galaxiesLength : Int
|
||||
get() {
|
||||
val o = __offset(6); return if (o != 0) __vector_len(o) else 0
|
||||
}
|
||||
companion object {
|
||||
fun validateVersion() = Constants.FLATBUFFERS_23_5_26()
|
||||
fun getRootAsUniverse(_bb: ByteBuffer): Universe = getRootAsUniverse(_bb, Universe())
|
||||
fun getRootAsUniverse(_bb: ByteBuffer, obj: Universe): Universe {
|
||||
_bb.order(ByteOrder.LITTLE_ENDIAN)
|
||||
return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb))
|
||||
}
|
||||
fun createUniverse(builder: FlatBufferBuilder, age: Double, galaxiesOffset: Int) : Int {
|
||||
builder.startTable(2)
|
||||
addAge(builder, age)
|
||||
addGalaxies(builder, galaxiesOffset)
|
||||
return endUniverse(builder)
|
||||
}
|
||||
fun startUniverse(builder: FlatBufferBuilder) = builder.startTable(2)
|
||||
fun addAge(builder: FlatBufferBuilder, age: Double) = builder.addDouble(0, age, 0.0)
|
||||
fun addGalaxies(builder: FlatBufferBuilder, galaxies: Int) = builder.addOffset(1, galaxies, 0)
|
||||
fun createGalaxiesVector(builder: FlatBufferBuilder, data: IntArray) : Int {
|
||||
builder.startVector(4, data.size, 4)
|
||||
for (i in data.size - 1 downTo 0) {
|
||||
builder.addOffset(data[i])
|
||||
}
|
||||
return builder.endVector()
|
||||
}
|
||||
fun startGalaxiesVector(builder: FlatBufferBuilder, numElems: Int) = builder.startVector(4, numElems, 4)
|
||||
fun endUniverse(builder: FlatBufferBuilder) : Int {
|
||||
val o = builder.endTable()
|
||||
return o
|
||||
}
|
||||
fun finishUniverseBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finish(offset)
|
||||
fun finishSizePrefixedUniverseBuffer(builder: FlatBufferBuilder, offset: Int) = builder.finishSizePrefixed(offset)
|
||||
}
|
||||
}
|
||||
10
goldens/kotlin/generate.py
Normal file
10
goldens/kotlin/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Kotlin specifics
|
||||
flatc_golden(options=["--kotlin"] + options, schema=schema, prefix="kotlin")
|
||||
|
||||
|
||||
def GenerateKotlin():
|
||||
flatc([], "basic.fbs")
|
||||
55
goldens/lobster/basic_generated.lobster
Normal file
55
goldens/lobster/basic_generated.lobster
Normal file
@@ -0,0 +1,55 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
import flatbuffers
|
||||
|
||||
class Galaxy
|
||||
|
||||
class Universe
|
||||
|
||||
class Galaxy : flatbuffers_handle
|
||||
def num_stars() -> int:
|
||||
return buf_.flatbuffers_field_int64(pos_, 4, 0)
|
||||
|
||||
def GetRootAsGalaxy(buf:string): return Galaxy { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
struct GalaxyBuilder:
|
||||
b_:flatbuffers_builder
|
||||
def start():
|
||||
b_.StartObject(1)
|
||||
return this
|
||||
def add_num_stars(num_stars:int):
|
||||
b_.PrependInt64Slot(0, num_stars, 0)
|
||||
return this
|
||||
def end():
|
||||
return b_.EndObject()
|
||||
|
||||
class Universe : flatbuffers_handle
|
||||
def age() -> float:
|
||||
return buf_.flatbuffers_field_float64(pos_, 4, 0.0)
|
||||
def galaxies(i:int) -> Galaxy:
|
||||
return Galaxy { buf_, buf_.flatbuffers_indirect(buf_.flatbuffers_field_vector(pos_, 6) + i * 4) }
|
||||
def galaxies_length() -> int:
|
||||
return buf_.flatbuffers_field_vector_len(pos_, 6)
|
||||
|
||||
def GetRootAsUniverse(buf:string): return Universe { buf, buf.flatbuffers_indirect(0) }
|
||||
|
||||
struct UniverseBuilder:
|
||||
b_:flatbuffers_builder
|
||||
def start():
|
||||
b_.StartObject(2)
|
||||
return this
|
||||
def add_age(age:float):
|
||||
b_.PrependFloat64Slot(0, age, 0.0)
|
||||
return this
|
||||
def add_galaxies(galaxies:flatbuffers_offset):
|
||||
b_.PrependUOffsetTRelativeSlot(1, galaxies)
|
||||
return this
|
||||
def end():
|
||||
return b_.EndObject()
|
||||
|
||||
def UniverseStartGalaxiesVector(b_:flatbuffers_builder, n_:int):
|
||||
b_.StartVector(4, n_, 4)
|
||||
def UniverseCreateGalaxiesVector(b_:flatbuffers_builder, v_:[flatbuffers_offset]):
|
||||
b_.StartVector(4, v_.length, 4)
|
||||
reverse(v_) e_: b_.PrependUOffsetTRelative(e_)
|
||||
return b_.EndVector(v_.length)
|
||||
|
||||
10
goldens/lobster/generate.py
Normal file
10
goldens/lobster/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Lobster specifics
|
||||
flatc_golden(options=["--lobster"] + options, schema=schema, prefix="lobster")
|
||||
|
||||
|
||||
def GenerateLobster():
|
||||
flatc([], "basic.fbs")
|
||||
48
goldens/lua/Galaxy.lua
Normal file
48
goldens/lua/Galaxy.lua
Normal file
@@ -0,0 +1,48 @@
|
||||
--[[ Galaxy
|
||||
|
||||
Automatically generated by the FlatBuffers compiler, do not modify.
|
||||
Or modify. I'm a message, not a cop.
|
||||
|
||||
flatc version: 23.5.9
|
||||
|
||||
Declared by : //basic.fbs
|
||||
Rooting type : Universe (//basic.fbs)
|
||||
|
||||
--]]
|
||||
|
||||
local flatbuffers = require('flatbuffers')
|
||||
|
||||
local Galaxy = {}
|
||||
local mt = {}
|
||||
|
||||
function Galaxy.New()
|
||||
local o = {}
|
||||
setmetatable(o, {__index = mt})
|
||||
return o
|
||||
end
|
||||
|
||||
function mt:Init(buf, pos)
|
||||
self.view = flatbuffers.view.New(buf, pos)
|
||||
end
|
||||
|
||||
function mt:NumStars()
|
||||
local o = self.view:Offset(4)
|
||||
if o ~= 0 then
|
||||
return self.view:Get(flatbuffers.N.Int64, self.view.pos + o)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function Galaxy.Start(builder)
|
||||
builder:StartObject(1)
|
||||
end
|
||||
|
||||
function Galaxy.AddNumStars(builder, numStars)
|
||||
builder:PrependInt64Slot(0, numStars, 0)
|
||||
end
|
||||
|
||||
function Galaxy.End(builder)
|
||||
return builder:EndObject()
|
||||
end
|
||||
|
||||
return Galaxy
|
||||
88
goldens/lua/Universe.lua
Normal file
88
goldens/lua/Universe.lua
Normal file
@@ -0,0 +1,88 @@
|
||||
--[[ Universe
|
||||
|
||||
Automatically generated by the FlatBuffers compiler, do not modify.
|
||||
Or modify. I'm a message, not a cop.
|
||||
|
||||
flatc version: 23.5.9
|
||||
|
||||
Declared by : //basic.fbs
|
||||
Rooting type : Universe (//basic.fbs)
|
||||
|
||||
--]]
|
||||
|
||||
local __Galaxy = require('Galaxy')
|
||||
local flatbuffers = require('flatbuffers')
|
||||
|
||||
local Universe = {}
|
||||
local mt = {}
|
||||
|
||||
function Universe.New()
|
||||
local o = {}
|
||||
setmetatable(o, {__index = mt})
|
||||
return o
|
||||
end
|
||||
|
||||
function Universe.GetRootAsUniverse(buf, offset)
|
||||
if type(buf) == "string" then
|
||||
buf = flatbuffers.binaryArray.New(buf)
|
||||
end
|
||||
|
||||
local n = flatbuffers.N.UOffsetT:Unpack(buf, offset)
|
||||
local o = Universe.New()
|
||||
o:Init(buf, n + offset)
|
||||
return o
|
||||
end
|
||||
|
||||
function mt:Init(buf, pos)
|
||||
self.view = flatbuffers.view.New(buf, pos)
|
||||
end
|
||||
|
||||
function mt:Age()
|
||||
local o = self.view:Offset(4)
|
||||
if o ~= 0 then
|
||||
return self.view:Get(flatbuffers.N.Float64, self.view.pos + o)
|
||||
end
|
||||
return 0.0
|
||||
end
|
||||
|
||||
function mt:Galaxies(j)
|
||||
local o = self.view:Offset(6)
|
||||
if o ~= 0 then
|
||||
local x = self.view:Vector(o)
|
||||
x = x + ((j-1) * 4)
|
||||
x = self.view:Indirect(x)
|
||||
local obj = __Galaxy.New()
|
||||
obj:Init(self.view.bytes, x)
|
||||
return obj
|
||||
end
|
||||
end
|
||||
|
||||
function mt:GalaxiesLength()
|
||||
local o = self.view:Offset(6)
|
||||
if o ~= 0 then
|
||||
return self.view:VectorLen(o)
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function Universe.Start(builder)
|
||||
builder:StartObject(2)
|
||||
end
|
||||
|
||||
function Universe.AddAge(builder, age)
|
||||
builder:PrependFloat64Slot(0, age, 0.0)
|
||||
end
|
||||
|
||||
function Universe.AddGalaxies(builder, galaxies)
|
||||
builder:PrependUOffsetTRelativeSlot(1, galaxies, 0)
|
||||
end
|
||||
|
||||
function Universe.StartGalaxiesVector(builder, numElems)
|
||||
return builder:StartVector(4, numElems, 4)
|
||||
end
|
||||
|
||||
function Universe.End(builder)
|
||||
return builder:EndObject()
|
||||
end
|
||||
|
||||
return Universe
|
||||
10
goldens/lua/generate.py
Normal file
10
goldens/lua/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Lua specifics
|
||||
flatc_golden(options=["--lua"] + options, schema=schema, prefix="lua")
|
||||
|
||||
|
||||
def GenerateLua():
|
||||
flatc([], "basic.fbs")
|
||||
26
goldens/nim/Galaxy.nim
Normal file
26
goldens/nim/Galaxy.nim
Normal file
@@ -0,0 +1,26 @@
|
||||
#[ Galaxy
|
||||
Automatically generated by the FlatBuffers compiler, do not modify.
|
||||
Or modify. I'm a message, not a cop.
|
||||
|
||||
flatc version: 23.5.9
|
||||
|
||||
Declared by : //basic.fbs
|
||||
Rooting type : Universe (//basic.fbs)
|
||||
]#
|
||||
|
||||
import flatbuffers
|
||||
|
||||
type Galaxy* = object of FlatObj
|
||||
func numStars*(self: Galaxy): int64 =
|
||||
let o = self.tab.Offset(4)
|
||||
if o != 0:
|
||||
return Get[int64](self.tab, self.tab.Pos + o)
|
||||
return 0
|
||||
func `numStars=`*(self: var Galaxy, n: int64): bool =
|
||||
return self.tab.MutateSlot(4, n)
|
||||
proc GalaxyStart*(builder: var Builder) =
|
||||
builder.StartObject(1)
|
||||
proc GalaxyAddnumStars*(builder: var Builder, numStars: int64) =
|
||||
builder.PrependSlot(0, numStars, default(int64))
|
||||
proc GalaxyEnd*(builder: var Builder): uoffset =
|
||||
return builder.EndObject()
|
||||
46
goldens/nim/Universe.nim
Normal file
46
goldens/nim/Universe.nim
Normal file
@@ -0,0 +1,46 @@
|
||||
#[ Universe
|
||||
Automatically generated by the FlatBuffers compiler, do not modify.
|
||||
Or modify. I'm a message, not a cop.
|
||||
|
||||
flatc version: 23.5.9
|
||||
|
||||
Declared by : //basic.fbs
|
||||
Rooting type : Universe (//basic.fbs)
|
||||
]#
|
||||
|
||||
import Galaxy as Galaxy
|
||||
import flatbuffers
|
||||
import std/options
|
||||
|
||||
type Universe* = object of FlatObj
|
||||
func age*(self: Universe): float64 =
|
||||
let o = self.tab.Offset(4)
|
||||
if o != 0:
|
||||
return Get[float64](self.tab, self.tab.Pos + o)
|
||||
return 0.0
|
||||
func `age=`*(self: var Universe, n: float64): bool =
|
||||
return self.tab.MutateSlot(4, n)
|
||||
func galaxiesLength*(self: Universe): int =
|
||||
let o = self.tab.Offset(6)
|
||||
if o != 0:
|
||||
return self.tab.VectorLen(o)
|
||||
func galaxies*(self: Universe, j: int): Galaxy.Galaxy =
|
||||
let o = self.tab.Offset(6)
|
||||
if o != 0:
|
||||
var x = self.tab.Vector(o)
|
||||
x += j.uoffset * 4.uoffset
|
||||
return Galaxy.Galaxy(tab: Vtable(Bytes: self.tab.Bytes, Pos: x))
|
||||
func galaxies*(self: Universe): seq[Galaxy.Galaxy] =
|
||||
let len = self.galaxiesLength
|
||||
for i in countup(0, len - 1):
|
||||
result.add(self.galaxies(i))
|
||||
proc UniverseStart*(builder: var Builder) =
|
||||
builder.StartObject(2)
|
||||
proc UniverseAddage*(builder: var Builder, age: float64) =
|
||||
builder.PrependSlot(0, age, default(float64))
|
||||
proc UniverseAddgalaxies*(builder: var Builder, galaxies: uoffset) =
|
||||
builder.PrependSlot(1, galaxies, default(uoffset))
|
||||
proc UniverseStartgalaxiesVector*(builder: var Builder, numElems: uoffset) =
|
||||
builder.StartVector(4, numElems, 4)
|
||||
proc UniverseEnd*(builder: var Builder): uoffset =
|
||||
return builder.EndObject()
|
||||
10
goldens/nim/generate.py
Normal file
10
goldens/nim/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Nim specifics
|
||||
flatc_golden(options=["--nim"] + options, schema=schema, prefix="nim")
|
||||
|
||||
|
||||
def GenerateNim():
|
||||
flatc([], "basic.fbs")
|
||||
82
goldens/php/Galaxy.php
Normal file
82
goldens/php/Galaxy.php
Normal file
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
use \Google\FlatBuffers\Struct;
|
||||
use \Google\FlatBuffers\Table;
|
||||
use \Google\FlatBuffers\ByteBuffer;
|
||||
use \Google\FlatBuffers\FlatBufferBuilder;
|
||||
|
||||
class Galaxy extends Table
|
||||
{
|
||||
/**
|
||||
* @param ByteBuffer $bb
|
||||
* @return Galaxy
|
||||
*/
|
||||
public static function getRootAsGalaxy(ByteBuffer $bb)
|
||||
{
|
||||
$obj = new Galaxy();
|
||||
return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $_i offset
|
||||
* @param ByteBuffer $_bb
|
||||
* @return Galaxy
|
||||
**/
|
||||
public function init($_i, ByteBuffer $_bb)
|
||||
{
|
||||
$this->bb_pos = $_i;
|
||||
$this->bb = $_bb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return long
|
||||
*/
|
||||
public function getNumStars()
|
||||
{
|
||||
$o = $this->__offset(4);
|
||||
return $o != 0 ? $this->bb->getLong($o + $this->bb_pos) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return void
|
||||
*/
|
||||
public static function startGalaxy(FlatBufferBuilder $builder)
|
||||
{
|
||||
$builder->StartObject(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return Galaxy
|
||||
*/
|
||||
public static function createGalaxy(FlatBufferBuilder $builder, $num_stars)
|
||||
{
|
||||
$builder->startObject(1);
|
||||
self::addNumStars($builder, $num_stars);
|
||||
$o = $builder->endObject();
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param long
|
||||
* @return void
|
||||
*/
|
||||
public static function addNumStars(FlatBufferBuilder $builder, $numStars)
|
||||
{
|
||||
$builder->addLongX(0, $numStars, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return int table offset
|
||||
*/
|
||||
public static function endGalaxy(FlatBufferBuilder $builder)
|
||||
{
|
||||
$o = $builder->endObject();
|
||||
return $o;
|
||||
}
|
||||
}
|
||||
141
goldens/php/Universe.php
Normal file
141
goldens/php/Universe.php
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
use \Google\FlatBuffers\Struct;
|
||||
use \Google\FlatBuffers\Table;
|
||||
use \Google\FlatBuffers\ByteBuffer;
|
||||
use \Google\FlatBuffers\FlatBufferBuilder;
|
||||
|
||||
class Universe extends Table
|
||||
{
|
||||
/**
|
||||
* @param ByteBuffer $bb
|
||||
* @return Universe
|
||||
*/
|
||||
public static function getRootAsUniverse(ByteBuffer $bb)
|
||||
{
|
||||
$obj = new Universe();
|
||||
return ($obj->init($bb->getInt($bb->getPosition()) + $bb->getPosition(), $bb));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $_i offset
|
||||
* @param ByteBuffer $_bb
|
||||
* @return Universe
|
||||
**/
|
||||
public function init($_i, ByteBuffer $_bb)
|
||||
{
|
||||
$this->bb_pos = $_i;
|
||||
$this->bb = $_bb;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return double
|
||||
*/
|
||||
public function getAge()
|
||||
{
|
||||
$o = $this->__offset(4);
|
||||
return $o != 0 ? $this->bb->getDouble($o + $this->bb_pos) : 0.0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returnVectorOffset
|
||||
*/
|
||||
public function getGalaxies($j)
|
||||
{
|
||||
$o = $this->__offset(6);
|
||||
$obj = new Galaxy();
|
||||
return $o != 0 ? $obj->init($this->__indirect($this->__vector($o) + $j * 4), $this->bb) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getGalaxiesLength()
|
||||
{
|
||||
$o = $this->__offset(6);
|
||||
return $o != 0 ? $this->__vector_len($o) : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return void
|
||||
*/
|
||||
public static function startUniverse(FlatBufferBuilder $builder)
|
||||
{
|
||||
$builder->StartObject(2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return Universe
|
||||
*/
|
||||
public static function createUniverse(FlatBufferBuilder $builder, $age, $galaxies)
|
||||
{
|
||||
$builder->startObject(2);
|
||||
self::addAge($builder, $age);
|
||||
self::addGalaxies($builder, $galaxies);
|
||||
$o = $builder->endObject();
|
||||
return $o;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param double
|
||||
* @return void
|
||||
*/
|
||||
public static function addAge(FlatBufferBuilder $builder, $age)
|
||||
{
|
||||
$builder->addDoubleX(0, $age, 0.0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param VectorOffset
|
||||
* @return void
|
||||
*/
|
||||
public static function addGalaxies(FlatBufferBuilder $builder, $galaxies)
|
||||
{
|
||||
$builder->addOffsetX(1, $galaxies, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param array offset array
|
||||
* @return int vector offset
|
||||
*/
|
||||
public static function createGalaxiesVector(FlatBufferBuilder $builder, array $data)
|
||||
{
|
||||
$builder->startVector(4, count($data), 4);
|
||||
for ($i = count($data) - 1; $i >= 0; $i--) {
|
||||
$builder->putOffset($data[$i]);
|
||||
}
|
||||
return $builder->endVector();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @param int $numElems
|
||||
* @return void
|
||||
*/
|
||||
public static function startGalaxiesVector(FlatBufferBuilder $builder, $numElems)
|
||||
{
|
||||
$builder->startVector(4, $numElems, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param FlatBufferBuilder $builder
|
||||
* @return int table offset
|
||||
*/
|
||||
public static function endUniverse(FlatBufferBuilder $builder)
|
||||
{
|
||||
$o = $builder->endObject();
|
||||
return $o;
|
||||
}
|
||||
|
||||
public static function finishUniverseBuffer(FlatBufferBuilder $builder, $offset)
|
||||
{
|
||||
$builder->finish($offset);
|
||||
}
|
||||
}
|
||||
10
goldens/php/generate.py
Normal file
10
goldens/php/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with PHP specifics
|
||||
flatc_golden(options=["--php"] + options, schema=schema, prefix="php")
|
||||
|
||||
|
||||
def GeneratePhp():
|
||||
flatc([], "basic.fbs")
|
||||
50
goldens/py/Galaxy.py
Normal file
50
goldens/py/Galaxy.py
Normal file
@@ -0,0 +1,50 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace:
|
||||
|
||||
import flatbuffers
|
||||
from flatbuffers.compat import import_numpy
|
||||
np = import_numpy()
|
||||
|
||||
class Galaxy(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = Galaxy()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsGalaxy(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# Galaxy
|
||||
def Init(self, buf, pos):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
# Galaxy
|
||||
def NumStars(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
||||
if o != 0:
|
||||
return self._tab.Get(flatbuffers.number_types.Int64Flags, o + self._tab.Pos)
|
||||
return 0
|
||||
|
||||
def GalaxyStart(builder):
|
||||
builder.StartObject(1)
|
||||
|
||||
def Start(builder):
|
||||
GalaxyStart(builder)
|
||||
|
||||
def GalaxyAddNumStars(builder, numStars):
|
||||
builder.PrependInt64Slot(0, numStars, 0)
|
||||
|
||||
def AddNumStars(builder: flatbuffers.Builder, numStars: int):
|
||||
GalaxyAddNumStars(builder, numStars)
|
||||
|
||||
def GalaxyEnd(builder):
|
||||
return builder.EndObject()
|
||||
|
||||
def End(builder):
|
||||
return GalaxyEnd(builder)
|
||||
87
goldens/py/Universe.py
Normal file
87
goldens/py/Universe.py
Normal file
@@ -0,0 +1,87 @@
|
||||
# automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
# namespace:
|
||||
|
||||
import flatbuffers
|
||||
from flatbuffers.compat import import_numpy
|
||||
np = import_numpy()
|
||||
|
||||
class Universe(object):
|
||||
__slots__ = ['_tab']
|
||||
|
||||
@classmethod
|
||||
def GetRootAs(cls, buf, offset=0):
|
||||
n = flatbuffers.encode.Get(flatbuffers.packer.uoffset, buf, offset)
|
||||
x = Universe()
|
||||
x.Init(buf, n + offset)
|
||||
return x
|
||||
|
||||
@classmethod
|
||||
def GetRootAsUniverse(cls, buf, offset=0):
|
||||
"""This method is deprecated. Please switch to GetRootAs."""
|
||||
return cls.GetRootAs(buf, offset)
|
||||
# Universe
|
||||
def Init(self, buf, pos):
|
||||
self._tab = flatbuffers.table.Table(buf, pos)
|
||||
|
||||
# Universe
|
||||
def Age(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(4))
|
||||
if o != 0:
|
||||
return self._tab.Get(flatbuffers.number_types.Float64Flags, o + self._tab.Pos)
|
||||
return 0.0
|
||||
|
||||
# Universe
|
||||
def Galaxies(self, j):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
||||
if o != 0:
|
||||
x = self._tab.Vector(o)
|
||||
x += flatbuffers.number_types.UOffsetTFlags.py_type(j) * 4
|
||||
x = self._tab.Indirect(x)
|
||||
from .Galaxy import Galaxy
|
||||
obj = Galaxy()
|
||||
obj.Init(self._tab.Bytes, x)
|
||||
return obj
|
||||
return None
|
||||
|
||||
# Universe
|
||||
def GalaxiesLength(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
||||
if o != 0:
|
||||
return self._tab.VectorLen(o)
|
||||
return 0
|
||||
|
||||
# Universe
|
||||
def GalaxiesIsNone(self):
|
||||
o = flatbuffers.number_types.UOffsetTFlags.py_type(self._tab.Offset(6))
|
||||
return o == 0
|
||||
|
||||
def UniverseStart(builder):
|
||||
builder.StartObject(2)
|
||||
|
||||
def Start(builder):
|
||||
UniverseStart(builder)
|
||||
|
||||
def UniverseAddAge(builder, age):
|
||||
builder.PrependFloat64Slot(0, age, 0.0)
|
||||
|
||||
def AddAge(builder: flatbuffers.Builder, age: float):
|
||||
UniverseAddAge(builder, age)
|
||||
|
||||
def UniverseAddGalaxies(builder, galaxies):
|
||||
builder.PrependUOffsetTRelativeSlot(1, flatbuffers.number_types.UOffsetTFlags.py_type(galaxies), 0)
|
||||
|
||||
def AddGalaxies(builder: flatbuffers.Builder, galaxies: int):
|
||||
UniverseAddGalaxies(builder, galaxies)
|
||||
|
||||
def UniverseStartGalaxiesVector(builder, numElems):
|
||||
return builder.StartVector(4, numElems, 4)
|
||||
|
||||
def StartGalaxiesVector(builder, numElems: int) -> int:
|
||||
return UniverseStartGalaxiesVector(builder, numElems)
|
||||
|
||||
def UniverseEnd(builder):
|
||||
return builder.EndObject()
|
||||
|
||||
def End(builder):
|
||||
return UniverseEnd(builder)
|
||||
0
goldens/py/__init__.py
Normal file
0
goldens/py/__init__.py
Normal file
10
goldens/py/generate.py
Normal file
10
goldens/py/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Python specifics
|
||||
flatc_golden(options=["--python"] + options, schema=schema, prefix="py")
|
||||
|
||||
|
||||
def GeneratePython():
|
||||
flatc([], "basic.fbs")
|
||||
293
goldens/rust/basic_generated.rs
Normal file
293
goldens/rust/basic_generated.rs
Normal file
@@ -0,0 +1,293 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
|
||||
// @generated
|
||||
|
||||
use core::mem;
|
||||
use core::cmp::Ordering;
|
||||
|
||||
extern crate flatbuffers;
|
||||
use self::flatbuffers::{EndianScalar, Follow};
|
||||
|
||||
pub enum GalaxyOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
pub struct Galaxy<'a> {
|
||||
pub _tab: flatbuffers::Table<'a>,
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Follow<'a> for Galaxy<'a> {
|
||||
type Inner = Galaxy<'a>;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table::new(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Galaxy<'a> {
|
||||
pub const VT_NUM_STARS: flatbuffers::VOffsetT = 4;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
Galaxy { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
|
||||
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
|
||||
args: &'args GalaxyArgs
|
||||
) -> flatbuffers::WIPOffset<Galaxy<'bldr>> {
|
||||
let mut builder = GalaxyBuilder::new(_fbb);
|
||||
builder.add_num_stars(args.num_stars);
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn num_stars(&self) -> i64 {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<i64>(Galaxy::VT_NUM_STARS, Some(0)).unwrap()}
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Galaxy<'_> {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<i64>("num_stars", Self::VT_NUM_STARS, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct GalaxyArgs {
|
||||
pub num_stars: i64,
|
||||
}
|
||||
impl<'a> Default for GalaxyArgs {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
GalaxyArgs {
|
||||
num_stars: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct GalaxyBuilder<'a: 'b, 'b> {
|
||||
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
|
||||
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
|
||||
}
|
||||
impl<'a: 'b, 'b> GalaxyBuilder<'a, 'b> {
|
||||
#[inline]
|
||||
pub fn add_num_stars(&mut self, num_stars: i64) {
|
||||
self.fbb_.push_slot::<i64>(Galaxy::VT_NUM_STARS, num_stars, 0);
|
||||
}
|
||||
#[inline]
|
||||
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> GalaxyBuilder<'a, 'b> {
|
||||
let start = _fbb.start_table();
|
||||
GalaxyBuilder {
|
||||
fbb_: _fbb,
|
||||
start_: start,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish(self) -> flatbuffers::WIPOffset<Galaxy<'a>> {
|
||||
let o = self.fbb_.end_table(self.start_);
|
||||
flatbuffers::WIPOffset::new(o.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Galaxy<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let mut ds = f.debug_struct("Galaxy");
|
||||
ds.field("num_stars", &self.num_stars());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
pub enum UniverseOffset {}
|
||||
#[derive(Copy, Clone, PartialEq)]
|
||||
|
||||
pub struct Universe<'a> {
|
||||
pub _tab: flatbuffers::Table<'a>,
|
||||
}
|
||||
|
||||
impl<'a> flatbuffers::Follow<'a> for Universe<'a> {
|
||||
type Inner = Universe<'a>;
|
||||
#[inline]
|
||||
unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
|
||||
Self { _tab: flatbuffers::Table::new(buf, loc) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Universe<'a> {
|
||||
pub const VT_AGE: flatbuffers::VOffsetT = 4;
|
||||
pub const VT_GALAXIES: flatbuffers::VOffsetT = 6;
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn init_from_table(table: flatbuffers::Table<'a>) -> Self {
|
||||
Universe { _tab: table }
|
||||
}
|
||||
#[allow(unused_mut)]
|
||||
pub fn create<'bldr: 'args, 'args: 'mut_bldr, 'mut_bldr>(
|
||||
_fbb: &'mut_bldr mut flatbuffers::FlatBufferBuilder<'bldr>,
|
||||
args: &'args UniverseArgs<'args>
|
||||
) -> flatbuffers::WIPOffset<Universe<'bldr>> {
|
||||
let mut builder = UniverseBuilder::new(_fbb);
|
||||
builder.add_age(args.age);
|
||||
if let Some(x) = args.galaxies { builder.add_galaxies(x); }
|
||||
builder.finish()
|
||||
}
|
||||
|
||||
|
||||
#[inline]
|
||||
pub fn age(&self) -> f64 {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<f64>(Universe::VT_AGE, Some(0.0)).unwrap()}
|
||||
}
|
||||
#[inline]
|
||||
pub fn galaxies(&self) -> Option<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Galaxy<'a>>>> {
|
||||
// Safety:
|
||||
// Created from valid Table for this object
|
||||
// which contains a valid value in this slot
|
||||
unsafe { self._tab.get::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Galaxy>>>>(Universe::VT_GALAXIES, None)}
|
||||
}
|
||||
}
|
||||
|
||||
impl flatbuffers::Verifiable for Universe<'_> {
|
||||
#[inline]
|
||||
fn run_verifier(
|
||||
v: &mut flatbuffers::Verifier, pos: usize
|
||||
) -> Result<(), flatbuffers::InvalidFlatbuffer> {
|
||||
use self::flatbuffers::Verifiable;
|
||||
v.visit_table(pos)?
|
||||
.visit_field::<f64>("age", Self::VT_AGE, false)?
|
||||
.visit_field::<flatbuffers::ForwardsUOffset<flatbuffers::Vector<'_, flatbuffers::ForwardsUOffset<Galaxy>>>>("galaxies", Self::VT_GALAXIES, false)?
|
||||
.finish();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub struct UniverseArgs<'a> {
|
||||
pub age: f64,
|
||||
pub galaxies: Option<flatbuffers::WIPOffset<flatbuffers::Vector<'a, flatbuffers::ForwardsUOffset<Galaxy<'a>>>>>,
|
||||
}
|
||||
impl<'a> Default for UniverseArgs<'a> {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
UniverseArgs {
|
||||
age: 0.0,
|
||||
galaxies: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct UniverseBuilder<'a: 'b, 'b> {
|
||||
fbb_: &'b mut flatbuffers::FlatBufferBuilder<'a>,
|
||||
start_: flatbuffers::WIPOffset<flatbuffers::TableUnfinishedWIPOffset>,
|
||||
}
|
||||
impl<'a: 'b, 'b> UniverseBuilder<'a, 'b> {
|
||||
#[inline]
|
||||
pub fn add_age(&mut self, age: f64) {
|
||||
self.fbb_.push_slot::<f64>(Universe::VT_AGE, age, 0.0);
|
||||
}
|
||||
#[inline]
|
||||
pub fn add_galaxies(&mut self, galaxies: flatbuffers::WIPOffset<flatbuffers::Vector<'b , flatbuffers::ForwardsUOffset<Galaxy<'b >>>>) {
|
||||
self.fbb_.push_slot_always::<flatbuffers::WIPOffset<_>>(Universe::VT_GALAXIES, galaxies);
|
||||
}
|
||||
#[inline]
|
||||
pub fn new(_fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>) -> UniverseBuilder<'a, 'b> {
|
||||
let start = _fbb.start_table();
|
||||
UniverseBuilder {
|
||||
fbb_: _fbb,
|
||||
start_: start,
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish(self) -> flatbuffers::WIPOffset<Universe<'a>> {
|
||||
let o = self.fbb_.end_table(self.start_);
|
||||
flatbuffers::WIPOffset::new(o.value())
|
||||
}
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Universe<'_> {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
let mut ds = f.debug_struct("Universe");
|
||||
ds.field("age", &self.age());
|
||||
ds.field("galaxies", &self.galaxies());
|
||||
ds.finish()
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a `Universe`
|
||||
/// and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_universe_unchecked`.
|
||||
pub fn root_as_universe(buf: &[u8]) -> Result<Universe, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root::<Universe>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies that a buffer of bytes contains a size prefixed
|
||||
/// `Universe` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `size_prefixed_root_as_universe_unchecked`.
|
||||
pub fn size_prefixed_root_as_universe(buf: &[u8]) -> Result<Universe, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root::<Universe>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given options, that a buffer of bytes
|
||||
/// contains a `Universe` and returns it.
|
||||
/// Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_universe_unchecked`.
|
||||
pub fn root_as_universe_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<Universe<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::root_with_opts::<Universe<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Verifies, with the given verifier options, that a buffer of
|
||||
/// bytes contains a size prefixed `Universe` and returns
|
||||
/// it. Note that verification is still experimental and may not
|
||||
/// catch every error, or be maximally performant. For the
|
||||
/// previous, unchecked, behavior use
|
||||
/// `root_as_universe_unchecked`.
|
||||
pub fn size_prefixed_root_as_universe_with_opts<'b, 'o>(
|
||||
opts: &'o flatbuffers::VerifierOptions,
|
||||
buf: &'b [u8],
|
||||
) -> Result<Universe<'b>, flatbuffers::InvalidFlatbuffer> {
|
||||
flatbuffers::size_prefixed_root_with_opts::<Universe<'b>>(opts, buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a Universe and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid `Universe`.
|
||||
pub unsafe fn root_as_universe_unchecked(buf: &[u8]) -> Universe {
|
||||
flatbuffers::root_unchecked::<Universe>(buf)
|
||||
}
|
||||
#[inline]
|
||||
/// Assumes, without verification, that a buffer of bytes contains a size prefixed Universe and returns it.
|
||||
/// # Safety
|
||||
/// Callers must trust the given bytes do indeed contain a valid size prefixed `Universe`.
|
||||
pub unsafe fn size_prefixed_root_as_universe_unchecked(buf: &[u8]) -> Universe {
|
||||
flatbuffers::size_prefixed_root_unchecked::<Universe>(buf)
|
||||
}
|
||||
#[inline]
|
||||
pub fn finish_universe_buffer<'a, 'b>(
|
||||
fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>,
|
||||
root: flatbuffers::WIPOffset<Universe<'a>>) {
|
||||
fbb.finish(root, None);
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn finish_size_prefixed_universe_buffer<'a, 'b>(fbb: &'b mut flatbuffers::FlatBufferBuilder<'a>, root: flatbuffers::WIPOffset<Universe<'a>>) {
|
||||
fbb.finish_size_prefixed(root, None);
|
||||
}
|
||||
10
goldens/rust/generate.py
Normal file
10
goldens/rust/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Rust specifics
|
||||
flatc_golden(options=["--rust"] + options, schema=schema, prefix="rust")
|
||||
|
||||
|
||||
def GenerateRust():
|
||||
flatc([], "basic.fbs")
|
||||
13
goldens/schema/basic.fbs
Normal file
13
goldens/schema/basic.fbs
Normal file
@@ -0,0 +1,13 @@
|
||||
// This file should contain the basics of flatbuffers that all languages should
|
||||
// support.
|
||||
|
||||
table Galaxy {
|
||||
num_stars:long;
|
||||
}
|
||||
|
||||
table Universe {
|
||||
age:double;
|
||||
galaxies:[Galaxy];
|
||||
}
|
||||
|
||||
root_type Universe;
|
||||
84
goldens/swift/basic_generated.swift
Normal file
84
goldens/swift/basic_generated.swift
Normal file
@@ -0,0 +1,84 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
// swiftlint:disable all
|
||||
// swiftformat:disable all
|
||||
|
||||
import FlatBuffers
|
||||
|
||||
public struct Galaxy: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_23_5_26() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
private init(_ t: Table) { _accessor = t }
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||
|
||||
private enum VTOFFSET: VOffset {
|
||||
case numStars = 4
|
||||
var v: Int32 { Int32(self.rawValue) }
|
||||
var p: VOffset { self.rawValue }
|
||||
}
|
||||
|
||||
public var numStars: Int64 { let o = _accessor.offset(VTOFFSET.numStars.v); return o == 0 ? 0 : _accessor.readBuffer(of: Int64.self, at: o) }
|
||||
public static func startGalaxy(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) }
|
||||
public static func add(numStars: Int64, _ fbb: inout FlatBufferBuilder) { fbb.add(element: numStars, def: 0, at: VTOFFSET.numStars.p) }
|
||||
public static func endGalaxy(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||
public static func createGalaxy(
|
||||
_ fbb: inout FlatBufferBuilder,
|
||||
numStars: Int64 = 0
|
||||
) -> Offset {
|
||||
let __start = Galaxy.startGalaxy(&fbb)
|
||||
Galaxy.add(numStars: numStars, &fbb)
|
||||
return Galaxy.endGalaxy(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.numStars.p, fieldName: "numStars", required: false, type: Int64.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
public struct Universe: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_23_5_26() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
private init(_ t: Table) { _accessor = t }
|
||||
public init(_ bb: ByteBuffer, o: Int32) { _accessor = Table(bb: bb, position: o) }
|
||||
|
||||
private enum VTOFFSET: VOffset {
|
||||
case age = 4
|
||||
case galaxies = 6
|
||||
var v: Int32 { Int32(self.rawValue) }
|
||||
var p: VOffset { self.rawValue }
|
||||
}
|
||||
|
||||
public var age: Double { let o = _accessor.offset(VTOFFSET.age.v); return o == 0 ? 0.0 : _accessor.readBuffer(of: Double.self, at: o) }
|
||||
public var hasGalaxies: Bool { let o = _accessor.offset(VTOFFSET.galaxies.v); return o == 0 ? false : true }
|
||||
public var galaxiesCount: Int32 { let o = _accessor.offset(VTOFFSET.galaxies.v); return o == 0 ? 0 : _accessor.vector(count: o) }
|
||||
public func galaxies(at index: Int32) -> Galaxy? { let o = _accessor.offset(VTOFFSET.galaxies.v); return o == 0 ? nil : Galaxy(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
|
||||
public static func startUniverse(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 2) }
|
||||
public static func add(age: Double, _ fbb: inout FlatBufferBuilder) { fbb.add(element: age, def: 0.0, at: VTOFFSET.age.p) }
|
||||
public static func addVectorOf(galaxies: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: galaxies, at: VTOFFSET.galaxies.p) }
|
||||
public static func endUniverse(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end }
|
||||
public static func createUniverse(
|
||||
_ fbb: inout FlatBufferBuilder,
|
||||
age: Double = 0.0,
|
||||
galaxiesVectorOffset galaxies: Offset = Offset()
|
||||
) -> Offset {
|
||||
let __start = Universe.startUniverse(&fbb)
|
||||
Universe.add(age: age, &fbb)
|
||||
Universe.addVectorOf(galaxies: galaxies, &fbb)
|
||||
return Universe.endUniverse(&fbb, start: __start)
|
||||
}
|
||||
|
||||
public static func verify<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
|
||||
var _v = try verifier.visitTable(at: position)
|
||||
try _v.visit(field: VTOFFSET.age.p, fieldName: "age", required: false, type: Double.self)
|
||||
try _v.visit(field: VTOFFSET.galaxies.p, fieldName: "galaxies", required: false, type: ForwardOffset<Vector<ForwardOffset<Galaxy>, Galaxy>>.self)
|
||||
_v.finish()
|
||||
}
|
||||
}
|
||||
|
||||
10
goldens/swift/generate.py
Normal file
10
goldens/swift/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Swift specifics
|
||||
flatc_golden(options=["--swift"] + options, schema=schema, prefix="swift")
|
||||
|
||||
|
||||
def GenerateSwift():
|
||||
flatc([], "basic.fbs")
|
||||
4
goldens/ts/basic.ts
Normal file
4
goldens/ts/basic.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
export { Galaxy } from './galaxy.js';
|
||||
export { Universe } from './universe.js';
|
||||
46
goldens/ts/galaxy.ts
Normal file
46
goldens/ts/galaxy.ts
Normal file
@@ -0,0 +1,46 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
export class Galaxy {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):Galaxy {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsGalaxy(bb:flatbuffers.ByteBuffer, obj?:Galaxy):Galaxy {
|
||||
return (obj || new Galaxy()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsGalaxy(bb:flatbuffers.ByteBuffer, obj?:Galaxy):Galaxy {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new Galaxy()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
numStars():bigint {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readInt64(this.bb_pos + offset) : BigInt('0');
|
||||
}
|
||||
|
||||
static startGalaxy(builder:flatbuffers.Builder) {
|
||||
builder.startObject(1);
|
||||
}
|
||||
|
||||
static addNumStars(builder:flatbuffers.Builder, numStars:bigint) {
|
||||
builder.addFieldInt64(0, numStars, BigInt('0'));
|
||||
}
|
||||
|
||||
static endGalaxy(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static createGalaxy(builder:flatbuffers.Builder, numStars:bigint):flatbuffers.Offset {
|
||||
Galaxy.startGalaxy(builder);
|
||||
Galaxy.addNumStars(builder, numStars);
|
||||
return Galaxy.endGalaxy(builder);
|
||||
}
|
||||
}
|
||||
10
goldens/ts/generate.py
Normal file
10
goldens/ts/generate.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from golden_utils import flatc_golden
|
||||
|
||||
|
||||
def flatc(options, schema):
|
||||
# Wrap the golden flatc generator with Swift specifics
|
||||
flatc_golden(options=["--ts"] + options, schema=schema, prefix="ts")
|
||||
|
||||
|
||||
def GenerateTs():
|
||||
flatc([], "basic.fbs")
|
||||
84
goldens/ts/universe.ts
Normal file
84
goldens/ts/universe.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
// automatically generated by the FlatBuffers compiler, do not modify
|
||||
|
||||
import * as flatbuffers from 'flatbuffers';
|
||||
|
||||
import { Galaxy } from './galaxy.js';
|
||||
|
||||
|
||||
export class Universe {
|
||||
bb: flatbuffers.ByteBuffer|null = null;
|
||||
bb_pos = 0;
|
||||
__init(i:number, bb:flatbuffers.ByteBuffer):Universe {
|
||||
this.bb_pos = i;
|
||||
this.bb = bb;
|
||||
return this;
|
||||
}
|
||||
|
||||
static getRootAsUniverse(bb:flatbuffers.ByteBuffer, obj?:Universe):Universe {
|
||||
return (obj || new Universe()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
static getSizePrefixedRootAsUniverse(bb:flatbuffers.ByteBuffer, obj?:Universe):Universe {
|
||||
bb.setPosition(bb.position() + flatbuffers.SIZE_PREFIX_LENGTH);
|
||||
return (obj || new Universe()).__init(bb.readInt32(bb.position()) + bb.position(), bb);
|
||||
}
|
||||
|
||||
age():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 4);
|
||||
return offset ? this.bb!.readFloat64(this.bb_pos + offset) : 0.0;
|
||||
}
|
||||
|
||||
galaxies(index: number, obj?:Galaxy):Galaxy|null {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? (obj || new Galaxy()).__init(this.bb!.__indirect(this.bb!.__vector(this.bb_pos + offset) + index * 4), this.bb!) : null;
|
||||
}
|
||||
|
||||
galaxiesLength():number {
|
||||
const offset = this.bb!.__offset(this.bb_pos, 6);
|
||||
return offset ? this.bb!.__vector_len(this.bb_pos + offset) : 0;
|
||||
}
|
||||
|
||||
static startUniverse(builder:flatbuffers.Builder) {
|
||||
builder.startObject(2);
|
||||
}
|
||||
|
||||
static addAge(builder:flatbuffers.Builder, age:number) {
|
||||
builder.addFieldFloat64(0, age, 0.0);
|
||||
}
|
||||
|
||||
static addGalaxies(builder:flatbuffers.Builder, galaxiesOffset:flatbuffers.Offset) {
|
||||
builder.addFieldOffset(1, galaxiesOffset, 0);
|
||||
}
|
||||
|
||||
static createGalaxiesVector(builder:flatbuffers.Builder, data:flatbuffers.Offset[]):flatbuffers.Offset {
|
||||
builder.startVector(4, data.length, 4);
|
||||
for (let i = data.length - 1; i >= 0; i--) {
|
||||
builder.addOffset(data[i]!);
|
||||
}
|
||||
return builder.endVector();
|
||||
}
|
||||
|
||||
static startGalaxiesVector(builder:flatbuffers.Builder, numElems:number) {
|
||||
builder.startVector(4, numElems, 4);
|
||||
}
|
||||
|
||||
static endUniverse(builder:flatbuffers.Builder):flatbuffers.Offset {
|
||||
const offset = builder.endObject();
|
||||
return offset;
|
||||
}
|
||||
|
||||
static finishUniverseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset);
|
||||
}
|
||||
|
||||
static finishSizePrefixedUniverseBuffer(builder:flatbuffers.Builder, offset:flatbuffers.Offset) {
|
||||
builder.finish(offset, undefined, true);
|
||||
}
|
||||
|
||||
static createUniverse(builder:flatbuffers.Builder, age:number, galaxiesOffset:flatbuffers.Offset):flatbuffers.Offset {
|
||||
Universe.startUniverse(builder);
|
||||
Universe.addAge(builder, age);
|
||||
Universe.addGalaxies(builder, galaxiesOffset);
|
||||
return Universe.endUniverse(builder);
|
||||
}
|
||||
}
|
||||
@@ -40,7 +40,7 @@ def Start(builder):
|
||||
def HelloReplyAddMessage(builder, message):
|
||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(message), 0)
|
||||
|
||||
def AddMessage(builder: flatbuffers.Builder, message: int):
|
||||
def AddMessage(builder, message):
|
||||
HelloReplyAddMessage(builder, message)
|
||||
|
||||
def HelloReplyEnd(builder):
|
||||
|
||||
@@ -40,7 +40,7 @@ def Start(builder):
|
||||
def HelloRequestAddName(builder, name):
|
||||
builder.PrependUOffsetTRelativeSlot(0, flatbuffers.number_types.UOffsetTFlags.py_type(name), 0)
|
||||
|
||||
def AddName(builder: flatbuffers.Builder, name: int):
|
||||
def AddName(builder, name):
|
||||
HelloRequestAddName(builder, name)
|
||||
|
||||
def HelloRequestEnd(builder):
|
||||
|
||||
@@ -6,7 +6,7 @@ import FlatBuffers
|
||||
|
||||
public struct models_HelloReply: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_23_3_3() }
|
||||
static func validateVersion() { FlatBuffersVersion_23_5_26() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
@@ -53,7 +53,7 @@ extension models_HelloReply: Encodable {
|
||||
|
||||
public struct models_HelloRequest: FlatBufferObject, Verifiable {
|
||||
|
||||
static func validateVersion() { FlatBuffersVersion_23_3_3() }
|
||||
static func validateVersion() { FlatBuffersVersion_23_5_26() }
|
||||
public var __buffer: ByteBuffer! { return _accessor.bb }
|
||||
private var _accessor: Table
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef FLATBUFFERS_ARRAY_H_
|
||||
#define FLATBUFFERS_ARRAY_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <memory>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
@@ -37,7 +38,7 @@ template<typename T, uint16_t length> class Array {
|
||||
public:
|
||||
typedef uint16_t size_type;
|
||||
typedef typename IndirectHelper<IndirectHelperType>::return_type return_type;
|
||||
typedef VectorConstIterator<T, return_type> const_iterator;
|
||||
typedef VectorConstIterator<T, return_type, uoffset_t> const_iterator;
|
||||
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||
|
||||
// If T is a LE-scalar or a struct (!scalar_tag::value).
|
||||
@@ -158,11 +159,13 @@ template<typename T, uint16_t length> class Array {
|
||||
|
||||
// Specialization for Array[struct] with access using Offset<void> pointer.
|
||||
// This specialization used by idl_gen_text.cpp.
|
||||
template<typename T, uint16_t length> class Array<Offset<T>, length> {
|
||||
template<typename T, uint16_t length, template<typename> class OffsetT>
|
||||
class Array<OffsetT<T>, length> {
|
||||
static_assert(flatbuffers::is_same<T, void>::value, "unexpected type T");
|
||||
|
||||
public:
|
||||
typedef const void *return_type;
|
||||
typedef uint16_t size_type;
|
||||
|
||||
const uint8_t *Data() const { return data_; }
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
|
||||
@@ -139,8 +140,8 @@
|
||||
#endif // !defined(FLATBUFFERS_LITTLEENDIAN)
|
||||
|
||||
#define FLATBUFFERS_VERSION_MAJOR 23
|
||||
#define FLATBUFFERS_VERSION_MINOR 3
|
||||
#define FLATBUFFERS_VERSION_REVISION 3
|
||||
#define FLATBUFFERS_VERSION_MINOR 5
|
||||
#define FLATBUFFERS_VERSION_REVISION 26
|
||||
#define FLATBUFFERS_STRING_EXPAND(X) #X
|
||||
#define FLATBUFFERS_STRING(X) FLATBUFFERS_STRING_EXPAND(X)
|
||||
namespace flatbuffers {
|
||||
@@ -278,14 +279,14 @@ namespace flatbuffers {
|
||||
#endif // !FLATBUFFERS_LOCALE_INDEPENDENT
|
||||
|
||||
// Suppress Undefined Behavior Sanitizer (recoverable only). Usage:
|
||||
// - __suppress_ubsan__("undefined")
|
||||
// - __suppress_ubsan__("signed-integer-overflow")
|
||||
// - FLATBUFFERS_SUPPRESS_UBSAN("undefined")
|
||||
// - FLATBUFFERS_SUPPRESS_UBSAN("signed-integer-overflow")
|
||||
#if defined(__clang__) && (__clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >=7))
|
||||
#define __suppress_ubsan__(type) __attribute__((no_sanitize(type)))
|
||||
#define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize(type)))
|
||||
#elif defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 409)
|
||||
#define __suppress_ubsan__(type) __attribute__((no_sanitize_undefined))
|
||||
#define FLATBUFFERS_SUPPRESS_UBSAN(type) __attribute__((no_sanitize_undefined))
|
||||
#else
|
||||
#define __suppress_ubsan__(type)
|
||||
#define FLATBUFFERS_SUPPRESS_UBSAN(type)
|
||||
#endif
|
||||
|
||||
// This is constexpr function used for checking compile-time constants.
|
||||
@@ -323,9 +324,11 @@ namespace flatbuffers {
|
||||
// Also, using a consistent offset type maintains compatibility of serialized
|
||||
// offset values between 32bit and 64bit systems.
|
||||
typedef uint32_t uoffset_t;
|
||||
typedef uint64_t uoffset64_t;
|
||||
|
||||
// Signed offsets for references that can go in both directions.
|
||||
typedef int32_t soffset_t;
|
||||
typedef int64_t soffset64_t;
|
||||
|
||||
// Offset/index used in v-tables, can be changed to uint8_t in
|
||||
// format forks to save a bit of space if desired.
|
||||
@@ -334,7 +337,8 @@ typedef uint16_t voffset_t;
|
||||
typedef uintmax_t largest_scalar_t;
|
||||
|
||||
// In 32bits, this evaluates to 2GB - 1
|
||||
#define FLATBUFFERS_MAX_BUFFER_SIZE ((1ULL << (sizeof(::flatbuffers::soffset_t) * 8 - 1)) - 1)
|
||||
#define FLATBUFFERS_MAX_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset_t>::max()
|
||||
#define FLATBUFFERS_MAX_64_BUFFER_SIZE std::numeric_limits<::flatbuffers::soffset64_t>::max()
|
||||
|
||||
// The minimum size buffer that can be a valid flatbuffer.
|
||||
// Includes the offset to the root table (uoffset_t), the offset to the vtable
|
||||
@@ -418,7 +422,7 @@ template<typename T> T EndianScalar(T t) {
|
||||
|
||||
template<typename T>
|
||||
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
|
||||
__suppress_ubsan__("alignment")
|
||||
FLATBUFFERS_SUPPRESS_UBSAN("alignment")
|
||||
T ReadScalar(const void *p) {
|
||||
return EndianScalar(*reinterpret_cast<const T *>(p));
|
||||
}
|
||||
@@ -432,13 +436,13 @@ T ReadScalar(const void *p) {
|
||||
|
||||
template<typename T>
|
||||
// UBSAN: C++ aliasing type rules, see std::bit_cast<> for details.
|
||||
__suppress_ubsan__("alignment")
|
||||
FLATBUFFERS_SUPPRESS_UBSAN("alignment")
|
||||
void WriteScalar(void *p, T t) {
|
||||
*reinterpret_cast<T *>(p) = EndianScalar(t);
|
||||
}
|
||||
|
||||
template<typename T> struct Offset;
|
||||
template<typename T> __suppress_ubsan__("alignment") void WriteScalar(void *p, Offset<T> t) {
|
||||
template<typename T> FLATBUFFERS_SUPPRESS_UBSAN("alignment") void WriteScalar(void *p, Offset<T> t) {
|
||||
*reinterpret_cast<uoffset_t *>(p) = EndianScalar(t.o);
|
||||
}
|
||||
|
||||
@@ -449,7 +453,7 @@ template<typename T> __suppress_ubsan__("alignment") void WriteScalar(void *p, O
|
||||
// Computes how many bytes you'd have to pad to be able to write an
|
||||
// "scalar_size" scalar if the buffer had grown to "buf_size" (downwards in
|
||||
// memory).
|
||||
__suppress_ubsan__("unsigned-integer-overflow")
|
||||
FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow")
|
||||
inline size_t PaddingBytes(size_t buf_size, size_t scalar_size) {
|
||||
return ((~buf_size) + 1) & (scalar_size - 1);
|
||||
}
|
||||
|
||||
@@ -25,14 +25,33 @@ namespace flatbuffers {
|
||||
|
||||
// Wrapper for uoffset_t to allow safe template specialization.
|
||||
// Value is allowed to be 0 to indicate a null object (see e.g. AddOffset).
|
||||
template<typename T> struct Offset {
|
||||
uoffset_t o;
|
||||
template<typename T = void> struct Offset {
|
||||
// The type of offset to use.
|
||||
typedef uoffset_t offset_type;
|
||||
|
||||
offset_type o;
|
||||
Offset() : o(0) {}
|
||||
Offset(uoffset_t _o) : o(_o) {}
|
||||
Offset<void> Union() const { return Offset<void>(o); }
|
||||
Offset(const offset_type _o) : o(_o) {}
|
||||
Offset<> Union() const { return o; }
|
||||
bool IsNull() const { return !o; }
|
||||
};
|
||||
|
||||
// Wrapper for uoffset64_t Offsets.
|
||||
template<typename T = void> struct Offset64 {
|
||||
// The type of offset to use.
|
||||
typedef uoffset64_t offset_type;
|
||||
|
||||
offset_type o;
|
||||
Offset64() : o(0) {}
|
||||
Offset64(const offset_type offset) : o(offset) {}
|
||||
Offset64<> Union() const { return o; }
|
||||
bool IsNull() const { return !o; }
|
||||
};
|
||||
|
||||
// Litmus check for ensuring the Offsets are the expected size.
|
||||
static_assert(sizeof(Offset<>) == 4, "Offset has wrong size");
|
||||
static_assert(sizeof(Offset64<>) == 8, "Offset64 has wrong size");
|
||||
|
||||
inline void EndianCheck() {
|
||||
int endiantest = 1;
|
||||
// If this fails, see FLATBUFFERS_LITTLEENDIAN above.
|
||||
@@ -75,35 +94,59 @@ template<typename T> struct IndirectHelper {
|
||||
typedef T return_type;
|
||||
typedef T mutable_return_type;
|
||||
static const size_t element_stride = sizeof(T);
|
||||
static return_type Read(const uint8_t *p, uoffset_t i) {
|
||||
|
||||
static return_type Read(const uint8_t *p, const size_t i) {
|
||||
return EndianScalar((reinterpret_cast<const T *>(p))[i]);
|
||||
}
|
||||
static return_type Read(uint8_t *p, uoffset_t i) {
|
||||
return Read(const_cast<const uint8_t *>(p), i);
|
||||
static mutable_return_type Read(uint8_t *p, const size_t i) {
|
||||
return reinterpret_cast<mutable_return_type>(
|
||||
Read(const_cast<const uint8_t *>(p), i));
|
||||
}
|
||||
};
|
||||
template<typename T> struct IndirectHelper<Offset<T>> {
|
||||
|
||||
// For vector of Offsets.
|
||||
template<typename T, template<typename> class OffsetT>
|
||||
struct IndirectHelper<OffsetT<T>> {
|
||||
typedef const T *return_type;
|
||||
typedef T *mutable_return_type;
|
||||
static const size_t element_stride = sizeof(uoffset_t);
|
||||
static return_type Read(const uint8_t *p, uoffset_t i) {
|
||||
p += i * sizeof(uoffset_t);
|
||||
return reinterpret_cast<return_type>(p + ReadScalar<uoffset_t>(p));
|
||||
typedef typename OffsetT<T>::offset_type offset_type;
|
||||
static const offset_type element_stride = sizeof(offset_type);
|
||||
|
||||
static return_type Read(const uint8_t *const p, const offset_type i) {
|
||||
// Offsets are relative to themselves, so first update the pointer to
|
||||
// point to the offset location.
|
||||
const uint8_t *const offset_location = p + i * element_stride;
|
||||
|
||||
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
||||
// then determine the relative location from the offset location.
|
||||
return reinterpret_cast<return_type>(
|
||||
offset_location + ReadScalar<offset_type>(offset_location));
|
||||
}
|
||||
static mutable_return_type Read(uint8_t *p, uoffset_t i) {
|
||||
p += i * sizeof(uoffset_t);
|
||||
return reinterpret_cast<mutable_return_type>(p + ReadScalar<uoffset_t>(p));
|
||||
static mutable_return_type Read(uint8_t *const p, const offset_type i) {
|
||||
// Offsets are relative to themselves, so first update the pointer to
|
||||
// point to the offset location.
|
||||
uint8_t *const offset_location = p + i * element_stride;
|
||||
|
||||
// Then read the scalar value of the offset (which may be 32 or 64-bits) and
|
||||
// then determine the relative location from the offset location.
|
||||
return reinterpret_cast<mutable_return_type>(
|
||||
offset_location + ReadScalar<offset_type>(offset_location));
|
||||
}
|
||||
};
|
||||
|
||||
// For vector of structs.
|
||||
template<typename T> struct IndirectHelper<const T *> {
|
||||
typedef const T *return_type;
|
||||
typedef T *mutable_return_type;
|
||||
static const size_t element_stride = sizeof(T);
|
||||
static return_type Read(const uint8_t *p, uoffset_t i) {
|
||||
return reinterpret_cast<return_type>(p + i * sizeof(T));
|
||||
|
||||
static return_type Read(const uint8_t *const p, const size_t i) {
|
||||
// Structs are stored inline, relative to the first struct pointer.
|
||||
return reinterpret_cast<return_type>(p + i * element_stride);
|
||||
}
|
||||
static mutable_return_type Read(uint8_t *p, uoffset_t i) {
|
||||
return reinterpret_cast<mutable_return_type>(p + i * sizeof(T));
|
||||
static mutable_return_type Read(uint8_t *const p, const size_t i) {
|
||||
// Structs are stored inline, relative to the first struct pointer.
|
||||
return reinterpret_cast<mutable_return_type>(p + i * element_stride);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -130,23 +173,25 @@ inline bool BufferHasIdentifier(const void *buf, const char *identifier,
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
// Helpers to get a typed pointer to the root object contained in the buffer.
|
||||
template<typename T> T *GetMutableRoot(void *buf) {
|
||||
if (!buf) return nullptr;
|
||||
EndianCheck();
|
||||
return reinterpret_cast<T *>(
|
||||
reinterpret_cast<uint8_t *>(buf) +
|
||||
EndianScalar(*reinterpret_cast<uoffset_t *>(buf)));
|
||||
}
|
||||
|
||||
template<typename T> T *GetMutableSizePrefixedRoot(void *buf) {
|
||||
return GetMutableRoot<T>(reinterpret_cast<uint8_t *>(buf) +
|
||||
sizeof(uoffset_t));
|
||||
template<typename T, typename SizeT = uoffset_t>
|
||||
T *GetMutableSizePrefixedRoot(void *buf) {
|
||||
return GetMutableRoot<T>(reinterpret_cast<uint8_t *>(buf) + sizeof(SizeT));
|
||||
}
|
||||
|
||||
template<typename T> const T *GetRoot(const void *buf) {
|
||||
return GetMutableRoot<T>(const_cast<void *>(buf));
|
||||
}
|
||||
|
||||
template<typename T> const T *GetSizePrefixedRoot(const void *buf) {
|
||||
return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(uoffset_t));
|
||||
template<typename T, typename SizeT = uoffset_t>
|
||||
const T *GetSizePrefixedRoot(const void *buf) {
|
||||
return GetRoot<T>(reinterpret_cast<const uint8_t *>(buf) + sizeof(SizeT));
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
|
||||
namespace flatbuffers {
|
||||
|
||||
struct CodeGenOptions {
|
||||
std::string output_path;
|
||||
};
|
||||
|
||||
// A code generator interface for producing converting flatbuffer schema into
|
||||
// code.
|
||||
class CodeGenerator {
|
||||
@@ -36,15 +40,28 @@ class CodeGenerator {
|
||||
NOT_IMPLEMENTED = 3
|
||||
};
|
||||
|
||||
std::string status_detail;
|
||||
|
||||
// Generate code from the provided `parser`.
|
||||
//
|
||||
// DEPRECATED: prefer using the other overload of GenerateCode for bfbs.
|
||||
virtual Status GenerateCode(const Parser &parser, const std::string &path,
|
||||
const std::string &filename) = 0;
|
||||
|
||||
// Generate code from the provided `parser` and place it in the output.
|
||||
virtual Status GenerateCodeString(const Parser &parser,
|
||||
const std::string &filename,
|
||||
std::string &output) {
|
||||
(void)parser;
|
||||
(void)filename;
|
||||
(void)output;
|
||||
return Status::NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Generate code from the provided `buffer` of given `length`. The buffer is a
|
||||
// serialized reflection.fbs.
|
||||
virtual Status GenerateCode(const uint8_t *buffer, int64_t length) = 0;
|
||||
virtual Status GenerateCode(const uint8_t *buffer, int64_t length,
|
||||
const CodeGenOptions &options) = 0;
|
||||
|
||||
virtual Status GenerateMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &filename,
|
||||
|
||||
@@ -229,6 +229,10 @@ class TypedFloatConstantGenerator : public FloatConstantGenerator {
|
||||
const std::string neg_inf_number_;
|
||||
};
|
||||
|
||||
std::string JavaCSharpMakeRule(const bool java, const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_CODE_GENERATORS_H_
|
||||
|
||||
@@ -18,12 +18,15 @@
|
||||
#define FLATBUFFERS_FLATBUFFER_BUILDER_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <initializer_list>
|
||||
#include <type_traits>
|
||||
|
||||
#include "flatbuffers/allocator.h"
|
||||
#include "flatbuffers/array.h"
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/buffer.h"
|
||||
#include "flatbuffers/buffer_ref.h"
|
||||
#include "flatbuffers/default_allocator.h"
|
||||
#include "flatbuffers/detached_buffer.h"
|
||||
@@ -40,8 +43,9 @@ namespace flatbuffers {
|
||||
// Converts a Field ID to a virtual table offset.
|
||||
inline voffset_t FieldIndexToOffset(voffset_t field_id) {
|
||||
// Should correspond to what EndTable() below builds up.
|
||||
const int fixed_fields = 2; // Vtable size and Object Size.
|
||||
return static_cast<voffset_t>((field_id + fixed_fields) * sizeof(voffset_t));
|
||||
const voffset_t fixed_fields =
|
||||
2 * sizeof(voffset_t); // Vtable size and Object Size.
|
||||
return fixed_fields + field_id * sizeof(voffset_t);
|
||||
}
|
||||
|
||||
template<typename T, typename Alloc = std::allocator<T>>
|
||||
@@ -68,8 +72,13 @@ T *data(std::vector<T, Alloc> &v) {
|
||||
/// `PushElement`/`AddElement`/`EndTable`, or the builtin `CreateString`/
|
||||
/// `CreateVector` functions. Do this is depth-first order to build up a tree to
|
||||
/// the root. `Finish()` wraps up the buffer ready for transport.
|
||||
class FlatBufferBuilder {
|
||||
template<bool Is64Aware = false> class FlatBufferBuilderImpl {
|
||||
public:
|
||||
// This switches the size type of the builder, based on if its 64-bit aware
|
||||
// (uoffset64_t) or not (uoffset_t).
|
||||
typedef
|
||||
typename std::conditional<Is64Aware, uoffset64_t, uoffset_t>::type SizeT;
|
||||
|
||||
/// @brief Default constructor for FlatBufferBuilder.
|
||||
/// @param[in] initial_size The initial size of the buffer, in bytes. Defaults
|
||||
/// to `1024`.
|
||||
@@ -81,13 +90,16 @@ class FlatBufferBuilder {
|
||||
/// minimum alignment upon reallocation. Only needed if you intend to store
|
||||
/// types with custom alignment AND you wish to read the buffer in-place
|
||||
/// directly after creation.
|
||||
explicit FlatBufferBuilder(
|
||||
explicit FlatBufferBuilderImpl(
|
||||
size_t initial_size = 1024, Allocator *allocator = nullptr,
|
||||
bool own_allocator = false,
|
||||
size_t buffer_minalign = AlignOf<largest_scalar_t>())
|
||||
: buf_(initial_size, allocator, own_allocator, buffer_minalign),
|
||||
: buf_(initial_size, allocator, own_allocator, buffer_minalign,
|
||||
static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
|
||||
: FLATBUFFERS_MAX_BUFFER_SIZE)),
|
||||
num_field_loc(0),
|
||||
max_voffset_(0),
|
||||
length_of_64_bit_region_(0),
|
||||
nested(false),
|
||||
finished(false),
|
||||
minalign_(1),
|
||||
@@ -98,10 +110,13 @@ class FlatBufferBuilder {
|
||||
}
|
||||
|
||||
/// @brief Move constructor for FlatBufferBuilder.
|
||||
FlatBufferBuilder(FlatBufferBuilder &&other) noexcept
|
||||
: buf_(1024, nullptr, false, AlignOf<largest_scalar_t>()),
|
||||
FlatBufferBuilderImpl(FlatBufferBuilderImpl &&other) noexcept
|
||||
: buf_(1024, nullptr, false, AlignOf<largest_scalar_t>(),
|
||||
static_cast<SizeT>(Is64Aware ? FLATBUFFERS_MAX_64_BUFFER_SIZE
|
||||
: FLATBUFFERS_MAX_BUFFER_SIZE)),
|
||||
num_field_loc(0),
|
||||
max_voffset_(0),
|
||||
length_of_64_bit_region_(0),
|
||||
nested(false),
|
||||
finished(false),
|
||||
minalign_(1),
|
||||
@@ -116,18 +131,19 @@ class FlatBufferBuilder {
|
||||
}
|
||||
|
||||
/// @brief Move assignment operator for FlatBufferBuilder.
|
||||
FlatBufferBuilder &operator=(FlatBufferBuilder &&other) noexcept {
|
||||
FlatBufferBuilderImpl &operator=(FlatBufferBuilderImpl &&other) noexcept {
|
||||
// Move construct a temporary and swap idiom
|
||||
FlatBufferBuilder temp(std::move(other));
|
||||
FlatBufferBuilderImpl temp(std::move(other));
|
||||
Swap(temp);
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Swap(FlatBufferBuilder &other) {
|
||||
void Swap(FlatBufferBuilderImpl &other) {
|
||||
using std::swap;
|
||||
buf_.swap(other.buf_);
|
||||
swap(num_field_loc, other.num_field_loc);
|
||||
swap(max_voffset_, other.max_voffset_);
|
||||
swap(length_of_64_bit_region_, other.length_of_64_bit_region_);
|
||||
swap(nested, other.nested);
|
||||
swap(finished, other.finished);
|
||||
swap(minalign_, other.minalign_);
|
||||
@@ -136,7 +152,7 @@ class FlatBufferBuilder {
|
||||
swap(string_pool, other.string_pool);
|
||||
}
|
||||
|
||||
~FlatBufferBuilder() {
|
||||
~FlatBufferBuilderImpl() {
|
||||
if (string_pool) delete string_pool;
|
||||
}
|
||||
|
||||
@@ -153,12 +169,36 @@ class FlatBufferBuilder {
|
||||
nested = false;
|
||||
finished = false;
|
||||
minalign_ = 1;
|
||||
length_of_64_bit_region_ = 0;
|
||||
if (string_pool) string_pool->clear();
|
||||
}
|
||||
|
||||
/// @brief The current size of the serialized buffer, counting from the end.
|
||||
/// @return Returns an `SizeT` with the current size of the buffer.
|
||||
SizeT GetSize() const { return buf_.size(); }
|
||||
|
||||
/// @brief The current size of the serialized buffer relative to the end of
|
||||
/// the 32-bit region.
|
||||
/// @return Returns an `uoffset_t` with the current size of the buffer.
|
||||
uoffset_t GetSize() const { return buf_.size(); }
|
||||
template<bool is_64 = Is64Aware>
|
||||
// Only enable this method for the 64-bit builder, as only that builder is
|
||||
// concerned with the 32/64-bit boundary, and should be the one to bare any
|
||||
// run time costs.
|
||||
typename std::enable_if<is_64, uoffset_t>::type GetSizeRelative32BitRegion()
|
||||
const {
|
||||
//[32-bit region][64-bit region]
|
||||
// [XXXXXXXXXXXXXXXXXXX] GetSize()
|
||||
// [YYYYYYYYYYYYY] length_of_64_bit_region_
|
||||
// [ZZZZ] return size
|
||||
return static_cast<uoffset_t>(GetSize() - length_of_64_bit_region_);
|
||||
}
|
||||
|
||||
template<bool is_64 = Is64Aware>
|
||||
// Only enable this method for the 32-bit builder.
|
||||
typename std::enable_if<!is_64, uoffset_t>::type GetSizeRelative32BitRegion()
|
||||
const {
|
||||
return static_cast<uoffset_t>(GetSize());
|
||||
}
|
||||
|
||||
/// @brief Get the serialized buffer (after you call `Finish()`).
|
||||
/// @return Returns an `uint8_t` pointer to the FlatBuffer data inside the
|
||||
@@ -270,14 +310,16 @@ class FlatBufferBuilder {
|
||||
}
|
||||
|
||||
// Write a single aligned scalar to the buffer
|
||||
template<typename T> uoffset_t PushElement(T element) {
|
||||
template<typename T, typename ReturnT = uoffset_t>
|
||||
ReturnT PushElement(T element) {
|
||||
AssertScalarT<T>();
|
||||
Align(sizeof(T));
|
||||
buf_.push_small(EndianScalar(element));
|
||||
return GetSize();
|
||||
return CalculateOffset<ReturnT>();
|
||||
}
|
||||
|
||||
template<typename T> uoffset_t PushElement(Offset<T> off) {
|
||||
template<typename T, template<typename> class OffsetT = Offset>
|
||||
uoffset_t PushElement(OffsetT<T> off) {
|
||||
// Special case for offsets: see ReferTo below.
|
||||
return PushElement(ReferTo(off.o));
|
||||
}
|
||||
@@ -307,11 +349,16 @@ class FlatBufferBuilder {
|
||||
AddElement(field, ReferTo(off.o), static_cast<uoffset_t>(0));
|
||||
}
|
||||
|
||||
template<typename T> void AddOffset(voffset_t field, Offset64<T> off) {
|
||||
if (off.IsNull()) return; // Don't store.
|
||||
AddElement(field, ReferTo(off.o), static_cast<uoffset64_t>(0));
|
||||
}
|
||||
|
||||
template<typename T> void AddStruct(voffset_t field, const T *structptr) {
|
||||
if (!structptr) return; // Default, don't store.
|
||||
Align(AlignOf<T>());
|
||||
buf_.push_small(*structptr);
|
||||
TrackField(field, GetSize());
|
||||
TrackField(field, CalculateOffset<uoffset_t>());
|
||||
}
|
||||
|
||||
void AddStructOffset(voffset_t field, uoffset_t off) {
|
||||
@@ -322,12 +369,29 @@ class FlatBufferBuilder {
|
||||
// This function converts them to be relative to the current location
|
||||
// in the buffer (when stored here), pointing upwards.
|
||||
uoffset_t ReferTo(uoffset_t off) {
|
||||
// Align to ensure GetSize() below is correct.
|
||||
// Align to ensure GetSizeRelative32BitRegion() below is correct.
|
||||
Align(sizeof(uoffset_t));
|
||||
// Offset must refer to something already in buffer.
|
||||
const uoffset_t size = GetSize();
|
||||
// 32-bit offsets are relative to the tail of the 32-bit region of the
|
||||
// buffer. For most cases (without 64-bit entities) this is equivalent to
|
||||
// size of the whole buffer (e.g. GetSize())
|
||||
return ReferTo(off, GetSizeRelative32BitRegion());
|
||||
}
|
||||
|
||||
uoffset64_t ReferTo(uoffset64_t off) {
|
||||
// Align to ensure GetSize() below is correct.
|
||||
Align(sizeof(uoffset64_t));
|
||||
// 64-bit offsets are relative to tail of the whole buffer
|
||||
return ReferTo(off, GetSize());
|
||||
}
|
||||
|
||||
template<typename T, typename T2> T ReferTo(const T off, const T2 size) {
|
||||
FLATBUFFERS_ASSERT(off && off <= size);
|
||||
return size - off + static_cast<uoffset_t>(sizeof(uoffset_t));
|
||||
return size - off + static_cast<T>(sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T> T ReferTo(const T off, const T size) {
|
||||
FLATBUFFERS_ASSERT(off && off <= size);
|
||||
return size - off + static_cast<T>(sizeof(T));
|
||||
}
|
||||
|
||||
void NotNested() {
|
||||
@@ -349,7 +413,7 @@ class FlatBufferBuilder {
|
||||
uoffset_t StartTable() {
|
||||
NotNested();
|
||||
nested = true;
|
||||
return GetSize();
|
||||
return GetSizeRelative32BitRegion();
|
||||
}
|
||||
|
||||
// This finishes one serialized object by generating the vtable if it's a
|
||||
@@ -360,7 +424,9 @@ class FlatBufferBuilder {
|
||||
FLATBUFFERS_ASSERT(nested);
|
||||
// Write the vtable offset, which is the start of any Table.
|
||||
// We fill its value later.
|
||||
auto vtableoffsetloc = PushElement<soffset_t>(0);
|
||||
// This is relative to the end of the 32-bit region.
|
||||
const uoffset_t vtable_offset_loc =
|
||||
static_cast<uoffset_t>(PushElement<soffset_t>(0));
|
||||
// Write a vtable, which consists entirely of voffset_t elements.
|
||||
// It starts with the number of offsets, followed by a type id, followed
|
||||
// by the offsets themselves. In reverse:
|
||||
@@ -370,7 +436,7 @@ class FlatBufferBuilder {
|
||||
(std::max)(static_cast<voffset_t>(max_voffset_ + sizeof(voffset_t)),
|
||||
FieldIndexToOffset(0));
|
||||
buf_.fill_big(max_voffset_);
|
||||
auto table_object_size = vtableoffsetloc - start;
|
||||
const uoffset_t table_object_size = vtable_offset_loc - start;
|
||||
// Vtable use 16bit offsets.
|
||||
FLATBUFFERS_ASSERT(table_object_size < 0x10000);
|
||||
WriteScalar<voffset_t>(buf_.data() + sizeof(voffset_t),
|
||||
@@ -380,7 +446,8 @@ class FlatBufferBuilder {
|
||||
for (auto it = buf_.scratch_end() - num_field_loc * sizeof(FieldLoc);
|
||||
it < buf_.scratch_end(); it += sizeof(FieldLoc)) {
|
||||
auto field_location = reinterpret_cast<FieldLoc *>(it);
|
||||
auto pos = static_cast<voffset_t>(vtableoffsetloc - field_location->off);
|
||||
const voffset_t pos =
|
||||
static_cast<voffset_t>(vtable_offset_loc - field_location->off);
|
||||
// If this asserts, it means you've set a field twice.
|
||||
FLATBUFFERS_ASSERT(
|
||||
!ReadScalar<voffset_t>(buf_.data() + field_location->id));
|
||||
@@ -389,7 +456,7 @@ class FlatBufferBuilder {
|
||||
ClearOffsets();
|
||||
auto vt1 = reinterpret_cast<voffset_t *>(buf_.data());
|
||||
auto vt1_size = ReadScalar<voffset_t>(vt1);
|
||||
auto vt_use = GetSize();
|
||||
auto vt_use = GetSizeRelative32BitRegion();
|
||||
// See if we already have generated a vtable with this exact same
|
||||
// layout before. If so, make it point to the old one, remove this one.
|
||||
if (dedup_vtables_) {
|
||||
@@ -400,23 +467,24 @@ class FlatBufferBuilder {
|
||||
auto vt2_size = ReadScalar<voffset_t>(vt2);
|
||||
if (vt1_size != vt2_size || 0 != memcmp(vt2, vt1, vt1_size)) continue;
|
||||
vt_use = *vt_offset_ptr;
|
||||
buf_.pop(GetSize() - vtableoffsetloc);
|
||||
buf_.pop(GetSizeRelative32BitRegion() - vtable_offset_loc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If this is a new vtable, remember it.
|
||||
if (vt_use == GetSize()) { buf_.scratch_push_small(vt_use); }
|
||||
if (vt_use == GetSizeRelative32BitRegion()) {
|
||||
buf_.scratch_push_small(vt_use);
|
||||
}
|
||||
// Fill the vtable offset we created above.
|
||||
// The offset points from the beginning of the object to where the
|
||||
// vtable is stored.
|
||||
// The offset points from the beginning of the object to where the vtable is
|
||||
// stored.
|
||||
// Offsets default direction is downward in memory for future format
|
||||
// flexibility (storing all vtables at the start of the file).
|
||||
WriteScalar(buf_.data_at(vtableoffsetloc),
|
||||
WriteScalar(buf_.data_at(vtable_offset_loc + length_of_64_bit_region_),
|
||||
static_cast<soffset_t>(vt_use) -
|
||||
static_cast<soffset_t>(vtableoffsetloc));
|
||||
|
||||
static_cast<soffset_t>(vtable_offset_loc));
|
||||
nested = false;
|
||||
return vtableoffsetloc;
|
||||
return vtable_offset_loc;
|
||||
}
|
||||
|
||||
FLATBUFFERS_ATTRIBUTE([[deprecated("call the version above instead")]])
|
||||
@@ -426,14 +494,20 @@ class FlatBufferBuilder {
|
||||
|
||||
// This checks a required field has been set in a given table that has
|
||||
// just been constructed.
|
||||
template<typename T> void Required(Offset<T> table, voffset_t field);
|
||||
template<typename T> void Required(Offset<T> table, voffset_t field) {
|
||||
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
|
||||
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
|
||||
// If this fails, the caller will show what field needs to be set.
|
||||
FLATBUFFERS_ASSERT(ok);
|
||||
(void)ok;
|
||||
}
|
||||
|
||||
uoffset_t StartStruct(size_t alignment) {
|
||||
Align(alignment);
|
||||
return GetSize();
|
||||
return GetSizeRelative32BitRegion();
|
||||
}
|
||||
|
||||
uoffset_t EndStruct() { return GetSize(); }
|
||||
uoffset_t EndStruct() { return GetSizeRelative32BitRegion(); }
|
||||
|
||||
void ClearOffsets() {
|
||||
buf_.scratch_pop(num_field_loc * sizeof(FieldLoc));
|
||||
@@ -442,15 +516,18 @@ class FlatBufferBuilder {
|
||||
}
|
||||
|
||||
// Aligns such that when "len" bytes are written, an object can be written
|
||||
// after it with "alignment" without padding.
|
||||
// after it (forward in the buffer) with "alignment" without padding.
|
||||
void PreAlign(size_t len, size_t alignment) {
|
||||
if (len == 0) return;
|
||||
TrackMinAlign(alignment);
|
||||
buf_.fill(PaddingBytes(GetSize() + len, alignment));
|
||||
}
|
||||
template<typename T> void PreAlign(size_t len) {
|
||||
AssertScalarT<T>();
|
||||
PreAlign(len, AlignOf<T>());
|
||||
|
||||
// Aligns such than when "len" bytes are written, an object of type `AlignT`
|
||||
// can be written after it (forward in the buffer) without padding.
|
||||
template<typename AlignT> void PreAlign(size_t len) {
|
||||
AssertScalarT<AlignT>();
|
||||
PreAlign(len, AlignOf<AlignT>());
|
||||
}
|
||||
/// @endcond
|
||||
|
||||
@@ -458,43 +535,45 @@ class FlatBufferBuilder {
|
||||
/// @param[in] str A const char pointer to the data to be stored as a string.
|
||||
/// @param[in] len The number of bytes that should be stored from `str`.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
Offset<String> CreateString(const char *str, size_t len) {
|
||||
NotNested();
|
||||
PreAlign<uoffset_t>(len + 1); // Always 0-terminated.
|
||||
buf_.fill(1);
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(str), len);
|
||||
PushElement(static_cast<uoffset_t>(len));
|
||||
return Offset<String>(GetSize());
|
||||
template<template<typename> class OffsetT = Offset>
|
||||
OffsetT<String> CreateString(const char *str, size_t len) {
|
||||
CreateStringImpl(str, len);
|
||||
return OffsetT<String>(
|
||||
CalculateOffset<typename OffsetT<String>::offset_type>());
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which is null-terminated.
|
||||
/// @param[in] str A const char pointer to a C-string to add to the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
Offset<String> CreateString(const char *str) {
|
||||
return CreateString(str, strlen(str));
|
||||
template<template<typename> class OffsetT = Offset>
|
||||
OffsetT<String> CreateString(const char *str) {
|
||||
return CreateString<OffsetT>(str, strlen(str));
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which is null-terminated.
|
||||
/// @param[in] str A char pointer to a C-string to add to the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
Offset<String> CreateString(char *str) {
|
||||
return CreateString(str, strlen(str));
|
||||
template<template<typename> class OffsetT = Offset>
|
||||
OffsetT<String> CreateString(char *str) {
|
||||
return CreateString<OffsetT>(str, strlen(str));
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
/// @param[in] str A const reference to a std::string to store in the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
Offset<String> CreateString(const std::string &str) {
|
||||
return CreateString(str.c_str(), str.length());
|
||||
template<template<typename> class OffsetT = Offset>
|
||||
OffsetT<String> CreateString(const std::string &str) {
|
||||
return CreateString<OffsetT>(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
// clang-format off
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_HAS_STRING_VIEW
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
/// @param[in] str A const string_view to copy in to the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
Offset<String> CreateString(flatbuffers::string_view str) {
|
||||
return CreateString(str.data(), str.size());
|
||||
template<template <typename> class OffsetT = Offset>
|
||||
OffsetT<String>CreateString(flatbuffers::string_view str) {
|
||||
return CreateString<OffsetT>(str.data(), str.size());
|
||||
}
|
||||
#endif // FLATBUFFERS_HAS_STRING_VIEW
|
||||
// clang-format on
|
||||
@@ -502,16 +581,21 @@ class FlatBufferBuilder {
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
/// @param[in] str A const pointer to a `String` struct to add to the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts
|
||||
Offset<String> CreateString(const String *str) {
|
||||
return str ? CreateString(str->c_str(), str->size()) : 0;
|
||||
template<template<typename> class OffsetT = Offset>
|
||||
OffsetT<String> CreateString(const String *str) {
|
||||
return str ? CreateString<OffsetT>(str->c_str(), str->size()) : 0;
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
/// @param[in] str A const reference to a std::string like type with support
|
||||
/// of T::c_str() and T::length() to store in the buffer.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
template<typename T> Offset<String> CreateString(const T &str) {
|
||||
return CreateString(str.c_str(), str.length());
|
||||
template<template<typename> class OffsetT = Offset,
|
||||
// No need to explicitly declare the T type, let the compiler deduce
|
||||
// it.
|
||||
int &...ExplicitArgumentBarrier, typename T>
|
||||
OffsetT<String> CreateString(const T &str) {
|
||||
return CreateString<OffsetT>(str.c_str(), str.length());
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
@@ -523,12 +607,14 @@ class FlatBufferBuilder {
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
Offset<String> CreateSharedString(const char *str, size_t len) {
|
||||
FLATBUFFERS_ASSERT(FLATBUFFERS_GENERAL_HEAP_ALLOC_OK);
|
||||
if (!string_pool)
|
||||
if (!string_pool) {
|
||||
string_pool = new StringOffsetMap(StringOffsetCompare(buf_));
|
||||
auto size_before_string = buf_.size();
|
||||
}
|
||||
|
||||
const size_t size_before_string = buf_.size();
|
||||
// Must first serialize the string, since the set is all offsets into
|
||||
// buffer.
|
||||
auto off = CreateString(str, len);
|
||||
const Offset<String> off = CreateString<Offset>(str, len);
|
||||
auto it = string_pool->find(off);
|
||||
// If it exists we reuse existing serialized data!
|
||||
if (it != string_pool->end()) {
|
||||
@@ -584,21 +670,27 @@ class FlatBufferBuilder {
|
||||
}
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
uoffset_t EndVector(size_t len) {
|
||||
template<typename LenT = uoffset_t, typename ReturnT = uoffset_t>
|
||||
ReturnT EndVector(size_t len) {
|
||||
FLATBUFFERS_ASSERT(nested); // Hit if no corresponding StartVector.
|
||||
nested = false;
|
||||
return PushElement(static_cast<uoffset_t>(len));
|
||||
return PushElement<LenT, ReturnT>(static_cast<LenT>(len));
|
||||
}
|
||||
|
||||
template<template<typename> class OffsetT = Offset, typename LenT = uint32_t>
|
||||
void StartVector(size_t len, size_t elemsize, size_t alignment) {
|
||||
NotNested();
|
||||
nested = true;
|
||||
PreAlign<uoffset_t>(len * elemsize);
|
||||
// Align to the Length type of the vector (either 32-bit or 64-bit), so
|
||||
// that the length of the buffer can be added without padding.
|
||||
PreAlign<LenT>(len * elemsize);
|
||||
PreAlign(len * elemsize, alignment); // Just in case elemsize > uoffset_t.
|
||||
}
|
||||
|
||||
template<typename T> void StartVector(size_t len) {
|
||||
return StartVector(len, sizeof(T), AlignOf<T>());
|
||||
template<typename T, template<typename> class OffsetT = Offset,
|
||||
typename LenT = uint32_t>
|
||||
void StartVector(size_t len) {
|
||||
return StartVector<OffsetT, LenT>(len, sizeof(T), AlignOf<T>());
|
||||
}
|
||||
|
||||
// Call this right before StartVector/CreateVector if you want to force the
|
||||
@@ -606,12 +698,27 @@ class FlatBufferBuilder {
|
||||
// normally dictate.
|
||||
// This is useful when storing a nested_flatbuffer in a vector of bytes,
|
||||
// or when storing SIMD floats, etc.
|
||||
void ForceVectorAlignment(size_t len, size_t elemsize, size_t alignment) {
|
||||
void ForceVectorAlignment(const size_t len, const size_t elemsize,
|
||||
const size_t alignment) {
|
||||
if (len == 0) return;
|
||||
FLATBUFFERS_ASSERT(VerifyAlignmentRequirements(alignment));
|
||||
PreAlign(len * elemsize, alignment);
|
||||
}
|
||||
|
||||
template<bool is_64 = Is64Aware>
|
||||
typename std::enable_if<is_64, void>::type ForceVectorAlignment64(
|
||||
const size_t len, const size_t elemsize, const size_t alignment) {
|
||||
// If you hit this assertion, you are trying to force alignment on a
|
||||
// vector with offset64 after serializing a 32-bit offset.
|
||||
FLATBUFFERS_ASSERT(GetSize() == length_of_64_bit_region_);
|
||||
|
||||
// Call through.
|
||||
ForceVectorAlignment(len, elemsize, alignment);
|
||||
|
||||
// Update the 64 bit region.
|
||||
length_of_64_bit_region_ = GetSize();
|
||||
}
|
||||
|
||||
// Similar to ForceVectorAlignment but for String fields.
|
||||
void ForceStringAlignment(size_t len, size_t alignment) {
|
||||
if (len == 0) return;
|
||||
@@ -623,31 +730,39 @@ class FlatBufferBuilder {
|
||||
|
||||
/// @brief Serialize an array into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the array elements.
|
||||
/// @tparam OffsetT the type of offset to return
|
||||
/// @tparam VectorT the type of vector to cast to.
|
||||
/// @param[in] v A pointer to the array of type `T` to serialize into the
|
||||
/// buffer as a `vector`.
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// @return Returns a typed `TOffset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T> Offset<Vector<T>> CreateVector(const T *v, size_t len) {
|
||||
template<typename T, template<typename...> class OffsetT = Offset,
|
||||
template<typename...> class VectorT = Vector>
|
||||
OffsetT<VectorT<T>> CreateVector(const T *v, size_t len) {
|
||||
// The type of the length field in the vector.
|
||||
typedef typename VectorT<T>::size_type LenT;
|
||||
typedef typename OffsetT<VectorT<T>>::offset_type offset_type;
|
||||
// If this assert hits, you're specifying a template argument that is
|
||||
// causing the wrong overload to be selected, remove it.
|
||||
AssertScalarT<T>();
|
||||
StartVector<T>(len);
|
||||
if (len == 0) { return Offset<Vector<T>>(EndVector(len)); }
|
||||
// clang-format off
|
||||
#if FLATBUFFERS_LITTLEENDIAN
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
|
||||
#else
|
||||
if (sizeof(T) == 1) {
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(v), len);
|
||||
} else {
|
||||
for (auto i = len; i > 0; ) {
|
||||
PushElement(v[--i]);
|
||||
StartVector<T, OffsetT, LenT>(len);
|
||||
if (len > 0) {
|
||||
// clang-format off
|
||||
#if FLATBUFFERS_LITTLEENDIAN
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(v), len * sizeof(T));
|
||||
#else
|
||||
if (sizeof(T) == 1) {
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(v), len);
|
||||
} else {
|
||||
for (auto i = len; i > 0; ) {
|
||||
PushElement(v[--i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
// clang-format on
|
||||
return Offset<Vector<T>>(EndVector(len));
|
||||
#endif
|
||||
// clang-format on
|
||||
}
|
||||
return OffsetT<VectorT<T>>(EndVector<LenT, offset_type>(len));
|
||||
}
|
||||
|
||||
/// @brief Serialize an array like object into a FlatBuffer `vector`.
|
||||
@@ -689,6 +804,12 @@ class FlatBufferBuilder {
|
||||
return CreateVector(data(v), v.size());
|
||||
}
|
||||
|
||||
template<template<typename...> class VectorT = Vector64,
|
||||
int &...ExplicitArgumentBarrier, typename T>
|
||||
Offset64<VectorT<T>> CreateVector64(const std::vector<T> &v) {
|
||||
return CreateVector<T, Offset64, VectorT>(data(v), v.size());
|
||||
}
|
||||
|
||||
// vector<bool> may be implemented using a bit-set, so we can't access it as
|
||||
// an array. Instead, read elements manually.
|
||||
// Background: https://isocpp.org/blog/2012/11/on-vectorbool
|
||||
@@ -785,47 +906,19 @@ class FlatBufferBuilder {
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T>
|
||||
Offset<Vector<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
|
||||
StartVector(len * sizeof(T) / AlignOf<T>(), sizeof(T), AlignOf<T>());
|
||||
template<typename T, template<typename...> class OffsetT = Offset,
|
||||
template<typename...> class VectorT = Vector>
|
||||
OffsetT<VectorT<const T *>> CreateVectorOfStructs(const T *v, size_t len) {
|
||||
// The type of the length field in the vector.
|
||||
typedef typename VectorT<T>::size_type LenT;
|
||||
typedef typename OffsetT<VectorT<const T *>>::offset_type offset_type;
|
||||
|
||||
StartVector<OffsetT, LenT>(len * sizeof(T) / AlignOf<T>(), sizeof(T),
|
||||
AlignOf<T>());
|
||||
if (len > 0) {
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(v), sizeof(T) * len);
|
||||
}
|
||||
return Offset<Vector<const T *>>(EndVector(len));
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of native structs into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the struct array elements.
|
||||
/// @tparam S The data type of the native struct array elements.
|
||||
/// @param[in] v A pointer to the array of type `S` to serialize into the
|
||||
/// buffer as a `vector`.
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @param[in] pack_func Pointer to a function to convert the native struct
|
||||
/// to the FlatBuffer struct.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename S>
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
||||
const S *v, size_t len, T (*const pack_func)(const S &)) {
|
||||
FLATBUFFERS_ASSERT(pack_func);
|
||||
auto structs = StartVectorOfStructs<T>(len);
|
||||
for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); }
|
||||
return EndVectorOfStructs<T>(len);
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of native structs into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the struct array elements.
|
||||
/// @tparam S The data type of the native struct array elements.
|
||||
/// @param[in] v A pointer to the array of type `S` to serialize into the
|
||||
/// buffer as a `vector`.
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename S>
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
|
||||
size_t len) {
|
||||
extern T Pack(const S &);
|
||||
return CreateVectorOfNativeStructs(v, len, Pack);
|
||||
return OffsetT<VectorT<const T *>>(EndVector<LenT, offset_type>(len));
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of structs into a FlatBuffer `vector`.
|
||||
@@ -873,10 +966,52 @@ class FlatBufferBuilder {
|
||||
/// serialize into the buffer as a `vector`.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename Alloc = std::allocator<T>>
|
||||
Offset<Vector<const T *>> CreateVectorOfStructs(
|
||||
template<typename T, template<typename...> class OffsetT = Offset,
|
||||
template<typename...> class VectorT = Vector,
|
||||
typename Alloc = std::allocator<T>>
|
||||
OffsetT<VectorT<const T *>> CreateVectorOfStructs(
|
||||
const std::vector<T, Alloc> &v) {
|
||||
return CreateVectorOfStructs(data(v), v.size());
|
||||
return CreateVectorOfStructs<T, OffsetT, VectorT>(data(v), v.size());
|
||||
}
|
||||
|
||||
template<template<typename...> class VectorT = Vector64, int &..., typename T>
|
||||
Offset64<VectorT<const T *>> CreateVectorOfStructs64(
|
||||
const std::vector<T> &v) {
|
||||
return CreateVectorOfStructs<T, Offset64, VectorT>(data(v), v.size());
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of native structs into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the struct array elements.
|
||||
/// @tparam S The data type of the native struct array elements.
|
||||
/// @param[in] v A pointer to the array of type `S` to serialize into the
|
||||
/// buffer as a `vector`.
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @param[in] pack_func Pointer to a function to convert the native struct
|
||||
/// to the FlatBuffer struct.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename S>
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(
|
||||
const S *v, size_t len, T (*const pack_func)(const S &)) {
|
||||
FLATBUFFERS_ASSERT(pack_func);
|
||||
auto structs = StartVectorOfStructs<T>(len);
|
||||
for (size_t i = 0; i < len; i++) { structs[i] = pack_func(v[i]); }
|
||||
return EndVectorOfStructs<T>(len);
|
||||
}
|
||||
|
||||
/// @brief Serialize an array of native structs into a FlatBuffer `vector`.
|
||||
/// @tparam T The data type of the struct array elements.
|
||||
/// @tparam S The data type of the native struct array elements.
|
||||
/// @param[in] v A pointer to the array of type `S` to serialize into the
|
||||
/// buffer as a `vector`.
|
||||
/// @param[in] len The number of elements to serialize.
|
||||
/// @return Returns a typed `Offset` into the serialized data indicating
|
||||
/// where the vector is stored.
|
||||
template<typename T, typename S>
|
||||
Offset<Vector<const T *>> CreateVectorOfNativeStructs(const S *v,
|
||||
size_t len) {
|
||||
extern T Pack(const S &);
|
||||
return CreateVectorOfNativeStructs(v, len, Pack);
|
||||
}
|
||||
|
||||
/// @brief Serialize a `std::vector` of native structs into a FlatBuffer
|
||||
@@ -979,14 +1114,14 @@ class FlatBufferBuilder {
|
||||
|
||||
/// @cond FLATBUFFERS_INTERNAL
|
||||
template<typename T> struct TableKeyComparator {
|
||||
TableKeyComparator(vector_downward &buf) : buf_(buf) {}
|
||||
explicit TableKeyComparator(vector_downward<SizeT> &buf) : buf_(buf) {}
|
||||
TableKeyComparator(const TableKeyComparator &other) : buf_(other.buf_) {}
|
||||
bool operator()(const Offset<T> &a, const Offset<T> &b) const {
|
||||
auto table_a = reinterpret_cast<T *>(buf_.data_at(a.o));
|
||||
auto table_b = reinterpret_cast<T *>(buf_.data_at(b.o));
|
||||
return table_a->KeyCompareLessThan(table_b);
|
||||
}
|
||||
vector_downward &buf_;
|
||||
vector_downward<SizeT> &buf_;
|
||||
|
||||
private:
|
||||
FLATBUFFERS_DELETE_FUNC(
|
||||
@@ -1034,7 +1169,7 @@ class FlatBufferBuilder {
|
||||
NotNested();
|
||||
StartVector(len, elemsize, alignment);
|
||||
buf_.make_space(len * elemsize);
|
||||
auto vec_start = GetSize();
|
||||
const uoffset_t vec_start = GetSizeRelative32BitRegion();
|
||||
auto vec_end = EndVector(len);
|
||||
*buf = buf_.data_at(vec_start);
|
||||
return vec_end;
|
||||
@@ -1085,7 +1220,8 @@ class FlatBufferBuilder {
|
||||
NotNested();
|
||||
Align(AlignOf<T>());
|
||||
buf_.push_small(structobj);
|
||||
return Offset<const T *>(GetSize());
|
||||
return Offset<const T *>(
|
||||
CalculateOffset<typename Offset<const T *>::offset_type>());
|
||||
}
|
||||
|
||||
/// @brief Finish serializing a buffer by writing the root offset.
|
||||
@@ -1109,7 +1245,7 @@ class FlatBufferBuilder {
|
||||
Finish(root.o, file_identifier, true);
|
||||
}
|
||||
|
||||
void SwapBufAllocator(FlatBufferBuilder &other) {
|
||||
void SwapBufAllocator(FlatBufferBuilderImpl &other) {
|
||||
buf_.swap_allocator(other.buf_);
|
||||
}
|
||||
|
||||
@@ -1119,16 +1255,23 @@ class FlatBufferBuilder {
|
||||
|
||||
protected:
|
||||
// You shouldn't really be copying instances of this class.
|
||||
FlatBufferBuilder(const FlatBufferBuilder &);
|
||||
FlatBufferBuilder &operator=(const FlatBufferBuilder &);
|
||||
FlatBufferBuilderImpl(const FlatBufferBuilderImpl &);
|
||||
FlatBufferBuilderImpl &operator=(const FlatBufferBuilderImpl &);
|
||||
|
||||
void Finish(uoffset_t root, const char *file_identifier, bool size_prefix) {
|
||||
NotNested();
|
||||
buf_.clear_scratch();
|
||||
|
||||
const size_t prefix_size = size_prefix ? sizeof(SizeT) : 0;
|
||||
// Make sure we track the alignment of the size prefix.
|
||||
TrackMinAlign(prefix_size);
|
||||
|
||||
const size_t root_offset_size = sizeof(uoffset_t);
|
||||
const size_t file_id_size = file_identifier ? kFileIdentifierLength : 0;
|
||||
|
||||
// This will cause the whole buffer to be aligned.
|
||||
PreAlign((size_prefix ? sizeof(uoffset_t) : 0) + sizeof(uoffset_t) +
|
||||
(file_identifier ? kFileIdentifierLength : 0),
|
||||
minalign_);
|
||||
PreAlign(prefix_size + root_offset_size + file_id_size, minalign_);
|
||||
|
||||
if (file_identifier) {
|
||||
FLATBUFFERS_ASSERT(strlen(file_identifier) == kFileIdentifierLength);
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(file_identifier),
|
||||
@@ -1144,7 +1287,7 @@ class FlatBufferBuilder {
|
||||
voffset_t id;
|
||||
};
|
||||
|
||||
vector_downward buf_;
|
||||
vector_downward<SizeT> buf_;
|
||||
|
||||
// Accumulating offsets of table members while it is being built.
|
||||
// We store these in the scratch pad of buf_, after the vtable offsets.
|
||||
@@ -1153,6 +1296,26 @@ class FlatBufferBuilder {
|
||||
// possible vtable.
|
||||
voffset_t max_voffset_;
|
||||
|
||||
// This is the length of the 64-bit region of the buffer. The buffer supports
|
||||
// 64-bit offsets by forcing serialization of those elements in the "tail"
|
||||
// region of the buffer (i.e. "64-bit region"). To properly keep track of
|
||||
// offsets that are referenced from the tail of the buffer to not overflow
|
||||
// their size (e.g. Offset is a uint32_t type), the boundary of the 32-/64-bit
|
||||
// regions must be tracked.
|
||||
//
|
||||
// [ Complete FlatBuffer ]
|
||||
// [32-bit region][64-bit region]
|
||||
// ^ ^
|
||||
// | Tail of the buffer.
|
||||
// |
|
||||
// Tail of the 32-bit region of the buffer.
|
||||
//
|
||||
// This keeps track of the size of the 64-bit region so that the tail of the
|
||||
// 32-bit region can be calculated as `GetSize() - length_of_64_bit_region_`.
|
||||
//
|
||||
// This will remain 0 if no 64-bit offset types are added to the buffer.
|
||||
size_t length_of_64_bit_region_;
|
||||
|
||||
// Ensure objects are not nested.
|
||||
bool nested;
|
||||
|
||||
@@ -1166,14 +1329,15 @@ class FlatBufferBuilder {
|
||||
bool dedup_vtables_;
|
||||
|
||||
struct StringOffsetCompare {
|
||||
StringOffsetCompare(const vector_downward &buf) : buf_(&buf) {}
|
||||
explicit StringOffsetCompare(const vector_downward<SizeT> &buf)
|
||||
: buf_(&buf) {}
|
||||
bool operator()(const Offset<String> &a, const Offset<String> &b) const {
|
||||
auto stra = reinterpret_cast<const String *>(buf_->data_at(a.o));
|
||||
auto strb = reinterpret_cast<const String *>(buf_->data_at(b.o));
|
||||
return StringLessThan(stra->data(), stra->size(), strb->data(),
|
||||
strb->size());
|
||||
}
|
||||
const vector_downward *buf_;
|
||||
const vector_downward<SizeT> *buf_;
|
||||
};
|
||||
|
||||
// For use with CreateSharedString. Instantiated on first use only.
|
||||
@@ -1181,23 +1345,122 @@ class FlatBufferBuilder {
|
||||
StringOffsetMap *string_pool;
|
||||
|
||||
private:
|
||||
void CanAddOffset64() {
|
||||
// If you hit this assertion, you are attempting to add a 64-bit offset to
|
||||
// a 32-bit only builder. This is because the builder has overloads that
|
||||
// differ only on the offset size returned: e.g.:
|
||||
//
|
||||
// FlatBufferBuilder builder;
|
||||
// Offset64<String> string_offset = builder.CreateString<Offset64>();
|
||||
//
|
||||
// Either use a 64-bit aware builder, or don't try to create an Offset64
|
||||
// return type.
|
||||
//
|
||||
// TODO(derekbailey): we can probably do more enable_if to avoid this
|
||||
// looking like its possible to the user.
|
||||
static_assert(Is64Aware, "cannot add 64-bit offset to a 32-bit builder");
|
||||
|
||||
// If you hit this assertion, you are attempting to add an 64-bit offset
|
||||
// item after already serializing a 32-bit item. All 64-bit offsets have to
|
||||
// added to the tail of the buffer before any 32-bit items can be added.
|
||||
// Otherwise some items might not be addressable due to the maximum range of
|
||||
// the 32-bit offset.
|
||||
FLATBUFFERS_ASSERT(GetSize() == length_of_64_bit_region_);
|
||||
}
|
||||
|
||||
/// @brief Store a string in the buffer, which can contain any binary data.
|
||||
/// @param[in] str A const char pointer to the data to be stored as a string.
|
||||
/// @param[in] len The number of bytes that should be stored from `str`.
|
||||
/// @return Returns the offset in the buffer where the string starts.
|
||||
void CreateStringImpl(const char *str, size_t len) {
|
||||
NotNested();
|
||||
PreAlign<uoffset_t>(len + 1); // Always 0-terminated.
|
||||
buf_.fill(1);
|
||||
PushBytes(reinterpret_cast<const uint8_t *>(str), len);
|
||||
PushElement(static_cast<uoffset_t>(len));
|
||||
}
|
||||
|
||||
// Allocates space for a vector of structures.
|
||||
// Must be completed with EndVectorOfStructs().
|
||||
template<typename T> T *StartVectorOfStructs(size_t vector_size) {
|
||||
StartVector(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T),
|
||||
AlignOf<T>());
|
||||
template<typename T, template<typename> class OffsetT = Offset>
|
||||
T *StartVectorOfStructs(size_t vector_size) {
|
||||
StartVector<OffsetT>(vector_size * sizeof(T) / AlignOf<T>(), sizeof(T),
|
||||
AlignOf<T>());
|
||||
return reinterpret_cast<T *>(buf_.make_space(vector_size * sizeof(T)));
|
||||
}
|
||||
|
||||
// End the vector of structures in the flatbuffers.
|
||||
// Vector should have previously be started with StartVectorOfStructs().
|
||||
template<typename T, template<typename> class OffsetT = Offset>
|
||||
OffsetT<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
|
||||
return OffsetT<Vector<const T *>>(
|
||||
EndVector<typename Vector<const T *>::size_type,
|
||||
typename OffsetT<Vector<const T *>>::offset_type>(
|
||||
vector_size));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
Offset<Vector<const T *>> EndVectorOfStructs(size_t vector_size) {
|
||||
return Offset<Vector<const T *>>(EndVector(vector_size));
|
||||
typename std::enable_if<std::is_same<T, uoffset_t>::value, T>::type
|
||||
CalculateOffset() {
|
||||
// Default to the end of the 32-bit region. This may or may not be the end
|
||||
// of the buffer, depending on if any 64-bit offsets have been added.
|
||||
return GetSizeRelative32BitRegion();
|
||||
}
|
||||
|
||||
// Specializations to handle the 64-bit CalculateOffset, which is relative to
|
||||
// end of the buffer.
|
||||
template<typename T>
|
||||
typename std::enable_if<std::is_same<T, uoffset64_t>::value, T>::type
|
||||
CalculateOffset() {
|
||||
// This should never be compiled in when not using a 64-bit builder.
|
||||
static_assert(Is64Aware, "invalid 64-bit offset in 32-bit builder");
|
||||
|
||||
// Store how big the 64-bit region of the buffer is, so we can determine
|
||||
// where the 32/64 bit boundary is.
|
||||
length_of_64_bit_region_ = GetSize();
|
||||
|
||||
return length_of_64_bit_region_;
|
||||
}
|
||||
};
|
||||
/// @}
|
||||
|
||||
// Hack to `FlatBufferBuilder` mean `FlatBufferBuilder<false>` or
|
||||
// `FlatBufferBuilder<>`, where the template < > syntax is required.
|
||||
using FlatBufferBuilder = FlatBufferBuilderImpl<false>;
|
||||
using FlatBufferBuilder64 = FlatBufferBuilderImpl<true>;
|
||||
|
||||
// These are external due to GCC not allowing them in the class.
|
||||
// See: https://stackoverflow.com/q/8061456/868247
|
||||
template<>
|
||||
template<>
|
||||
inline Offset64<String> FlatBufferBuilder64::CreateString(const char *str,
|
||||
size_t len) {
|
||||
CanAddOffset64();
|
||||
CreateStringImpl(str, len);
|
||||
return Offset64<String>(
|
||||
CalculateOffset<typename Offset64<String>::offset_type>());
|
||||
}
|
||||
|
||||
// Used to distinguish from real Offsets.
|
||||
template<typename T = void> struct EmptyOffset {};
|
||||
|
||||
// TODO(derekbailey): it would be nice to combine these two methods.
|
||||
template<>
|
||||
template<>
|
||||
inline void FlatBufferBuilder64::StartVector<Offset64, uint32_t>(
|
||||
size_t len, size_t elemsize, size_t alignment) {
|
||||
CanAddOffset64();
|
||||
StartVector<EmptyOffset, uint32_t>(len, elemsize, alignment);
|
||||
}
|
||||
|
||||
template<>
|
||||
template<>
|
||||
inline void FlatBufferBuilder64::StartVector<Offset64, uint64_t>(
|
||||
size_t len, size_t elemsize, size_t alignment) {
|
||||
CanAddOffset64();
|
||||
StartVector<EmptyOffset, uint64_t>(len, elemsize, alignment);
|
||||
}
|
||||
|
||||
/// Helpers to get a typed pointer to objects that are currently being built.
|
||||
/// @warning Creating new objects will lead to reallocations and invalidates
|
||||
/// the pointer!
|
||||
@@ -1212,15 +1475,6 @@ const T *GetTemporaryPointer(FlatBufferBuilder &fbb, Offset<T> offset) {
|
||||
return GetMutableTemporaryPointer<T>(fbb, offset);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void FlatBufferBuilder::Required(Offset<T> table, voffset_t field) {
|
||||
auto table_ptr = reinterpret_cast<const Table *>(buf_.data_at(table.o));
|
||||
bool ok = table_ptr->GetOptionalFieldOffset(field) != 0;
|
||||
// If this fails, the caller will show what field needs to be set.
|
||||
FLATBUFFERS_ASSERT(ok);
|
||||
(void)ok;
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_VECTOR_DOWNWARD_H_
|
||||
#endif // FLATBUFFERS_FLATBUFFER_BUILDER_H_
|
||||
|
||||
@@ -76,8 +76,20 @@ inline const uint8_t *GetBufferStartFromRootPointer(const void *root) {
|
||||
}
|
||||
|
||||
/// @brief This return the prefixed size of a FlatBuffer.
|
||||
inline uoffset_t GetPrefixedSize(const uint8_t *buf) {
|
||||
return ReadScalar<uoffset_t>(buf);
|
||||
template<typename SizeT = uoffset_t>
|
||||
inline SizeT GetPrefixedSize(const uint8_t *buf) {
|
||||
return ReadScalar<SizeT>(buf);
|
||||
}
|
||||
|
||||
// Gets the total length of the buffer given a sized prefixed FlatBuffer.
|
||||
//
|
||||
// This includes the size of the prefix as well as the buffer:
|
||||
//
|
||||
// [size prefix][flatbuffer]
|
||||
// |---------length--------|
|
||||
template<typename SizeT = uoffset_t>
|
||||
inline SizeT GetSizePrefixedBufferLength(const uint8_t *const buf) {
|
||||
return ReadScalar<SizeT>(buf) + sizeof(SizeT);
|
||||
}
|
||||
|
||||
// Base class for native objects (FlatBuffer data de-serialized into native
|
||||
|
||||
@@ -360,16 +360,40 @@ class Map : public Vector {
|
||||
bool IsTheEmptyMap() const { return data_ == EmptyMap().data_; }
|
||||
};
|
||||
|
||||
inline void IndentString(std::string &s, int indent,
|
||||
const char *indent_string) {
|
||||
for (int i = 0; i < indent; i++) s += indent_string;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void AppendToString(std::string &s, T &&v, bool keys_quoted, bool indented,
|
||||
int cur_indent, const char *indent_string) {
|
||||
s += "[";
|
||||
s += indented ? "\n" : " ";
|
||||
for (size_t i = 0; i < v.size(); i++) {
|
||||
if (i) {
|
||||
s += ",";
|
||||
s += indented ? "\n" : " ";
|
||||
}
|
||||
if (indented) IndentString(s, cur_indent, indent_string);
|
||||
v[i].ToString(true, keys_quoted, s, indented, cur_indent,
|
||||
indent_string);
|
||||
}
|
||||
if (indented) {
|
||||
s += "\n";
|
||||
IndentString(s, cur_indent - 1, indent_string);
|
||||
} else {
|
||||
s += " ";
|
||||
}
|
||||
s += "]";
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void AppendToString(std::string &s, T &&v, bool keys_quoted) {
|
||||
s += "[ ";
|
||||
for (size_t i = 0; i < v.size(); i++) {
|
||||
if (i) s += ", ";
|
||||
v[i].ToString(true, keys_quoted, s);
|
||||
}
|
||||
s += " ]";
|
||||
AppendToString(s, v, keys_quoted);
|
||||
}
|
||||
|
||||
|
||||
class Reference {
|
||||
public:
|
||||
Reference()
|
||||
@@ -542,8 +566,13 @@ class Reference {
|
||||
// Convert any type to a JSON-like string. strings_quoted determines if
|
||||
// string values at the top level receive "" quotes (inside other values
|
||||
// they always do). keys_quoted determines if keys are quoted, at any level.
|
||||
// TODO(wvo): add further options to have indentation/newlines.
|
||||
void ToString(bool strings_quoted, bool keys_quoted, std::string &s) const {
|
||||
ToString(strings_quoted, keys_quoted, s, false, 0, "");
|
||||
}
|
||||
|
||||
// This version additionally allow you to specify if you want indentation.
|
||||
void ToString(bool strings_quoted, bool keys_quoted, std::string &s,
|
||||
bool indented, int cur_indent, const char *indent_string) const {
|
||||
if (type_ == FBT_STRING) {
|
||||
String str(Indirect(), byte_width_);
|
||||
if (strings_quoted) {
|
||||
@@ -569,7 +598,8 @@ class Reference {
|
||||
} else if (IsBool()) {
|
||||
s += AsBool() ? "true" : "false";
|
||||
} else if (IsMap()) {
|
||||
s += "{ ";
|
||||
s += "{";
|
||||
s += indented ? "\n" : " ";
|
||||
auto m = AsMap();
|
||||
auto keys = m.Keys();
|
||||
auto vals = m.Values();
|
||||
@@ -590,18 +620,28 @@ class Reference {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (indented) IndentString(s, cur_indent + 1, indent_string);
|
||||
keys[i].ToString(true, kq, s);
|
||||
s += ": ";
|
||||
vals[i].ToString(true, keys_quoted, s);
|
||||
if (i < keys.size() - 1) s += ", ";
|
||||
vals[i].ToString(true, keys_quoted, s, indented, cur_indent + 1, indent_string);
|
||||
if (i < keys.size() - 1) {
|
||||
s += ",";
|
||||
if (!indented) s += " ";
|
||||
}
|
||||
if (indented) s += "\n";
|
||||
}
|
||||
s += " }";
|
||||
if (!indented) s += " ";
|
||||
if (indented) IndentString(s, cur_indent, indent_string);
|
||||
s += "}";
|
||||
} else if (IsVector()) {
|
||||
AppendToString<Vector>(s, AsVector(), keys_quoted);
|
||||
AppendToString<Vector>(s, AsVector(), keys_quoted, indented,
|
||||
cur_indent + 1, indent_string);
|
||||
} else if (IsTypedVector()) {
|
||||
AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted);
|
||||
AppendToString<TypedVector>(s, AsTypedVector(), keys_quoted, indented,
|
||||
cur_indent + 1, indent_string);
|
||||
} else if (IsFixedTypedVector()) {
|
||||
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted);
|
||||
AppendToString<FixedTypedVector>(s, AsFixedTypedVector(), keys_quoted,
|
||||
indented, cur_indent + 1, indent_string);
|
||||
} else if (IsBlob()) {
|
||||
auto blob = AsBlob();
|
||||
flatbuffers::EscapeString(reinterpret_cast<const char *>(blob.data()),
|
||||
@@ -1128,10 +1168,7 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
|
||||
size_t EndMap(size_t start) {
|
||||
// We should have interleaved keys and values on the stack.
|
||||
// Make sure it is an even number:
|
||||
auto len = stack_.size() - start;
|
||||
FLATBUFFERS_ASSERT(!(len & 1));
|
||||
len /= 2;
|
||||
auto len = MapElementCount(start);
|
||||
// Make sure keys are all strings:
|
||||
for (auto key = start; key < stack_.size(); key += 2) {
|
||||
FLATBUFFERS_ASSERT(stack_[key].type_ == FBT_KEY);
|
||||
@@ -1289,6 +1326,14 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
EndMap(start);
|
||||
}
|
||||
|
||||
size_t MapElementCount(size_t start) {
|
||||
// Make sure it is an even number:
|
||||
auto len = stack_.size() - start;
|
||||
FLATBUFFERS_ASSERT(!(len & 1));
|
||||
len /= 2;
|
||||
return len;
|
||||
}
|
||||
|
||||
// If you wish to share a value explicitly (a value not shared automatically
|
||||
// through one of the BUILDER_FLAG_SHARE_* flags) you can do so with these
|
||||
// functions. Or if you wish to turn those flags off for performance reasons
|
||||
@@ -1307,6 +1352,12 @@ class Builder FLATBUFFERS_FINAL_CLASS {
|
||||
ReuseValue(v);
|
||||
}
|
||||
|
||||
// Undo the last element serialized. Call once for a value and once for a
|
||||
// key.
|
||||
void Undo() {
|
||||
stack_.pop_back();
|
||||
}
|
||||
|
||||
// Overloaded Add that tries to call the correct function above.
|
||||
void Add(int8_t i) { Int(i); }
|
||||
void Add(int16_t i) { Int(i); }
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
// Helper functionality to glue FlatBuffers and GRPC.
|
||||
|
||||
#include "flatbuffers/flatbuffers.h"
|
||||
#include "grpc/byte_buffer_reader.h"
|
||||
#include "grpcpp/support/byte_buffer.h"
|
||||
#include "grpcpp/support/slice.h"
|
||||
|
||||
|
||||
@@ -45,26 +45,27 @@ namespace flatbuffers {
|
||||
// of type tokens.
|
||||
// clang-format off
|
||||
#define FLATBUFFERS_GEN_TYPES_SCALAR(TD) \
|
||||
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 0) \
|
||||
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 1) /* begin scalar/int */ \
|
||||
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool, 2) \
|
||||
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8, 3) \
|
||||
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 4) \
|
||||
TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16, 5) \
|
||||
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16, 6) \
|
||||
TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32, 7) \
|
||||
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32, 8) \
|
||||
TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64, 9) \
|
||||
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64, 10) /* end int */ \
|
||||
TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32, 11) /* begin float */ \
|
||||
TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double, 12) /* end float/scalar */
|
||||
TD(NONE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 0) \
|
||||
TD(UTYPE, "", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 1) /* begin scalar/int */ \
|
||||
TD(BOOL, "bool", uint8_t, boolean,bool, bool, bool, bool, Boolean, Bool, 2) \
|
||||
TD(CHAR, "byte", int8_t, byte, int8, sbyte, int8, i8, Byte, Int8, 3) \
|
||||
TD(UCHAR, "ubyte", uint8_t, byte, byte, byte, uint8, u8, UByte, UInt8, 4) \
|
||||
TD(SHORT, "short", int16_t, short, int16, short, int16, i16, Short, Int16, 5) \
|
||||
TD(USHORT, "ushort", uint16_t, short, uint16, ushort, uint16, u16, UShort, UInt16, 6) \
|
||||
TD(INT, "int", int32_t, int, int32, int, int32, i32, Int, Int32, 7) \
|
||||
TD(UINT, "uint", uint32_t, int, uint32, uint, uint32, u32, UInt, UInt32, 8) \
|
||||
TD(LONG, "long", int64_t, long, int64, long, int64, i64, Long, Int64, 9) \
|
||||
TD(ULONG, "ulong", uint64_t, long, uint64, ulong, uint64, u64, ULong, UInt64, 10) /* end int */ \
|
||||
TD(FLOAT, "float", float, float, float32, float, float32, f32, Float, Float32, 11) /* begin float */ \
|
||||
TD(DOUBLE, "double", double, double, float64, double, float64, f64, Double, Double, 12) /* end float/scalar */
|
||||
#define FLATBUFFERS_GEN_TYPES_POINTER(TD) \
|
||||
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>, 13) \
|
||||
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 14) \
|
||||
TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>, 15) \
|
||||
TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>, 16)
|
||||
TD(STRING, "string", Offset<void>, int, int, StringOffset, int, unused, Int, Offset<String>, 13) \
|
||||
TD(VECTOR, "", Offset<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 14) \
|
||||
TD(VECTOR64, "", Offset64<void>, int, int, VectorOffset, int, unused, Int, Offset<UOffset>, 18) \
|
||||
TD(STRUCT, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>, 15) \
|
||||
TD(UNION, "", Offset<void>, int, int, int, int, unused, Int, Offset<UOffset>, 16)
|
||||
#define FLATBUFFERS_GEN_TYPE_ARRAY(TD) \
|
||||
TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>, 17)
|
||||
TD(ARRAY, "", int, int, int, int, int, unused, Int, Offset<UOffset>, 17)
|
||||
// The fields are:
|
||||
// - enum
|
||||
// - FlatBuffers schema type.
|
||||
@@ -139,6 +140,8 @@ inline bool IsLong (BaseType t) { return t == BASE_TYPE_LONG ||
|
||||
inline bool IsBool (BaseType t) { return t == BASE_TYPE_BOOL; }
|
||||
inline bool IsOneByte(BaseType t) { return t >= BASE_TYPE_UTYPE &&
|
||||
t <= BASE_TYPE_UCHAR; }
|
||||
inline bool IsVector (BaseType t) { return t == BASE_TYPE_VECTOR ||
|
||||
t == BASE_TYPE_VECTOR64; }
|
||||
|
||||
inline bool IsUnsigned(BaseType t) {
|
||||
return (t == BASE_TYPE_UTYPE) || (t == BASE_TYPE_UCHAR) ||
|
||||
@@ -210,7 +213,8 @@ struct Type {
|
||||
bool Deserialize(const Parser &parser, const reflection::Type *type);
|
||||
|
||||
BaseType base_type;
|
||||
BaseType element; // only set if t == BASE_TYPE_VECTOR
|
||||
BaseType element; // only set if t == BASE_TYPE_VECTOR or
|
||||
// BASE_TYPE_VECTOR64
|
||||
StructDef *struct_def; // only set if t or element == BASE_TYPE_STRUCT
|
||||
EnumDef *enum_def; // set if t == BASE_TYPE_UNION / BASE_TYPE_UTYPE,
|
||||
// or for an integral type derived from an enum.
|
||||
@@ -326,6 +330,7 @@ struct FieldDef : public Definition {
|
||||
shared(false),
|
||||
native_inline(false),
|
||||
flexbuffer(false),
|
||||
offset64(false),
|
||||
presence(kDefault),
|
||||
nested_flatbuffer(nullptr),
|
||||
padding(0),
|
||||
@@ -337,7 +342,10 @@ struct FieldDef : public Definition {
|
||||
bool Deserialize(Parser &parser, const reflection::Field *field);
|
||||
|
||||
bool IsScalarOptional() const {
|
||||
return IsScalar(value.type.base_type) && IsOptional();
|
||||
return IsScalar() && IsOptional();
|
||||
}
|
||||
bool IsScalar() const {
|
||||
return ::flatbuffers::IsScalar(value.type.base_type);
|
||||
}
|
||||
bool IsOptional() const { return presence == kOptional; }
|
||||
bool IsRequired() const { return presence == kRequired; }
|
||||
@@ -352,6 +360,7 @@ struct FieldDef : public Definition {
|
||||
bool native_inline; // Field will be defined inline (instead of as a pointer)
|
||||
// for native tables if field is a struct.
|
||||
bool flexbuffer; // This field contains FlexBuffer data.
|
||||
bool offset64; // If the field uses 64-bit offsets.
|
||||
|
||||
enum Presence {
|
||||
// Field must always be present.
|
||||
@@ -528,9 +537,7 @@ inline bool IsUnionType(const Type &type) {
|
||||
return IsUnion(type) && IsInteger(type.base_type);
|
||||
}
|
||||
|
||||
inline bool IsVector(const Type &type) {
|
||||
return type.base_type == BASE_TYPE_VECTOR;
|
||||
}
|
||||
inline bool IsVector(const Type &type) { return IsVector(type.base_type); }
|
||||
|
||||
inline bool IsVectorOfStruct(const Type &type) {
|
||||
return IsVector(type) && IsStruct(type.VectorType());
|
||||
@@ -721,6 +728,7 @@ struct IDLOptions {
|
||||
kSwift = 1 << 16,
|
||||
kNim = 1 << 17,
|
||||
kProto = 1 << 18,
|
||||
kKotlinKmp = 1 << 19,
|
||||
kMAX
|
||||
};
|
||||
|
||||
@@ -952,6 +960,13 @@ class Parser : public ParserState {
|
||||
known_attributes_["native_default"] = true;
|
||||
known_attributes_["flexbuffer"] = true;
|
||||
known_attributes_["private"] = true;
|
||||
|
||||
// An attribute added to a field to indicate that is uses 64-bit addressing.
|
||||
known_attributes_["offset64"] = true;
|
||||
|
||||
// An attribute added to a vector field to indicate that it uses 64-bit
|
||||
// addressing and it has a 64-bit length.
|
||||
known_attributes_["vector64"] = true;
|
||||
}
|
||||
|
||||
// Copying is not allowed
|
||||
@@ -1062,7 +1077,7 @@ class Parser : public ParserState {
|
||||
FLATBUFFERS_CHECKED_ERROR ParseAnyValue(Value &val, FieldDef *field,
|
||||
size_t parent_fieldn,
|
||||
const StructDef *parent_struct_def,
|
||||
uoffset_t count,
|
||||
size_t count,
|
||||
bool inside_vector = false);
|
||||
template<typename F>
|
||||
FLATBUFFERS_CHECKED_ERROR ParseTableDelimiters(size_t &fieldn,
|
||||
@@ -1074,7 +1089,7 @@ class Parser : public ParserState {
|
||||
void SerializeStruct(FlatBufferBuilder &builder, const StructDef &struct_def,
|
||||
const Value &val);
|
||||
template<typename F>
|
||||
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(uoffset_t &count, F body);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseVectorDelimiters(size_t &count, F body);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseVector(const Type &type, uoffset_t *ovalue,
|
||||
FieldDef *field, size_t fieldn);
|
||||
FLATBUFFERS_CHECKED_ERROR ParseArray(Value &array);
|
||||
@@ -1139,6 +1154,8 @@ class Parser : public ParserState {
|
||||
bool SupportsAdvancedArrayFeatures() const;
|
||||
bool SupportsOptionalScalars() const;
|
||||
bool SupportsDefaultVectorsAndStrings() const;
|
||||
bool Supports64BitOffsets() const;
|
||||
bool SupportsUnionUnderlyingType() const;
|
||||
Namespace *UniqueNamespace(Namespace *ns);
|
||||
|
||||
FLATBUFFERS_CHECKED_ERROR RecurseError();
|
||||
@@ -1198,136 +1215,27 @@ class Parser : public ParserState {
|
||||
// if it is less than 0, no linefeeds will be generated either.
|
||||
// See idl_gen_text.cpp.
|
||||
// strict_json adds "quotes" around field names if true.
|
||||
// If the flatbuffer cannot be encoded in JSON (e.g., it contains non-UTF-8
|
||||
// byte arrays in String values), returns false.
|
||||
extern bool GenerateTextFromTable(const Parser &parser, const void *table,
|
||||
const std::string &tablename,
|
||||
std::string *text);
|
||||
extern bool GenerateText(const Parser &parser, const void *flatbuffer,
|
||||
std::string *text);
|
||||
extern bool GenerateTextFile(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
// These functions return nullptr on success, or an error string,
|
||||
// which may happen if the flatbuffer cannot be encoded in JSON (e.g.,
|
||||
// it contains non-UTF-8 byte arrays in String values).
|
||||
extern bool GenerateTextFromTable(const Parser &parser,
|
||||
const void *table,
|
||||
const std::string &tablename,
|
||||
std::string *text);
|
||||
extern const char *GenerateText(const Parser &parser, const void *flatbuffer,
|
||||
std::string *text);
|
||||
extern const char *GenerateTextFile(const Parser &parser,
|
||||
const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Json schema to string
|
||||
// See idl_gen_json_schema.cpp.
|
||||
extern bool GenerateJsonSchema(const Parser &parser, std::string *json);
|
||||
|
||||
// Generate binary files from a given FlatBuffer, and a given Parser
|
||||
// object that has been populated with the corresponding schema.
|
||||
// See code_generators.cpp.
|
||||
extern bool GenerateBinary(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a C++ header from the definitions in the Parser object.
|
||||
// See idl_gen_cpp.
|
||||
extern bool GenerateCPP(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate C# files from the definitions in the Parser object.
|
||||
// See idl_gen_csharp.cpp.
|
||||
extern bool GenerateCSharp(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
extern bool GenerateDart(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Java files from the definitions in the Parser object.
|
||||
// See idl_gen_java.cpp.
|
||||
extern bool GenerateJava(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate JavaScript or TypeScript code from the definitions in the Parser
|
||||
// object. See idl_gen_js.
|
||||
extern bool GenerateTS(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Go files from the definitions in the Parser object.
|
||||
// See idl_gen_go.cpp.
|
||||
extern bool GenerateGo(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Php code from the definitions in the Parser object.
|
||||
// See idl_gen_php.
|
||||
extern bool GeneratePhp(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Python files from the definitions in the Parser object.
|
||||
// See idl_gen_python.cpp.
|
||||
extern bool GeneratePython(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Lobster files from the definitions in the Parser object.
|
||||
// See idl_gen_lobster.cpp.
|
||||
extern bool GenerateLobster(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Lua files from the definitions in the Parser object.
|
||||
// See idl_gen_lua.cpp.
|
||||
extern bool GenerateLua(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Rust files from the definitions in the Parser object.
|
||||
// See idl_gen_rust.cpp.
|
||||
extern bool GenerateRust(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Json schema file
|
||||
// See idl_gen_json_schema.cpp.
|
||||
extern bool GenerateJsonSchema(const Parser &parser, const std::string &path,
|
||||
extern const char *GenTextFromTable(const Parser &parser, const void *table,
|
||||
const std::string &tablename,
|
||||
std::string *text);
|
||||
extern const char *GenText(const Parser &parser, const void *flatbuffer,
|
||||
std::string *text);
|
||||
extern const char *GenTextFile(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
extern bool GenerateKotlin(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate Swift classes.
|
||||
// See idl_gen_swift.cpp
|
||||
extern bool GenerateSwift(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a schema file from the internal representation, useful after
|
||||
// parsing a .proto schema.
|
||||
extern std::string GenerateFBS(const Parser &parser,
|
||||
const std::string &file_name);
|
||||
extern bool GenerateFBS(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a make rule for the generated TypeScript code.
|
||||
// See idl_gen_ts.cpp.
|
||||
extern std::string TSMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a make rule for the generated C++ header.
|
||||
// See idl_gen_cpp.cpp.
|
||||
extern std::string CPPMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a make rule for the generated Dart code
|
||||
// see idl_gen_dart.cpp
|
||||
extern std::string DartMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a make rule for the generated Rust code.
|
||||
// See idl_gen_rust.cpp.
|
||||
extern std::string RustMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a make rule for generated Java or C# files.
|
||||
// See code_generators.cpp.
|
||||
extern std::string CSharpMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
extern std::string JavaMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate a make rule for the generated text (JSON) files.
|
||||
// See idl_gen_text.cpp.
|
||||
extern std::string TextMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_names);
|
||||
|
||||
// Generate a make rule for the generated binary files.
|
||||
// See code_generators.cpp.
|
||||
extern std::string BinaryMakeRule(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
// Generate GRPC Cpp interfaces.
|
||||
// See idl_gen_grpc.cpp.
|
||||
bool GenerateCppGRPC(const Parser &parser, const std::string &path,
|
||||
@@ -1355,9 +1263,6 @@ extern bool GenerateSwiftGRPC(const Parser &parser, const std::string &path,
|
||||
|
||||
extern bool GenerateTSGRPC(const Parser &parser, const std::string &path,
|
||||
const std::string &file_name);
|
||||
|
||||
extern bool GenerateRustModuleRootFile(const Parser &parser,
|
||||
const std::string &path);
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_IDL_H_
|
||||
|
||||
@@ -66,6 +66,7 @@ inline size_t GetTypeSize(reflection::BaseType base_type) {
|
||||
4, // Union
|
||||
0, // Array. Only used in structs. 0 was chosen to prevent out-of-bounds
|
||||
// errors.
|
||||
8, // Vector64
|
||||
|
||||
0 // MaxBaseType. This must be kept the last entry in this array.
|
||||
};
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
// Ensure the included flatbuffers.h is the same version as when this file was
|
||||
// generated, otherwise it may not be compatible.
|
||||
static_assert(FLATBUFFERS_VERSION_MAJOR == 23 &&
|
||||
FLATBUFFERS_VERSION_MINOR == 3 &&
|
||||
FLATBUFFERS_VERSION_REVISION == 3,
|
||||
FLATBUFFERS_VERSION_MINOR == 5 &&
|
||||
FLATBUFFERS_VERSION_REVISION == 26,
|
||||
"Non-compatible flatbuffers version included");
|
||||
|
||||
namespace reflection {
|
||||
@@ -64,10 +64,11 @@ enum BaseType {
|
||||
Obj = 15,
|
||||
Union = 16,
|
||||
Array = 17,
|
||||
MaxBaseType = 18
|
||||
Vector64 = 18,
|
||||
MaxBaseType = 19
|
||||
};
|
||||
|
||||
inline const BaseType (&EnumValuesBaseType())[19] {
|
||||
inline const BaseType (&EnumValuesBaseType())[20] {
|
||||
static const BaseType values[] = {
|
||||
None,
|
||||
UType,
|
||||
@@ -87,13 +88,14 @@ inline const BaseType (&EnumValuesBaseType())[19] {
|
||||
Obj,
|
||||
Union,
|
||||
Array,
|
||||
Vector64,
|
||||
MaxBaseType
|
||||
};
|
||||
return values;
|
||||
}
|
||||
|
||||
inline const char * const *EnumNamesBaseType() {
|
||||
static const char * const names[20] = {
|
||||
static const char * const names[21] = {
|
||||
"None",
|
||||
"UType",
|
||||
"Bool",
|
||||
@@ -112,6 +114,7 @@ inline const char * const *EnumNamesBaseType() {
|
||||
"Obj",
|
||||
"Union",
|
||||
"Array",
|
||||
"Vector64",
|
||||
"MaxBaseType",
|
||||
nullptr
|
||||
};
|
||||
@@ -601,7 +604,8 @@ struct Field FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
VT_ATTRIBUTES = 22,
|
||||
VT_DOCUMENTATION = 24,
|
||||
VT_OPTIONAL = 26,
|
||||
VT_PADDING = 28
|
||||
VT_PADDING = 28,
|
||||
VT_OFFSET64 = 30
|
||||
};
|
||||
const ::flatbuffers::String *name() const {
|
||||
return GetPointer<const ::flatbuffers::String *>(VT_NAME);
|
||||
@@ -649,6 +653,10 @@ struct Field FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
uint16_t padding() const {
|
||||
return GetField<uint16_t>(VT_PADDING, 0);
|
||||
}
|
||||
/// If the field uses 64-bit offsets.
|
||||
bool offset64() const {
|
||||
return GetField<uint8_t>(VT_OFFSET64, 0) != 0;
|
||||
}
|
||||
bool Verify(::flatbuffers::Verifier &verifier) const {
|
||||
return VerifyTableStart(verifier) &&
|
||||
VerifyOffsetRequired(verifier, VT_NAME) &&
|
||||
@@ -670,6 +678,7 @@ struct Field FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
verifier.VerifyVectorOfStrings(documentation()) &&
|
||||
VerifyField<uint8_t>(verifier, VT_OPTIONAL, 1) &&
|
||||
VerifyField<uint16_t>(verifier, VT_PADDING, 2) &&
|
||||
VerifyField<uint8_t>(verifier, VT_OFFSET64, 1) &&
|
||||
verifier.EndTable();
|
||||
}
|
||||
};
|
||||
@@ -717,6 +726,9 @@ struct FieldBuilder {
|
||||
void add_padding(uint16_t padding) {
|
||||
fbb_.AddElement<uint16_t>(Field::VT_PADDING, padding, 0);
|
||||
}
|
||||
void add_offset64(bool offset64) {
|
||||
fbb_.AddElement<uint8_t>(Field::VT_OFFSET64, static_cast<uint8_t>(offset64), 0);
|
||||
}
|
||||
explicit FieldBuilder(::flatbuffers::FlatBufferBuilder &_fbb)
|
||||
: fbb_(_fbb) {
|
||||
start_ = fbb_.StartTable();
|
||||
@@ -744,7 +756,8 @@ inline ::flatbuffers::Offset<Field> CreateField(
|
||||
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<reflection::KeyValue>>> attributes = 0,
|
||||
::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> documentation = 0,
|
||||
bool optional = false,
|
||||
uint16_t padding = 0) {
|
||||
uint16_t padding = 0,
|
||||
bool offset64 = false) {
|
||||
FieldBuilder builder_(_fbb);
|
||||
builder_.add_default_real(default_real);
|
||||
builder_.add_default_integer(default_integer);
|
||||
@@ -755,6 +768,7 @@ inline ::flatbuffers::Offset<Field> CreateField(
|
||||
builder_.add_padding(padding);
|
||||
builder_.add_offset(offset);
|
||||
builder_.add_id(id);
|
||||
builder_.add_offset64(offset64);
|
||||
builder_.add_optional(optional);
|
||||
builder_.add_key(key);
|
||||
builder_.add_required(required);
|
||||
@@ -776,7 +790,8 @@ inline ::flatbuffers::Offset<Field> CreateFieldDirect(
|
||||
std::vector<::flatbuffers::Offset<reflection::KeyValue>> *attributes = nullptr,
|
||||
const std::vector<::flatbuffers::Offset<::flatbuffers::String>> *documentation = nullptr,
|
||||
bool optional = false,
|
||||
uint16_t padding = 0) {
|
||||
uint16_t padding = 0,
|
||||
bool offset64 = false) {
|
||||
auto name__ = name ? _fbb.CreateString(name) : 0;
|
||||
auto attributes__ = attributes ? _fbb.CreateVectorOfSortedTables<reflection::KeyValue>(attributes) : 0;
|
||||
auto documentation__ = documentation ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*documentation) : 0;
|
||||
@@ -794,7 +809,8 @@ inline ::flatbuffers::Offset<Field> CreateFieldDirect(
|
||||
attributes__,
|
||||
documentation__,
|
||||
optional,
|
||||
padding);
|
||||
padding,
|
||||
offset64);
|
||||
}
|
||||
|
||||
struct Object FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table {
|
||||
|
||||
@@ -52,8 +52,10 @@ class Registry {
|
||||
Parser parser;
|
||||
if (!LoadSchema(ident, &parser)) return false;
|
||||
// Now we're ready to generate text.
|
||||
if (!GenerateText(parser, flatbuf, dest)) {
|
||||
lasterror_ = "unable to generate text for FlatBuffer binary";
|
||||
auto err = GenText(parser, flatbuf, dest);
|
||||
if (err) {
|
||||
lasterror_ =
|
||||
"unable to generate text for FlatBuffer binary: " + std::string(err);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
||||
@@ -47,14 +47,24 @@ class Table {
|
||||
return field_offset ? ReadScalar<T>(data_ + field_offset) : defaultval;
|
||||
}
|
||||
|
||||
template<typename P> P GetPointer(voffset_t field) {
|
||||
template<typename P, typename OffsetSize = uoffset_t>
|
||||
P GetPointer(voffset_t field) {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
auto p = data_ + field_offset;
|
||||
return field_offset ? reinterpret_cast<P>(p + ReadScalar<uoffset_t>(p))
|
||||
return field_offset ? reinterpret_cast<P>(p + ReadScalar<OffsetSize>(p))
|
||||
: nullptr;
|
||||
}
|
||||
template<typename P> P GetPointer(voffset_t field) const {
|
||||
return const_cast<Table *>(this)->GetPointer<P>(field);
|
||||
template<typename P, typename OffsetSize = uoffset_t>
|
||||
P GetPointer(voffset_t field) const {
|
||||
return const_cast<Table *>(this)->GetPointer<P, OffsetSize>(field);
|
||||
}
|
||||
|
||||
template<typename P> P GetPointer64(voffset_t field) {
|
||||
return GetPointer<P, uoffset64_t>(field);
|
||||
}
|
||||
|
||||
template<typename P> P GetPointer64(voffset_t field) const {
|
||||
return GetPointer<P, uoffset64_t>(field);
|
||||
}
|
||||
|
||||
template<typename P> P GetStruct(voffset_t field) const {
|
||||
@@ -131,15 +141,25 @@ class Table {
|
||||
}
|
||||
|
||||
// Versions for offsets.
|
||||
template<typename OffsetT = uoffset_t>
|
||||
bool VerifyOffset(const Verifier &verifier, voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return !field_offset || verifier.VerifyOffset(data_, field_offset);
|
||||
return !field_offset || verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
||||
}
|
||||
|
||||
template<typename OffsetT = uoffset_t>
|
||||
bool VerifyOffsetRequired(const Verifier &verifier, voffset_t field) const {
|
||||
auto field_offset = GetOptionalFieldOffset(field);
|
||||
return verifier.Check(field_offset != 0) &&
|
||||
verifier.VerifyOffset(data_, field_offset);
|
||||
verifier.VerifyOffset<OffsetT>(data_, field_offset);
|
||||
}
|
||||
|
||||
bool VerifyOffset64(const Verifier &verifier, voffset_t field) const {
|
||||
return VerifyOffset<uoffset64_t>(verifier, field);
|
||||
}
|
||||
|
||||
bool VerifyOffset64Required(const Verifier &verifier, voffset_t field) const {
|
||||
return VerifyOffsetRequired<uoffset64_t>(verifier, field);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -257,7 +257,7 @@ inline void strtoval_impl(double *val, const char *str, char **endptr) {
|
||||
}
|
||||
|
||||
// UBSAN: double to float is safe if numeric_limits<float>::is_iec559 is true.
|
||||
__suppress_ubsan__("float-cast-overflow")
|
||||
FLATBUFFERS_SUPPRESS_UBSAN("float-cast-overflow")
|
||||
inline void strtoval_impl(float *val, const char *str, char **endptr) {
|
||||
*val = __strtof_impl(str, endptr);
|
||||
}
|
||||
@@ -623,7 +623,7 @@ inline bool EscapeString(const char *s, size_t length, std::string *_text,
|
||||
// we previously checked for non-UTF-8, so we shouldn't reach
|
||||
// here.
|
||||
//
|
||||
// 2) We reached here by someone calling GenerateText()
|
||||
// 2) We reached here by someone calling GenText()
|
||||
// on a previously-serialized flatbuffer. The data might have
|
||||
// non-UTF-8 Strings, or might be corrupt.
|
||||
//
|
||||
|
||||
@@ -27,7 +27,8 @@ struct String;
|
||||
|
||||
// An STL compatible iterator implementation for Vector below, effectively
|
||||
// calling Get() for every element.
|
||||
template<typename T, typename IT, typename Data = uint8_t *>
|
||||
template<typename T, typename IT, typename Data = uint8_t *,
|
||||
typename SizeT = uoffset_t>
|
||||
struct VectorIterator {
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef IT value_type;
|
||||
@@ -35,8 +36,9 @@ struct VectorIterator {
|
||||
typedef IT *pointer;
|
||||
typedef IT &reference;
|
||||
|
||||
VectorIterator(Data data, uoffset_t i)
|
||||
: data_(data + IndirectHelper<T>::element_stride * i) {}
|
||||
static const SizeT element_stride = IndirectHelper<T>::element_stride;
|
||||
|
||||
VectorIterator(Data data, SizeT i) : data_(data + element_stride * i) {}
|
||||
VectorIterator(const VectorIterator &other) : data_(other.data_) {}
|
||||
VectorIterator() : data_(nullptr) {}
|
||||
|
||||
@@ -63,7 +65,7 @@ struct VectorIterator {
|
||||
}
|
||||
|
||||
difference_type operator-(const VectorIterator &other) const {
|
||||
return (data_ - other.data_) / IndirectHelper<T>::element_stride;
|
||||
return (data_ - other.data_) / element_stride;
|
||||
}
|
||||
|
||||
// Note: return type is incompatible with the standard
|
||||
@@ -75,44 +77,42 @@ struct VectorIterator {
|
||||
IT operator->() const { return IndirectHelper<T>::Read(data_, 0); }
|
||||
|
||||
VectorIterator &operator++() {
|
||||
data_ += IndirectHelper<T>::element_stride;
|
||||
data_ += element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator++(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ += IndirectHelper<T>::element_stride;
|
||||
data_ += element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator+(const uoffset_t &offset) const {
|
||||
return VectorIterator(data_ + offset * IndirectHelper<T>::element_stride,
|
||||
0);
|
||||
VectorIterator operator+(const SizeT &offset) const {
|
||||
return VectorIterator(data_ + offset * element_stride, 0);
|
||||
}
|
||||
|
||||
VectorIterator &operator+=(const uoffset_t &offset) {
|
||||
data_ += offset * IndirectHelper<T>::element_stride;
|
||||
VectorIterator &operator+=(const SizeT &offset) {
|
||||
data_ += offset * element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator &operator--() {
|
||||
data_ -= IndirectHelper<T>::element_stride;
|
||||
data_ -= element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
VectorIterator operator--(int) {
|
||||
VectorIterator temp(data_, 0);
|
||||
data_ -= IndirectHelper<T>::element_stride;
|
||||
data_ -= element_stride;
|
||||
return temp;
|
||||
}
|
||||
|
||||
VectorIterator operator-(const uoffset_t &offset) const {
|
||||
return VectorIterator(data_ - offset * IndirectHelper<T>::element_stride,
|
||||
0);
|
||||
VectorIterator operator-(const SizeT &offset) const {
|
||||
return VectorIterator(data_ - offset * element_stride, 0);
|
||||
}
|
||||
|
||||
VectorIterator &operator-=(const uoffset_t &offset) {
|
||||
data_ -= offset * IndirectHelper<T>::element_stride;
|
||||
VectorIterator &operator-=(const SizeT &offset) {
|
||||
data_ -= offset * element_stride;
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -120,8 +120,8 @@ struct VectorIterator {
|
||||
Data data_;
|
||||
};
|
||||
|
||||
template<typename T, typename IT>
|
||||
using VectorConstIterator = VectorIterator<T, IT, const uint8_t *>;
|
||||
template<typename T, typename IT, typename SizeT = uoffset_t>
|
||||
using VectorConstIterator = VectorIterator<T, IT, const uint8_t *, SizeT>;
|
||||
|
||||
template<typename Iterator>
|
||||
struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
||||
@@ -145,11 +145,12 @@ struct VectorReverseIterator : public std::reverse_iterator<Iterator> {
|
||||
|
||||
// This is used as a helper type for accessing vectors.
|
||||
// Vector::data() assumes the vector elements start after the length field.
|
||||
template<typename T> class Vector {
|
||||
template<typename T, typename SizeT = uoffset_t> class Vector {
|
||||
public:
|
||||
typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type>
|
||||
typedef VectorIterator<T, typename IndirectHelper<T>::mutable_return_type,
|
||||
uint8_t *, SizeT>
|
||||
iterator;
|
||||
typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type>
|
||||
typedef VectorConstIterator<T, typename IndirectHelper<T>::return_type, SizeT>
|
||||
const_iterator;
|
||||
typedef VectorReverseIterator<iterator> reverse_iterator;
|
||||
typedef VectorReverseIterator<const_iterator> const_reverse_iterator;
|
||||
@@ -160,39 +161,40 @@ template<typename T> class Vector {
|
||||
static FLATBUFFERS_CONSTEXPR bool is_span_observable =
|
||||
scalar_tag::value && (FLATBUFFERS_LITTLEENDIAN || sizeof(T) == 1);
|
||||
|
||||
uoffset_t size() const { return EndianScalar(length_); }
|
||||
SizeT size() const { return EndianScalar(length_); }
|
||||
|
||||
// Deprecated: use size(). Here for backwards compatibility.
|
||||
FLATBUFFERS_ATTRIBUTE([[deprecated("use size() instead")]])
|
||||
uoffset_t Length() const { return size(); }
|
||||
SizeT Length() const { return size(); }
|
||||
|
||||
typedef SizeT size_type;
|
||||
typedef typename IndirectHelper<T>::return_type return_type;
|
||||
typedef typename IndirectHelper<T>::mutable_return_type mutable_return_type;
|
||||
typedef return_type value_type;
|
||||
|
||||
return_type Get(uoffset_t i) const {
|
||||
return_type Get(SizeT i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return IndirectHelper<T>::Read(Data(), i);
|
||||
}
|
||||
|
||||
return_type operator[](uoffset_t i) const { return Get(i); }
|
||||
return_type operator[](SizeT i) const { return Get(i); }
|
||||
|
||||
// If this is a Vector of enums, T will be its storage type, not the enum
|
||||
// type. This function makes it convenient to retrieve value with enum
|
||||
// type E.
|
||||
template<typename E> E GetEnum(uoffset_t i) const {
|
||||
template<typename E> E GetEnum(SizeT i) const {
|
||||
return static_cast<E>(Get(i));
|
||||
}
|
||||
|
||||
// If this a vector of unions, this does the cast for you. There's no check
|
||||
// to make sure this is the right type!
|
||||
template<typename U> const U *GetAs(uoffset_t i) const {
|
||||
template<typename U> const U *GetAs(SizeT i) const {
|
||||
return reinterpret_cast<const U *>(Get(i));
|
||||
}
|
||||
|
||||
// If this a vector of unions, this does the cast for you. There's no check
|
||||
// to make sure this is actually a string!
|
||||
const String *GetAsString(uoffset_t i) const {
|
||||
const String *GetAsString(SizeT i) const {
|
||||
return reinterpret_cast<const String *>(Get(i));
|
||||
}
|
||||
|
||||
@@ -226,7 +228,7 @@ template<typename T> class Vector {
|
||||
|
||||
// Change elements if you have a non-const pointer to this object.
|
||||
// Scalars only. See reflection.h, and the documentation.
|
||||
void Mutate(uoffset_t i, const T &val) {
|
||||
void Mutate(SizeT i, const T &val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
WriteScalar(data() + i, val);
|
||||
}
|
||||
@@ -234,15 +236,15 @@ template<typename T> class Vector {
|
||||
// Change an element of a vector of tables (or strings).
|
||||
// "val" points to the new table/string, as you can obtain from
|
||||
// e.g. reflection::AddFlatBuffer().
|
||||
void MutateOffset(uoffset_t i, const uint8_t *val) {
|
||||
void MutateOffset(SizeT i, const uint8_t *val) {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
static_assert(sizeof(T) == sizeof(uoffset_t), "Unrelated types");
|
||||
static_assert(sizeof(T) == sizeof(SizeT), "Unrelated types");
|
||||
WriteScalar(data() + i,
|
||||
static_cast<uoffset_t>(val - (Data() + i * sizeof(uoffset_t))));
|
||||
static_cast<SizeT>(val - (Data() + i * sizeof(SizeT))));
|
||||
}
|
||||
|
||||
// Get a mutable pointer to tables/strings inside this vector.
|
||||
mutable_return_type GetMutableObject(uoffset_t i) const {
|
||||
mutable_return_type GetMutableObject(SizeT i) const {
|
||||
FLATBUFFERS_ASSERT(i < size());
|
||||
return const_cast<mutable_return_type>(IndirectHelper<T>::Read(Data(), i));
|
||||
}
|
||||
@@ -280,7 +282,7 @@ template<typename T> class Vector {
|
||||
// try to construct these manually.
|
||||
Vector();
|
||||
|
||||
uoffset_t length_;
|
||||
SizeT length_;
|
||||
|
||||
private:
|
||||
// This class is a pointer. Copying will therefore create an invalid object.
|
||||
@@ -299,6 +301,8 @@ template<typename T> class Vector {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> using Vector64 = Vector<T, uoffset64_t>;
|
||||
|
||||
template<class U>
|
||||
FLATBUFFERS_CONSTEXPR_CPP11 flatbuffers::span<U> make_span(Vector<U> &vec)
|
||||
FLATBUFFERS_NOEXCEPT {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define FLATBUFFERS_VECTOR_DOWNWARD_H_
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
|
||||
#include "flatbuffers/base.h"
|
||||
#include "flatbuffers/default_allocator.h"
|
||||
@@ -31,13 +32,15 @@ namespace flatbuffers {
|
||||
// Since this vector leaves the lower part unused, we support a "scratch-pad"
|
||||
// that can be stored there for temporary data, to share the allocated space.
|
||||
// Essentially, this supports 2 std::vectors in a single buffer.
|
||||
class vector_downward {
|
||||
template<typename SizeT = uoffset_t> class vector_downward {
|
||||
public:
|
||||
explicit vector_downward(size_t initial_size, Allocator *allocator,
|
||||
bool own_allocator, size_t buffer_minalign)
|
||||
bool own_allocator, size_t buffer_minalign,
|
||||
const SizeT max_size = FLATBUFFERS_MAX_BUFFER_SIZE)
|
||||
: allocator_(allocator),
|
||||
own_allocator_(own_allocator),
|
||||
initial_size_(initial_size),
|
||||
max_size_(max_size),
|
||||
buffer_minalign_(buffer_minalign),
|
||||
reserved_(0),
|
||||
size_(0),
|
||||
@@ -50,6 +53,7 @@ class vector_downward {
|
||||
: allocator_(other.allocator_),
|
||||
own_allocator_(other.own_allocator_),
|
||||
initial_size_(other.initial_size_),
|
||||
max_size_(other.max_size_),
|
||||
buffer_minalign_(other.buffer_minalign_),
|
||||
reserved_(other.reserved_),
|
||||
size_(other.size_),
|
||||
@@ -111,7 +115,7 @@ class vector_downward {
|
||||
uint8_t *release_raw(size_t &allocated_bytes, size_t &offset) {
|
||||
auto *buf = buf_;
|
||||
allocated_bytes = reserved_;
|
||||
offset = static_cast<size_t>(cur_ - buf_);
|
||||
offset = vector_downward::offset();
|
||||
|
||||
// release_raw only relinquishes the buffer ownership.
|
||||
// Does not deallocate or reset the allocator. Destructor will do that.
|
||||
@@ -136,10 +140,10 @@ class vector_downward {
|
||||
|
||||
size_t ensure_space(size_t len) {
|
||||
FLATBUFFERS_ASSERT(cur_ >= scratch_ && scratch_ >= buf_);
|
||||
if (len > static_cast<size_t>(cur_ - scratch_)) { reallocate(len); }
|
||||
// Beyond this, signed offsets may not have enough range:
|
||||
// (FlatBuffers > 2GB not supported).
|
||||
FLATBUFFERS_ASSERT(size() < FLATBUFFERS_MAX_BUFFER_SIZE);
|
||||
// If the length is larger than the unused part of the buffer, we need to
|
||||
// grow.
|
||||
if (len > unused_buffer_size()) { reallocate(len); }
|
||||
FLATBUFFERS_ASSERT(size() < max_size_);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -147,7 +151,7 @@ class vector_downward {
|
||||
if (len) {
|
||||
ensure_space(len);
|
||||
cur_ -= len;
|
||||
size_ += static_cast<uoffset_t>(len);
|
||||
size_ += static_cast<SizeT>(len);
|
||||
}
|
||||
return cur_;
|
||||
}
|
||||
@@ -155,12 +159,20 @@ class vector_downward {
|
||||
// Returns nullptr if using the DefaultAllocator.
|
||||
Allocator *get_custom_allocator() { return allocator_; }
|
||||
|
||||
inline uoffset_t size() const { return size_; }
|
||||
// The current offset into the buffer.
|
||||
size_t offset() const { return cur_ - buf_; }
|
||||
|
||||
uoffset_t scratch_size() const {
|
||||
return static_cast<uoffset_t>(scratch_ - buf_);
|
||||
// The total size of the vector (both the buffer and scratch parts).
|
||||
inline SizeT size() const { return size_; }
|
||||
|
||||
// The size of the buffer part of the vector that is currently unused.
|
||||
SizeT unused_buffer_size() const {
|
||||
return static_cast<SizeT>(cur_ - scratch_);
|
||||
}
|
||||
|
||||
// The size of the scratch part of the vector.
|
||||
SizeT scratch_size() const { return static_cast<SizeT>(scratch_ - buf_); }
|
||||
|
||||
size_t capacity() const { return reserved_; }
|
||||
|
||||
uint8_t *data() const {
|
||||
@@ -211,7 +223,7 @@ class vector_downward {
|
||||
|
||||
void pop(size_t bytes_to_remove) {
|
||||
cur_ += bytes_to_remove;
|
||||
size_ -= static_cast<uoffset_t>(bytes_to_remove);
|
||||
size_ -= static_cast<SizeT>(bytes_to_remove);
|
||||
}
|
||||
|
||||
void scratch_pop(size_t bytes_to_remove) { scratch_ -= bytes_to_remove; }
|
||||
@@ -224,6 +236,7 @@ class vector_downward {
|
||||
swap(buffer_minalign_, other.buffer_minalign_);
|
||||
swap(reserved_, other.reserved_);
|
||||
swap(size_, other.size_);
|
||||
swap(max_size_, other.max_size_);
|
||||
swap(buf_, other.buf_);
|
||||
swap(cur_, other.cur_);
|
||||
swap(scratch_, other.scratch_);
|
||||
@@ -243,9 +256,12 @@ class vector_downward {
|
||||
Allocator *allocator_;
|
||||
bool own_allocator_;
|
||||
size_t initial_size_;
|
||||
|
||||
// The maximum size the vector can be.
|
||||
SizeT max_size_;
|
||||
size_t buffer_minalign_;
|
||||
size_t reserved_;
|
||||
uoffset_t size_;
|
||||
SizeT size_;
|
||||
uint8_t *buf_;
|
||||
uint8_t *cur_; // Points at location between empty (below) and used (above).
|
||||
uint8_t *scratch_; // Points to the end of the scratchpad in use.
|
||||
|
||||
@@ -34,12 +34,16 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
bool check_alignment = true;
|
||||
// If true, run verifier on nested flatbuffers
|
||||
bool check_nested_flatbuffers = true;
|
||||
// The maximum size of a buffer.
|
||||
size_t max_size = FLATBUFFERS_MAX_BUFFER_SIZE;
|
||||
// Use assertions to check for errors.
|
||||
bool assert = false;
|
||||
};
|
||||
|
||||
explicit Verifier(const uint8_t *const buf, const size_t buf_len,
|
||||
const Options &opts)
|
||||
: buf_(buf), size_(buf_len), opts_(opts) {
|
||||
FLATBUFFERS_ASSERT(size_ < FLATBUFFERS_MAX_BUFFER_SIZE);
|
||||
FLATBUFFERS_ASSERT(size_ < opts.max_size);
|
||||
}
|
||||
|
||||
// Deprecated API, please construct with Verifier::Options.
|
||||
@@ -58,7 +62,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
bool Check(const bool ok) const {
|
||||
// clang-format off
|
||||
#ifdef FLATBUFFERS_DEBUG_VERIFICATION_FAILURE
|
||||
FLATBUFFERS_ASSERT(ok);
|
||||
if (opts_.assert) { FLATBUFFERS_ASSERT(ok); }
|
||||
#endif
|
||||
#ifdef FLATBUFFERS_TRACK_VERIFIER_BUFFER_SIZE
|
||||
if (!ok)
|
||||
@@ -113,41 +117,43 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) of any vector type.
|
||||
template<typename T> bool VerifyVector(const Vector<T> *const vec) const {
|
||||
return !vec || VerifyVectorOrString(reinterpret_cast<const uint8_t *>(vec),
|
||||
sizeof(T));
|
||||
template<int &..., typename T, typename LenT>
|
||||
bool VerifyVector(const Vector<T, LenT> *const vec) const {
|
||||
return !vec || VerifyVectorOrString<LenT>(
|
||||
reinterpret_cast<const uint8_t *>(vec), sizeof(T));
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) of a vector to struct.
|
||||
template<typename T>
|
||||
bool VerifyVector(const Vector<const T *> *const vec) const {
|
||||
return VerifyVector(reinterpret_cast<const Vector<T> *>(vec));
|
||||
template<int &..., typename T, typename LenT>
|
||||
bool VerifyVector(const Vector<const T *, LenT> *const vec) const {
|
||||
return VerifyVector(reinterpret_cast<const Vector<T, LenT> *>(vec));
|
||||
}
|
||||
|
||||
// Verify a pointer (may be NULL) to string.
|
||||
bool VerifyString(const String *const str) const {
|
||||
size_t end;
|
||||
return !str || (VerifyVectorOrString(reinterpret_cast<const uint8_t *>(str),
|
||||
1, &end) &&
|
||||
return !str || (VerifyVectorOrString<uoffset_t>(
|
||||
reinterpret_cast<const uint8_t *>(str), 1, &end) &&
|
||||
Verify(end, 1) && // Must have terminator
|
||||
Check(buf_[end] == '\0')); // Terminating byte must be 0.
|
||||
}
|
||||
|
||||
// Common code between vectors and strings.
|
||||
template<typename LenT = uoffset_t>
|
||||
bool VerifyVectorOrString(const uint8_t *const vec, const size_t elem_size,
|
||||
size_t *const end = nullptr) const {
|
||||
const auto veco = static_cast<size_t>(vec - buf_);
|
||||
const auto vec_offset = static_cast<size_t>(vec - buf_);
|
||||
// Check we can read the size field.
|
||||
if (!Verify<uoffset_t>(veco)) return false;
|
||||
if (!Verify<LenT>(vec_offset)) return false;
|
||||
// Check the whole array. If this is a string, the byte past the array must
|
||||
// be 0.
|
||||
const auto size = ReadScalar<uoffset_t>(vec);
|
||||
const auto max_elems = FLATBUFFERS_MAX_BUFFER_SIZE / elem_size;
|
||||
const LenT size = ReadScalar<LenT>(vec);
|
||||
const auto max_elems = opts_.max_size / elem_size;
|
||||
if (!Check(size < max_elems))
|
||||
return false; // Protect against byte_size overflowing.
|
||||
const auto byte_size = sizeof(size) + elem_size * size;
|
||||
if (end) *end = veco + byte_size;
|
||||
return Verify(veco, byte_size);
|
||||
const auto byte_size = sizeof(LenT) + elem_size * size;
|
||||
if (end) *end = vec_offset + byte_size;
|
||||
return Verify(vec_offset, byte_size);
|
||||
}
|
||||
|
||||
// Special case for string contents, after the above has been called.
|
||||
@@ -171,8 +177,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
return true;
|
||||
}
|
||||
|
||||
__suppress_ubsan__("unsigned-integer-overflow") bool VerifyTableStart(
|
||||
const uint8_t *const table) {
|
||||
FLATBUFFERS_SUPPRESS_UBSAN("unsigned-integer-overflow")
|
||||
bool VerifyTableStart(const uint8_t *const table) {
|
||||
// Check the vtable offset.
|
||||
const auto tableo = static_cast<size_t>(table - buf_);
|
||||
if (!Verify<soffset_t>(tableo)) return false;
|
||||
@@ -203,7 +209,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
}
|
||||
|
||||
// Call T::Verify, which must be in the generated code for this type.
|
||||
const auto o = VerifyOffset(start);
|
||||
const auto o = VerifyOffset<uoffset_t>(start);
|
||||
return Check(o != 0) &&
|
||||
reinterpret_cast<const T *>(buf_ + start + o)->Verify(*this)
|
||||
// clang-format off
|
||||
@@ -214,8 +220,8 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
// clang-format on
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool VerifyNestedFlatBuffer(const Vector<uint8_t> *const buf,
|
||||
template<typename T, int &..., typename SizeT>
|
||||
bool VerifyNestedFlatBuffer(const Vector<uint8_t, SizeT> *const buf,
|
||||
const char *const identifier) {
|
||||
// Caller opted out of this.
|
||||
if (!opts_.check_nested_flatbuffers) return true;
|
||||
@@ -226,7 +232,7 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
// If there is a nested buffer, it must be greater than the min size.
|
||||
if (!Check(buf->size() >= FLATBUFFERS_MIN_BUFFER_SIZE)) return false;
|
||||
|
||||
Verifier nested_verifier(buf->data(), buf->size());
|
||||
Verifier nested_verifier(buf->data(), buf->size(), opts_);
|
||||
return nested_verifier.VerifyBuffer<T>(identifier);
|
||||
}
|
||||
|
||||
@@ -237,29 +243,32 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
return VerifyBufferFromStart<T>(identifier, 0);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template<typename T, typename SizeT = uoffset_t>
|
||||
bool VerifySizePrefixedBuffer(const char *const identifier) {
|
||||
return Verify<uoffset_t>(0U) &&
|
||||
Check(ReadScalar<uoffset_t>(buf_) == size_ - sizeof(uoffset_t)) &&
|
||||
VerifyBufferFromStart<T>(identifier, sizeof(uoffset_t));
|
||||
return Verify<SizeT>(0U) &&
|
||||
// Ensure the prefixed size is within the bounds of the provided
|
||||
// length.
|
||||
Check(ReadScalar<SizeT>(buf_) + sizeof(SizeT) <= size_) &&
|
||||
VerifyBufferFromStart<T>(identifier, sizeof(SizeT));
|
||||
}
|
||||
|
||||
uoffset_t VerifyOffset(const size_t start) const {
|
||||
if (!Verify<uoffset_t>(start)) return 0;
|
||||
const auto o = ReadScalar<uoffset_t>(buf_ + start);
|
||||
template<typename OffsetT = uoffset_t, typename SOffsetT = soffset_t>
|
||||
size_t VerifyOffset(const size_t start) const {
|
||||
if (!Verify<OffsetT>(start)) return 0;
|
||||
const auto o = ReadScalar<OffsetT>(buf_ + start);
|
||||
// May not point to itself.
|
||||
if (!Check(o != 0)) return 0;
|
||||
// Can't wrap around / buffers are max 2GB.
|
||||
if (!Check(static_cast<soffset_t>(o) >= 0)) return 0;
|
||||
// Can't wrap around larger than the max size.
|
||||
if (!Check(static_cast<SOffsetT>(o) >= 0)) return 0;
|
||||
// Must be inside the buffer to create a pointer from it (pointer outside
|
||||
// buffer is UB).
|
||||
if (!Verify(start + o, 1)) return 0;
|
||||
return o;
|
||||
}
|
||||
|
||||
uoffset_t VerifyOffset(const uint8_t *const base,
|
||||
const voffset_t start) const {
|
||||
return VerifyOffset(static_cast<size_t>(base - buf_) + start);
|
||||
template<typename OffsetT = uoffset_t>
|
||||
size_t VerifyOffset(const uint8_t *const base, const voffset_t start) const {
|
||||
return VerifyOffset<OffsetT>(static_cast<size_t>(base - buf_) + start);
|
||||
}
|
||||
|
||||
// Called at the start of a table to increase counters measuring data
|
||||
@@ -312,6 +321,12 @@ class Verifier FLATBUFFERS_FINAL_CLASS {
|
||||
std::vector<uint8_t> *flex_reuse_tracker_ = nullptr;
|
||||
};
|
||||
|
||||
// Specialization for 64-bit offsets.
|
||||
template<>
|
||||
inline size_t Verifier::VerifyOffset<uoffset64_t>(const size_t start) const {
|
||||
return VerifyOffset<uoffset64_t, soffset64_t>(start);
|
||||
}
|
||||
|
||||
} // namespace flatbuffers
|
||||
|
||||
#endif // FLATBUFFERS_VERIFIER_H_
|
||||
|
||||
198
java/pom.xml
198
java/pom.xml
@@ -3,7 +3,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.google.flatbuffers</groupId>
|
||||
<artifactId>flatbuffers-java</artifactId>
|
||||
<version>23.3.3</version>
|
||||
<version>23.5.26</version>
|
||||
<packaging>bundle</packaging>
|
||||
<name>FlatBuffers Java API</name>
|
||||
<description>
|
||||
@@ -59,15 +59,91 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<release>8</release>
|
||||
<testExcludes>
|
||||
<testExclude>MyGame/Example/MonsterStorageGrpc.java</testExclude>
|
||||
<testExclude>MyGame/OtherNameSpace/TableBT.java</testExclude>
|
||||
</testExcludes>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
</configuration>
|
||||
<version>2.22.2</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<additionalparam>-Xdoclint:none</additionalparam>
|
||||
<additionalOptions>-Xdoclint:none</additionalOptions>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>5.1.2</version>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<gpgArguments>
|
||||
<arg>--pinentry-mode</arg>
|
||||
<arg>loopback</arg>
|
||||
</gpgArguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
<configuration>
|
||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||
<useReleaseProfile>false</useReleaseProfile>
|
||||
<releaseProfiles>release</releaseProfiles>
|
||||
<goals>deploy</goals>
|
||||
</configuration>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
@@ -80,91 +156,39 @@
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<release>8</release>
|
||||
<testExcludes>
|
||||
<testExclude>MyGame/Example/MonsterStorageGrpc.java</testExclude>
|
||||
<testExclude>MyGame/OtherNameSpace/TableBT.java</testExclude>
|
||||
</testExcludes>
|
||||
</configuration>
|
||||
<version>2.22.2</version>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>jdk8</id>
|
||||
<activation>
|
||||
<jdk>1.8</jdk>
|
||||
</activation>
|
||||
<properties>
|
||||
<maven.compiler.target>8</maven.compiler.target>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<additionalparam>-Xdoclint:none</additionalparam>
|
||||
<additionalOptions>-Xdoclint:none</additionalOptions>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-javadocs</id>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<version>5.1.2</version>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.sonatype.plugins</groupId>
|
||||
<artifactId>nexus-staging-maven-plugin</artifactId>
|
||||
<version>1.6.8</version>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<serverId>ossrh</serverId>
|
||||
<nexusUrl>https://oss.sonatype.org/</nexusUrl>
|
||||
<autoReleaseAfterClose>true</autoReleaseAfterClose>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>3.0.1</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<gpgArguments>
|
||||
<arg>--pinentry-mode</arg>
|
||||
<arg>loopback</arg>
|
||||
</gpgArguments>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-release-plugin</artifactId>
|
||||
<version>2.5.3</version>
|
||||
<configuration>
|
||||
<autoVersionSubmodules>true</autoVersionSubmodules>
|
||||
<useReleaseProfile>false</useReleaseProfile>
|
||||
<releaseProfiles>release</releaseProfiles>
|
||||
<goals>deploy</goals>
|
||||
<testExcludes>
|
||||
<testExclude>MyGame/Example/MonsterStorageGrpc.java</testExclude>
|
||||
<testExclude>MyGame/OtherNameSpace/TableBT.java</testExclude>
|
||||
</testExcludes>
|
||||
</configuration>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
@@ -46,7 +46,7 @@ public class Constants {
|
||||
Changes to the Java implementation need to be sure to change
|
||||
the version here and in the code generator on every possible
|
||||
incompatible change */
|
||||
public static void FLATBUFFERS_23_3_3() {}
|
||||
public static void FLATBUFFERS_23_5_26() {}
|
||||
}
|
||||
|
||||
/// @endcond
|
||||
|
||||
@@ -23,9 +23,10 @@ public final class BaseType {
|
||||
public static final byte Obj = 15;
|
||||
public static final byte Union = 16;
|
||||
public static final byte Array = 17;
|
||||
public static final byte MaxBaseType = 18;
|
||||
public static final byte Vector64 = 18;
|
||||
public static final byte MaxBaseType = 19;
|
||||
|
||||
public static final String[] names = { "None", "UType", "Bool", "Byte", "UByte", "Short", "UShort", "Int", "UInt", "Long", "ULong", "Float", "Double", "String", "Vector", "Obj", "Union", "Array", "MaxBaseType", };
|
||||
public static final String[] names = { "None", "UType", "Bool", "Byte", "UByte", "Short", "UShort", "Int", "UInt", "Long", "ULong", "Float", "Double", "String", "Vector", "Obj", "Union", "Array", "Vector64", "MaxBaseType", };
|
||||
|
||||
public static String name(int e) { return names[e]; }
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Enum extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Enum getRootAsEnum(ByteBuffer _bb) { return getRootAsEnum(_bb, new Enum()); }
|
||||
public static Enum getRootAsEnum(ByteBuffer _bb, Enum obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class EnumVal extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static EnumVal getRootAsEnumVal(ByteBuffer _bb) { return getRootAsEnumVal(_bb, new EnumVal()); }
|
||||
public static EnumVal getRootAsEnumVal(ByteBuffer _bb, EnumVal obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Field extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Field getRootAsField(ByteBuffer _bb) { return getRootAsField(_bb, new Field()); }
|
||||
public static Field getRootAsField(ByteBuffer _bb, Field obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
@@ -55,6 +55,10 @@ public final class Field extends Table {
|
||||
* Number of padding octets to always add after this field. Structs only.
|
||||
*/
|
||||
public int padding() { int o = __offset(28); return o != 0 ? bb.getShort(o + bb_pos) & 0xFFFF : 0; }
|
||||
/**
|
||||
* If the field uses 64-bit offsets.
|
||||
*/
|
||||
public boolean offset64() { int o = __offset(30); return o != 0 ? 0!=bb.get(o + bb_pos) : false; }
|
||||
|
||||
public static int createField(FlatBufferBuilder builder,
|
||||
int nameOffset,
|
||||
@@ -69,8 +73,9 @@ public final class Field extends Table {
|
||||
int attributesOffset,
|
||||
int documentationOffset,
|
||||
boolean optional,
|
||||
int padding) {
|
||||
builder.startTable(13);
|
||||
int padding,
|
||||
boolean offset64) {
|
||||
builder.startTable(14);
|
||||
Field.addDefaultReal(builder, defaultReal);
|
||||
Field.addDefaultInteger(builder, defaultInteger);
|
||||
Field.addDocumentation(builder, documentationOffset);
|
||||
@@ -80,6 +85,7 @@ public final class Field extends Table {
|
||||
Field.addPadding(builder, padding);
|
||||
Field.addOffset(builder, offset);
|
||||
Field.addId(builder, id);
|
||||
Field.addOffset64(builder, offset64);
|
||||
Field.addOptional(builder, optional);
|
||||
Field.addKey(builder, key);
|
||||
Field.addRequired(builder, required);
|
||||
@@ -87,7 +93,7 @@ public final class Field extends Table {
|
||||
return Field.endField(builder);
|
||||
}
|
||||
|
||||
public static void startField(FlatBufferBuilder builder) { builder.startTable(13); }
|
||||
public static void startField(FlatBufferBuilder builder) { builder.startTable(14); }
|
||||
public static void addName(FlatBufferBuilder builder, int nameOffset) { builder.addOffset(nameOffset); builder.slot(0); }
|
||||
public static void addType(FlatBufferBuilder builder, int typeOffset) { builder.addOffset(1, typeOffset, 0); }
|
||||
public static void addId(FlatBufferBuilder builder, int id) { builder.addShort(2, (short) id, (short) 0); }
|
||||
@@ -105,6 +111,7 @@ public final class Field extends Table {
|
||||
public static void startDocumentationVector(FlatBufferBuilder builder, int numElems) { builder.startVector(4, numElems, 4); }
|
||||
public static void addOptional(FlatBufferBuilder builder, boolean optional) { builder.addBoolean(11, optional, false); }
|
||||
public static void addPadding(FlatBufferBuilder builder, int padding) { builder.addShort(12, (short) padding, (short) 0); }
|
||||
public static void addOffset64(FlatBufferBuilder builder, boolean offset64) { builder.addBoolean(13, offset64, false); }
|
||||
public static int endField(FlatBufferBuilder builder) {
|
||||
int o = builder.endTable();
|
||||
builder.required(o, 4); // name
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class KeyValue extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static KeyValue getRootAsKeyValue(ByteBuffer _bb) { return getRootAsKeyValue(_bb, new KeyValue()); }
|
||||
public static KeyValue getRootAsKeyValue(ByteBuffer _bb, KeyValue obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Object extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Object getRootAsObject(ByteBuffer _bb) { return getRootAsObject(_bb, new Object()); }
|
||||
public static Object getRootAsObject(ByteBuffer _bb, Object obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class RPCCall extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static RPCCall getRootAsRPCCall(ByteBuffer _bb) { return getRootAsRPCCall(_bb, new RPCCall()); }
|
||||
public static RPCCall getRootAsRPCCall(ByteBuffer _bb, RPCCall obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Schema extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Schema getRootAsSchema(ByteBuffer _bb) { return getRootAsSchema(_bb, new Schema()); }
|
||||
public static Schema getRootAsSchema(ByteBuffer _bb, Schema obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public static boolean SchemaBufferHasIdentifier(ByteBuffer _bb) { return __has_identifier(_bb, "BFBS"); }
|
||||
|
||||
@@ -26,7 +26,7 @@ import java.nio.ByteOrder;
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public final class SchemaFile extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static SchemaFile getRootAsSchemaFile(ByteBuffer _bb) { return getRootAsSchemaFile(_bb, new SchemaFile()); }
|
||||
public static SchemaFile getRootAsSchemaFile(ByteBuffer _bb, SchemaFile obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Service extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Service getRootAsService(ByteBuffer _bb) { return getRootAsService(_bb, new Service()); }
|
||||
public static Service getRootAsService(ByteBuffer _bb, Service obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.nio.ByteOrder;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public final class Type extends Table {
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_3_3(); }
|
||||
public static void ValidateVersion() { Constants.FLATBUFFERS_23_5_26(); }
|
||||
public static Type getRootAsType(ByteBuffer _bb) { return getRootAsType(_bb, new Type()); }
|
||||
public static Type getRootAsType(ByteBuffer _bb, Type obj) { _bb.order(ByteOrder.LITTLE_ENDIAN); return (obj.__assign(_bb.getInt(_bb.position()) + _bb.position(), _bb)); }
|
||||
public void __init(int _i, ByteBuffer _bb) { __reset(_i, _bb); }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import org.jetbrains.kotlin.ir.backend.js.compile
|
||||
import groovy.xml.XmlParser
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
@@ -10,6 +10,18 @@ plugins {
|
||||
group = "com.google.flatbuffers.jmh"
|
||||
version = "2.0.0-SNAPSHOT"
|
||||
|
||||
// Reads latest version from Java's runtime pom.xml,
|
||||
// so we can use it for benchmarking against Kotlin's
|
||||
// runtime
|
||||
fun readJavaFlatBufferVersion(): String {
|
||||
val pom = XmlParser().parse(File("../java/pom.xml"))
|
||||
val versionTag = pom.children().find {
|
||||
val node = it as groovy.util.Node
|
||||
node.name().toString().contains("version")
|
||||
} as groovy.util.Node
|
||||
return versionTag.value().toString()
|
||||
}
|
||||
|
||||
// This plugin generates a static html page with the aggregation
|
||||
// of all benchmarks ran. very useful visualization tool.
|
||||
jmhReport {
|
||||
@@ -27,7 +39,7 @@ benchmark {
|
||||
iterationTime = 300
|
||||
iterationTimeUnit = "ms"
|
||||
// uncomment for benchmarking JSON op only
|
||||
include(".*JsonBenchmark.*")
|
||||
include(".*FlatbufferBenchmark.*")
|
||||
}
|
||||
}
|
||||
targets {
|
||||
@@ -36,24 +48,34 @@ benchmark {
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
jvm {
|
||||
compilations {
|
||||
val main by getting { }
|
||||
// custom benchmark compilation
|
||||
val benchmarks by compilations.creating {
|
||||
defaultSourceSet {
|
||||
dependencies {
|
||||
// Compile against the main compilation's compile classpath and outputs:
|
||||
implementation(main.compileDependencyFiles + main.output.classesDirs)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
all {
|
||||
languageSettings.enableLanguageFeature("InlineClasses")
|
||||
}
|
||||
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("stdlib-common"))
|
||||
implementation(project(":flatbuffers-kotlin"))
|
||||
implementation(libs.kotlinx.benchmark.runtime)
|
||||
implementation("com.google.flatbuffers:flatbuffers-java:2.0.3")
|
||||
implementation("com.google.flatbuffers:flatbuffers-java:${readJavaFlatBufferVersion()}")
|
||||
// json serializers
|
||||
implementation(libs.moshi.kotlin)
|
||||
implementation(libs.gson)
|
||||
}
|
||||
kotlin.srcDir("src/jvmMain/generated/kotlin/")
|
||||
kotlin.srcDir("src/jvmMain/generated/java/")
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -67,3 +89,64 @@ tasks.register<de.undercouch.gradle.tasks.download.Download>("downloadMultipleFi
|
||||
dest(File("${project.projectDir.absolutePath}/src/jvmMain/resources"))
|
||||
overwrite(false)
|
||||
}
|
||||
|
||||
abstract class GenerateFBTestClasses : DefaultTask() {
|
||||
@get:InputFiles
|
||||
abstract val inputFiles: ConfigurableFileCollection
|
||||
|
||||
@get:Input
|
||||
abstract val includeFolder: Property<String>
|
||||
|
||||
@get:Input
|
||||
abstract val outputFolder: Property<String>
|
||||
|
||||
@get:Input
|
||||
abstract val variants: ListProperty<String>
|
||||
|
||||
@Inject
|
||||
protected open fun getExecActionFactory(): org.gradle.process.internal.ExecActionFactory? {
|
||||
throw UnsupportedOperationException()
|
||||
}
|
||||
|
||||
init {
|
||||
includeFolder.set("")
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun compile() {
|
||||
val execAction = getExecActionFactory()!!.newExecAction()
|
||||
val sources = inputFiles.asPath.split(":")
|
||||
val langs = variants.get().map { "--$it" }
|
||||
val args = mutableListOf("flatc","-o", outputFolder.get(), *langs.toTypedArray())
|
||||
if (includeFolder.get().isNotEmpty()) {
|
||||
args.add("-I")
|
||||
args.add(includeFolder.get())
|
||||
}
|
||||
args.addAll(sources)
|
||||
println(args)
|
||||
execAction.commandLine = args
|
||||
print(execAction.execute())
|
||||
}
|
||||
}
|
||||
|
||||
// Use the default greeting
|
||||
tasks.register<GenerateFBTestClasses>("generateFBTestClassesKt") {
|
||||
inputFiles.setFrom("$projectDir/monster_test_kotlin.fbs")
|
||||
includeFolder.set("$rootDir/../tests/include_test")
|
||||
outputFolder.set("${projectDir}/src/jvmMain/generated/kotlin/")
|
||||
variants.addAll("kotlin-kmp")
|
||||
}
|
||||
|
||||
tasks.register<GenerateFBTestClasses>("generateFBTestClassesJava") {
|
||||
inputFiles.setFrom("$projectDir/monster_test_java.fbs")
|
||||
includeFolder.set("$rootDir/../tests/include_test")
|
||||
outputFolder.set("${projectDir}/src/jvmMain/generated/java/")
|
||||
variants.addAll("kotlin")
|
||||
}
|
||||
|
||||
project.tasks.forEach {
|
||||
if (it.name.contains("compileKotlin")) {
|
||||
it.dependsOn("generateFBTestClassesKt")
|
||||
it.dependsOn("generateFBTestClassesJava")
|
||||
}
|
||||
}
|
||||
|
||||
37
kotlin/benchmark/monster_test_java.fbs
Normal file
37
kotlin/benchmark/monster_test_java.fbs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Example IDL file for our monster's schema.
|
||||
|
||||
namespace jmonster;
|
||||
|
||||
enum JColor:byte { Red = 0, Green, Blue = 2 }
|
||||
|
||||
union JEquipment { JWeapon } // Optionally add more tables.
|
||||
|
||||
struct JVec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
z:float;
|
||||
}
|
||||
|
||||
table JMonster {
|
||||
pos:JVec3;
|
||||
mana:short = 150;
|
||||
hp:short = 100;
|
||||
name:string;
|
||||
friendly:bool = false (deprecated);
|
||||
inventory:[ubyte];
|
||||
color:JColor = Blue;
|
||||
weapons:[JWeapon];
|
||||
equipped:JEquipment;
|
||||
path:[JVec3];
|
||||
}
|
||||
|
||||
table JWeapon {
|
||||
name:string;
|
||||
damage:short;
|
||||
}
|
||||
|
||||
table JAllMonsters {
|
||||
monsters: [JMonster];
|
||||
}
|
||||
|
||||
root_type JAllMonsters;
|
||||
37
kotlin/benchmark/monster_test_kotlin.fbs
Normal file
37
kotlin/benchmark/monster_test_kotlin.fbs
Normal file
@@ -0,0 +1,37 @@
|
||||
// Example IDL file for our monster's schema.
|
||||
|
||||
namespace monster;
|
||||
|
||||
enum Color:byte { Red = 0, Green, Blue = 2 }
|
||||
|
||||
union Equipment { Weapon } // Optionally add more tables.
|
||||
|
||||
struct Vec3 {
|
||||
x:float;
|
||||
y:float;
|
||||
z:float;
|
||||
}
|
||||
|
||||
table Monster {
|
||||
pos:Vec3;
|
||||
mana:short = 150;
|
||||
hp:short = 100;
|
||||
name:string;
|
||||
friendly:bool = false (deprecated);
|
||||
inventory:[ubyte];
|
||||
color:Color = Blue;
|
||||
weapons:[Weapon];
|
||||
equipped:Equipment;
|
||||
path:[Vec3];
|
||||
}
|
||||
|
||||
table Weapon {
|
||||
name:string;
|
||||
damage:short;
|
||||
}
|
||||
|
||||
table AllMonsters {
|
||||
monsters: [Monster];
|
||||
}
|
||||
|
||||
root_type AllMonsters;
|
||||
@@ -1 +0,0 @@
|
||||
../../../../java/src/main/java
|
||||
@@ -0,0 +1,129 @@
|
||||
@file:OptIn(ExperimentalUnsignedTypes::class)
|
||||
|
||||
package com.google.flatbuffers.kotlin.benchmark
|
||||
|
||||
|
||||
import com.google.flatbuffers.kotlin.FlatBufferBuilder
|
||||
import jmonster.JAllMonsters
|
||||
import jmonster.JColor
|
||||
import jmonster.JMonster
|
||||
import jmonster.JVec3
|
||||
import monster.AllMonsters
|
||||
import monster.AllMonsters.Companion.createAllMonsters
|
||||
import monster.AllMonsters.Companion.createMonstersVector
|
||||
import monster.Monster
|
||||
import monster.Monster.Companion.createInventoryVector
|
||||
import monster.MonsterOffsetArray
|
||||
import monster.Vec3
|
||||
import org.openjdk.jmh.annotations.*
|
||||
import org.openjdk.jmh.infra.Blackhole
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
@State(Scope.Benchmark)
|
||||
@BenchmarkMode(Mode.AverageTime)
|
||||
@OutputTimeUnit(TimeUnit.NANOSECONDS)
|
||||
@Measurement(iterations = 20, time = 1, timeUnit = TimeUnit.NANOSECONDS)
|
||||
open class FlatbufferBenchmark {
|
||||
|
||||
val repetition = 1000000
|
||||
val fbKotlin = FlatBufferBuilder(1024 * repetition)
|
||||
val fbDeserializationKotlin = FlatBufferBuilder(1024 * repetition)
|
||||
val fbJava = com.google.flatbuffers.FlatBufferBuilder(1024 * repetition)
|
||||
val fbDeserializationJava = com.google.flatbuffers.FlatBufferBuilder(1024 * repetition)
|
||||
|
||||
init {
|
||||
populateMosterKotlin(fbDeserializationKotlin)
|
||||
populateMosterJava(fbDeserializationJava)
|
||||
}
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
private fun populateMosterKotlin(fb: FlatBufferBuilder) {
|
||||
fb.clear()
|
||||
val monsterName = fb.createString("MonsterName");
|
||||
val items = ubyteArrayOf(0u, 1u, 2u, 3u, 4u)
|
||||
val inv = createInventoryVector(fb, items)
|
||||
val monsterOffsets: MonsterOffsetArray = MonsterOffsetArray(repetition) {
|
||||
Monster.startMonster(fb)
|
||||
Monster.addName(fb, monsterName)
|
||||
Monster.addPos(fb, Vec3.createVec3(fb, 1.0f, 2.0f, 3.0f))
|
||||
Monster.addHp(fb, 80)
|
||||
Monster.addMana(fb, 150)
|
||||
Monster.addInventory(fb, inv)
|
||||
Monster.addColor(fb, monster.Color.Red)
|
||||
Monster.endMonster(fb)
|
||||
}
|
||||
val monsters = createMonstersVector(fb, monsterOffsets)
|
||||
val allMonsters = createAllMonsters(fb, monsters)
|
||||
fb.finish(allMonsters)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
private fun populateMosterJava(fb: com.google.flatbuffers.FlatBufferBuilder){
|
||||
fb.clear()
|
||||
val monsterName = fb.createString("MonsterName");
|
||||
val inv = JMonster.createInventoryVector(fb, ubyteArrayOf(0u, 1u, 2u, 3u, 4u))
|
||||
val monsters = JAllMonsters.createMonstersVector(fb, IntArray(repetition) {
|
||||
JMonster.startJMonster(fb)
|
||||
JMonster.addName(fb, monsterName)
|
||||
JMonster.addPos(fb, JVec3.createJVec3(fb, 1.0f, 2.0f, 3.0f))
|
||||
JMonster.addHp(fb, 80)
|
||||
JMonster.addMana(fb, 150)
|
||||
JMonster.addInventory(fb, inv)
|
||||
JMonster.addColor(fb, JColor.Red)
|
||||
JMonster.endJMonster(fb)
|
||||
})
|
||||
val allMonsters = JAllMonsters.createJAllMonsters(fb, monsters)
|
||||
fb.finish(allMonsters)
|
||||
}
|
||||
@Benchmark
|
||||
fun monstersSerializationKotlin() {
|
||||
populateMosterKotlin(fbKotlin)
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalUnsignedTypes::class)
|
||||
@Benchmark
|
||||
fun monstersDeserializationKotlin(hole: Blackhole) {
|
||||
val monstersRef = AllMonsters.asRoot(fbDeserializationKotlin.dataBuffer())
|
||||
|
||||
for (i in 0 until monstersRef.monstersLength) {
|
||||
val monster = monstersRef.monsters(i)!!
|
||||
val pos = monster.pos!!
|
||||
hole.consume(monster.name)
|
||||
hole.consume(pos.x)
|
||||
hole.consume(pos.y)
|
||||
hole.consume(pos.z)
|
||||
hole.consume(monster.hp)
|
||||
hole.consume(monster.mana)
|
||||
hole.consume(monster.color)
|
||||
hole.consume(monster.inventory(0).toByte())
|
||||
hole.consume(monster.inventory(1))
|
||||
hole.consume(monster.inventory(2))
|
||||
hole.consume(monster.inventory(3))
|
||||
}
|
||||
}
|
||||
@Benchmark
|
||||
fun monstersSerializationJava() {
|
||||
populateMosterJava(fbJava)
|
||||
}
|
||||
|
||||
@Benchmark
|
||||
fun monstersDeserializationJava(hole: Blackhole) {
|
||||
val monstersRef = JAllMonsters.getRootAsJAllMonsters(fbDeserializationJava.dataBuffer())
|
||||
|
||||
for (i in 0 until monstersRef.monstersLength) {
|
||||
val monster = monstersRef.monsters(i)!!
|
||||
val pos = monster.pos!!
|
||||
hole.consume(monster.name)
|
||||
hole.consume(pos.x)
|
||||
hole.consume(pos.y)
|
||||
hole.consume(pos.z)
|
||||
hole.consume(monster.hp)
|
||||
hole.consume(monster.mana)
|
||||
hole.consume(monster.color)
|
||||
hole.consume(monster.inventory(0))
|
||||
hole.consume(monster.inventory(1))
|
||||
hole.consume(monster.inventory(2))
|
||||
hole.consume(monster.inventory(3))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -13,6 +13,8 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
@file:OptIn(ExperimentalUnsignedTypes::class)
|
||||
|
||||
package com.google.flatbuffers.kotlin.benchmark
|
||||
import com.google.flatbuffers.ArrayReadWriteBuf
|
||||
import com.google.flatbuffers.FlexBuffers
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user